summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--nl_examples/bjt_eb.c4
-rw-r--r--nl_examples/vccs.c2
-rw-r--r--nl_examples/vccs1.c2
-rw-r--r--src/emu/drawgfxm.h9
-rw-r--r--src/emu/emualloc.c10
-rw-r--r--src/emu/machine/netlist.h2
-rw-r--r--src/emu/netlist/analog/nld_fourterm.h6
-rw-r--r--src/emu/netlist/analog/nld_solver.c296
-rw-r--r--src/emu/netlist/analog/nld_solver.h15
-rw-r--r--src/emu/netlist/devices/net_lib.c6
-rw-r--r--src/emu/netlist/devices/nld_system.h2
-rw-r--r--src/emu/netlist/nl_base.c31
-rw-r--r--src/emu/netlist/nl_lists.h306
-rw-r--r--src/emu/netlist/nl_setup.c2
-rw-r--r--src/emu/netlist/nl_setup.h28
-rw-r--r--src/emu/render.c6
-rw-r--r--src/emu/screen.c985
-rw-r--r--src/emu/screen.h114
-rw-r--r--src/emu/ui/ui.c242
19 files changed, 1711 insertions, 357 deletions
diff --git a/nl_examples/bjt_eb.c b/nl_examples/bjt_eb.c
index b6cfab70994..bc35345a44d 100644
--- a/nl_examples/bjt_eb.c
+++ b/nl_examples/bjt_eb.c
@@ -36,7 +36,7 @@ NETLIST_START(bjt)
NET_C(RCE.1, Q.C)
NET_C(RCE.2, GND)
- LOG(logB, Q.B)
- LOG(logC, Q.C)
+ //LOG(logB, Q.B)
+ //LOG(logC, Q.C)
NETLIST_END()
diff --git a/nl_examples/vccs.c b/nl_examples/vccs.c
index 73cefd15fb1..fdad0c04a64 100644
--- a/nl_examples/vccs.c
+++ b/nl_examples/vccs.c
@@ -13,7 +13,7 @@ NETLIST_START(vccs)
PARAM(Solver.ACCURACY, 1e-12)
PARAM(Solver.RESCHED_LOOPS, 10000)
- NETDEV_VCCS(VV)
+ VCCS(VV)
PARAM(VV.G, 100) // typical OP-AMP amplification
RES(R2, 1)
diff --git a/nl_examples/vccs1.c b/nl_examples/vccs1.c
index c1a5725f93c..72db7467d84 100644
--- a/nl_examples/vccs1.c
+++ b/nl_examples/vccs1.c
@@ -13,7 +13,7 @@ NETLIST_START(vccs)
PARAM(Solver.ACCURACY, 1e-6)
- NETDEV_VCCS(VV)
+ VCCS(VV)
PARAM(VV.G, 100000) // typical OP-AMP amplification
RES(R1, 10000)
RES(R2, 1)
diff --git a/src/emu/drawgfxm.h b/src/emu/drawgfxm.h
index fe8c7dae69f..42028b9e38a 100644
--- a/src/emu/drawgfxm.h
+++ b/src/emu/drawgfxm.h
@@ -147,6 +147,15 @@ do
} \
while (0)
+#define PIXEL_OP_REMAP_TRANSPEN_IND16(DEST, PRIORITY, SOURCE) \
+do \
+{ \
+ UINT32 srcdata = (SOURCE); \
+ if (srcdata != transpen) \
+ (DEST) = srcdata + palbase; \
+} \
+while (0) \
+
/*-------------------------------------------------
PIXEL_OP_REBASE_TRANSPEN - render all pixels
except those matching 'transpen', adding
diff --git a/src/emu/emualloc.c b/src/emu/emualloc.c
index 22c0e044fed..43cea456b20 100644
--- a/src/emu/emualloc.c
+++ b/src/emu/emualloc.c
@@ -574,6 +574,16 @@ void memory_entry::report_unfreed()
fprintf(stderr, "--- memory leak warning ---\n");
total += entry->m_size;
fprintf(stderr, "#%06d, nofree %d bytes (%s:%d)\n", (UINT32)entry->m_id, static_cast<UINT32>(entry->m_size), entry->m_file, (int)entry->m_line);
+ char * p = static_cast<char *>(entry->m_base);
+ for (int i = 0; i< entry->m_size; i++)
+ {
+ char c = p[i];
+ if (c>=32 && c<127)
+ fprintf(stderr, "%c", c);
+ else
+ fprintf(stderr, ".");
+ }
+ fprintf(stderr,"\n");
}
release_lock();
diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h
index 9bd77f3ca87..e13954e360a 100644
--- a/src/emu/machine/netlist.h
+++ b/src/emu/machine/netlist.h
@@ -98,7 +98,7 @@
// ----------------------------------------------------------------------------------------
#define NETLIST_MEMREGION(_name) \
- netlist.parse((char *)downcast<netlist_mame_t &>(netlist.netlist()).machine().root_device().memregion(_name)->base());
+ setup.parse((char *)downcast<netlist_mame_t &>(setup.netlist()).machine().root_device().memregion(_name)->base());
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
void _name(const double data, const attotime &time)
diff --git a/src/emu/netlist/analog/nld_fourterm.h b/src/emu/netlist/analog/nld_fourterm.h
index 6ef3c6ce3e9..0f330333bcd 100644
--- a/src/emu/netlist/analog/nld_fourterm.h
+++ b/src/emu/netlist/analog/nld_fourterm.h
@@ -14,13 +14,11 @@
// Macros
// ----------------------------------------------------------------------------------------
-#define NETDEV_VCCS(_name) \
+#define VCCS(_name) \
NET_REGISTER_DEV(VCCS, _name)
-//NETDEV_PARAMI(_name, model, _model)
-#define NETDEV_VCVS(_name) \
+#define VCVS(_name) \
NET_REGISTER_DEV(VCVS, _name)
-//NETDEV_PARAMI(_name, model, _model)
// ----------------------------------------------------------------------------------------
// nld_CCCS
diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c
index 8f9ee0e53b1..7441f5e8057 100644
--- a/src/emu/netlist/analog/nld_solver.c
+++ b/src/emu/netlist/analog/nld_solver.c
@@ -5,6 +5,7 @@
#include "nld_solver.h"
#include "nld_twoterm.h"
+#include "../nl_lists.h"
#if HAS_OPENMP
#include "omp.h"
@@ -19,73 +20,73 @@
ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &aowner)
{
- m_owner = &aowner;
-
- NL_VERBOSE_OUT(("New solver setup\n"));
-
- for (netlist_net_t * const * pn = nets.first(); pn != NULL; pn = nets.next(pn))
- {
- NL_VERBOSE_OUT(("setting up net\n"));
-
- m_nets.add(*pn);
-
- (*pn)->m_solver = this;
-
- for (netlist_core_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next)
- {
- NL_VERBOSE_OUT(("%s %s %d\n", p->name().cstr(), (*pn)->name().cstr(), (int) (*pn)->isRailNet()));
- switch (p->type())
- {
- case netlist_terminal_t::TERMINAL:
- switch (p->netdev().family())
- {
- case netlist_device_t::CAPACITOR:
- if (!m_steps.contains(&p->netdev()))
- m_steps.add(&p->netdev());
- break;
- case netlist_device_t::BJT_EB:
+ m_owner = &aowner;
+
+ NL_VERBOSE_OUT(("New solver setup\n"));
+
+ for (netlist_net_t * const * pn = nets.first(); pn != NULL; pn = nets.next(pn))
+ {
+ NL_VERBOSE_OUT(("setting up net\n"));
+
+ m_nets.add(*pn);
+
+ (*pn)->m_solver = this;
+
+ for (netlist_core_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next)
+ {
+ NL_VERBOSE_OUT(("%s %s %d\n", p->name().cstr(), (*pn)->name().cstr(), (int) (*pn)->isRailNet()));
+ switch (p->type())
+ {
+ case netlist_terminal_t::TERMINAL:
+ switch (p->netdev().family())
+ {
+ case netlist_device_t::CAPACITOR:
+ if (!m_steps.contains(&p->netdev()))
+ m_steps.add(&p->netdev());
+ break;
+ case netlist_device_t::BJT_EB:
case netlist_device_t::DIODE:
- //case netlist_device_t::VCVS:
- case netlist_device_t::BJT_SWITCH:
+ //case netlist_device_t::VCVS:
+ case netlist_device_t::BJT_SWITCH:
NL_VERBOSE_OUT(("found BJT/Diode\n"));
- if (!m_dynamic.contains(&p->netdev()))
- m_dynamic.add(&p->netdev());
- break;
- default:
- break;
- }
- {
- netlist_terminal_t *pterm = static_cast<netlist_terminal_t *>(p);
- if (pterm->m_otherterm->net().isRailNet())
- (*pn)->m_rails.add(pterm);
- else
- (*pn)->m_terms.add(pterm);
- }
- NL_VERBOSE_OUT(("Added terminal\n"));
- break;
- case netlist_terminal_t::INPUT:
- if (!m_inps.contains(p))
- m_inps.add(p);
- NL_VERBOSE_OUT(("Added input\n"));
- break;
- default:
- owner().netlist().error("unhandled element found\n");
- break;
- }
- }
+ if (!m_dynamic.contains(&p->netdev()))
+ m_dynamic.add(&p->netdev());
+ break;
+ default:
+ break;
+ }
+ {
+ netlist_terminal_t *pterm = static_cast<netlist_terminal_t *>(p);
+ if (pterm->m_otherterm->net().isRailNet())
+ (*pn)->m_rails.add(pterm);
+ else
+ (*pn)->m_terms.add(pterm);
+ }
+ NL_VERBOSE_OUT(("Added terminal\n"));
+ break;
+ case netlist_terminal_t::INPUT:
+ if (!m_inps.contains(p))
+ m_inps.add(p);
+ NL_VERBOSE_OUT(("Added input\n"));
+ break;
+ default:
+ owner().netlist().error("unhandled element found\n");
+ break;
+ }
+ }
NL_VERBOSE_OUT(("added net with %d populated connections (%d railnets)\n", (*pn)->m_terms.count(), (*pn)->m_rails.count()));
- }
+ }
}
-ATTR_HOT ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
+ATTR_HOT void netlist_matrix_solver_t::update_inputs()
{
- for (netlist_core_terminal_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
- {
- if ((*p)->net().m_last.Analog != (*p)->net().m_cur.Analog)
- {
- (*p)->netdev().update_dev();
- }
- }
+ for (netlist_core_terminal_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ {
+ if ((*p)->net().m_last.Analog != (*p)->net().m_cur.Analog)
+ {
+ (*p)->netdev().update_dev();
+ }
+ }
for (netlist_core_terminal_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
{
(*p)->net().m_last.Analog = (*p)->net().m_cur.Analog;
@@ -94,7 +95,7 @@ ATTR_HOT ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
}
-ATTR_HOT ATTR_HOT inline void netlist_matrix_solver_t::update_dynamic()
+ATTR_HOT void netlist_matrix_solver_t::update_dynamic()
{
/* update all non-linear devices */
for (netlist_core_device_t * const *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
@@ -109,7 +110,7 @@ ATTR_HOT ATTR_HOT inline void netlist_matrix_solver_t::update_dynamic()
}
}
-void netlist_matrix_solver_t::schedule()
+ATTR_HOT void netlist_matrix_solver_t::schedule()
{
if (!solve())
{
@@ -131,14 +132,14 @@ ATTR_COLD void netlist_matrix_solver_t::reset()
m_last_step = netlist_time::zero;
}
-ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
+ATTR_HOT void netlist_matrix_solver_t::step(const netlist_time delta)
{
const double dd = delta.as_double();
for (int k=0; k < m_steps.count(); k++)
m_steps[k]->step_time(dd);
}
-ATTR_HOT inline bool netlist_matrix_solver_t::solve()
+ATTR_HOT bool netlist_matrix_solver_t::solve()
{
int resched_cnt = 0;
@@ -162,14 +163,14 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve()
update_dynamic();
this_resched = solve_non_dynamic();
resched_cnt += this_resched;
- } while (this_resched > 1 && resched_cnt < m_resched_loops);
+ } while (this_resched > 1 && resched_cnt < m_params.m_resched_loops);
}
else
{
resched_cnt = solve_non_dynamic();
//printf("resched_cnt %d %d\n", resched_cnt, m_resched_loops);
}
- return (resched_cnt >= m_resched_loops);
+ return (resched_cnt >= m_params.m_resched_loops);
}
// ----------------------------------------------------------------------------------------
@@ -240,7 +241,7 @@ ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::setup(netlist_ne
}
template <int m_N, int _storage_N>
-ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE(
+ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE(
double (* RESTRICT A)[_storage_N],
double (* RESTRICT RHS))
{
@@ -282,7 +283,7 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE(
}
template <int m_N, int _storage_N>
-ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::gauss_LE(
+ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::gauss_LE(
double (* RESTRICT A)[_storage_N],
double (* RESTRICT RHS),
double (* RESTRICT x))
@@ -324,11 +325,14 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::gauss_LE(
{
double f1 = A[j][i] * f;
- for (int k = i; k < N(); k++)
+ if (f1 != 0.0)
{
- A[j][k] -= A[i][k] * f1;
+ for (int k = i; k < N(); k++)
+ {
+ A[j][k] -= A[i][k] * f1;
+ }
+ RHS[j] -= RHS[i] * f1;
}
- RHS[j] -= RHS[i] * f1;
}
}
/* back substitution */
@@ -353,7 +357,7 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::gauss_LE(
}
template <int m_N, int _storage_N>
-ATTR_HOT inline double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta(
+ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta(
const double (* RESTRICT RHS),
const double (* RESTRICT V))
{
@@ -370,7 +374,7 @@ ATTR_HOT inline double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta(
}
template <int m_N, int _storage_N>
-ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::store(
+ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::store(
const double (* RESTRICT RHS),
const double (* RESTRICT V))
{
@@ -404,7 +408,7 @@ ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(
store(RHS, new_v);
- if (err > this->m_accuracy * this->m_accuracy)
+ if (err > this->m_params.m_accuracy * this->m_params.m_accuracy)
{
return 2;
}
@@ -419,7 +423,7 @@ ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(
// netlist_matrix_solver - Direct1
// ----------------------------------------------------------------------------------------
-ATTR_HOT inline int netlist_matrix_solver_direct1_t::solve_non_dynamic()
+ATTR_HOT int netlist_matrix_solver_direct1_t::solve_non_dynamic()
{
#if 1
@@ -454,7 +458,7 @@ ATTR_HOT inline int netlist_matrix_solver_direct1_t::solve_non_dynamic()
net->m_cur.Analog = net->m_new.Analog = new_val;
- if (is_dynamic() && (cerr > m_accuracy * m_accuracy))
+ if (is_dynamic() && (cerr > m_params.m_accuracy * m_params.m_accuracy))
{
return 2;
}
@@ -491,7 +495,7 @@ ATTR_HOT int netlist_matrix_solver_direct2_t::solve_non_dynamic()
{
double err = delta(RHS, new_val);
store(RHS, new_val);
- if (err > m_accuracy * m_accuracy)
+ if (err > m_params.m_accuracy * m_params.m_accuracy)
return 2;
else
return 1;
@@ -505,7 +509,7 @@ ATTR_HOT int netlist_matrix_solver_direct2_t::solve_non_dynamic()
// ----------------------------------------------------------------------------------------
template <int m_N, int _storage_N>
-ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::solve_non_dynamic()
+ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::solve_non_dynamic()
{
bool resched = false;
@@ -547,7 +551,7 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::solve
RHS_t += terms[i]->m_Idr;
}
- gabs_t *= m_convergence_factor;
+ gabs_t *= m_params.m_convergence_factor;
if (gabs_t > gtot_t)
{
// Actually 1.0 / g_tot * g_tot / (gtot_t + gabs_t)
@@ -589,13 +593,13 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::solve
net->m_cur.Analog = net->m_new.Analog = new_val;
}
- if (resched || cerr / m_nets.count() > m_accuracy * m_accuracy)
+ if (resched || cerr / m_nets.count() > m_params.m_accuracy * m_params.m_accuracy)
{
resched = true;
//last_resched_net = net;
}
resched_cnt++;
- } while (resched && (resched_cnt < m_resched_loops / 3 ));
+ } while (resched && (resched_cnt < m_params.m_resched_loops / 3 ));
if (resched)
return m_fallback.solve_non_dynamic();
@@ -611,64 +615,64 @@ typedef netlist_net_t::list_t *net_groups_t;
ATTR_COLD static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
{
- if (net->isRailNet())
- return true;
- for (int i = 0; i <= cur_group; i++)
- {
- if (groups[i].contains(net))
- return true;
- }
- return false;
+ if (net->isRailNet())
+ return true;
+ for (int i = 0; i <= cur_group; i++)
+ {
+ if (groups[i].contains(net))
+ return true;
+ }
+ return false;
}
ATTR_COLD static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
{
- if (net->m_head == NULL)
- return;
+ if (net->m_head == NULL)
+ return;
/* add the net */
- SOLVER_VERBOSE_OUT(("add %d - %s\n", cur_group, net->name().cstr()));
- groups[cur_group].add(net);
- for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next)
- {
- SOLVER_VERBOSE_OUT(("terminal %s\n", p->name().cstr()));
- if (p->isType(netlist_terminal_t::TERMINAL))
- {
- SOLVER_VERBOSE_OUT(("isterminal\n"));
- netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
- netlist_net_t *other_net = &pt->m_otherterm->net();
- if (!already_processed(groups, cur_group, other_net))
- process_net(groups, cur_group, other_net);
- }
- }
+ SOLVER_VERBOSE_OUT(("add %d - %s\n", cur_group, net->name().cstr()));
+ groups[cur_group].add(net);
+ for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next)
+ {
+ SOLVER_VERBOSE_OUT(("terminal %s\n", p->name().cstr()));
+ if (p->isType(netlist_terminal_t::TERMINAL))
+ {
+ SOLVER_VERBOSE_OUT(("isterminal\n"));
+ netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
+ netlist_net_t *other_net = &pt->m_otherterm->net();
+ if (!already_processed(groups, cur_group, other_net))
+ process_net(groups, cur_group, other_net);
+ }
+ }
}
NETLIB_START(solver)
{
- register_output("Q_sync", m_Q_sync);
- register_output("Q_step", m_Q_step);
- //register_input("FB", m_feedback);
+ register_output("Q_sync", m_Q_sync);
+ register_output("Q_step", m_Q_step);
+ //register_input("FB", m_feedback);
- register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(5).as_double());
- m_nt_sync_delay = m_sync_delay.Value();
+ register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(5).as_double());
+ m_nt_sync_delay = m_sync_delay.Value();
- register_param("FREQ", m_freq, 48000.0);
- m_inc = netlist_time::from_hz(m_freq.Value());
+ register_param("FREQ", m_freq, 48000.0);
+ m_inc = netlist_time::from_hz(m_freq.Value());
- register_param("ACCURACY", m_accuracy, 1e-7);
- register_param("CONVERG", m_convergence, 0.3);
+ register_param("ACCURACY", m_accuracy, 1e-7);
+ register_param("CONVERG", m_convergence, 0.3);
register_param("RESCHED_LOOPS", m_resched_loops, 35);
register_param("PARALLEL", m_parallel, 0);
- // internal staff
+ // internal staff
- register_input("FB_sync", m_fb_sync);
- register_input("FB_step", m_fb_step);
+ register_input("FB_sync", m_fb_sync);
+ register_input("FB_step", m_fb_step);
- connect(m_fb_sync, m_Q_sync);
- connect(m_fb_step, m_Q_step);
+ connect(m_fb_sync, m_Q_sync);
+ connect(m_fb_step, m_Q_step);
- save(NAME(m_last_step));
+ save(NAME(m_last_step));
}
@@ -682,26 +686,26 @@ NETLIB_RESET(solver)
NETLIB_UPDATE_PARAM(solver)
{
- m_inc = netlist_time::from_hz(m_freq.Value());
+ m_inc = netlist_time::from_hz(m_freq.Value());
}
NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
{
- netlist_matrix_solver_t * const *e = m_mat_solvers.first();
- while (e != NULL)
- {
- netlist_matrix_solver_t * const *en = m_mat_solvers.next(e);
- delete *e;
- e = en;
- }
+ netlist_matrix_solver_t * const *e = m_mat_solvers.first();
+ while (e != NULL)
+ {
+ netlist_matrix_solver_t * const *en = m_mat_solvers.next(e);
+ delete *e;
+ e = en;
+ }
}
NETLIB_UPDATE(solver)
{
- netlist_time now = netlist().time();
- netlist_time delta = now - m_last_step;
- bool do_full = false;
+ netlist_time now = netlist().time();
+ netlist_time delta = now - m_last_step;
+ bool do_full = false;
bool global_resched = false;
bool this_resched[100];
int t_cnt = m_mat_solvers.count();
@@ -749,17 +753,17 @@ NETLIB_UPDATE(solver)
}
}
- if (global_resched)
- {
- netlist().warning("Gobal reschedule .. Consider increasing RESCHED_LOOPS");
- schedule();
- }
- else
- {
- /* step circuit */
- if (!m_Q_step.net().is_queued())
- m_Q_step.net().push_to_queue(m_inc);
- }
+ if (global_resched)
+ {
+ netlist().warning("Gobal reschedule .. Consider increasing RESCHED_LOOPS");
+ schedule();
+ }
+ else
+ {
+ /* step circuit */
+ if (!m_Q_step.net().is_queued())
+ m_Q_step.net().push_to_queue(m_inc);
+ }
}
@@ -838,9 +842,9 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
break;
}
- ms->m_accuracy = m_accuracy.Value();
- ms->m_convergence_factor = m_convergence.Value();
- ms->m_resched_loops = m_resched_loops.Value();
+ ms->m_params.m_accuracy = m_accuracy.Value();
+ ms->m_params.m_convergence_factor = m_convergence.Value();
+ ms->m_params.m_resched_loops = m_resched_loops.Value();
ms->setup(groups[i], *this);
m_mat_solvers.add(ms);
SOLVER_VERBOSE_OUT(("%d ==> %d nets %s\n", i, groups[i].count(), (*groups[i].first())->m_head->name().cstr()));
diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h
index 0618a5f6f0b..09cbede5b6d 100644
--- a/src/emu/netlist/analog/nld_solver.h
+++ b/src/emu/netlist/analog/nld_solver.h
@@ -25,6 +25,13 @@ class NETLIB_NAME(solver);
/* FIXME: these should become proper devices */
+struct netlist_solver_parameters_t
+{
+ double m_accuracy;
+ double m_convergence_factor;
+ int m_resched_loops;
+};
+
class netlist_matrix_solver_t
{
public:
@@ -53,9 +60,7 @@ public:
ATTR_HOT inline const NETLIB_NAME(solver) &owner() const;
ATTR_COLD virtual void reset();
- double m_accuracy;
- double m_convergence_factor;
- int m_resched_loops;
+ netlist_solver_parameters_t m_params;
protected:
netlist_net_t::list_t m_nets;
@@ -120,9 +125,7 @@ public:
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
{
netlist_matrix_solver_t::setup(nets, owner);
- m_fallback.m_accuracy = m_accuracy;
- m_fallback.m_convergence_factor = m_convergence_factor;
- m_fallback.m_resched_loops = m_resched_loops;
+ m_fallback.m_params = m_params;
m_fallback.setup(nets, owner);
}
diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c
index 459fcd9d85e..1774d014923 100644
--- a/src/emu/netlist/devices/net_lib.c
+++ b/src/emu/netlist/devices/net_lib.c
@@ -78,8 +78,8 @@ void netlist_factory_t::initialize()
ENTRY(POT, POT, "R")
ENTRY(C, CAP, "C")
ENTRY(D, DIODE, "model")
- ENTRY(VCVS, NETDEV_VCVS, "-")
- ENTRY(VCCS, NETDEV_VCCS, "-")
+ ENTRY(VCVS, VCVS, "-") // FIXME: STD parameters ?
+ ENTRY(VCCS, VCCS, "-")
ENTRY(QBJT_EB, QBJT_EB, "model")
ENTRY(QBJT_switch, QBJT_SW, "model")
ENTRY(ttl_input, TTL_INPUT, "IN")
@@ -89,7 +89,7 @@ void netlist_factory_t::initialize()
ENTRY(clock, CLOCK, "FREQ")
ENTRY(mainclock, MAINCLOCK, "FREQ")
ENTRY(solver, SOLVER, "FREQ")
- ENTRY(gnd, NETDEV_GND, "-")
+ ENTRY(gnd, GND, "-")
ENTRY(switch2, SWITCH2, "+i1,i2")
ENTRY(nicRSFF, NETDEV_RSFF, "+S,R")
ENTRY(7400, TTL_7400_NAND, "+A,B")
diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h
index cf1588e3c5c..5bb2b4154f2 100644
--- a/src/emu/netlist/devices/nld_system.h
+++ b/src/emu/netlist/devices/nld_system.h
@@ -33,7 +33,7 @@
NET_REGISTER_DEV(clock, _name) \
PARAM(_name.FREQ, _freq)
-#define NETDEV_GND() \
+#define GND() \
NET_REGISTER_DEV(gnd, GND)
// ----------------------------------------------------------------------------------------
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c
index d4828773eec..e3053ca8ff5 100644
--- a/src/emu/netlist/nl_base.c
+++ b/src/emu/netlist/nl_base.c
@@ -240,17 +240,17 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta)
} else {
#if 0
- netlist_net_t &mcQ = m_mainclock->m_Q.net();
+ netlist_net_t &mc_net = m_mainclock->m_Q.net();
const netlist_time inc = m_mainclock->m_inc;
while (m_time < m_stop)
{
if (m_queue.is_not_empty())
{
- while (m_queue.peek().time() > mcQ.time())
+ while (m_queue.peek().time() > mc_net.time())
{
- m_time = mcQ.time();
- NETLIB_NAME(mainclock)::mc_update(mcQ, m_time + inc);
+ m_time = mc_net.time();
+ NETLIB_NAME(mainclock)::mc_update(mc_net, m_time + inc);
}
const netlist_queue_t::entry_t &e = m_queue.pop();
@@ -258,8 +258,8 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta)
e.object()->update_devs();
} else {
- m_time = mcQ.time();
- NETLIB_NAME(mainclock)::mc_update(mcQ, m_time + inc);
+ m_time = mc_net.time();
+ NETLIB_NAME(mainclock)::mc_update(mc_net, m_time + inc);
}
if (FATAL_ERROR_AFTER_NS)
if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS))
@@ -268,9 +268,9 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta)
add_to_stat(m_perf_out_processed, 1);
}
#else
- netlist_net_t &mcQ = m_mainclock->m_Q.net();
+ netlist_net_t &mc_net = m_mainclock->m_Q.net();
const netlist_time inc = m_mainclock->m_inc;
- netlist_time mc_time = mcQ.time();
+ netlist_time mc_time = mc_net.time();
netlist_time cur_time = m_time;
while (cur_time < m_stop)
@@ -282,7 +282,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta)
cur_time = mc_time;
mc_time += inc;
m_time = cur_time;
- NETLIB_NAME(mainclock)::mc_update(mcQ);
+ NETLIB_NAME(mainclock)::mc_update(mc_net);
}
const netlist_queue_t::entry_t &e = m_queue.pop();
@@ -293,7 +293,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta)
cur_time = mc_time;
mc_time += inc;
m_time = cur_time;
- NETLIB_NAME(mainclock)::mc_update(mcQ);
+ NETLIB_NAME(mainclock)::mc_update(mc_net);
}
if (FATAL_ERROR_AFTER_NS)
if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS))
@@ -301,7 +301,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta)
add_to_stat(m_perf_out_processed, 1);
}
- mcQ.set_time(mc_time);
+ mc_net.set_time(mc_time);
m_time = cur_time;
#endif
}
@@ -825,20 +825,11 @@ ATTR_COLD double netlist_param_model_t::model_value(const pstring &entity, const
// mainclock
// ----------------------------------------------------------------------------------------
-#if 0
-ATTR_HOT inline void NETLIB_NAME(mainclock)::mc_update(netlist_net_t &net, const netlist_time curtime)
-{
- net.m_new.Q ^= 1;
- net.set_time(curtime);
- net.update_devs();
-}
-#else
ATTR_HOT inline void NETLIB_NAME(mainclock)::mc_update(netlist_net_t &net)
{
net.m_new.Q ^= 1;
net.update_devs();
}
-#endif
NETLIB_START(mainclock)
{
diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h
index 256f9f340b8..57842dd7883 100644
--- a/src/emu/netlist/nl_lists.h
+++ b/src/emu/netlist/nl_lists.h
@@ -5,6 +5,8 @@
*
*/
+#pragma once
+
#ifndef NLLISTS_H_
#define NLLISTS_H_
@@ -20,78 +22,78 @@ class netlist_list_t
{
public:
- ATTR_COLD netlist_list_t(int numElements = _NumElem)
- {
- m_num_elements = numElements;
- m_list = new _ListClass[m_num_elements];
+ ATTR_COLD netlist_list_t(int numElements = _NumElem)
+ {
+ m_num_elements = numElements;
+ m_list = new _ListClass[m_num_elements];
m_count = 0;
- }
-
- ATTR_COLD netlist_list_t(const netlist_list_t &rhs)
- {
- m_num_elements = rhs.capacity();
- m_list = new _ListClass[m_num_elements];
- m_count = 0;
- for (int i=0; i<rhs.count(); i++)
- {
- this->add(rhs[i]);
- }
- }
-
- ATTR_COLD netlist_list_t &operator=(const netlist_list_t &rhs)
- {
- this->reset();
- for (int i=0; i<rhs.count(); i++)
- {
- this->add(rhs[i]);
- }
- return *this;
- }
-
-
- ATTR_COLD ~netlist_list_t()
- {
- delete[] m_list;
- }
-
- ATTR_HOT inline void add(const _ListClass &elem)
- {
- if (m_count >= m_num_elements)
- resize(m_num_elements * 2);
-
- m_list[m_count++] = elem;
- }
-
- ATTR_HOT inline void resize(const int new_size)
- {
- int cnt = count();
- _ListClass *m_new = new _ListClass[new_size];
- _ListClass *pd = m_new;
-
- for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++)
- *pd = *ps;
- delete[] m_list;
- m_list = m_new;
- m_count = cnt;
- m_num_elements = new_size;
- }
-
- ATTR_HOT inline void remove(const _ListClass &elem)
- {
- for (int i = 0; i < m_count; i++)
- {
- if (m_list[i] == elem)
- {
- m_count --;
- while (i < m_count)
- {
- m_list[i] = m_list[i+1];
- i++;
- }
- return;
- }
- }
- }
+ }
+
+ ATTR_COLD netlist_list_t(const netlist_list_t &rhs)
+ {
+ m_num_elements = rhs.capacity();
+ m_list = new _ListClass[m_num_elements];
+ m_count = 0;
+ for (int i=0; i<rhs.count(); i++)
+ {
+ this->add(rhs[i]);
+ }
+ }
+
+ ATTR_COLD netlist_list_t &operator=(const netlist_list_t &rhs)
+ {
+ this->reset();
+ for (int i=0; i<rhs.count(); i++)
+ {
+ this->add(rhs[i]);
+ }
+ return *this;
+ }
+
+
+ ATTR_COLD ~netlist_list_t()
+ {
+ delete[] m_list;
+ }
+
+ ATTR_HOT inline void add(const _ListClass &elem)
+ {
+ if (m_count >= m_num_elements)
+ resize(m_num_elements * 2);
+
+ m_list[m_count++] = elem;
+ }
+
+ ATTR_HOT inline void resize(const int new_size)
+ {
+ int cnt = count();
+ _ListClass *m_new = new _ListClass[new_size];
+ _ListClass *pd = m_new;
+
+ for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++)
+ *pd = *ps;
+ delete[] m_list;
+ m_list = m_new;
+ m_count = cnt;
+ m_num_elements = new_size;
+ }
+
+ ATTR_HOT inline void remove(const _ListClass &elem)
+ {
+ for (int i = 0; i < m_count; i++)
+ {
+ if (m_list[i] == elem)
+ {
+ m_count --;
+ while (i < m_count)
+ {
+ m_list[i] = m_list[i+1];
+ i++;
+ }
+ return;
+ }
+ }
+ }
ATTR_HOT inline void remove_at(const int pos)
{
@@ -103,15 +105,15 @@ public:
}
}
- ATTR_HOT inline bool contains(const _ListClass &elem) const
- {
- for (_ListClass *i = m_list; i < m_list + m_count; i++)
- {
- if (*i == elem)
- return true;
- }
- return false;
- }
+ ATTR_HOT inline bool contains(const _ListClass &elem) const
+ {
+ for (_ListClass *i = m_list; i < m_list + m_count; i++)
+ {
+ if (*i == elem)
+ return true;
+ }
+ return false;
+ }
ATTR_HOT inline int indexof(const _ListClass &elem) const
{
@@ -123,30 +125,30 @@ public:
return -1;
}
- ATTR_HOT inline const _ListClass *first() const { return ((m_count > 0) ? &m_list[0] : NULL ); }
- ATTR_HOT inline const _ListClass *next(const _ListClass *lc) const { return ((lc < last()) ? lc + 1 : NULL ); }
- ATTR_HOT inline const _ListClass *last() const { return &m_list[m_count -1]; }
- ATTR_HOT inline int count() const { return m_count; }
- ATTR_HOT inline bool empty() const { return (m_count == 0); }
- ATTR_HOT inline void reset() { m_count = 0; }
+ ATTR_HOT inline const _ListClass *first() const { return ((m_count > 0) ? &m_list[0] : NULL ); }
+ ATTR_HOT inline const _ListClass *next(const _ListClass *lc) const { return ((lc < last()) ? lc + 1 : NULL ); }
+ ATTR_HOT inline const _ListClass *last() const { return &m_list[m_count -1]; }
+ ATTR_HOT inline int count() const { return m_count; }
+ ATTR_HOT inline bool empty() const { return (m_count == 0); }
+ ATTR_HOT inline void reset() { m_count = 0; }
ATTR_HOT inline int capacity() const { return m_num_elements; }
- ATTR_COLD void reset_and_free()
- {
- for (_ListClass *i = m_list; i < m_list + m_count; i++)
- {
- delete *i;
- }
- reset();
- }
+ ATTR_COLD void reset_and_free()
+ {
+ for (_ListClass *i = m_list; i < m_list + m_count; i++)
+ {
+ delete *i;
+ }
+ reset();
+ }
- ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index]; }
- ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index]; }
+ ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index]; }
+ ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index]; }
private:
- int m_count;
- _ListClass * m_list;
- int m_num_elements;
+ int m_count;
+ _ListClass * m_list;
+ int m_num_elements;
};
// ----------------------------------------------------------------------------------------
@@ -156,35 +158,35 @@ private:
template <class _Element, class _Time, int _Size>
class netlist_timed_queue
{
- NETLIST_PREVENT_COPYING(netlist_timed_queue)
+ NETLIST_PREVENT_COPYING(netlist_timed_queue)
public:
- struct entry_t
- {
- public:
- ATTR_HOT inline entry_t()
- : m_time(), m_object() {}
- ATTR_HOT inline entry_t(const _Time atime, const _Element elem) : m_time(atime), m_object(elem) {}
- ATTR_HOT inline const _Time time() const { return m_time; }
- ATTR_HOT inline const _Element object() const { return m_object; }
-
- private:
- _Time m_time;
- _Element m_object;
- };
-
- netlist_timed_queue()
- {
- //m_list = global_alloc_array(entry_t, SIZE);
- clear();
- }
-
- ATTR_HOT inline int capacity() const { return _Size; }
- ATTR_HOT inline bool is_empty() const { return (m_end == &m_list[0]); }
- ATTR_HOT inline bool is_not_empty() const { return (m_end > &m_list[0]); }
-
- ATTR_HOT ATTR_ALIGN inline void push(const entry_t &e)
- {
+ struct entry_t
+ {
+ public:
+ ATTR_HOT inline entry_t()
+ : m_time(), m_object() {}
+ ATTR_HOT inline entry_t(const _Time atime, const _Element elem) : m_time(atime), m_object(elem) {}
+ ATTR_HOT inline const _Time time() const { return m_time; }
+ ATTR_HOT inline const _Element object() const { return m_object; }
+
+ private:
+ _Time m_time;
+ _Element m_object;
+ };
+
+ netlist_timed_queue()
+ {
+ //m_list = global_alloc_array(entry_t, SIZE);
+ clear();
+ }
+
+ ATTR_HOT inline int capacity() const { return _Size; }
+ ATTR_HOT inline bool is_empty() const { return (m_end == &m_list[0]); }
+ ATTR_HOT inline bool is_not_empty() const { return (m_end > &m_list[0]); }
+
+ ATTR_HOT ATTR_ALIGN inline void push(const entry_t &e)
+ {
entry_t * RESTRICT i = m_end++;
while ((i > &m_list[0]) && (e.time() > (i - 1)->time()) )
{
@@ -194,43 +196,43 @@ public:
}
*i = e;
inc_stat(m_prof_sort);
- assert(m_end - m_list < _Size);
- }
+ assert(m_end - m_list < _Size);
+ }
- ATTR_HOT inline const entry_t &pop()
- {
- return *--m_end;
- }
+ ATTR_HOT inline const entry_t &pop()
+ {
+ return *--m_end;
+ }
- ATTR_HOT inline const entry_t &peek() const
- {
- return *(m_end-1);
- }
+ ATTR_HOT inline const entry_t &peek() const
+ {
+ return *(m_end-1);
+ }
- ATTR_COLD void clear()
- {
- m_end = &m_list[0];
- }
+ ATTR_COLD void clear()
+ {
+ m_end = &m_list[0];
+ }
- // save state support & mame disasm
+ // save state support & mame disasm
- ATTR_COLD inline const entry_t *listptr() const { return &m_list[0]; }
- ATTR_HOT inline int count() const { return m_end - m_list; }
- ATTR_HOT inline const entry_t & operator[](const int & index) const { return m_list[index]; }
+ ATTR_COLD inline const entry_t *listptr() const { return &m_list[0]; }
+ ATTR_HOT inline int count() const { return m_end - m_list; }
+ ATTR_HOT inline const entry_t & operator[](const int & index) const { return m_list[index]; }
#if (NL_KEEP_STATISTICS)
- // profiling
- INT32 m_prof_start;
- INT32 m_prof_end;
- INT32 m_prof_sortmove;
- INT32 m_prof_sort;
+ // profiling
+ INT32 m_prof_start;
+ INT32 m_prof_end;
+ INT32 m_prof_sortmove;
+ INT32 m_prof_sort;
#endif
private:
- entry_t * RESTRICT m_end;
- //entry_t *m_list;
- entry_t m_list[_Size];
+ entry_t * RESTRICT m_end;
+ //entry_t *m_list;
+ entry_t m_list[_Size];
};
diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c
index 23d705b6551..35cccd3ad82 100644
--- a/src/emu/netlist/nl_setup.c
+++ b/src/emu/netlist/nl_setup.c
@@ -16,7 +16,7 @@
static NETLIST_START(base)
TTL_INPUT(ttlhigh, 1)
TTL_INPUT(ttllow, 0)
- NETDEV_GND()
+ GND()
NET_MODEL(".model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
NET_MODEL(".model 1N4148 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h
index 5de2022b95f..370f51740a5 100644
--- a/src/emu/netlist/nl_setup.h
+++ b/src/emu/netlist/nl_setup.h
@@ -19,49 +19,49 @@
#define NET_STR(_x) # _x
#define NET_MODEL(_model) \
- netlist.register_model(_model);
+ setup.register_model(_model);
#define ALIAS(_alias, _name) \
- netlist.register_alias(# _alias, # _name);
+ setup.register_alias(# _alias, # _name);
-#define NET_NEW(_type) netlist.factory().new_device_by_classname(NETLIB_NAME_STR(_type), netlist)
+#define NET_NEW(_type) setup.factory().new_device_by_classname(NETLIB_NAME_STR(_type), setup)
#define NET_REGISTER_DEV(_type, _name) \
- netlist.register_dev(NET_NEW(_type), # _name);
+ setup.register_dev(NET_NEW(_type), # _name);
#define NET_REMOVE_DEV(_name) \
- netlist.remove_dev(# _name);
+ setup.remove_dev(# _name);
#define NET_REGISTER_SIGNAL(_type, _name) \
NET_REGISTER_DEV(_type ## _ ## sig, _name)
#define NET_CONNECT(_name, _input, _output) \
- netlist.register_link(# _name "." # _input, # _output);
+ setup.register_link(# _name "." # _input, # _output);
#define NET_C(_input, _output) \
- netlist.register_link(NET_STR(_input) , NET_STR(_output));
+ setup.register_link(NET_STR(_input) , NET_STR(_output));
#define PARAM(_name, _val) \
- netlist.register_param(# _name, _val);
+ setup.register_param(# _name, _val);
#define NETDEV_PARAMI(_name, _param, _val) \
- netlist.register_param(# _name "." # _param, _val);
+ setup.register_param(# _name "." # _param, _val);
#define NETLIST_NAME(_name) netlist ## _ ## _name
#define NETLIST_START(_name) \
-ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &netlist) \
+ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &setup) \
{
#define NETLIST_END() }
#define INCLUDE(_name) \
- NETLIST_NAME(_name)(netlist);
+ NETLIST_NAME(_name)(setup);
#define SUBMODEL(_name, _model) \
- netlist.namespace_push(# _name); \
- NETLIST_NAME(_model)(netlist); \
- netlist.namespace_pop();
+ setup.namespace_push(# _name); \
+ NETLIST_NAME(_model)(setup); \
+ setup.namespace_pop();
// ----------------------------------------------------------------------------------------
// FIXME: Clean this up
diff --git a/src/emu/render.c b/src/emu/render.c
index 57b31a12a70..bff2c367295 100644
--- a/src/emu/render.c
+++ b/src/emu/render.c
@@ -401,7 +401,7 @@ void render_texture::release()
void render_texture::set_bitmap(bitmap_t &bitmap, const rectangle &sbounds, texture_format format)
{
- assert(bitmap.cliprect().contains(sbounds));
+ //assert(bitmap.cliprect().contains(sbounds));
// ensure we have a valid palette for palettized modes
if (format == TEXFORMAT_PALETTE16 || format == TEXFORMAT_PALETTEA16)
@@ -1338,7 +1338,10 @@ render_primitive_list &render_target::get_primitives()
// if there is no associated element, it must be a screen element
if (curitem->screen() != NULL)
+ {
add_container_primitives(list, item_xform, curitem->screen()->container(), blendmode);
+ curitem->screen()->set_render_size((int) item_xform.xscale, (int) item_xform.yscale);
+ }
else
add_element_primitives(list, item_xform, *curitem->element(), curitem->state(), blendmode);
}
@@ -1701,7 +1704,6 @@ void render_target::add_container_primitives(render_primitive_list &list, const
prim->bounds.x1 = render_round_nearest(container_xform.xoffs + bounds.x1 * container_xform.xscale);
prim->bounds.y1 = render_round_nearest(container_xform.yoffs + bounds.y1 * container_xform.yscale);
}
-
// compute the color of the primitive
prim->color.r = container_xform.color.r * curitem->color().r;
prim->color.g = container_xform.color.g * curitem->color().g;
diff --git a/src/emu/screen.c b/src/emu/screen.c
index 4acde133dab..b3327eb20ad 100644
--- a/src/emu/screen.c
+++ b/src/emu/screen.c
@@ -22,6 +22,7 @@
#define VERBOSE (0)
#define LOG_PARTIAL_UPDATES(x) do { if (VERBOSE) logerror x; } while (0)
+//#define USE_MONITOR (1)
//**************************************************************************
@@ -77,6 +78,10 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
m_unique_id = m_id_counter;
m_id_counter++;
memset(m_texture, 0, sizeof(m_texture));
+
+ m_render_width = m_width;
+ m_render_height = m_height;
+
}
@@ -446,6 +451,13 @@ void screen_device::configure(int width, int height, const rectangle &visarea, a
machine().video().update_refresh_speed();
}
+const rectangle &screen_device::visible_area() const
+{
+ if (0 && m_crt.type() != crt_monitor::PASSTHROUGHX)
+ return m_crt.get_visible();
+ else
+ return m_visarea;
+}
//-------------------------------------------------
// reset_origin - reset the timing such that the
@@ -494,9 +506,20 @@ void screen_device::realloc_screen_bitmaps()
for (auto_bitmap_item *item = m_auto_bitmap_list.first(); item != NULL; item = item->next())
item->m_bitmap.resize(effwidth, effheight);
- // re-set up textures
+ // set up textures
+
+ if (m_crt.type() != crt_monitor::PASSTHROUGHX)
+ {
+ m_crt.resize(m_width, m_height);
+ rectangle crt_vis = m_crt.get_visible();
+ m_texture[0]->set_bitmap(m_crt.final_bitmap(0), crt_vis, TEXFORMAT_RGB32);
+ m_texture[1]->set_bitmap(m_crt.final_bitmap(1), crt_vis, TEXFORMAT_RGB32);
+ }
+ else
+ {
m_texture[0]->set_bitmap(m_bitmap[0], m_visarea, m_bitmap[0].texformat());
m_texture[1]->set_bitmap(m_bitmap[1], m_visarea, m_bitmap[1].texformat());
+ }
}
@@ -823,10 +846,25 @@ bool screen_device::update_quads()
// only update if empty and not a vector game; otherwise assume the driver did it directly
if (m_type != SCREEN_TYPE_VECTOR && (machine().config().m_video_attributes & VIDEO_SELF_RENDER) == 0)
{
+ if (m_crt.type() != crt_monitor::PASSTHROUGHX)
+ {
+ m_crt.resize(m_render_width, m_render_height);
+ m_crt.process(machine(), m_bitmap[m_curbitmap], m_curbitmap, m_visarea);
+ }
+
// if we're not skipping the frame and if the screen actually changed, then update the texture
if (!machine().video().skip_this_frame() && m_changed)
{
- m_texture[m_curbitmap]->set_bitmap(m_bitmap[m_curbitmap], m_visarea, m_bitmap[m_curbitmap].texformat());
+ if (m_crt.type() != crt_monitor::PASSTHROUGHX)
+ {
+ rectangle fixedvis = m_crt.get_visible();
+ m_texture[m_curbitmap]->set_bitmap(m_crt.final_bitmap(m_curbitmap), fixedvis, TEXFORMAT_RGB32);
+ }
+ else
+ {
+ m_texture[m_curbitmap]->set_bitmap(m_bitmap[m_curbitmap], m_visarea, m_bitmap[m_curbitmap].texformat());
+ }
+
m_curtexture = m_curbitmap;
m_curbitmap = 1 - m_curbitmap;
}
@@ -1010,3 +1048,946 @@ void screen_device::load_effect_overlay(const char *filename)
else
mame_printf_warning("Unable to load effect PNG file '%s'\n", fullname.cstr());
}
+
+void screen_device::set_render_size(int width, int height)
+{
+ if (width<=4096 && height <=4096)
+ {
+ m_render_width = width;
+ m_render_height = height;
+ }
+}
+
+//-------------------------------------------------
+// The 3x3 matrix class
+//-------------------------------------------------
+
+class vec3d
+{
+ friend class mat33d;
+public:
+ vec3d()
+ {
+ }
+ vec3d(double a0, double a1, double a2)
+ {
+ a[0] = a0;
+ a[1] = a1;
+ a[2] = a2;
+ }
+ void set(double a0, double a1, double a2)
+ {
+ a[0] = a0;
+ a[1] = a1;
+ a[2] = a2;
+ }
+ double elem(int row)
+ {
+ return a[row];
+ }
+
+ void dump(void)
+ {
+ //printf("%10.4f %10.4f %10.4f\n", a[0], a[1], a[2]);
+ }
+protected:
+ double a[3];
+};
+
+class mat33d
+{
+public:
+
+ void setConst(double val)
+ {
+ for (int i=0;i<3;i++)
+ for (int j=0;j<3; j++)
+ a[i][j] = val;
+ }
+
+ void multScalar(double val)
+ {
+ for (int i=0;i<3;i++)
+ for (int j=0;j<3; j++)
+ a[i][j] = a[i][j]*val;
+ }
+
+ void copyFrom(mat33d &src)
+ {
+ for (int i=0;i<3;i++)
+ for (int j=0;j<3; j++)
+ a[i][j] = src.a[i][j];
+ }
+
+ double det(void)
+ {
+ // a11(a33a22-a32a23)-a21(a33a12-a32a13)+a31(a23a12-a22a13)
+ return a[0][0] * (a[2][2]*a[1][1] - a[2][1]*a[1][2])
+ - a[1][0] * (a[2][2]*a[0][1] - a[2][1]*a[0][2])
+ + a[2][0] * (a[1][2]*a[0][1] - a[1][1]*a[0][2]);
+ }
+
+ void invert(void)
+ {
+ mat33d ret;
+ double temdet = det();
+
+ //| a11 a12 a13 |-1 | a33a22-a32a23 -(a33a12-a32a13) a23a12-a22a13 |
+ //| a21 a22 a23 | = 1/DET * | -(a33a21-a31a23) a33a11-a31a13 -(a23a11-a21a13) |
+ //| a31 a32 a33 | | a32a21-a31a22 -(a32a11-a31a12) a22a11-a21a12 |
+
+
+ ret.a[0][0] = a[2][2]*a[1][1]-a[2][1]*a[1][2];
+ ret.a[0][1] = -(a[2][2]*a[0][1]-a[2][1]*a[0][2]);
+ ret.a[0][2] = a[1][2]*a[0][1]-a[1][1]*a[0][2];
+ ret.a[1][0] = -(a[2][2]*a[1][0]-a[2][0]*a[1][2]);
+ ret.a[1][1] = a[2][2]*a[0][0]-a[2][0]*a[0][2];
+ ret.a[1][2] = -(a[1][2]*a[0][0]-a[1][0]*a[0][2]);
+ ret.a[2][0] = a[2][1]*a[1][0]-a[2][0]*a[1][1];
+ ret.a[2][1] = -(a[2][1]*a[0][0]-a[2][0]*a[0][1]);
+ ret.a[2][2] = a[1][1]*a[0][0]-a[1][0]*a[0][1];
+ copyFrom(ret);
+ multScalar(1.0f / temdet);
+ }
+
+ void multVec(vec3d &r, vec3d &v)
+ {
+ for (int row = 0; row < 3; row++)
+ {
+ r.a[row] = a[row][0] * v.a[0] + a[row][1] * v.a[1] + a[row][2] * v.a[2];
+ }
+ }
+
+ void setRow(int row, double c0, double c1, double c2)
+ {
+ a[row][0] = c0;
+ a[row][1] = c1;
+ a[row][2] = c2;
+ }
+
+ void setCol(int col, double r0, double r1, double r2)
+ {
+ a[0][col] = r0;
+ a[1][col] = r1;
+ a[2][col] = r2;
+ }
+
+ double elem(int row, int col)
+ {
+ return a[row][col];
+ }
+
+ mat33d()
+ {
+ setConst(0.0f);
+ }
+
+protected:
+ double a[3][3];
+};
+
+//-------------------------------------------------
+// The monitor class
+//-------------------------------------------------
+
+typedef struct
+{
+ const char *desc;
+ double xr, yr, xg, yg, xb, yb, xw, yw, gamma;
+} CIE_Chroma_t;
+
+/*
+ * White points below use CIE 1964
+ */
+
+static const CIE_Chroma_t CIE_Mons[] =
+{
+ { "Guru", 0.57585, 0.34435, 0.28773, 0.55582, 0.18631,0.10346, 0.3138, 0.3310, 2.2 }, // D65
+ //{ "Short-Persistence", 0.61, 0.35, 0.29, 0.59, 0.15, 0.063 }, // N/A N/A [Foley96, p. 583]
+ //{ "Long-Persistence", 0.62, 0.33, 0.21, 0.685, 0.15, 0.063 }, // N/A N/A [Foley96, p. 583]
+ //CCIR 601-1 is the old NTSC standard. Now called Rec 601-1.
+ { "NTSC", 0.67, 0.33, 0.21, 0.71, 0.14, 0.08, 0.3104, 0.319, 2.2 }, // 1ILLUMINANT_C [Walker98]
+ { "EBU", 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, 0.3138, 0.3310, 2.4 }, // D65 [Walker98]
+ // (all monitors except 21, " Mitsubishi p/n 65532)
+ { "Dell", 0.625, 0.340, 0.275, 0.605, 0.150, 0.065, 0.280, 0.315, 2.2 }, // 9300K [Dell, E-mail, 12 Jan 99]
+ { "SMPTE", 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, 0.3138, 0.3310, 2.2 }, // D65 [Walker98]
+ { "P22 NEC C400", 0.610, 0.350, 0.307, 0.595, 0.150, 0.065, 0.280, 0.315, 2.2 }, // [NEC98], 9300 K Gamma = 2.2
+ { "P22 KDS VS19", 0.625, 0.340, 0.285, 0.605, 0.150, 0.065, 0.281, 0.311, 2.2 }, //
+ { "High Brightness LED",0.700, 0.300, 0.170, 0.700, 0.130, 0.075, 0.310, 0.320, 2.2 }, // Nichia Corporation
+ { "sRGB", 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, 0.3138, 0.3310, 2.4 }, // D65
+ { "Couriersud", 0.633, 0.336, 0.279, 0.598, 0.149, 0.073, 0.327, 0.355, 2.4 },
+
+ { NULL }
+};
+
+/*
+ * Calculate the RGB to CIE matrix ...
+ */
+
+static void calc_mat(CIE_Chroma_t cie, mat33d &m)
+{
+ mat33d ms;
+ vec3d vwhite;
+ vec3d s;
+
+ ms.setCol(0, cie.xr / cie.yr, 1.0, (1.0f - cie.xr - cie.yr) / cie.yr);
+ ms.setCol(1, cie.xg / cie.yg, 1.0, (1.0f - cie.xg - cie.yg) / cie.yg);
+ ms.setCol(2, cie.xb / cie.yb, 1.0, (1.0f - cie.xb - cie.yb) / cie.yb);
+
+ ms.invert();
+
+ vwhite.set(cie.xw / cie.yw, 1.0, (1.0f - cie.xw - cie.yw) / cie.yw);
+ ms.multVec(s, vwhite);
+
+ m.setCol(0, s.elem(0) * cie.xr / cie.yr, s.elem(0) * 1.0, s.elem(0) * (1.0f - cie.xr - cie.yr) / cie.yr);
+ m.setCol(1, s.elem(1) * cie.xg / cie.yg, s.elem(1) * 1.0, s.elem(1) * (1.0f - cie.xg - cie.yg) / cie.yg);
+ m.setCol(2, s.elem(2) * cie.xb / cie.yb, s.elem(2) * 1.0, s.elem(2) * (1.0f - cie.xb - cie.yb) / cie.yb);
+}
+
+static double src_gamma(double v, double g)
+{
+ return pow(v, g );
+}
+
+static double srgb_gamma(double v)
+{
+ return v;
+ if ( v > 0.0031308 )
+ return 1.055 * ( pow(v, 1.0f / 2.4f ) ) - 0.055;
+ else
+ return 12.92 * v;
+}
+
+static rgb_t vec_to_rgb_t(vec3d v)
+{
+ return rgb_t(
+ rgb_t::clamp((INT32) (srgb_gamma(v.elem(0)) * 255.0f)),
+ rgb_t::clamp((INT32) (srgb_gamma(v.elem(1)) * 255.0f)),
+ rgb_t::clamp((INT32) (srgb_gamma(v.elem(2)) * 255.0f))
+ );
+}
+
+static void CIE_xy_to_rgbA(CIE_Chroma_t cie, rgb_t *base_r, rgb_t *base_g, rgb_t *base_b)
+{
+ mat33d rgb_to_cie;
+ mat33d cie_to_rgb;
+ vec3d tt, tn;
+
+ tt.set(1,1,1);
+
+ calc_mat(cie, rgb_to_cie);
+ rgb_to_cie.multVec(tn, tt);
+ tn.dump();
+
+ cie_to_rgb.setRow(0, 3.2406, -1.5372, -0.4986);
+ cie_to_rgb.setRow(1, -0.9689, 1.8758, 0.0415);
+ cie_to_rgb.setRow(2, 0.0557, -0.2040, 1.0570);
+
+ for (int i = 0; i < 768; i++)
+ {
+ vec3d v_r, v_g, v_b, v_cie, v_rgb;
+ double val = src_gamma((double) i / 256.0f, cie.gamma);
+
+ /* desaturate colors for more brightness for val > 1.0
+ * at the expense of accuracy
+ */
+
+ double val2 = (val < 1.0) ? 0 : (val - 1.0) * 0.25;
+ v_r.set(val, val2, val2);
+ v_g.set(val2, val, val2);
+ v_b.set(val2, val2, val);
+
+ rgb_to_cie.multVec(v_cie, v_r);
+ cie_to_rgb.multVec(v_rgb, v_cie);
+ base_r[i] = vec_to_rgb_t(v_rgb);
+
+#if 0
+ if (i == 256)
+ {
+ printf("val %10.4f", val);
+ v_rgb.dump();
+ }
+#endif
+
+ rgb_to_cie.multVec(v_cie, v_g);
+ cie_to_rgb.multVec(v_rgb, v_cie);
+ base_g[i] = vec_to_rgb_t(v_rgb);
+
+#if 0
+ if (i == 256)
+ {
+ printf("val %10.4f", val);
+ v_rgb.dump();
+ }
+#endif
+
+ rgb_to_cie.multVec(v_cie, v_b);
+ cie_to_rgb.multVec(v_rgb, v_cie);
+ base_b[i] = vec_to_rgb_t(v_rgb);
+
+#if 0
+ if (i == 256)
+ {
+ printf("val %10.4f", val);
+ v_rgb.dump();
+ }
+#endif
+
+ }
+}
+
+
+void crt_monitor::set_param(crt_monitor_param &param) {
+ m_param = param;
+
+ CIE_xy_to_rgbA(CIE_Mons[m_param.source_cie], base_red, base_green, base_blue);
+
+ for (int i=0; i<256; i++)
+ {
+ m_exp[i] = 255.0f * (1.0f - exp(-(double) i / 255.0f * (double) (m_param.bandwidth * m_param.bandwidth) / 4096.0f));
+ //printf("%d %d\n", i, m_exp[i]);
+ }
+}
+
+
+crt_monitor::crt_monitor(void)
+ : m_amplifier_r(NULL), m_amplifier_g(NULL), m_amplifier_b(NULL)
+{
+ m_param.r_off = -256 * 3 / 10;
+ m_param.g_off = -256 * 3 / 10;
+ m_param.b_off = -256 * 3 / 10;
+ m_param.r_gain = 256 * 11 / 10;
+ m_param.g_gain = 256 * 11 / 10;
+ m_param.b_gain = 256 * 11 / 10;
+ m_param.bandwidth = 255 * 32 / 100;
+ m_param.focus = 255 * 21 / 100 ;
+ m_param.decay = 255 * 30 / 100;
+ m_param.source_cie = 0;
+
+ //m_param.m_type = CROMA_CLEAR;
+ //m_param.m_type = SHADOW_MASK;
+ m_param.m_type = PASSTHROUGHX;
+
+ set_param(m_param);
+ m_horz_pixel = 0;
+ m_vert_pixel = 0;
+ resize(288*11/8 * 3, 288*11/8 * 3 / 4 * 3);
+
+}
+
+crt_monitor::~crt_monitor(void)
+{
+ free_bitmaps();
+}
+
+void crt_monitor::free_bitmaps(void)
+{
+ if (m_amplifier_r != NULL)
+ global_free(m_amplifier_r);
+ if (m_amplifier_g != NULL)
+ global_free(m_amplifier_g);
+ if (m_amplifier_b != NULL)
+ global_free(m_amplifier_b);
+#if 0
+ // FIXME: should be done automatically ?
+ if (m_mask_bm != NULL)
+ bitmap_free(m_mask_bm);
+ if (m_phos_bm[0] != NULL)
+ bitmap_free(m_phos_bm[0]);
+ if (m_phos_bm[1] != NULL)
+ bitmap_free(m_phos_bm[1]);
+#endif
+}
+
+void crt_monitor::resize(int new_width, int new_height)
+{
+ int scal_width;
+ //int scal_height;
+ int adj = (m_param.m_type == SHADOW_MASK) ? 6 : 0;
+
+ //printf("new %d %d\n", new_width, new_height);
+
+ if (new_width > new_height)
+ {
+ scal_width = (new_width - adj) / 3;
+ //scal_height = (new_height - adj) / 3;
+ }
+ else
+ {
+ //scal_height = (new_width - adj) / 3;
+ scal_width = (new_height - adj) / 3;
+ int temp = new_height;
+ new_height = new_width;
+ new_width = temp;
+ }
+
+
+ if (scal_width == m_horz_pixel || scal_width <= 0)
+ return;
+
+ int vis_height = 2048; // be safe(scal_height + 3);
+ int do_realloc = (scal_width > m_horz_pixel);
+
+ m_horz_pixel = scal_width;
+ m_vert_pixel = m_horz_pixel * 3 / 4;
+
+
+ if (0 && m_param.m_type == SHADOW_MASK)
+ {
+ m_width = new_width; //m_horz_pixel * 3 + 6;
+ m_height = new_height;//m_vert_pixel * 3 + 6;
+ m_visible.min_x = 3;
+ m_visible.min_y = 3;
+ m_visible.max_x = m_width - 4;
+ m_visible.max_y = m_height - 4;
+ }
+ else
+ {
+ m_width = new_width; //m_horz_pixel * 3 + 6;
+ m_height = new_height;//m_vert_pixel * 3 + 6;
+ m_visible.min_x = 0;
+ m_visible.min_y = 0;
+ m_visible.max_x = m_width -1;
+ m_visible.max_y = m_height - 1;
+ }
+
+ if (0 || do_realloc)
+ {
+ //free_bitmaps();
+
+ //printf("realloc %d %d\n", m_width, m_height);
+ m_amplifier_r = global_alloc_array(INT16, m_horz_pixel * vis_height);
+ m_amplifier_g = global_alloc_array(INT16, m_horz_pixel * vis_height);
+ m_amplifier_b = global_alloc_array(INT16, m_horz_pixel * vis_height);
+
+ m_mask_bm.allocate(m_width, m_height);
+ m_phos_bm[0].allocate(m_width, m_height);
+ m_phos_bm[1].allocate(m_width, m_height);
+
+#if 0
+ bitmap_fill(m_phos_bm[0], NULL, 0);
+ bitmap_fill(m_phos_bm[1], NULL, 0);
+#endif
+ }
+}
+
+
+INLINE rgb_t bpixel(running_machine &machine, bitmap_t &bm, int y, int x)
+{
+ //return machine-> pens[*((UINT16 *) bm->base + y * bm->rowpixels + x)];
+
+ if (bm.format() == BITMAP_FORMAT_RGB32)
+ return bm.pixt<rgb_t>(y, x);
+ else
+ return palette_get_color(machine, bm.pixt<UINT16>(y, x));
+
+ //return *((UINT16 *) bm->base + y * bm->rowpixels + x);
+}
+#if 1
+
+INLINE void set_chan(INT16 *pix, int val, int w)
+{
+#if 1
+ if (val-*pix>0)
+ *pix += ((val-*pix)*w)>>8;
+#else
+ int nv = (val * w) >> 8;
+ if (nv > *pix)
+ *pix = nv;
+#endif
+
+}
+
+void crt_monitor::scale_and_bandwith(running_machine &machine, bitmap_t &bm_src, const rectangle &cliprect)
+{
+ int y,w,x;
+
+ for (y = cliprect.min_y - 1; y <= cliprect.max_y + 1; y++)
+ {
+ INT16 *dst_r = m_amplifier_r + (y - cliprect.min_y + 1) * m_horz_pixel;
+ INT16 *dst_g = m_amplifier_g + (y - cliprect.min_y + 1) * m_horz_pixel;
+ INT16 *dst_b = m_amplifier_b + (y - cliprect.min_y + 1) * m_horz_pixel;
+ for (x=0;x<m_horz_pixel;x++)
+ {
+ dst_r[x] = (dst_r[x] * m_param.decay)>>8;
+ dst_g[x] = (dst_g[x] * m_param.decay)>>8;
+ dst_b[x] = (dst_b[x] * m_param.decay)>>8;
+ }
+ }
+
+ w = MAX((cliprect.max_x - cliprect.min_x/* + 1*/), m_horz_pixel);
+ int x_add_s = (cliprect.max_x - cliprect.min_x /*+ 1*/) * 16384 / w;
+ int x_add_d = 16384 * m_horz_pixel / w;;
+
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ int r = 0;
+ int g = 0;
+ int b = 0;
+ int rn = 0;
+ int bn = 0;
+ int gn = 0;
+ int lx_d = -1;
+ int time_r;
+
+ INT16 *dst_r = m_amplifier_r + (y - cliprect.min_y + 1) * m_horz_pixel;
+ INT16 *dst_g = m_amplifier_g + (y - cliprect.min_y + 1) * m_horz_pixel;
+ INT16 *dst_b = m_amplifier_b + (y - cliprect.min_y + 1) * m_horz_pixel;
+
+ int sx_s = cliprect.min_x * 16384;
+ int sx_d = 0;
+ time_r = 0;
+ for (x=0; x<w; x++)
+ {
+ rgb_t src = bpixel(machine, bm_src, y, (sx_s >> 14));
+ int x_d = (sx_d >> 14);
+ int frac = (sx_s & 16383) >> 6;
+
+ int bandwidth1;
+ int bandwidth0;
+ if (frac>time_r)
+ bandwidth1 = m_exp[(frac-time_r)];
+ else
+ {
+ bandwidth1 = m_exp[(255 - time_r)];
+ bandwidth0 = 255- bandwidth1;
+ r = (r * bandwidth0 + rn * bandwidth1) >> 8;
+ g = (g * bandwidth0 + gn * bandwidth1) >> 8;
+ b = (b * bandwidth0 + bn * bandwidth1) >> 8;
+ bandwidth1 = m_exp[(frac)];
+ }
+ time_r = frac;
+ rn = ((MAX((int)src.r() - m_param.r_off, 0) * m_param.r_gain) >> 8);
+ gn = ((MAX((int)src.g() - m_param.g_off, 0) * m_param.g_gain) >> 8);
+ bn = ((MAX((int)src.b() - m_param.b_off, 0) * m_param.b_gain ) >> 8);
+ bandwidth0 = 255- bandwidth1;
+
+ r = (r * bandwidth0 + rn * bandwidth1) >> 8;
+ g = (g * bandwidth0 + gn * bandwidth1) >> 8;
+ b = (b * bandwidth0 + bn * bandwidth1) >> 8;
+
+ if (x_d>lx_d)
+ {
+ set_chan(&dst_r[x_d], r, 255);
+ set_chan(&dst_g[x_d], g, 255);
+ set_chan(&dst_b[x_d], b, 255);
+
+ set_chan(&dst_r[x_d-m_horz_pixel], r, m_param.focus);
+ set_chan(&dst_g[x_d-m_horz_pixel], g, m_param.focus);
+ set_chan(&dst_b[x_d-m_horz_pixel], b, m_param.focus);
+
+ set_chan(&dst_r[x_d+m_horz_pixel], r, m_param.focus);
+ set_chan(&dst_g[x_d+m_horz_pixel], g, m_param.focus);
+ set_chan(&dst_b[x_d+m_horz_pixel], b, m_param.focus);
+ lx_d = x_d;
+ }
+
+ sx_s += x_add_s;
+ sx_d += x_add_d;
+ }
+ }
+}
+#else
+void crt_monitor::scale_and_bandwith(running_machine *machine, bitmap_t *bm_src, const rectangle *cliprect)
+{
+ int x;
+ int y;
+ int bandwidth0 = m_param.bandwidth;
+ int bandwidth1 = 256 - bandwidth0;
+ UINT16 tr[4*1024];
+ UINT16 tg[4*1024];
+ UINT16 tb[4*1024];
+
+ int x_add = (cliprect.max_x - cliprect.min_x + 1) * 1024 * 4/ (m_horz_pixel);
+
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ int r = 0;
+ int g = 0;
+ int b = 0;
+
+ /* bandwidth first ! */
+ for (x=cliprect.min_x*4; x<=cliprect.max_x*4; x++)
+ {
+ rgb_t src = bpixel(machine, bm_src, y, x/4);
+
+ r = (r * bandwidth0 + ((MAX((int)RGB_RED(src) - m_param.r_off, 0) * m_param.r_gain) >> 8) * bandwidth1) >> 8;
+ g = (g * bandwidth0 + ((MAX((int)RGB_GREEN(src) - m_param.g_off, 0) * m_param.g_gain) >> 8) * bandwidth1) >> 8;
+ b = (b * bandwidth0 + ((MAX((int)RGB_BLUE(src) - m_param.b_off, 0) * m_param.b_gain ) >> 8) * bandwidth1) >> 8;
+
+ tr[x] = r;
+ tg[x] = g;
+ tb[x] = b;
+ }
+
+ int sx = cliprect.min_x * 1024 * 4;
+
+ INT16 *dst_r = m_amplifier_r + (y - cliprect.min_y) * m_horz_pixel;
+ INT16 *dst_g = m_amplifier_g + (y - cliprect.min_y) * m_horz_pixel;
+ INT16 *dst_b = m_amplifier_b + (y - cliprect.min_y) * m_horz_pixel;
+
+ /* doing a linear interpolation is an approximation,
+ * however should suffice here.
+ */
+ for (x = 0; x < m_horz_pixel; x++)
+ {
+ UINT16 frac = (sx & 0x3ff)>>2;
+ UINT16 xw = sx >> 10;
+
+ frac = 0;
+
+ *dst_r++ = (tr[xw] * (256-frac) + tr[xw+1] * frac)>>8;
+ *dst_g++ = (tg[xw] * (256-frac) + tg[xw+1] * frac)>>8;
+ *dst_b++ = (tb[xw] * (256-frac) + tb[xw+1] * frac)>>8;
+
+ sx += x_add;
+ }
+ }
+}
+#endif
+
+void crt_monitor::copyonly(bitmap_rgb32 &bm_dst, rectangle &clip)
+{
+ int x;
+ int y;
+
+ int sy = 0;
+ int s_add = (clip.max_y - clip.min_y + 1) * 256 / (m_visible.max_y - m_visible.min_y + 1) ;
+
+ for (y = m_visible.min_y; y <= m_visible.max_y; y++)
+ {
+ rgb_t *dst = (rgb_t *) bm_dst.raw_pixptr(y, 0);
+ for (x = m_visible.min_x; x <= m_visible.max_x; x++)
+ {
+ int offset = (sy >> 8) * m_horz_pixel + ((x-m_visible.min_x) / 3);
+ UINT8 r = MIN(255, m_amplifier_r[offset]);
+ UINT8 g = MIN(255, m_amplifier_g[offset]);
+ UINT8 b = MIN(255, m_amplifier_b[offset]);
+ dst[0] = rgb_t(r, g, b);
+ dst++;
+ }
+ sy += s_add;
+ }
+}
+
+INLINE void set_pixel(rgb_t *pix, int r, int g, int b)
+{
+ int rn = r;
+ int gn = g;
+ int bn = b;
+
+ *pix = rgb_t(
+ (rgb_t::clamp((int)pix->r() + rn)),
+ (rgb_t::clamp((int)pix->g() + gn)),
+ (rgb_t::clamp((int)pix->b() + bn))
+ );
+}
+
+INLINE void set_pixela(rgb_t *pix, rgb_t val, int w)
+{
+ UINT8 rn = val.r();
+ UINT8 gn = val.g();
+ UINT8 bn = val.b();
+
+ UINT8 ro = pix->r();
+ UINT8 go = pix->g();
+ UINT8 bo = pix->b();
+
+ if (rn-ro>0)
+ ro += ((rn-ro)*w)>>8;
+ if (gn-go>0)
+ go += ((gn-go)*w)>>8;
+ if (bn-bo>0)
+ bo += ((bn-bo)*w)>>8;
+
+ *pix = rgb_t(ro, go, bo);
+}
+
+void crt_monitor::copy_shadow_mask(bitmap_rgb32 &bm_dst, const rectangle &clip)
+{
+ int gainv[3] = { 100, 100, 100};
+ int sy = 0;
+ int s_add = (clip.max_y - clip.min_y + 1) * 16384 / (m_visible.max_y - m_visible.min_y + 1) ;
+
+ int x;
+ int y;
+
+ gainv[1] = 255;
+ gainv[0] = m_param.focus;
+ gainv[2] = m_param.focus;
+
+ for (y = m_visible.min_y+3; y <= m_visible.max_y-4; y++)
+ {
+ rgb_t *dst0 = (rgb_t *) bm_dst.raw_pixptr(y, m_visible.min_x);
+ rgb_t *dst1 = (rgb_t *) bm_dst.raw_pixptr(y + 1, m_visible.min_x);
+ int gaina = gainv[y % 3];
+
+ for (x = m_visible.min_x+3; x <= m_visible.max_x-4; x+=3)
+ {
+ int offset = ((sy + 8191) >> 14) * m_horz_pixel + (((y & 1) == 0) ? (x-m_visible.min_x) / 3 : (2*(x-m_visible.min_x)-3) / 6) ;
+
+ int rn = (m_amplifier_r[offset] * gaina)>>8;
+ int gn = (m_amplifier_g[offset] * gaina)>>8;
+ int bn = (m_amplifier_b[offset] * gaina)>>8;
+#if 0
+ int r_ov = MAX(rn - 255, 0);
+ int g_ov = MAX(gn - 255, 0);
+ int b_ov = MAX(bn - 255, 0);
+
+ if ((y & 1) == 0)
+ {
+ set_pixel(dst0 - 1, r_ov, 0, 0);
+ set_pixel(dst0 + 0, rn, g_ov, b_ov);
+ set_pixel(dst0 + 1, r_ov, gn, b_ov);
+ set_pixel(dst0 + 2, 0, g_ov, 0);
+ set_pixel(dst1 + 0, 0, 0, b_ov);
+ set_pixel(dst1 + 1, r_ov, g_ov, bn);
+ set_pixel(dst1 + 2, 0, 0, b_ov);
+ }
+ else
+ {
+ set_pixel(dst0 - 2, r_ov, 0, 0);
+ set_pixel(dst0 - 1, rn, g_ov, b_ov);
+ set_pixel(dst0 + 0, r_ov, gn, b_ov);
+ set_pixel(dst0 + 1, 0, g_ov, 0);
+ set_pixel(dst1 - 2, 0, 0, b_ov);
+ set_pixel(dst1 - 1, r_ov, g_ov, bn);
+ set_pixel(dst1 - 0, 0, 0, b_ov);
+ }
+#else
+ if ((y & 1) == 0)
+ {
+ *(dst0 + 0) = base_red[rn];
+ *(dst0 + 1) = base_green[gn];
+ *(dst1 + 1) = base_blue[bn];
+ }
+ else
+ {
+ *(dst0 - 1) = base_red[rn];
+ *(dst0 + 0) = base_green[gn];
+ *(dst1 - 1) = base_blue[bn];
+ }
+#endif
+ dst1 += 3;
+ dst0 += 3;
+ }
+ sy += s_add;
+ }
+}
+
+void crt_monitor::copy_chroma(bitmap_rgb32 &bm_dst, const rectangle &clip)
+{
+#if 1
+ int gainv[4][2] = {
+ { 256 / 4, 256 },
+ { 256, 256 },
+ { 256, 256 / 4 },
+ { 256, 256 }
+ };
+#else
+ int gainv[4][2] = {
+ { m_param.focus, 256 },
+ { m_param.focus, m_param.focus },
+ { 256, m_param.focus },
+ { m_param.focus, m_param.focus }
+ };
+#endif
+ int sy = 0;
+ int s_add = (clip.max_y - clip.min_y + 1) * 16384 / (m_visible.max_y - m_visible.min_y + 1) ;
+
+ int x;
+ int y;
+
+ //gainv[0][0] = m_param.focus;
+ //gainv[1][0] = m_param.focus;
+
+ for (y = m_visible.min_y; y <= m_visible.max_y; y++)
+ {
+ rgb_t *dst0 = (rgb_t *) bm_dst.raw_pixptr(y, m_visible.min_x);
+ rgb_t *dstm1 = dst0 - 3 * bm_dst.rowpixels();
+ rgb_t *dstp1 = dst0 + 3 * bm_dst.rowpixels();
+
+ for (x = m_visible.min_x; x <= m_visible.max_x; x+=3)
+ {
+ int offset = (((sy + 8191) >> 14)+1) * m_horz_pixel + (x-m_visible.min_x) / 3;
+ int gaina = gainv[y & 3][((x-m_visible.min_x)/3) & 1];
+
+ int rn = (m_amplifier_r[offset] * gaina)>>8;
+ int gn = (m_amplifier_g[offset] * gaina)>>8;
+ int bn = (m_amplifier_b[offset] * gaina)>>8;
+
+
+#if 0
+ int blank=0;
+
+ if ((((x / 3) & 1) == 0) && ((y % 4) == 0))
+ blank = 1;
+ else if ((((x / 3) & 1) == 1) && ((y % 4) == 2))
+ blank = 1;
+
+ if (!blank)
+ {
+#endif
+#if 0
+ int r_ov = MAX(rn - 255, 0);
+ int g_ov = MAX(gn - 255, 0);
+ int b_ov = MAX(bn - 255, 0);
+
+ set_pixel(dst0 - 1, r_ov, 0, 0);
+ set_pixel(dst0 + 0, rn, g_ov, 0);
+ set_pixel(dst0 + 1, 0, gn, b_ov);
+ set_pixel(dst0 + 2, 0, 0, bn);
+#elif 0
+ int r_ov = MAX(rn - 255, 0);
+ int g_ov = MAX(gn - 255, 0);
+ int b_ov = MAX(bn - 255, 0);
+
+ set_pixel(dst0 + 0, rn, r_ov, r_ov);
+ set_pixel(dst0 + 1, g_ov, gn, g_ov);
+ set_pixel(dst0 + 2, b_ov, b_ov, bn);
+#elif 0
+ int frac1 = (sy & 16383)>>6;
+ int frac = (255-frac1);
+ int rn1 = (m_amplifier_r[offset+m_horz_pixel] * gaina)>>8;
+ int gn1 = (m_amplifier_g[offset+m_horz_pixel] * gaina)>>8;
+ int bn1 = (m_amplifier_b[offset+m_horz_pixel] * gaina)>>8;
+
+ *(dst0+0) = base_red[(rn*frac+rn1*frac1)>>8];
+ *(dst0+1) = base_green[(gn*frac+gn1*frac1)>>8];
+ *(dst0+2) = base_blue[(bn*frac+bn1*frac1)>>8];
+#elif 1
+ *(dst0+0) = base_red[rn];
+ *(dst0+1) = base_green[gn];
+ *(dst0+2) = base_blue[bn];
+#elif 1
+ set_pixela(dst0 , base_red[rn],192);
+ set_pixela(dst0+1, base_green[gn],192);
+ set_pixela(dst0+2, base_blue[bn],192);
+ if (m_param.focus > 0)
+ {
+ set_pixela(dstm1 , base_red[rn],m_param.focus);
+ set_pixela(dstm1+1, base_green[gn],m_param.focus);
+ set_pixela(dstm1+2, base_blue[bn],m_param.focus);
+ set_pixela(dstp1 , base_red[rn],m_param.focus);
+ set_pixela(dstp1+1, base_green[gn],m_param.focus);
+ set_pixela(dstp1+2, base_blue[bn],m_param.focus);
+#if 0
+ set_pixela(dst0-3, base_red[rn],m_param.focus);
+ set_pixela(dst0-2, base_green[gn],m_param.focus);
+ set_pixela(dst0-1, base_blue[bn],m_param.focus);
+ set_pixela(dst0+3, base_red[rn],m_param.focus);
+ set_pixela(dst0+4, base_green[gn],m_param.focus);
+ set_pixela(dst0+5, base_blue[bn],m_param.focus);
+#endif
+ }
+
+#else
+ /* looks horrible */
+ int r = RGB_RED(base_red[rn]) + RGB_RED(base_green[gn]) + RGB_RED(base_blue[bn]);
+ int g = RGB_GREEN(base_red[rn]) + RGB_GREEN(base_green[gn]) + RGB_GREEN(base_blue[bn]);
+ int b = RGB_BLUE(base_red[rn]) + RGB_BLUE(base_green[gn]) + RGB_BLUE(base_blue[bn]);
+
+ rgb_t c = MAKE_RGB(rgb_clamp(r), rgb_clamp(g), rgb_clamp(b));
+ *(dst0+0) = c;
+ *(dst0+1) = c;
+ *(dst0+2) = c;
+#endif
+// }
+ dst0 += 3;
+ dstm1 += 3;
+ dstp1 += 3;
+ }
+ sy += s_add;
+ }
+}
+
+void crt_monitor::phosphor(bitmap_rgb32 &bm_dst, bitmap_rgb32 &bm_phos, bitmap_rgb32 &bm_src, const rectangle &cliprect)
+{
+ const int phos_decay = m_param.decay;
+
+ const int phos_red_decay = phos_decay;
+ const int phos_green_decay = phos_decay;
+ const int phos_blue_decay = phos_decay;
+
+ //int phos_red_decay1 = 256 - phos_red_decay;
+ //int phos_green_decay1 = 256 - phos_green_decay;
+ //int phos_blue_decay1 = 256 - phos_blue_decay;
+
+ int x;
+ int y;
+
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ rgb_t *src = (rgb_t *) bm_src.raw_pixptr(y, cliprect.min_x);
+ rgb_t *sp = (rgb_t *) bm_phos.raw_pixptr(y, cliprect.min_x);
+ rgb_t *dst = (rgb_t *) bm_dst.raw_pixptr(y, cliprect.min_x);
+
+ for (x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+#if 0
+ int r = ((int)RGB_RED(*src) * phos_red_decay1 + (int)RGB_RED(*sp) * phos_red_decay) >> 8;
+ int g = ((int)RGB_GREEN(*src) * phos_green_decay1 + (int)RGB_GREEN(*sp) * phos_green_decay) >> 8;;
+ int b = ((int)RGB_BLUE(*src) * phos_blue_decay1 + (int)RGB_BLUE(*sp) * phos_blue_decay) >> 8;
+#else
+ int r = ((int)sp->r() * phos_red_decay) >> 8;
+ int g = ((int)sp->g() * phos_green_decay) >> 8;;
+ int b = ((int)sp->b() * phos_blue_decay) >> 8;
+ int r1 = src->r();
+ int g1 = src->g();
+ int b1 = src->b();
+ if (r1 > r) r = r1;
+ if (g1 > g) g = g1;
+ if (b1 > b) b = b1;
+#endif
+ *dst = rgb_t(r, g, b);
+
+ src++; sp++; dst++;
+ }
+ }
+}
+
+void crt_monitor::process(running_machine &machine, screen_bitmap &src_bm, int cur_bm, rectangle &clip)
+{
+ bitmap_rgb32 *temp = (0 && m_param.decay > 0) ? &m_mask_bm : &m_phos_bm[cur_bm];
+
+ switch (m_param.m_type)
+ {
+ case PASSTHROUGHX:
+ break;
+ case SHADOW_MASK:
+ scale_and_bandwith(machine, src_bm, clip);
+ temp->fill(0);
+ copy_shadow_mask(*temp, clip );
+ break;
+ case CROMA_CLEAR:
+ scale_and_bandwith(machine, src_bm, clip);
+ temp->fill(0);
+ copy_chroma(*temp, clip );
+ break;
+ //case APERTURE_GRILLE:
+ //break;
+ }
+ if (m_param.m_type != PASSTHROUGHX)
+ {
+ if (0 && m_param.decay > 0)
+ phosphor(m_phos_bm[cur_bm],m_phos_bm[1-cur_bm], m_mask_bm, m_visible);
+ }
+}
+
+int crt_monitor::get_cie_count(void)
+{
+ int num = 0;
+ const CIE_Chroma_t *t = &CIE_Mons[0];
+
+ while (t->desc !=NULL)
+ {
+ t++;
+ num++;
+ }
+ return num;
+}
+
+const char * crt_monitor::get_cie_name(void)
+{
+ return CIE_Mons[m_param.source_cie].desc;
+}
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 4f44dbec031..551d840dc8e 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -127,6 +127,104 @@ typedef device_delegate<UINT32 (screen_device &, bitmap_rgb32 &, const rectangle
typedef device_delegate<void (screen_device &, bool)> screen_vblank_delegate;
+// ======================> monitor_device
+
+
+class crt_monitor
+{
+public:
+
+ typedef enum
+ {
+ PASSTHROUGHX = 0, // PASSTHROUGH somewhere defined in win32 environment
+ SHADOW_MASK = 1,
+ CROMA_CLEAR = 2,
+// APERTURE_GRILLE,
+ } crt_monitor_type;
+
+ typedef struct
+ {
+ crt_monitor_type m_type;
+ INT16 r_off;
+ INT16 g_off;
+ INT16 b_off;
+ UINT16 r_gain;
+ UINT16 b_gain;
+ UINT16 g_gain;
+ UINT16 focus;
+ UINT16 decay;
+ UINT16 bandwidth;
+ UINT8 source_cie;
+ } crt_monitor_param;
+
+ crt_monitor(void);
+ ~crt_monitor(void);
+
+ void resize(int new_width, int new_height);
+
+ bitmap_t &final_bitmap(int cur_bm) { return m_phos_bm[cur_bm]; }
+
+ void get_param(crt_monitor_param &param) { param = m_param; }
+ void set_param(crt_monitor_param &param);
+
+ crt_monitor_type type(void) const { return m_param.m_type; }
+ //void set_type(crt_monitor_type new_type) { m_type = new_type; }
+
+ //void set_horz_pixel(int num) { m_horz_pixel = num; }
+
+ void process(running_machine &machine, screen_bitmap &src_bm, int cur_bm, rectangle &clip);
+
+ const rectangle &get_visible() const { return m_visible; }
+
+ int get_cie_count(void);
+ const char * get_cie_name(void);
+
+ int get_type_count(void) { return 3; }
+ const char * get_type_name(void)
+ {
+ switch (m_param.m_type)
+ {
+ case PASSTHROUGHX:
+ return "Passthrough";
+ case CROMA_CLEAR:
+ return "Croma Clear";
+ case SHADOW_MASK:
+ return "Shadow Mask";
+ }
+ return "";
+ }
+
+
+private:
+ INT16 * m_amplifier_r;
+ INT16 * m_amplifier_g;
+ INT16 * m_amplifier_b;
+ bitmap_rgb32 m_mask_bm;
+ bitmap_rgb32 m_phos_bm[2];
+
+ crt_monitor_param m_param;
+ rectangle m_visible;
+ //rectangle m_src_visible;
+
+ int m_vert_pixel;
+ int m_horz_pixel;
+ int m_width;
+ int m_height;
+
+ void free_bitmaps(void);
+ void scale_and_bandwith(running_machine &machine, bitmap_t &bm_src, const rectangle &cliprect);
+ void copyonly(bitmap_rgb32 &bm_dst, rectangle &clip);
+ void copy_shadow_mask(bitmap_rgb32 &bm_dst, const rectangle &clip);
+ void copy_chroma(bitmap_rgb32 &bm_dst, const rectangle &clip);
+ void phosphor(bitmap_rgb32 &bm_dst, bitmap_rgb32 &bm_phos, bitmap_rgb32 &bm_src, const rectangle &cliprect);
+
+ rgb_t base_red[768];
+ rgb_t base_green[768];
+ rgb_t base_blue[768];
+ int m_exp[256];
+};
+
+
// ======================> screen_device
class screen_device : public device_t
@@ -142,7 +240,7 @@ public:
screen_type_enum screen_type() const { return m_type; }
int width() const { return m_width; }
int height() const { return m_height; }
- const rectangle &visible_area() const { return m_visarea; }
+ const rectangle &visible_area() const;// { return m_visarea; }
const rectangle &cliprect() const { return m_bitmap[0].cliprect(); }
bool oldstyle_vblank_supplied() const { return m_oldstyle_vblank_supplied; }
attoseconds_t refresh_attoseconds() const { return m_refresh; }
@@ -197,6 +295,8 @@ public:
void update_now();
void reset_partial_updates();
+ void set_render_size(int width, int height);
+
// additional helpers
void register_vblank_callback(vblank_state_delegate vblank_callback);
void register_screen_bitmap(bitmap_t &bitmap);
@@ -206,6 +306,10 @@ public:
bool update_quads();
void update_burnin();
+ // access to crt
+
+ crt_monitor &crt(void) { return m_crt; }
+
// globally accessible constants
static const int DEFAULT_FRAME_RATE = 60;
static const attotime DEFAULT_FRAME_PERIOD;
@@ -281,6 +385,10 @@ private:
UINT64 m_frame_number; // the current frame number
UINT32 m_partial_updates_this_frame;// partial update counter this frame
+ // render size
+ INT32 m_render_width;
+ INT32 m_render_height;
+
// VBLANK callbacks
class callback_item
{
@@ -312,6 +420,10 @@ private:
// static data
static UINT32 m_id_counter; // incremented for each constructed screen_device,
// used as a unique identifier during runtime
+
+ // monitor emulation
+
+ crt_monitor m_crt;
};
// device type definition
diff --git a/src/emu/ui/ui.c b/src/emu/ui/ui.c
index 8f50ead60f9..557c90099e8 100644
--- a/src/emu/ui/ui.c
+++ b/src/emu/ui/ui.c
@@ -123,6 +123,20 @@ static INT32 slider_overyoffset(running_machine &machine, void *arg, astring *st
static INT32 slider_flicker(running_machine &machine, void *arg, astring *string, INT32 newval);
static INT32 slider_beam(running_machine &machine, void *arg, astring *string, INT32 newval);
static char *slider_get_screen_desc(screen_device &screen);
+
+static INT32 slider_crt_red_off(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_green_off(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_blue_off(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_red_gain(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_green_gain(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_blue_gain(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_decay(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_bandwidth(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_focus(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_cie(running_machine &machine, void *arg, astring *string, INT32 newval);
+static INT32 slider_crt_type(running_machine &machine, void *arg, astring *string, INT32 newval);
+
+
#ifdef MAME_DEBUG
static INT32 slider_crossscale(running_machine &machine, void *arg, astring *string, INT32 newval);
static INT32 slider_crossoffset(running_machine &machine, void *arg, astring *string, INT32 newval);
@@ -1905,6 +1919,54 @@ static slider_state *slider_init(running_machine &machine)
break;
}
+ screen_device_iterator iter(machine.root_device());
+ for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next())
+ if (screen->screen_type() != SCREEN_TYPE_VECTOR)
+ {
+ void *param = (void *)screen;
+
+ string.printf("%s Red Offset", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, -256, 0, 256, 5, slider_crt_red_off, param);
+ tailptr = &(*tailptr)->next;
+ string.printf("%s Green Offset", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, -256, 0, 256, 5, slider_crt_green_off, param);
+ tailptr = &(*tailptr)->next;
+ string.printf("%s Blue Offset", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, -256, 0, 256, 5, slider_crt_blue_off, param);
+ tailptr = &(*tailptr)->next;
+
+ string.printf("%s Red Gain", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 256, 767, 5, slider_crt_red_gain, param);
+ tailptr = &(*tailptr)->next;
+ string.printf("%s Green Gain", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 256, 767, 5, slider_crt_green_gain, param);
+ tailptr = &(*tailptr)->next;
+ string.printf("%s Blue Gain", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 256, 767, 5, slider_crt_blue_gain, param);
+ tailptr = &(*tailptr)->next;
+
+ string.printf("%s Phosphor decay", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 0, 256, 5, slider_crt_decay, param);
+ tailptr = &(*tailptr)->next;
+
+ string.printf("%s Bandwidth", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 0, 256, 5, slider_crt_bandwidth, param);
+ tailptr = &(*tailptr)->next;
+
+ string.printf("%s Focus", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 256, 256, 5, slider_crt_focus, param);
+ tailptr = &(*tailptr)->next;
+
+ string.printf("%s CIE", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 0, screen->crt().get_cie_count()-1, 1, slider_crt_cie, param);
+ tailptr = &(*tailptr)->next;
+
+ string.printf("%s Monitor type", slider_get_screen_desc(*screen));
+ *tailptr = slider_alloc(machine, string, 0, 0, screen->crt().get_type_count()-1, 1, slider_crt_type, param);
+ tailptr = &(*tailptr)->next;
+
+ }
+
#ifdef MAME_DEBUG
// add crosshair adjusters
for (port = machine.ioport().first_port(); port != NULL; port = port->next())
@@ -1924,6 +1986,186 @@ static slider_state *slider_init(running_machine &machine)
return listhead;
}
+/*-------------------------------------------------
+ slider_crt_* - CRT Monitor sliders
+-------------------------------------------------*/
+
+static INT32 slider_crt_red_off(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.r_off = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.r_off / 256.0f);
+ return param.r_off;
+}
+
+static INT32 slider_crt_green_off(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.g_off = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.g_off / 256.0f);
+ return param.g_off;
+}
+
+static INT32 slider_crt_blue_off(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.b_off = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.b_off / 256.0f);
+ return param.b_off;
+}
+
+static INT32 slider_crt_red_gain(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.r_gain = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.r_gain / 256.0f);
+ return param.r_gain;
+}
+
+static INT32 slider_crt_green_gain(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.g_gain = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.g_gain / 256.0f);
+ return param.g_gain;
+}
+
+static INT32 slider_crt_blue_gain(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.b_gain = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.b_gain / 256.0f);
+ return param.b_gain;
+}
+
+static INT32 slider_crt_decay(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.decay = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.decay / 256.0f);
+ return param.decay;
+}
+
+static INT32 slider_crt_bandwidth(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.bandwidth = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.bandwidth / 256.0f);
+ return param.bandwidth;
+}
+
+static INT32 slider_crt_focus(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.focus = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%.2f", (double) param.focus / 256.0f);
+ return param.focus;
+}
+
+static INT32 slider_crt_cie(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.source_cie = newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%s", screen->crt().get_cie_name());
+ return param.source_cie;
+}
+
+static INT32 slider_crt_type(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ screen_device *screen = reinterpret_cast<screen_device *>(arg);
+ crt_monitor::crt_monitor_param param;
+
+ screen->crt().get_param(param);
+ if (newval != SLIDER_NOCHANGE)
+ {
+ param.m_type = (crt_monitor::crt_monitor_type) newval;
+ screen->crt().set_param(param);
+ }
+ if (string != NULL)
+ string->printf("%s", screen->crt().get_type_name());
+ return param.m_type;
+}
+
//-------------------------------------------------
// slider_volume - global volume slider callback