diff --git a/src/emu/sound/disc_cls.h b/src/emu/sound/disc_cls.h index ec6520f555b..f48bbd76ca8 100644 --- a/src/emu/sound/disc_cls.h +++ b/src/emu/sound/disc_cls.h @@ -20,22 +20,13 @@ #define DISCRETE_CLASS_NAME(_name) discrete_ ## _name ## _node -#if 0 -#define DISCRETE_CLASS_CONSTRUCTOR(_name, _base, _ctxsize) \ - DISCRETE_CLASS_NAME(_name)(discrete_device * pdev, const discrete_sound_block *block) \ - : DISCRETE_CLASS_NAME(_base)(pdev, block) { m_context_size = _ctxsize; } -#else -#define DISCRETE_CLASS_CONSTRUCTOR(_name, _base) \ - DISCRETE_CLASS_NAME(_name)() \ +#define DISCRETE_CLASS_CONSTRUCTOR(_name, _base) \ + DISCRETE_CLASS_NAME(_name)() \ : DISCRETE_CLASS_NAME(_base)() { } -#endif -#if 1 + #define DISCRETE_CLASS_DESTRUCTOR(_name) \ public: \ virtual ~ DISCRETE_CLASS_NAME(_name)(void) { } -#else -#define DISCRETE_CLASS_DESTRUCTOR(_name) -#endif #define DISCRETE_CLASS_STEP_RESETA(_name, _maxout, _priv) \ class DISCRETE_CLASS_NAME(_name): public discrete_base_node, public discrete_step_interface \ @@ -50,7 +41,7 @@ private: \ _priv \ } -#define DISCRETE_CLASS_STEPA(_name, _maxout, _priv) \ +#define DISCRETE_CLASS_STEPA(_name, _maxout, _priv) \ class DISCRETE_CLASS_NAME(_name): public discrete_base_node, public discrete_step_interface \ { \ public: \ @@ -63,7 +54,7 @@ private: \ _priv \ } -#define DISCRETE_CLASS_RESET(_name, _maxout) \ +#define DISCRETE_CLASS_RESET(_name, _maxout) \ class DISCRETE_CLASS_NAME(_name): public discrete_base_node \ { \ public: \ @@ -104,12 +95,6 @@ public: DISCRETE_CLASS_DESTRUCTOR(unimplemented) }; -struct dst_size_context -{ -// int size; -}; - - /************************************* * * disc_sys.c diff --git a/src/emu/sound/disc_dev.c b/src/emu/sound/disc_dev.c index b5230e34377..2a2fce139c3 100644 --- a/src/emu/sound/disc_dev.c +++ b/src/emu/sound/disc_dev.c @@ -284,8 +284,6 @@ DISCRETE_RESET(dsd_555_astbl) { DISCRETE_DECLARE_INFO(discrete_555_desc) - discrete_base_node *v_charge_node; - m_use_ctrlv = (this->input_is_node() >> 4) & 1; m_output_type = info->options & DISC_555_OUT_MASK; @@ -293,13 +291,10 @@ DISCRETE_RESET(dsd_555_astbl) m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; /* setup v_charge or node */ - v_charge_node = this->device->discrete_find_node(info->v_charge); - if (v_charge_node) - m_v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); - else + m_v_charge_node = m_device->node_output_ptr(info->v_charge); + if (m_v_charge_node == NULL) { m_v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge; - m_v_charge_node = NULL; if (info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) m_v_charge -= 0.5; } @@ -504,7 +499,7 @@ DISCRETE_RESET(dsd_555_mstbl) m_output_type = info->options & DISC_555_OUT_MASK; if ((m_output_type == DISC_555_OUT_COUNT_F) || (m_output_type == DISC_555_OUT_COUNT_R)) { - this->device->discrete_log("Invalid Output type in NODE_%d.\n", this->index()); + m_device->discrete_log("Invalid Output type in NODE_%d.\n", this->index()); m_output_type = DISC_555_OUT_SQW; } diff --git a/src/emu/sound/disc_dev.h b/src/emu/sound/disc_dev.h index c6ab28e62b2..91271a9915e 100644 --- a/src/emu/sound/disc_dev.h +++ b/src/emu/sound/disc_dev.h @@ -32,7 +32,7 @@ DISCRETE_CLASS_STEP_RESETA(dsd_555_astbl, 1, double m_trigger; double m_v_out_high; /* Logic 1 voltage level */ double m_v_charge; - double *m_v_charge_node; /* point to output of node */ + const double *m_v_charge_node; /* point to output of node */ int m_has_rc_nodes; double m_exp_bleed; double m_exp_charge; diff --git a/src/emu/sound/disc_flt.c b/src/emu/sound/disc_flt.c index 6c47bd4378f..189d3faa55c 100644 --- a/src/emu/sound/disc_flt.c +++ b/src/emu/sound/disc_flt.c @@ -110,7 +110,8 @@ static void calculate_filter1_coefficients(discrete_base_node *node, double fc, } else { - node->device->discrete_log("calculate_filter1_coefficients() - Invalid filter type for 1st order filter."); + /* FIXME: reenable */ + //node->m_device->discrete_log("calculate_filter1_coefficients() - Invalid filter type for 1st order filter."); } } @@ -191,7 +192,8 @@ static void calculate_filter2_coefficients(discrete_base_node *node, } else { - node->device->discrete_log("calculate_filter2_coefficients() - Invalid filter type for 2nd order filter."); + /* FIXME: reenable */ + //node->device->discrete_log("calculate_filter2_coefficients() - Invalid filter type for 2nd order filter."); } } @@ -723,17 +725,17 @@ DISCRETE_RESET( dst_rcdisc4) /* some error checking. */ if (DST_RCDISC4__R1 <= 0 || DST_RCDISC4__R2 <= 0 || DST_RCDISC4__C1 <= 0 || (DST_RCDISC4__R3 <= 0 && m_type == 1)) { - this->device->discrete_log("Invalid component values in NODE_%d.\n", this->index()); + m_device->discrete_log("Invalid component values in NODE_%d.\n", this->index()); return; } if (DST_RCDISC4__VP < 3) { - this->device->discrete_log("vP must be >= 3V in NODE_%d.\n", this->index()); + m_device->discrete_log("vP must be >= 3V in NODE_%d.\n", this->index()); return; } if (DST_RCDISC4__TYPE < 1 || DST_RCDISC4__TYPE > 3) { - this->device->discrete_log("Invalid circuit type in NODE_%d.\n", this->index()); + m_device->discrete_log("Invalid circuit type in NODE_%d.\n", this->index()); return; } @@ -1296,8 +1298,8 @@ DISCRETE_RESET(dst_rcfilterN) /* !!!!!!!!!!!!!! CAN'T CHEAT LIKE THIS !!!!!!!!!!!!!!!! */ /* Put this stuff in a context */ - this->input[2] = f; - this->input[3] = DISC_FILTER_LOWPASS; + this->m_input[2] = f; + this->m_input[3] = DISC_FILTER_LOWPASS; /* Use first order filter */ dst_filter1_reset(node); @@ -1329,8 +1331,8 @@ DISCRETE_RESET(dst_rcdiscN) /* !!!!!!!!!!!!!! CAN'T CHEAT LIKE THIS !!!!!!!!!!!!!!!! */ /* Put this stuff in a context */ - this->input[2] = f; - this->input[3] = DISC_FILTER_LOWPASS; + this->m_input[2] = f; + this->m_input[3] = DISC_FILTER_LOWPASS; /* Use first order filter */ dst_filter1_reset(node); diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c index 66f7c50705a..31c7eb98acf 100644 --- a/src/emu/sound/disc_inp.c +++ b/src/emu/sound/disc_inp.c @@ -75,7 +75,7 @@ DISCRETE_RESET(dss_adjustment) { double min, max; - m_port = device->machine->m_portlist.find((const char *)this->custom_data()); + m_port = m_device->machine->m_portlist.find((const char *)this->custom_data()); if (m_port == NULL) fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag", this->index()); @@ -148,7 +148,7 @@ void DISCRETE_CLASS_FUNC(dss_input_data, input_write)(int sub_node, UINT8 data ) if (m_data != new_data) { /* Bring the system up to now */ - device->update(); + m_device->update(); m_data = new_data; @@ -175,7 +175,7 @@ void DISCRETE_CLASS_FUNC(dss_input_logic, input_write)(int sub_node, UINT8 data if (m_data != new_data) { /* Bring the system up to now */ - device->update(); + m_device->update(); m_data = new_data; @@ -202,7 +202,7 @@ void DISCRETE_CLASS_FUNC(dss_input_not, input_write)(int sub_node, UINT8 data ) if (m_data != new_data) { /* Bring the system up to now */ - device->update(); + m_device->update(); m_data = new_data; @@ -235,7 +235,7 @@ void DISCRETE_CLASS_FUNC(dss_input_pulse, input_write)(int sub_node, UINT8 data if (m_data != new_data) { /* Bring the system up to now */ - device->update(); + m_device->update(); m_data = new_data; } } @@ -302,7 +302,7 @@ void DISCRETE_CLASS_FUNC(dss_input_stream, input_write)(int sub_node, UINT8 data else { /* Bring the system up to now */ - device->update(); + m_device->update(); m_data = new_data; @@ -316,7 +316,7 @@ DISCRETE_START(dss_input_stream) { discrete_base_node::start(); - assert(DSS_INPUT_STREAM__STREAM < this->device->m_input_stream_list.count()); + assert(DSS_INPUT_STREAM__STREAM < m_device->m_input_stream_list.count()); /* Stream out number is set during start */ m_stream_in_number = DSS_INPUT_STREAM__STREAM; @@ -327,9 +327,9 @@ DISCRETE_START(dss_input_stream) m_is_buffered = is_buffered(); if (m_is_buffered) { - m_buffer_stream = stream_create(this->device, 0, 1, this->sample_rate(), this, static_stream_generate); + m_buffer_stream = stream_create(m_device, 0, 1, this->sample_rate(), this, static_stream_generate); - stream_set_input(device->m_stream, m_stream_in_number, + stream_set_input(m_device->m_stream, m_stream_in_number, m_buffer_stream, 0, 1.0); } else diff --git a/src/emu/sound/disc_mth.c b/src/emu/sound/disc_mth.c index 333bb0270e7..61382b518c2 100644 --- a/src/emu/sound/disc_mth.c +++ b/src/emu/sound/disc_mth.c @@ -233,11 +233,11 @@ DISCRETE_RESET(dst_dac_r1) if (ladderLength < 2 && info->rBias == 0 && info->rGnd == 0) { /* You need at least 2 resistors for a ladder */ - this->device->discrete_log("dst_dac_r1_reset - Ladder length too small"); + m_device->discrete_log("dst_dac_r1_reset - Ladder length too small"); } if (ladderLength > DISC_LADDER_MAXRES ) { - this->device->discrete_log("dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES"); + m_device->discrete_log("dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES"); } /* @@ -363,7 +363,7 @@ DISCRETE_STEP(dst_divide) if(DST_DIVIDE__DIV == 0) { this->output[0 ]= DBL_MAX; /* Max out but don't break */ - this->device->discrete_log("dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",this->index()); + m_device->discrete_log("dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",this->index()); } else { @@ -1152,8 +1152,6 @@ DISCRETE_RESET(dst_mixer) { DISCRETE_DECLARE_INFO(discrete_mixer_desc) - discrete_base_node *r_node; - int bit; double rTemp = 0; @@ -1161,14 +1159,11 @@ DISCRETE_RESET(dst_mixer) m_r_node_bit_flag = 0; for (bit = 0; bit < 8; bit++) { - r_node = this->device->discrete_find_node(info->r_node[bit]); - if (r_node != NULL) + m_r_node[bit] = m_device->node_output_ptr(info->r_node[bit]); + if (m_r_node[bit] != NULL) { - m_r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]); m_r_node_bit_flag |= 1 << bit; } - else - m_r_node[bit] = NULL; /* flag any caps */ if (info->c[bit] != 0) @@ -1282,7 +1277,7 @@ DISCRETE_STEP(dst_multiplex) else { /* Bad address. We will leave the output alone. */ - this->device->discrete_log("NODE_%02d - Address = %d. Out of bounds\n", this->index(), addr); + m_device->discrete_log("NODE_%02d - Address = %d. Out of bounds\n", this->index(), addr); } } @@ -1469,7 +1464,7 @@ DISCRETE_STEP(dst_samphold) if (DST_SAMPHOLD__CLOCK == 0) this->output[0] = DST_SAMPHOLD__IN0; break; default: - this->device->discrete_log("dst_samphold_step - Invalid clocktype passed"); + m_device->discrete_log("dst_samphold_step - Invalid clocktype passed"); break; } /* Save the last value */ @@ -1653,7 +1648,7 @@ DISCRETE_STEP(dst_transform) top = (int)number1 ^ (int)top; break; default: - this->device->discrete_log("dst_transform_step - Invalid function type/variable passed: %s",(const char *)this->custom_data()); + m_device->discrete_log("dst_transform_step - Invalid function type/variable passed: %s",(const char *)this->custom_data()); /* that is enough to fatalerror */ fatalerror("dst_transform_step - Invalid function type/variable passed: %s", (const char *)this->custom_data()); break; diff --git a/src/emu/sound/disc_mth.h b/src/emu/sound/disc_mth.h index a20e60728cb..2c90282429a 100644 --- a/src/emu/sound/disc_mth.h +++ b/src/emu/sound/disc_mth.h @@ -131,7 +131,7 @@ DISCRETE_CLASS_STEP_RESETA(dst_mixer, 1, int m_r_node_bit_flag; int m_c_bit_flag; double m_r_total; - double *m_r_node[DISC_MIXER_MAX_INPS]; /* Either pointer to resistance node output OR NULL */ + const double *m_r_node[DISC_MIXER_MAX_INPS]; /* Either pointer to resistance node output OR NULL */ double m_r_last[DISC_MIXER_MAX_INPS]; double m_exponent_rc[DISC_MIXER_MAX_INPS]; /* For high pass filtering cause by cIn */ double m_v_cap[DISC_MIXER_MAX_INPS]; /* cap voltage of each input */ diff --git a/src/emu/sound/disc_sys.c b/src/emu/sound/disc_sys.c index 8725d9a7bd0..ba00ecebc5e 100644 --- a/src/emu/sound/disc_sys.c +++ b/src/emu/sound/disc_sys.c @@ -30,10 +30,10 @@ DISCRETE_START( dso_csvlog ) { int log_num, node_num; - log_num = device->same_module_index(*this); + log_num = m_device->same_module_index(*this); m_sample_num = 0; - sprintf(m_name, "discrete_%s_%d.csv", device->tag(), log_num); + sprintf(m_name, "discrete_%s_%d.csv", m_device->tag(), log_num); m_csv_file = fopen(m_name, "w"); /* Output some header info */ fprintf(m_csv_file, "\"MAME Discrete System Node Log\"\n"); @@ -63,7 +63,7 @@ DISCRETE_STEP( dso_csvlog ) fprintf(m_csv_file, "%" I64FMT "d", ++m_sample_num); for (nodenum = 0; nodenum < this->active_inputs(); nodenum++) { - fprintf(m_csv_file, ", %f", *this->input[nodenum]); + fprintf(m_csv_file, ", %f", *this->m_input[nodenum]); } fprintf(m_csv_file, "\n"); } @@ -78,8 +78,8 @@ DISCRETE_START( dso_wavlog ) { int log_num; - log_num = device->same_module_index(*this); - sprintf(m_name, "discrete_%s_%d.wav", device->tag(), log_num); + log_num = m_device->same_module_index(*this); + sprintf(m_name, "discrete_%s_%d.wav", m_device->tag(), log_num); m_wavfile = wav_open(m_name, sample_rate(), active_inputs()/2); } diff --git a/src/emu/sound/disc_wav.c b/src/emu/sound/disc_wav.c index 088554db08f..fdb9ea772e4 100644 --- a/src/emu/sound/disc_wav.c +++ b/src/emu/sound/disc_wav.c @@ -332,22 +332,22 @@ DISCRETE_STEP(dss_lfsr_noise) fbresult = (m_lfsr_reg >> info->bitlength) & 0x01; /* Stage 2 feedback combine fbresultNew with infeed bit */ - fbresult = dss_lfsr_function(this->device, info->feedback_function1, fbresult, noise_feed, 0x01); + fbresult = dss_lfsr_function(m_device, info->feedback_function1, fbresult, noise_feed, 0x01); /* Stage 3 first we setup where the bit is going to be shifted into */ fbresult = fbresult * info->feedback_function2_mask; /* Then we left shift the register, */ m_lfsr_reg = m_lfsr_reg << 1; /* Now move the fbresult into the shift register and mask it to the bitlength */ - m_lfsr_reg = dss_lfsr_function(this->device, info->feedback_function2, fbresult, m_lfsr_reg, (1 << info->bitlength) - 1 ); + m_lfsr_reg = dss_lfsr_function(m_device, info->feedback_function2, fbresult, m_lfsr_reg, (1 << info->bitlength) - 1 ); /* Now get and store the new feedback result */ /* Fetch the feedback bits */ fb0 = (m_lfsr_reg >> info->feedback_bitsel0) & 0x01; fb1 = (m_lfsr_reg >> info->feedback_bitsel1) & 0x01; /* Now do the combo on them */ - fbresult = dss_lfsr_function(this->device, info->feedback_function0, fb0, fb1, 0x01); - m_lfsr_reg = dss_lfsr_function(this->device, DISC_LFSR_REPLACE, m_lfsr_reg, fbresult << info->bitlength, (2 << info->bitlength) - 1); + fbresult = dss_lfsr_function(m_device, info->feedback_function0, fb0, fb1, 0x01); + m_lfsr_reg = dss_lfsr_function(m_device, DISC_LFSR_REPLACE, m_lfsr_reg, fbresult << info->bitlength, (2 << info->bitlength) - 1); } /* Now select the output bit */ @@ -387,7 +387,7 @@ DISCRETE_RESET(dss_lfsr_noise) m_out_lfsr_reg = (info->flags & DISC_LFSR_FLAG_OUTPUT_SR_SN1) ? 1 : 0; if ((info->clock_type < DISC_CLK_ON_F_EDGE) || (info->clock_type > DISC_CLK_IS_FREQ)) - this->device->discrete_log("Invalid clock type passed in NODE_%d\n", this->index()); + m_device->discrete_log("Invalid clock type passed in NODE_%d\n", this->index()); m_last = (DSS_COUNTER__CLOCK != 0); if (info->clock_type == DISC_CLK_IS_FREQ) m_t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK; @@ -400,8 +400,8 @@ DISCRETE_RESET(dss_lfsr_noise) fb0 = (m_lfsr_reg >> info->feedback_bitsel0) & 0x01; fb1=(m_lfsr_reg >> info->feedback_bitsel1) & 0x01; /* Now do the combo on them */ - fbresult = dss_lfsr_function(this->device, info->feedback_function0, fb0, fb1, 0x01); - m_lfsr_reg=dss_lfsr_function(this->device, DISC_LFSR_REPLACE, m_lfsr_reg, fbresult << info->bitlength, (2<< info->bitlength ) - 1); + fbresult = dss_lfsr_function(m_device, info->feedback_function0, fb0, fb1, 0x01); + m_lfsr_reg=dss_lfsr_function(m_device, DISC_LFSR_REPLACE, m_lfsr_reg, fbresult << info->bitlength, (2<< info->bitlength ) - 1); /* Now select and setup the output bit */ this->output[0] = (m_lfsr_reg >> info->output_bit) & 0x01; @@ -439,7 +439,7 @@ DISCRETE_STEP(dss_noise) if(m_phase > (2.0 * M_PI)) { /* GCC's rand returns a RAND_MAX value of 0x7fff */ - int newval = (this->device->machine->rand() & 0x7fff) - 16384; + int newval = (m_device->machine->rand() & 0x7fff) - 16384; /* make sure the peak to peak values are the amplitude */ this->output[0] = DSS_NOISE__AMP / 2; @@ -663,14 +663,14 @@ DISCRETE_STEP(dss_op_amp_osc) enable = 1; } /* Work out the charge rates. */ - charge[0] = DSS_OP_AMP_OSC_NORTON_VP_IN / *m_r1 - i; - charge[1] = (m_v_out_high - OP_AMP_NORTON_VBE) / *m_r2 - charge[0]; + charge[0] = DSS_OP_AMP_OSC_NORTON_VP_IN / *m_r[1-1] - i; + charge[1] = (m_v_out_high - OP_AMP_NORTON_VBE) / *m_r[2-1] - charge[0]; /* Work out the Inverting Schmitt thresholds. */ - i1 = DSS_OP_AMP_OSC_NORTON_VP_IN / *m_r5; - i2 = (0.0 - OP_AMP_NORTON_VBE) / *m_r4; - m_threshold_low = (i1 + i2) * *m_r3 + OP_AMP_NORTON_VBE; - i2 = (m_v_out_high - OP_AMP_NORTON_VBE) / *m_r4; - m_threshold_high = (i1 + i2) * *m_r3 + OP_AMP_NORTON_VBE; + i1 = DSS_OP_AMP_OSC_NORTON_VP_IN / *m_r[5-1]; + i2 = (0.0 - OP_AMP_NORTON_VBE) / *m_r[4-1]; + m_threshold_low = (i1 + i2) * *m_r[3-1] + OP_AMP_NORTON_VBE; + i2 = (m_v_out_high - OP_AMP_NORTON_VBE) / *m_r[4-1]; + m_threshold_high = (i1 + i2) * *m_r[3-1] + OP_AMP_NORTON_VBE; break; } @@ -884,27 +884,19 @@ DISCRETE_RESET(dss_op_amp_osc) DISCRETE_DECLARE_INFO(discrete_op_amp_osc_info) const double *r_info_ptr; - const double **r_context_ptr; int loop; - discrete_base_node *r_node; double i1 = 0; /* inverting input current */ double i2 = 0; /* non-inverting input current */ /* link to resistor static or node values */ r_info_ptr = &info->r1; - r_context_ptr = &m_r1; for (loop = 0; loop < 8; loop ++) { - if IS_VALUE_A_NODE(*r_info_ptr) - { - r_node = this->device->discrete_find_node(*r_info_ptr); - *r_context_ptr = &(r_node->output[NODE_CHILD_NODE_NUM((int)*r_info_ptr)]); - } - else - *r_context_ptr = r_info_ptr; + m_r[loop] = m_device->node_output_ptr(*r_info_ptr); + if (m_r[loop] == NULL) + m_r[loop] = r_info_ptr; r_info_ptr++; - r_context_ptr++; } m_is_linear_charge = 1; diff --git a/src/emu/sound/disc_wav.h b/src/emu/sound/disc_wav.h index baa9487ef28..bf25279444a 100644 --- a/src/emu/sound/disc_wav.h +++ b/src/emu/sound/disc_wav.h @@ -120,14 +120,7 @@ private: }; DISCRETE_CLASS_STEP_RESETA(dss_op_amp_osc, 1, - const double *m_r1; /* pointers to resistor values */ - const double *m_r2; - const double *m_r3; - const double *m_r4; - const double *m_r5; - const double *m_r6; - const double *m_r7; - const double *m_r8; + const double *m_r[8]; /* pointers to resistor values */ int m_type; UINT8 m_flip_flop; /* flip/flop output state */ UINT8 m_flip_flop_xor; /* flip_flop ^ flip_flop_xor, 0 = discharge, 1 = charge */ diff --git a/src/emu/sound/discrete.c b/src/emu/sound/discrete.c index 1c327c3d965..77fdf46d56e 100644 --- a/src/emu/sound/discrete.c +++ b/src/emu/sound/discrete.c @@ -65,7 +65,7 @@ * *************************************/ -#define DISCRETE_DEBUGLOG (0) +#define DISCRETE_DEBUGLOG (1) /************************************* @@ -89,7 +89,7 @@ typedef struct int output_node; double buffer; } discrete_source_node; -typedef linked_list_t source_node_list_t; +typedef dynamic_array_t source_node_list_t; class discrete_task { @@ -121,8 +121,8 @@ protected: discrete_task(discrete_device *pdev) : device(pdev), task_group(0), m_threadid(-1), m_numbuffered(0) { - source_list.reset(); - step_list.reset(); + source_list.clear(); + step_list.clear(); } static void *task_callback(void *param, int threadid); @@ -139,7 +139,7 @@ private: volatile int m_samples; const double *m_source[DISCRETE_MAX_TASK_OUTPUTS]; - discrete_base_node *m_nodes[DISCRETE_MAX_TASK_OUTPUTS]; + const discrete_base_node *m_nodes[DISCRETE_MAX_TASK_OUTPUTS]; }; @@ -162,44 +162,7 @@ private: * *************************************/ -INLINE void linked_list_tail_add(const discrete_device *info, linked_list_entry ***list_tail_ptr, const void *ptr) -{ - **list_tail_ptr = auto_alloc(info->machine, linked_list_entry); - (**list_tail_ptr)->ptr = ptr; - (**list_tail_ptr)->next = NULL; - *list_tail_ptr = &((**list_tail_ptr)->next); -} -INLINE int linked_list_count(const linked_list_entry *list) -{ - int cnt = 0; - const linked_list_entry *entry; - - for (entry = list; entry != NULL; entry = entry->next) - cnt++; - - return cnt; -} - -INLINE void linked_list_add(const discrete_device *info, linked_list_entry **list, const void *ptr) -{ - linked_list_entry *entry; - - if (*list == NULL) - { - *list = auto_alloc(info->machine, linked_list_entry); - (*list)->ptr = ptr; - (*list)->next = NULL; - } - else - { - for (entry = *list; entry != NULL && entry->next != NULL; entry = entry->next) - ; - entry->next = auto_alloc(info->machine, linked_list_entry); - entry->next->ptr = ptr; - entry->next->next = NULL; - } -} /************************************* * @@ -210,26 +173,26 @@ INLINE void linked_list_add(const discrete_device *info, linked_list_entry **lis inline void discrete_task::step_nodes(void) { - for_each(discrete_source_node *, sn, &source_list) + for_each(discrete_source_node **, sn, &source_list) { - sn.item()->buffer = *sn.item()->ptr++; + (*sn)->buffer = *(*sn)->ptr++; } if (EXPECTED(!device->profiling())) { - for_each(discrete_step_interface *, entry, &step_list) + for_each(discrete_step_interface **, entry, &step_list) { /* Now step the node */ - entry.item()->step(); + (*entry)->step(); } } else { osd_ticks_t last = get_profile_ticks(); - for_each(discrete_step_interface *, entry, &step_list) + for_each(discrete_step_interface **, entry, &step_list) { - discrete_step_interface *node = entry.item(); + discrete_step_interface *node = *entry; node->run_time -= last; node->step(); @@ -247,14 +210,14 @@ void *discrete_task::task_callback(void *param, int threadid) task_list_t *list = (task_list_t *) param; do { - for_each(discrete_task *, task, list) + for_each(discrete_task **, task, list) { /* try to lock */ - if (task.item()->lock_threadid(threadid)) + if ((*task)->lock_threadid(threadid)) { - if (!task.item()->process()) + if (!(*task)->process()) return NULL; - task.item()->unlock(); + (*task)->unlock(); } } } while (1); @@ -267,11 +230,11 @@ bool discrete_task::process(void) int samples = MIN(m_samples, MAX_SAMPLES_PER_TASK_SLICE); /* check dependencies */ - for_each(discrete_source_node *, sn, &source_list) + for_each(discrete_source_node **, sn, &source_list) { int avail; - avail = sn.item()->task->m_ptr[sn.item()->output_node] - sn.item()->ptr; + avail = (*sn)->task->m_ptr[(*sn)->output_node] - (*sn)->ptr; assert_always(avail >= 0, "task_callback: available samples are negative"); if (avail < samples) samples = avail; @@ -301,9 +264,9 @@ void discrete_task::prepare_for_queue(int samples) m_ptr[i] = m_node_buf[i]; /* initialize sources */ - for_each(discrete_source_node *, sn, &source_list) + for_each(discrete_source_node **, sn, &source_list) { - sn.item()->ptr = sn.item()->task->m_node_buf[sn.item()->output_node]; + (*sn)->ptr = (*sn)->task->m_node_buf[(*sn)->output_node]; } } @@ -314,14 +277,14 @@ void discrete_task::check(discrete_task *dest_task) /* Determine, which nodes in the task are referenced by nodes in dest_task * and add them to the list of nodes to be buffered for further processing */ - for_each(discrete_step_interface *, node_entry, &step_list) + for_each(discrete_step_interface **, node_entry, &step_list) { - discrete_base_node *task_node = node_entry.item()->self; + discrete_base_node *task_node = (*node_entry)->self; - for_each(discrete_step_interface *, step_entry, &dest_task->step_list) + for_each(discrete_step_interface **, step_entry, &dest_task->step_list) { - discrete_base_node *dest_node = step_entry.item()->self; + discrete_base_node *dest_node = (*step_entry)->self; /* loop over all active inputs */ for (inputnum = 0; inputnum < dest_node->active_inputs(); inputnum++) @@ -346,23 +309,23 @@ void discrete_task::check(discrete_task *dest_task) if (m_numbuffered >= DISCRETE_MAX_TASK_OUTPUTS) fatalerror("dso_task_start - Number of maximum buffered nodes exceeded"); - m_node_buf[m_numbuffered] = auto_alloc_array(task_node->device->machine, double, + m_node_buf[m_numbuffered] = auto_alloc_array(device->machine, double, ((task_node->sample_rate() + STREAMS_UPDATE_FREQUENCY) / STREAMS_UPDATE_FREQUENCY)); - m_source[m_numbuffered] = (double *) dest_node->input[inputnum]; - m_nodes[m_numbuffered] = task_node->device->discrete_find_node(inputnode); + m_source[m_numbuffered] = (double *) dest_node->m_input[inputnum]; + m_nodes[m_numbuffered] = device->discrete_find_node(inputnode); i = m_numbuffered; m_numbuffered++; } device->discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode), NODE_CHILD_NODE_NUM(inputnode), this, task_group, dest_node->index(), dest_task->task_group); /* register into source list */ - source = auto_alloc(dest_node->device->machine, discrete_source_node); - dest_task->source_list.add_tail(source); + source = auto_alloc(device->machine, discrete_source_node); + dest_task->source_list.add(source); source->task = this; source->output_node = i; /* point the input to a buffered location */ - dest_node->input[inputnum] = &source->buffer; + dest_node->m_input[inputnum] = &source->buffer; } } @@ -392,7 +355,7 @@ discrete_base_node::~discrete_base_node(void) void discrete_base_node::init(discrete_device * pdev, const discrete_sound_block *xblock) { - device = pdev; + m_device = pdev; m_block = xblock; m_custom = m_block->custom; @@ -409,28 +372,19 @@ void discrete_base_node::init(discrete_device * pdev, const discrete_sound_block } } -void discrete_base_node::start(void) -{ -} - -int discrete_base_node::index(void) -{ - return NODE_INDEX(m_block->node); -} - -void discrete_base_node::save_state(device_t *device) +void discrete_base_node::save_state(void) { if (m_block->node != NODE_SPECIAL) - state_save_register_device_item_array(device, m_block->node, output); + state_save_register_device_item_array(m_device, m_block->node, output); } -discrete_base_node *discrete_device::discrete_find_node(int node) +const discrete_base_node *discrete_device::discrete_find_node(int node) { if (node < NODE_START || node > NODE_END) return NULL; return m_indexed_node[NODE_INDEX(node)]; } -void discrete_base_node::find_input_nodes(void) +void discrete_base_node::resolve_input_nodes(void) { int inputnum; @@ -442,14 +396,14 @@ void discrete_base_node::find_input_nodes(void) /* if this input is node-based, find the node in the indexed list */ if IS_VALUE_A_NODE(inputnode) { - discrete_base_node *node_ref = device->m_indexed_node[NODE_INDEX(inputnode)]; + discrete_base_node *node_ref = m_device->m_indexed_node[NODE_INDEX(inputnode)]; if (!node_ref) fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", index(), NODE_INDEX(inputnode)); if ((NODE_CHILD_NODE_NUM(inputnode) >= node_ref->max_output()) /*&& (node_ref->module_type() != DST_CUSTOM)*/) fatalerror("discrete_start - NODE_%02d referenced non existent output %d on node NODE_%02d", index(), NODE_CHILD_NODE_NUM(inputnode), NODE_INDEX(inputnode)); - input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */ + m_input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */ m_input_is_node |= 1 << inputnum; /* Bit flag if input is node */ } else @@ -457,23 +411,36 @@ void discrete_base_node::find_input_nodes(void) /* warn if trying to use a node for an input that can only be static */ if IS_VALUE_A_NODE(m_block->initial[inputnum]) { - device->discrete_log("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum); + m_device->discrete_log("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum); /* also report it in the error log so it is not missed */ logerror("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum); } else { - input[inputnum] = &(m_block->initial[inputnum]); + m_input[inputnum] = &(m_block->initial[inputnum]); } } } for (inputnum = m_active_inputs; inputnum < DISCRETE_MAX_INPUTS; inputnum++) { /* FIXME: Check that no nodes follow ! */ - input[inputnum] = &(m_block->initial[inputnum]); + m_input[inputnum] = &(m_block->initial[inputnum]); } } +const double *discrete_device::node_output_ptr(int onode) +{ + const discrete_base_node *node; + node = discrete_find_node(onode); + + if (node != NULL) + { + return &(node->output[NODE_CHILD_NODE_NUM(onode)]); + } + else + return NULL; +} + /************************************* * * Device implementation @@ -507,7 +474,7 @@ void CLIB_DECL ATTR_PRINTF(2,3) discrete_device::discrete_log(const char *text, // discrete_build_list: Build import list //------------------------------------------------- -void discrete_device::discrete_build_list(const discrete_sound_block *intf, linked_list_entry ***current) +void discrete_device::discrete_build_list(const discrete_sound_block *intf, sound_block_list_t &block_list) { int node_count = 0; @@ -517,57 +484,55 @@ void discrete_device::discrete_build_list(const discrete_sound_block *intf, link if (intf[node_count].type == DSO_IMPORT) { discrete_log("discrete_build_list() - DISCRETE_IMPORT @ NODE_%02d", NODE_INDEX(intf[node_count].node) ); - discrete_build_list((discrete_sound_block *) intf[node_count].custom, current); + discrete_build_list((discrete_sound_block *) intf[node_count].custom, block_list); } else if (intf[node_count].type == DSO_REPLACE) { - linked_list_entry *entry; - + bool found = false; node_count++; if (intf[node_count].type == DSS_NULL) fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list"); - for (entry = m_block_list; entry != NULL; entry = entry->next) + for (int i=0; i < block_list.count(); i++) { - discrete_sound_block *block = (discrete_sound_block *) entry->ptr; + const discrete_sound_block *block = block_list[i]; if (block->type != NODE_SPECIAL ) if (block->node == intf[node_count].node) { - entry->ptr = (void *) &intf[node_count]; + block_list[i] = &intf[node_count]; discrete_log("discrete_build_list() - DISCRETE_REPLACE @ NODE_%02d", NODE_INDEX(intf[node_count].node) ); + found = true; break; } } - if (entry == NULL) + if (!found) fatalerror("discrete_build_list: DISCRETE_REPLACE did not found node %d", NODE_INDEX(intf[node_count].node)); } else if (intf[node_count].type == DSO_DELETE) { - linked_list_entry *entry, *last; + dynamic_array_t deletethem; - last = NULL; - for (entry = m_block_list; entry != NULL; last = entry, entry = entry->next) + for (int i=0; iptr; + const discrete_sound_block *block = block_list[i]; if ((block->node >= intf[node_count].input_node[0]) && (block->node <= intf[node_count].input_node[1])) { discrete_log("discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(block->node) ); - if (last != NULL) - last->next = entry->next; - else - m_block_list = entry->next; + deletethem.add(i); } } + for_each (int *, i, &deletethem) + block_list.delete(*i); } else { - discrete_log("discrete_build_list() - adding node %d (*current %p)\n", node_count, *current); - linked_list_tail_add(this, current, &intf[node_count]); + discrete_log("discrete_build_list() - adding node %d\n", node_count); + block_list.add(&intf[node_count]); } node_count++; @@ -578,15 +543,14 @@ void discrete_device::discrete_build_list(const discrete_sound_block *intf, link // discrete_sanity_check: Sanity check list //------------------------------------------------- -void discrete_device::discrete_sanity_check(void) +void discrete_device::discrete_sanity_check(const sound_block_list_t &block_list) { - const linked_list_entry *entry; int node_count = 0; discrete_log("discrete_start() - Doing node list sanity check"); - for (entry = m_block_list; entry != NULL; entry = entry->next) + for (int i=0; i < block_list.count(); i++) { - discrete_sound_block *block = (discrete_sound_block *) entry->ptr; + const discrete_sound_block *block = block_list[i]; /* make sure we don't have too many nodes overall */ if (node_count > DISCRETE_MAX_NODES) @@ -631,10 +595,10 @@ static UINT64 list_run_time(const node_list_t &list) { UINT64 total = 0; - for_each(discrete_base_node *, node, &list) + for_each(discrete_base_node **, node, &list) { discrete_step_interface *step; - if (node.item()->interface(step)) + if ((*node)->interface(step)) total += step->run_time; } return total; @@ -644,9 +608,9 @@ static UINT64 step_list_run_time(const node_step_list_t &list) { UINT64 total = 0; - for_each(discrete_step_interface *, node, &list) + for_each(discrete_step_interface **, node, &list) { - total += node.item()->run_time; + total += (*node)->run_time; } return total; } @@ -665,43 +629,26 @@ void discrete_device::display_profiling(void) printf("Total Samples : %16" I64FMT "d\n", m_total_samples); tresh = total / count; printf("Threshold (mean): %16" I64FMT "d\n", tresh / m_total_samples ); - for_each(discrete_base_node *, node, &m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { discrete_step_interface *step; - if (node.item()->interface(step)) + if ((*node)->interface(step)) if (step->run_time > tresh) - printf("%3d: %20s %8.2f %10.2f\n", node.item()->index(), node.item()->module_name(), (float) step->run_time / (float) total * 100.0, ((float) step->run_time) / (float) m_total_samples); + printf("%3d: %20s %8.2f %10.2f\n", (*node)->index(), (*node)->module_name(), (float) step->run_time / (float) total * 100.0, ((float) step->run_time) / (float) m_total_samples); } /* Task information */ - for_each(discrete_task *, task, &task_list) + for_each(discrete_task **, task, &task_list) { - tt = step_list_run_time(task.item()->step_list); + tt = step_list_run_time((*task)->step_list); - printf("Task(%d): %8.2f %15.2f\n", task.item()->task_group, tt / (double) total * 100.0, tt / (double) m_total_samples); + printf("Task(%d): %8.2f %15.2f\n", (*task)->task_group, tt / (double) total * 100.0, tt / (double) m_total_samples); } printf("Average samples/stream_update: %8.2f\n", (double) m_total_samples / (double) m_total_stream_updates); } - -/************************************* - * - * Master reset of all nodes - * - *************************************/ - -/************************************* - * - * Stream update functions - * - *************************************/ - - - - - /************************************* * * First pass init of nodes @@ -709,18 +656,16 @@ void discrete_device::display_profiling(void) *************************************/ -void discrete_device::init_nodes(const linked_list_entry *block_list) +void discrete_device::init_nodes(const sound_block_list_t &block_list) { - const linked_list_entry *entry; discrete_task *task = NULL; /* list tail pointers */ int has_tasks = 0; /* check whether we have tasks ... */ - for (entry = block_list; entry != NULL; entry = entry->next) + for (int i = 0; i < block_list.count(); i++) { - const discrete_sound_block *block = (discrete_sound_block *) entry->ptr; - if (block->type == DSO_TASK_START) + if (block_list[i]->type == DSO_TASK_START) has_tasks = 1; } @@ -730,14 +675,13 @@ void discrete_device::init_nodes(const linked_list_entry *block_list) * No need to create a node since there are no dependencies. */ task = auto_alloc_clear(machine, discrete_task(this)); - task_list.add_tail(task); + task_list.add(task); } /* loop over all nodes */ - for (entry = block_list; entry != NULL; entry = entry->next) + for (int i = 0; i < block_list.count(); i++) { - const discrete_sound_block *block = (discrete_sound_block *) entry->ptr; - //int modulenum; + const discrete_sound_block *block = block_list[i]; discrete_base_node *node = block->factory->Create(this, block); /* keep track of special nodes */ @@ -767,7 +711,7 @@ void discrete_device::init_nodes(const linked_list_entry *block_list) if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS) fatalerror("discrete_dso_task: illegal task_group %d", task->task_group); //printf("task group %d\n", task->task_group); - task_list.add_tail(task); + task_list.add(task); break; case DSO_TASK_END: @@ -792,11 +736,11 @@ void discrete_device::init_nodes(const linked_list_entry *block_list) discrete_dss_input_stream_node *input_stream = dynamic_cast(node); if (input_stream != NULL) { - m_input_stream_list.add_tail(input_stream); + m_input_stream_list.add(input_stream); } /* add to node list */ - m_node_list.add_tail(node); + m_node_list.add(node); /* our running order just follows the order specified */ /* does the node step ? */ @@ -807,13 +751,13 @@ void discrete_device::init_nodes(const linked_list_entry *block_list) if (task == NULL) fatalerror("init_nodes() - found node outside of task: %s", node->module_name() ); else - task->step_list.add_tail(step); + task->step_list.add(step); } /* if this is an output interface, add it the output list */ discrete_output_interface *out; if (node->interface(out)) - m_output_list.add_tail(out); + m_output_list.add(out); if (block->type == DSO_TASK_END) @@ -822,7 +766,7 @@ void discrete_device::init_nodes(const linked_list_entry *block_list) } /* and register save state */ - node->save_state(this); + node->save_state(); } if (!has_tasks) @@ -842,15 +786,15 @@ void discrete_device::init_nodes(const linked_list_entry *block_list) *************************************/ -int discrete_device::same_module_index(discrete_base_node &node) +int discrete_device::same_module_index(const discrete_base_node &node) { int index = 0; - for_each(discrete_base_node *, n, &m_node_list) + for_each(discrete_base_node **, n, &m_node_list) { - if (n.item() == &node) + if (*n == &node) return index; - if (n.item()->module_type() == node.module_type()) + if ((*n)->module_type() == node.module_type()) index++; } return -1; @@ -934,9 +878,9 @@ discrete_device::~discrete_device(void) /* Process nodes which have a stop func */ - for_each(discrete_base_node *, node, &m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { - node.item()->stop(); + (*node)->stop(); } if (DISCRETE_DEBUGLOG) @@ -957,7 +901,6 @@ void discrete_device::device_start() // create the stream //m_stream = stream_create(this, 0, 2, 22257, this, static_stream_generate); - linked_list_entry **intf; const discrete_sound_block *intf_start = (m_config.m_intf != NULL) ? m_config.m_intf : (discrete_sound_block *) baseconfig().static_config(); char name[32]; @@ -983,28 +926,27 @@ void discrete_device::device_start() m_profiling = atoi(getenv("DISCRETE_PROFILING")); /* Build the final block list */ - m_block_list = NULL; - intf = &m_block_list; - discrete_build_list(intf_start, &intf); + sound_block_list_t block_list; + discrete_build_list(intf_start, block_list); /* first pass through the nodes: sanity check, fill in the indexed_nodes, and make a total count */ - discrete_sanity_check(); + discrete_sanity_check(block_list); /* Start with empty lists */ - m_node_list.reset(); - m_output_list.reset(); - m_input_stream_list.reset(); + m_node_list.clear(); + m_output_list.clear(); + m_input_stream_list.clear(); /* allocate memory to hold pointers to nodes by index */ m_indexed_node = auto_alloc_array_clear(this->machine, discrete_base_node *, DISCRETE_MAX_NODES); /* initialize the node data */ - init_nodes(m_block_list); + init_nodes(block_list); /* now go back and find pointers to all input nodes */ - for_each(discrete_base_node *, node, &m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { - node.item()->find_input_nodes(); + (*node)->resolve_input_nodes(); } /* initialize the stream(s) */ @@ -1016,19 +958,19 @@ void discrete_device::device_start() /* Process nodes which have a start func */ - for_each(discrete_base_node *, node, &m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { - node.item()->start(); + (*node)->start(); } /* Now set up tasks */ - for_each(discrete_task *, task, &task_list) + for_each(discrete_task **, task, &task_list) { - for_each(discrete_task *, dest_task, &task_list) + for_each(discrete_task **, dest_task, &task_list) { - if (task.item()->task_group > dest_task.item()->task_group) - dest_task.item()->check(task.item()); + if ((*task)->task_group > (*dest_task)->task_group) + (*dest_task)->check((*task)); } } } @@ -1044,11 +986,12 @@ void discrete_device::device_reset() update(); /* loop over all nodes */ - for_each (discrete_base_node *, node, &m_node_list) + for_each (discrete_base_node **, node, &m_node_list) { - node.item()->output[0] = 0; + /* Fimxe : node_level */ + (*node)->output[0] = 0; - node.item()->reset(); + (*node)->reset(); } } @@ -1071,28 +1014,28 @@ void discrete_device::stream_generate(stream_sample_t **inputs, stream_sample_t return; /* Setup any output streams */ outputnum = 0; - for_each(discrete_output_interface *, node, &m_output_list) + for_each(discrete_output_interface **, node, &m_output_list) { - node.item()->set_output(outputs[outputnum]); + (*node)->set_output(outputs[outputnum]); outputnum++; } /* Setup any input streams */ - for_each(discrete_dss_input_stream_node *, node, &m_input_stream_list) + for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) { - node.item()->m_ptr = (stream_sample_t *) inputs[node.item()->m_stream_in_number]; + (*node)->m_ptr = (stream_sample_t *) inputs[(*node)->m_stream_in_number]; } /* Setup tasks */ - for_each(discrete_task *, task, &task_list) + for_each(discrete_task **, task, &task_list) { /* unlock the thread */ - task.item()->unlock(); + (*task)->unlock(); - task.item()->prepare_for_queue(samples); + (*task)->prepare_for_queue(samples); } - for_each(discrete_task *, task, &task_list) + for_each(discrete_task **, task, &task_list) { /* Fire a work item for each task */ osd_work_item_queue(m_queue, discrete_task::task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE); @@ -1112,7 +1055,7 @@ void discrete_device::stream_generate(stream_sample_t **inputs, stream_sample_t READ8_MEMBER( discrete_device::read ) { - discrete_base_node *node = discrete_find_node(offset); + const discrete_base_node *node = discrete_find_node(offset); UINT8 data = 0; @@ -1136,7 +1079,7 @@ READ8_MEMBER( discrete_device::read ) WRITE8_MEMBER( discrete_device::write ) { - discrete_base_node *node = discrete_find_node(offset); + const discrete_base_node *node = discrete_find_node(offset); /* Update the node input value if it's a proper input node */ if (node) diff --git a/src/emu/sound/discrete.h b/src/emu/sound/discrete.h index 5c38762c279..56579d4f2a2 100644 --- a/src/emu/sound/discrete.h +++ b/src/emu/sound/discrete.h @@ -3508,7 +3508,7 @@ #define DISCRETE_DECLARE_CONTEXT(_name) struct _name##_context *context = (struct _name##_context *)this->m_context; #define DISCRETE_DECLARE_INFO(_name) const _name *info = (const _name *)this->custom_data(); -#define DISCRETE_INPUT(_num) (*(this->input[_num])) +#define DISCRETE_INPUT(_num) (*(this->m_input[_num])) /************************************* * @@ -3750,94 +3750,84 @@ enum * *************************************/ -typedef struct _linked_list_entry linked_list_entry; -struct _linked_list_entry -{ - linked_list_entry *next; - const void *ptr; -}; +#define for_each(_T, _e, _l) for (_T _e = (_l)->begin_ptr() ; _e <= (_l)->end_ptr(); _e++) -template class enumerator_t +/* + * add and delete may be slow - the focus is on access! + */ + +template class dynamic_array_t { public: - enumerator_t(linked_list_entry *first, resource_pool &pool = global_resource_pool) : m_cur(first) { } - virtual ~enumerator_t() { } + dynamic_array_t(int initial) { + m_count = 0; + m_allocated = initial; + m_arr = global_alloc_array_clear(T, m_allocated); + } + dynamic_array_t() { + m_count = 0; + m_allocated = 16; + m_arr = global_alloc_array_clear(T, m_allocated); + } + ~dynamic_array_t() { + global_free(m_arr); + } + T& operator [] (unsigned int index) const // get array item + { + return m_arr[index]; + } - //inline void set_first(linked_list_entry *first) { m_cur = first; } - inline T item(void) { return (T) m_cur->ptr; } - inline void next(void) { m_cur = m_cur->next; } - inline bool has_item(void) { return (m_cur != NULL); } -protected: + dynamic_array_t(const dynamic_array_t &a) // copy constructor + { + m_allocated = a.count(); + if (m_allocated < 16) + m_allocated = 16; + m_count = a.count(); + m_arr = global_alloc_array_clear(T, m_allocated); + for (int i=0; i < m_count; i++) + m_arr[i] = a[i]; + } + dynamic_array_t& operator = (const dynamic_array_t &a) // assignment operator + { + if (this == &a) return *this; + m_allocated = a.count(); + if (m_allocated < 16) + m_allocated = 16; + m_count = a.count(); + m_arr = global_alloc_array_clear(T, m_allocated); + for (int i=0; i < m_count; i++) + m_arr[i] = a[i]; + return *this; + } + + inline void add(T object) + { + if (m_count >= m_allocated) + { + m_allocated *= 2; + T *newarr = global_alloc_array_clear(T, m_allocated); + for (int i=0; i < m_count; i++) + newarr[i] = m_arr[i]; + global_free(m_arr); + m_arr = newarr; + } + m_arr[m_count] = object; + m_count++; + } + inline void delete(int index) + { + for (int i=index+1; i < m_count; i++) + m_arr[i-1] = m_arr[i]; + m_count--; + } + inline void clear(void) { m_count = 0; } + inline int count(void) const { return m_count; } + inline T *begin_ptr(void) const { return m_arr; } + inline T *end_ptr(void) const { return m_arr + (m_count - 1); } private: - linked_list_entry *m_cur; -}; - -#define for_each(_T, _e, _l) for (enumerator_t<_T> _e = (_l)->enumerator() ; _e.has_item(); _e.next()) - -template class linked_list_t -{ -public: - linked_list_t() { m_first = NULL; m_last = NULL; } - ~linked_list_t() { reset(); } - - void add_tail(T object) - { - linked_list_entry *n = global_alloc(linked_list_entry); - n->ptr = (void *) object; - n->next = NULL; - if (m_last == NULL) - { - m_last = n; - m_first = n; - } - else - { - m_last->next = n; - m_last = n; - } - } - void add_head(T object) - { - linked_list_entry *n = global_alloc(linked_list_entry); - n->ptr = (void *) object; - n->next = NULL; - if (m_last == NULL) - { - m_last = n; - m_first = n; - } - else - { - n->next = m_first; - m_first = n; - } - } - void reset(void) - { - linked_list_entry *e = m_first; - while (e != NULL) - { - linked_list_entry *o = e; - e = e->next; - global_free(o); - } - m_first = NULL; m_last = NULL; - } - inline int count(void) const - { - int cnt = 0; - linked_list_entry *e = m_first; - while (e != NULL) - { - e = e->next; - cnt++; - } - return cnt; - } - inline enumerator_t enumerator(void) const { enumerator_t r(m_first); return r; } -private: - linked_list_entry *m_first; - linked_list_entry *m_last; + T *m_arr; + int m_count; + int m_allocated; }; /************************************* @@ -4241,9 +4231,9 @@ class discrete_task; class discrete_base_node; class discrete_dss_input_stream_node; class discrete_device; -typedef linked_list_t node_list_t; -typedef linked_list_t input_stream_node_list_t; -typedef linked_list_t task_list_t; +typedef dynamic_array_t node_list_t; +typedef dynamic_array_t istream_node_list_t; +typedef dynamic_array_t task_list_t; /************************************* @@ -4272,6 +4262,7 @@ struct _discrete_sound_block const char * name; /* Node Name */ const char * mod_name; /* Module / class name */ }; +typedef dynamic_array_t sound_block_list_t; /************************************* * @@ -4288,7 +4279,7 @@ public: osd_ticks_t run_time; discrete_base_node * self; }; -typedef linked_list_t node_step_list_t; +typedef dynamic_array_t node_step_list_t; class discrete_input_interface { @@ -4361,7 +4352,7 @@ protected: }; class discrete_output_interface; -typedef linked_list_t node_output_list_t; +typedef dynamic_array_t node_output_list_t; // ======================> discrete_device @@ -4370,6 +4361,7 @@ class discrete_device : public device_t, public device_sound_interface { friend class discrete_device_config; friend class discrete_base_node; + friend class discrete_task; friend class discrete_dss_input_stream_node; // construction/destruction @@ -4378,23 +4370,21 @@ class discrete_device : public device_t, public device_sound_interface public: DECLARE_READ8_MEMBER(read); DECLARE_WRITE8_MEMBER(write); - //sound_stream *m_stream; virtual ~discrete_device(void); /* --------------------------------- */ + void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const char *text, ...) const; - discrete_base_node *discrete_find_node(int node); + const double *node_output_ptr(int onode); + /* FIXME: this is used by csv and wav logs - going forward, identifiers should be explicitly passed */ - int same_module_index(discrete_base_node &node); + int same_module_index(const discrete_base_node &node); + inline int profiling(void) { return m_profiling; } - void update(void) { stream_update(m_stream); } + + void update(void) const { stream_update(m_stream); } /* FIXME: theses should be protected */ - /* tasks */ - task_list_t task_list; /* discrete_task_context * */ - /* the input streams */ - input_stream_node_list_t m_input_stream_list; - protected: @@ -4406,6 +4396,8 @@ protected: static STREAM_UPDATE( static_stream_generate ); virtual void stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples); + const discrete_base_node *discrete_find_node(int node); + // internal state const discrete_device_config &m_config; @@ -4421,34 +4413,36 @@ protected: private: - void discrete_build_list(const discrete_sound_block *intf, linked_list_entry ***current); - void discrete_sanity_check(void); + void discrete_build_list(const discrete_sound_block *intf, sound_block_list_t &block_list); + void discrete_sanity_check(const sound_block_list_t &block_list); void display_profiling(void); - void init_nodes(const linked_list_entry *block_list); + void init_nodes(const sound_block_list_t &block_list); /* internal node tracking */ - discrete_base_node **m_indexed_node; + discrete_base_node ** m_indexed_node; /* list of all nodes */ - node_list_t m_node_list; /* node_description * */ + node_list_t m_node_list; /* node_description * */ - /* list of discrete blocks after prescan (IMPORT, DELETE, REPLACE) */ - linked_list_entry *m_block_list; /* discrete_sound_block * */ + /* tasks */ + task_list_t task_list; /* discrete_task_context * */ + + /* the input streams */ + istream_node_list_t m_input_stream_list; /* output node tracking */ - node_output_list_t m_output_list; + node_output_list_t m_output_list; /* debugging statistics */ - FILE *m_disclogfile; + FILE * m_disclogfile; /* parallel tasks */ - osd_work_queue *m_queue; + osd_work_queue * m_queue; /* profiling */ - int m_profiling; - UINT64 m_total_samples; - UINT64 m_total_stream_updates; - + int m_profiling; + UINT64 m_total_samples; + UINT64 m_total_stream_updates; }; // device type definition @@ -4469,63 +4463,66 @@ class discrete_base_node public: virtual void reset(void) { } - virtual void start(void); + virtual void start(void) { } virtual void stop(void) { } + virtual void save_state(void); - inline bool interface(discrete_step_interface *&intf) { intf = m_step_intf; return (intf != NULL); } - inline bool interface(discrete_input_interface *&intf) { intf = m_input_intf; return (intf != NULL); } - inline bool interface(discrete_output_interface *&intf) { intf = m_output_intf; return (intf != NULL); } + inline bool interface(discrete_step_interface *&intf) const { intf = m_step_intf; return (intf != NULL); } + inline bool interface(discrete_input_interface *&intf) const { intf = m_input_intf; return (intf != NULL); } + inline bool interface(discrete_output_interface *&intf) const { intf = m_output_intf; return (intf != NULL); } virtual int max_output(void) { return 1; }; /* Return the node index, i.e. X from NODE(X) */ - int index(void); + inline int index(void) { return NODE_INDEX(m_block->node); } + /* Return the node number, i.e. NODE(X) */ - inline int block_node(void) { return m_block->node; } + inline int block_node(void) const { return m_block->node; } + /* Custom function specific initialisation data */ inline const void *custom_data(void) { return m_custom; } - void find_input_nodes(void); - void save_state(device_t *device); - inline int input_node(int inputnum) { return m_block->input_node[inputnum]; } - /* The node's last output value */ - double output[DISCRETE_MAX_OUTPUTS]; - - const double * input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */ - /* Number of active inputs on this node type */ inline int active_inputs(void) { return m_active_inputs; } /* Bit Flags. 1 in bit location means input_is_node */ inline int input_is_node(void) { return m_input_is_node; }; - inline double sample_time(void) { return device->m_sample_time; } - inline int sample_rate(void) { return device->m_sample_rate; } + inline double sample_time(void) { return m_device->m_sample_time; } + inline int sample_rate(void) { return m_device->m_sample_rate; } const char * module_name(void) { return m_block->mod_name; } - inline int module_type(void) { return m_block->type; } - - discrete_device *device; /* Points to the parent */ + inline int module_type(void) const { return m_block->type; } protected: discrete_base_node(); virtual ~discrete_base_node(); - /* finish node setup after allocation is complete */ void init(discrete_device * pdev, const discrete_sound_block *block); + void resolve_input_nodes(void); + + discrete_device * m_device; /* Points to the parent */ + + + double output[DISCRETE_MAX_OUTPUTS]; /* The node's last output value */ + + const double * m_input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */ + private: - const discrete_sound_block *m_block; /* Points to the node's setup block. */ - int m_active_inputs; /* Number of active inputs on this node type */ - /* Custom function specific initialisation data */ - const void * m_custom; - int m_input_is_node; - discrete_step_interface *m_step_intf; - discrete_input_interface *m_input_intf; - discrete_output_interface *m_output_intf; + + const discrete_sound_block * m_block; /* Points to the node's setup block. */ + int m_active_inputs; /* Number of active inputs on this node type */ + + const void * m_custom; /* Custom function specific initialisation data */ + int m_input_is_node; + + discrete_step_interface * m_step_intf; + discrete_input_interface * m_input_intf; + discrete_output_interface * m_output_intf; }; class discrete_node_base_factory