/*** * \brief To be called after monitor parameters are set */ public void start() { // FIXME: once moved to netlist this may no longer be necessary. // Only copies constructor init m_last_sync_val = 0.0; m_col = new rgb_t(0, 0, 0); m_last_x = 0; m_last_y = 0; m_last_sync_time = (fixedfreq_monitor_state_time_type)0; m_line_time = (fixedfreq_monitor_state_time_type)0; m_last_hsync_time = (fixedfreq_monitor_state_time_type)0; m_last_vsync_time = (fixedfreq_monitor_state_time_type)0; /* sync separator */ m_vsync_filter = 0.0; m_sig_vsync = 0; m_sig_composite = 0; m_sig_field = 0; // htotal = m_desc.m_hbackporch; // vtotal = m_desc.m_vbackporch; /* sync separator */ //m_vsync_threshold = (exp(- 3.0/(3.0+3.0))) - exp(-1.0); //printf("trigger %f with len %f\n", m_vsync_threshold, 1e6 / m_vsync_filter_timeconst); // Minimum frame period to be passed to video system ? m_fragments.clear(); m_intf.vsync_end_cb(m_desc.clock_period() * m_desc.vtotal() * m_desc.htotal()); }
//------------------------------------------------- // close - close a file and free all data; also // remove the file if requested //------------------------------------------------- public void close() { // close files and free memory if (m_zipfile != null) { m_zipfile.Dispose(); } m_zipfile = null; if (m_file != null) { m_file.Dispose(); } m_file = null; m_zipdata.clear(); if (m_remove_on_close) { m_osdfile.remove(m_fullpath); } m_remove_on_close = false; // reset our hashes and path as well m_hashes.reset(); m_fullpath = ""; }
//virtual ~input_code_poller(); public virtual void reset() { // iterate over device classes and devices m_axis_memory.clear(); m_switch_memory.clear(); for (input_device_class classno = input_device_class.DEVICE_CLASS_FIRST_VALID; input_device_class.DEVICE_CLASS_LAST_VALID >= classno; ++classno) { input_class devclass = m_manager.device_class(classno); if (devclass.enabled()) { for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum) { // fetch the device; ignore if nullptr input_device device = devclass.device(devnum); if (device != null) { // iterate over items within each device for (input_item_id itemid = input_item_id.ITEM_ID_FIRST_VALID; device.maxitem() >= itemid; ++itemid) { // for any non-switch items, set memory to the current value input_device_item item = device.item(itemid); if (item != null && (item.itemclass() != input_item_class.ITEM_CLASS_SWITCH)) { m_axis_memory.emplace_back(new std.pair <input_device_item, s32>(item, m_manager.code_value(item.code()))); } } } } } } m_axis_memory.Sort(); //std::sort(m_axis_memory.begin(), m_axis_memory.end()); }
// register for save states /*------------------------------------------------- * register_save - register for save states * -------------------------------------------------*/ public void register_save() { assert(m_save_order.empty()); assert(m_save_data == null); // make space for the data m_save_order.clear(); m_save_order.reserve(m_itemtable.size()); m_save_data = new s32 [m_itemtable.size()]; //m_save_data = std::make_unique<s32 []>(m_itemtable.size()); // sort existing outputs by name and register for save foreach (var item in m_itemtable) { m_save_order.emplace_back(item.second()); } m_save_order.Sort((l, r) => { return(string.Compare(l.name(), r.name())); }); //std::sort(m_save_order.begin(), m_save_order.end(), [] (auto const &l, auto const &r) { return l.get().name() < r.get().name(); }); // register the reserved space for saving //throw new emu_unimplemented(); #if false machine().save().save_pointer(nullptr, "output", nullptr, 0, NAME(m_save_data), m_itemtable.size()); #endif if (OUTPUT_VERBOSE) { osd_printf_verbose("Registered {0} outputs for save states\n", m_itemtable.size()); } }
public void clear() { m_terms.clear(); m_connected_net_idx.clear(); m_gt.clear(); m_go.clear(); m_Idr.clear(); m_connected_net_V.clear(); }
// internal helpers //------------------------------------------------- // video_exit - close down the video system //------------------------------------------------- void exit(running_machine machine_) { // stop recording any movie m_movie_recordings.clear(); // free the snapshot target machine().render().target_free(m_snap_target); m_snap_bitmap.reset(); // print a final result if we have at least 2 seconds' worth of data if (!emulator_info.standalone() && m_overall_emutime.seconds() >= 1) { osd_ticks_t tps = m_osdcore.osd_ticks_per_second(); double final_real_time = (double)m_overall_real_seconds + (double)m_overall_real_ticks / (double)tps; double final_emu_time = m_overall_emutime.as_double(); osd_printf_info("Average speed: {0}%% ({1} seconds)\n", 100 * final_emu_time / final_real_time, (m_overall_emutime + new attotime(0, ATTOSECONDS_PER_SECOND / 2)).seconds()); // %.2f%% (%d seconds)\n } }
//template <typename NT> void compile_postfix(std.vector <string> inputs, std.vector <string> cmds, string expr) //void pfunction<NT>::compile_postfix(const inputs_container &inputs, const std::vector<pstring> &cmds, const pstring &expr) noexcept(false) { m_precompiled.clear(); int stk = 0; foreach (string cmd in cmds) { rpn_inst rc = new rpn_inst(); var p = pcmds().find(cmd); if (p != default) { rc = new rpn_inst(p.cmd); stk -= p.adj; } else { for (size_t i = 0; i < inputs.size(); i++) { if (inputs[i] == cmd) { rc = new rpn_inst(rpn_cmd.PUSH_INPUT, i); stk += 1; break; } } if (rc.cmd() != rpn_cmd.PUSH_INPUT) { bool err = false; var rs = plib.pg.right(cmd, 1); var r = units_si().find(rs); //auto r=units_si<NT>().find(rs); if (ops.equals(r, ops.default_)) //if (r == units_si<NT>().end()) { rc = new rpn_inst(ops.pstonum_ne(false, cmd, out err)); //rc = rpn_inst(plib::pstonum_ne<NT>(cmd, err)); } else { rc = new rpn_inst(ops.multiply(ops.pstonum_ne(false, plib.pg.left(cmd, cmd.length() - 1), out err), r)); //rc = rpn_inst(plib::pstonum_ne<NT>(plib::left(cmd, cmd.length()-1), err) * r->second); } if (err) { throw new pexception(new plib.pfmt("pfunction: unknown/misformatted token <{0}> in <{1}>").op(cmd, expr)); } stk += 1; } } if (stk < 1) { throw new pexception(new plib.pfmt("pfunction: stack underflow on token <{0}> in <{1}>").op(cmd, expr)); } if (stk >= (int)MAX_STACK) { throw new pexception(new plib.pfmt("pfunction: stack overflow on token <{0}> in <{1}>").op(cmd, expr)); } if (rc.cmd() == rpn_cmd.LP || rc.cmd() == rpn_cmd.RP) { throw new pexception(new plib.pfmt("pfunction: parenthesis inequality on token <{1}> in <{2}>").op(cmd, expr)); } m_precompiled.push_back(rc); } if (stk != 1) { throw new pexception(new plib.pfmt("pfunction: stack count {0} different to one on <{1}>").op(stk, expr)); } compress(); }
// setters //------------------------------------------------- // set_layout - set the layout for a gfx_element //------------------------------------------------- void set_layout(gfx_layout gl, ListBytesPointer srcdata) //const u8 *srcdata) { m_srcdata = srcdata; // configure ourselves m_width = m_origwidth = gl.width; m_height = m_origheight = gl.height; m_startx = m_starty = 0; m_total_elements = gl.total; m_color_granularity = (UInt16)(1 << gl.planes); m_color_depth = m_color_granularity; // copy data from the layout m_layout_is_raw = gl.planeoffset[0] == digfx_global.GFX_RAW; m_layout_planes = (byte)gl.planes; m_layout_charincrement = gl.charincrement; // raw graphics case if (m_layout_is_raw) { // RAW layouts don't need these arrays m_layout_planeoffset.clear(); m_layout_xoffset.clear(); m_layout_yoffset.clear(); m_gfxdata_allocated.clear(); // modulos are determined for us by the layout m_line_modulo = gl.yoffs(0) / 8; m_char_modulo = gl.charincrement / 8; // RAW graphics must have a pointer up front //assert(srcdata != NULL); m_gfxdata = new ListBytesPointer(srcdata); //m_gfxdata = const_cast<u8 *>(srcdata); } // decoded graphics case else { // copy offsets m_layout_planeoffset.resize(m_layout_planes); m_layout_xoffset.resize(m_width); m_layout_yoffset.resize(m_height); for (int p = 0; p < m_layout_planes; p++) { m_layout_planeoffset[p] = gl.planeoffset[p]; } for (int y = 0; y < m_height; y++) { m_layout_yoffset[y] = gl.yoffs(y); } for (int x = 0; x < m_width; x++) { m_layout_xoffset[x] = gl.xoffs(x); } // we get to pick our own modulos m_line_modulo = m_origwidth; m_char_modulo = m_line_modulo * m_origheight; // allocate memory for the data m_gfxdata_allocated.resize((int)(m_total_elements * m_char_modulo)); m_gfxdata = new ListBytesPointer(m_gfxdata_allocated); //m_gfxdata = &m_gfxdata_allocated[0]; } // mark everything dirty m_dirty.resize((int)m_total_elements); memset(m_dirty, (u8)1, m_total_elements); // allocate a pen usage array for entries with 32 pens or less if (m_color_depth <= 32) { m_pen_usage.resize((int)m_total_elements); } else { m_pen_usage.clear(); } }
//template <typename T> //void store(const T * RESTRICT V); //template <typename T> //T delta(const T * RESTRICT V); //template <typename T> //void build_LE_A(); //template <typename T> //void build_LE_RHS(); /* calculate matrix */ void setup_matrix() { UInt32 iN = (UInt32)m_nets.size(); for (UInt32 k = 0; k < iN; k++) { m_terms[k].railstart = m_terms[k].count(); for (UInt32 i = 0; i < m_rails_temp[k].count(); i++) { this.m_terms[k].add(m_rails_temp[k].terms()[i], m_rails_temp[k].connected_net_idx()[i], false); } m_terms[k].set_pointers(); } foreach (terms_for_net_t rt in m_rails_temp) { rt.clear(); // no longer needed //plib::pfree(rt); // no longer needed } m_rails_temp.clear(); /* Sort in descending order by number of connected matrix voltages. * The idea is, that for Gauss-Seidel algo the first voltage computed * depends on the greatest number of previous voltages thus taking into * account the maximum amout of information. * * This actually improves performance on popeye slightly. Average * GS computations reduce from 2.509 to 2.370 * * Smallest to largest : 2.613 * Unsorted : 2.509 * Largest to smallest : 2.370 * * Sorting as a general matrix pre-conditioning is mentioned in * literature but I have found no articles about Gauss Seidel. * * For Gaussian Elimination however increasing order is better suited. * NOTE: Even better would be to sort on elements right of the matrix diagonal. * */ if (m_sort != eSortType.NOSORT) { int sort_order = (m_sort == eSortType.DESCENDING ? 1 : -1); for (UInt32 k = 0; k < iN - 1; k++) { for (UInt32 i = k + 1; i < iN; i++) { if (((int)(m_terms[k].railstart) - (int)(m_terms[i].railstart)) * sort_order < 0) { //std::swap(m_terms[i], m_terms[k]); var termsTemp = m_terms[i]; m_terms[i] = m_terms[k]; m_terms[k] = termsTemp; //std::swap(m_nets[i], m_nets[k]); var netsTemp = m_nets[i]; m_nets[i] = m_nets[k]; m_nets[k] = netsTemp; } } } foreach (var term in m_terms) { var other = term.connected_net_idx(); for (UInt32 i = 0; i < term.count(); i++) { if (other[i] != -1) { other[i] = get_net_idx(term.terms()[i].otherterm.net()); } } } } /* create a list of non zero elements. */ for (UInt32 k = 0; k < iN; k++) { terms_for_net_t t = m_terms[k]; /* pretty brutal */ var other = t.connected_net_idx(); t.nz.clear(); for (UInt32 i = 0; i < t.railstart; i++) { if (!t.nz.Contains((UInt32)other[i])) //if (!plib::container::contains(t->m_nz, static_cast<unsigned>(other[i]))) { t.nz.push_back((UInt32)other[i]); } } t.nz.push_back(k); // add diagonal /* and sort */ t.nz.Sort(); //std::sort(t.m_nz.begin(), t.m_nz.end()); } /* create a list of non zero elements right of the diagonal * These list anticipate the population of array elements by * Gaussian elimination. */ for (UInt32 k = 0; k < iN; k++) { terms_for_net_t t = m_terms[k]; /* pretty brutal */ var other = t.connected_net_idx(); if (k == 0) { t.nzrd.clear(); } else { t.nzrd = m_terms[k - 1].nzrd; for (var jIdx = 0; jIdx < t.nzrd.Count;) //for (var j = t.nzrd.begin(); j != t.nzrd.end(); ) { var j = t.nzrd[jIdx]; if (j < k + 1) { t.nzrd.erase(jIdx); } else { ++jIdx; } } } for (UInt32 i = 0; i < t.railstart; i++) { if (!t.nzrd.Contains((UInt32)other[i]) && other[i] >= (int)(k + 1)) //if (!plib::container::contains(t->m_nzrd, static_cast<unsigned>(other[i])) && other[i] >= static_cast<int>(k + 1)) { t.nzrd.push_back((UInt32)other[i]); } } /* and sort */ t.nzrd.Sort(); //std::sort(t.m_nzrd.begin(), t.m_nzrd.end()); } /* create a list of non zero elements below diagonal k * This should reduce cache misses ... */ bool [,] touched = new bool [iN, iN]; //bool **touched = plib::palloc_array<bool *>(iN); //for (UInt32 k = 0; k < iN; k++) // touched[k] = plib::palloc_array<bool>(iN); for (UInt32 k = 0; k < iN; k++) { for (UInt32 j = 0; j < iN; j++) { touched[k, j] = false; } for (UInt32 j = 0; j < m_terms[k].nz.size(); j++) { touched[k, m_terms[k].nz[j]] = true; } } m_ops = 0; for (UInt32 k = 0; k < iN; k++) { m_ops++; // 1/A(k,k) for (UInt32 row = k + 1; row < iN; row++) { if (touched[row, k]) { m_ops++; if (!m_terms[k].nzbd.Contains(row)) //if (!plib::container::contains(m_terms[k]->m_nzbd, row)) { m_terms[k].nzbd.push_back(row); } for (UInt32 col = k + 1; col < iN; col++) { if (touched[k, col]) { touched[row, col] = true; m_ops += 2; } } } } } log().verbose.op("Number of mults/adds for {0}: {1}", name(), m_ops); #if false if ((0)) { for (unsigned k = 0; k < iN; k++) { pstring line = plib::pfmt("{1:3}")(k); for (unsigned j = 0; j < m_terms[k]->m_nzrd.size(); j++) { line += plib::pfmt(" {1:3}")(m_terms[k]->m_nzrd[j]); } log().verbose("{1}", line); } } #endif /* * save states */ for (UInt32 k = 0; k < iN; k++) { string num = new plib.pfmt("{0}").op(k); state().save(this, m_terms[k].last_V, "lastV." + num); state().save(this, m_terms[k].DD_n_m_1, "m_DD_n_m_1." + num); state().save(this, m_terms[k].h_n_m_1, "m_h_n_m_1." + num); state().save(this, m_terms[k].go(), "GO" + num, m_terms[k].count()); state().save(this, m_terms[k].gt(), "GT" + num, m_terms[k].count()); state().save(this, m_terms[k].Idr(), "IDR" + num, m_terms[k].count()); } //for (UInt32 k = 0; k < iN; k++) // plib::pfree_array(touched[k]); //plib::pfree_array(touched); touched = null; }
/* return number of floating point operations for solve */ //std::size_t ops() { return m_ops; } protected void setup_base(analog_net_t_list_t nets) { log().debug.op("New solver setup\n"); m_nets.clear(); m_terms.clear(); foreach (var net in nets) { m_nets.push_back(net); m_terms.push_back(new terms_for_net_t()); m_rails_temp.push_back(new terms_for_net_t()); } for (UInt32 k = 0; k < nets.size(); k++) { analog_net_t net = nets[k]; log().debug.op("setting up net\n"); net.set_solver(this); foreach (var p in net.core_terms) { log().debug.op("{0} {1} {2}\n", p.name(), net.name(), net.isRailNet()); switch (p.type()) { case detail.terminal_type.TERMINAL: if (p.device().is_timestep()) { if (!m_step_devices.Contains(p.device())) //(!plib::container::contains(m_step_devices, &p->device())) { m_step_devices.push_back(p.device()); } } if (p.device().is_dynamic()) { if (!m_dynamic_devices.Contains(p.device())) //if (!plib::container::contains(m_dynamic_devices, &p->device())) { m_dynamic_devices.push_back(p.device()); } } { terminal_t pterm = (terminal_t)p; add_term(k, pterm); } log().debug.op("Added terminal {0}\n", p.name()); break; case detail.terminal_type.INPUT: { proxied_analog_output_t net_proxy_output = null; foreach (var input in m_inps) { if (input.proxied_net == p.net()) { net_proxy_output = input; break; } } if (net_proxy_output == null) { string nname = this.name() + "." + new plib.pfmt("m{0}").op(m_inps.size()); var net_proxy_output_u = new proxied_analog_output_t(this, nname); net_proxy_output = net_proxy_output_u; m_inps.push_back(net_proxy_output_u); nl_base_global.nl_assert(p.net().is_analog()); net_proxy_output.proxied_net = (analog_net_t)p.net(); } net_proxy_output.net().add_terminal(p); // FIXME: repeated calling - kind of brute force net_proxy_output.net().rebuild_list(); log().debug.op("Added input\n"); } break; case detail.terminal_type.OUTPUT: log().fatal.op(nl_errstr_global.MF_1_UNHANDLED_ELEMENT_1_FOUND, p.name()); break; } } log().debug.op("added net with {0} populated connections\n", net.core_terms.size()); } /* now setup the matrix */ setup_matrix(); }
void render_font_command_glyph() { // FIXME: this is copy/pasta from the BDC loading, and it shouldn't be injected into every font emu_file file = new emu_file(OPEN_FLAG_READ); if (!file.open_ram(new MemoryU8(font_uicmd14), (u32)font_uicmd14.Length)) { // get the file size, read the header, and check that it looks good u64 filesize = file.size(); bdc_header header = new bdc_header(); if (!header.read(file)) { osd_printf_warning("render_font::render_font_command_glyph: error reading BDC header\n"); file.close(); return; } else if (!header.check_magic() || (bdc_header.MAJVERSION != header.get_major_version()) || (bdc_header.MINVERSION != header.get_minor_version())) { LOG("render_font::render_font_command_glyph: incompatible BDC file\n"); file.close(); return; } // get global properties from the header m_height_cmd = header.get_height(); m_yoffs_cmd = header.get_y_offset(); u32 numchars = header.get_glyph_count(); if ((file.tell() + ((u64)numchars * bdc_table_entry.size())) > filesize) { LOG("render_font::render_font_command_glyph: BDC file is too small to hold glyph table\n"); file.close(); return; } // now read the rest of the data u64 remaining = filesize - file.tell(); //try { m_rawdata_cmd.resize(remaining); } //catch (...) //{ // global.osd_printf_error("render_font::render_font_command_glyph: allocation error\n"); //} for (u64 bytes_read = 0; remaining > bytes_read;) { u32 chunk = (u32)std.min(u32.MaxValue, remaining); if (file.read(new Pointer <u8>(m_rawdata_cmd, (int)bytes_read), chunk) != chunk) { osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n"); m_rawdata_cmd.clear(); file.close(); return; } bytes_read += chunk; } file.close(); // extract the data from the data size_t offset = (size_t)numchars * bdc_table_entry.size(); bdc_table_entry entry = new bdc_table_entry(m_rawdata_cmd.empty() ? null : new Pointer <u8>(m_rawdata_cmd)); for (unsigned chindex = 0; chindex < numchars; chindex++, entry = entry.get_next()) { // if we don't have a subtable yet, make one int chnum = (int)entry.get_encoding(); LOG("render_font::render_font_command_glyph: loading character {0}\n", chnum); if (m_glyphs_cmd[chnum / 256] == null) { //try { m_glyphs_cmd[chnum / 256] = new List <glyph>(256); // new glyph[256]; for (int i = 0; i < 256; i++) { m_glyphs_cmd[chnum / 256].Add(new glyph()); } } //catch (...) //{ // osd_printf_error("render_font::render_font_command_glyph: allocation error\n"); // m_rawdata_cmd.clear(); // return; //} } // fill in the entry glyph gl = m_glyphs_cmd[chnum / 256][chnum % 256]; gl.width = entry.get_x_advance(); gl.xoffs = entry.get_bb_x_offset(); gl.yoffs = entry.get_bb_y_offset(); gl.bmwidth = entry.get_bb_width(); gl.bmheight = entry.get_bb_height(); gl.rawdata = new Pointer <u8>(m_rawdata_cmd, (int)offset); // advance the offset past the character offset += (size_t)((gl.bmwidth * gl.bmheight + 7) / 8); if (m_rawdata_cmd.size() < offset) { osd_printf_verbose("render_font::render_font_command_glyph: BDC file too small to hold all glyphs\n"); m_rawdata_cmd.clear(); return; } } } }
//------------------------------------------------- // load_cached - load a font in cached format //------------------------------------------------- bool load_cached(emu_file file, u64 length, u32 hash) { // get the file size, read the header, and check that it looks good u64 filesize = file.size(); bdc_header header = new bdc_header(); if (!header.read(file)) { osd_printf_warning("render_font::load_cached: error reading BDC header\n"); return(false); } else if (!header.check_magic() || (bdc_header.MAJVERSION != header.get_major_version()) || (bdc_header.MINVERSION != header.get_minor_version())) { LOG("render_font::load_cached: incompatible BDC file\n"); return(false); } else if (length != 0 && ((header.get_original_length() != length) || (header.get_original_hash() != hash))) { LOG("render_font::load_cached: BDC file does not match original BDF file\n"); return(false); } // get global properties from the header m_height = header.get_height(); m_scale = 1.0f / (float)(m_height); m_yoffs = header.get_y_offset(); m_defchar = header.get_default_character(); u32 numchars = header.get_glyph_count(); if (file.tell() + ((u64)numchars * bdc_table_entry.size()) > filesize) { LOG("render_font::load_cached: BDC file is too small to hold glyph table\n"); return(false); } // now read the rest of the data u64 remaining = filesize - file.tell(); try { m_rawdata.resize(remaining); } catch (Exception) { osd_printf_error("render_font::load_cached: allocation error\n"); } for (u64 bytes_read = 0; remaining > bytes_read;) { u32 chunk = (u32)std.min(u32.MaxValue, remaining); if (file.read(new Pointer <u8>(m_rawdata, (int)bytes_read), chunk) != chunk) //if (file.read(&m_rawdata[bytes_read], chunk) != chunk) { osd_printf_error("render_font::load_cached: error reading BDC data\n"); m_rawdata.clear(); return(false); } bytes_read += chunk; } // extract the data from the data size_t offset = (size_t)numchars * bdc_table_entry.size(); bdc_table_entry entry = new bdc_table_entry(m_rawdata.empty() ? null : new Pointer <u8>(m_rawdata)); for (unsigned chindex = 0; chindex < numchars; chindex++, entry = entry.get_next()) { // if we don't have a subtable yet, make one int chnum = (int)entry.get_encoding(); LOG("render_font::load_cached: loading character {0}\n", chnum); if (m_glyphs[chnum / 256] == null || m_glyphs[chnum / 256].Count == 0) { //try { m_glyphs[chnum / 256] = new List <glyph>(256); // new glyph[256]; for (int i = 0; i < 256; i++) { m_glyphs[chnum / 256].Add(new glyph()); } } //catch (Exception ) //{ // global.osd_printf_error("render_font::load_cached: allocation error\n"); // m_rawdata.clear(); // return false; //} } // fill in the entry glyph gl = m_glyphs[chnum / 256][chnum % 256]; gl.width = entry.get_x_advance(); gl.xoffs = entry.get_bb_x_offset(); gl.yoffs = entry.get_bb_y_offset(); gl.bmwidth = entry.get_bb_width(); gl.bmheight = entry.get_bb_height(); gl.rawdata = new Pointer <u8>(m_rawdata, (int)offset); // advance the offset past the character offset += (size_t)((gl.bmwidth * gl.bmheight + 7) / 8); if (m_rawdata.size() < offset) { osd_printf_verbose("render_font::load_cached: BDC file too small to hold all glyphs\n"); m_rawdata.clear(); return(false); } } // got everything m_format = format.CACHED; return(true); }
} //void gaussian_back_substitution(V1 &V, const V2 &RHS) //template <typename V1> //void gaussian_back_substitution(V1 &V) //template <typename M> void build_parallel_gaussian_execution_scheme(std.vector <std.vector <unsigned> > fill) //void build_parallel_gaussian_execution_scheme(const M &fill) { // calculate parallel scheme for gaussian elimination std.vector <std.vector <size_t> > rt = new std.vector <std.vector <size_t> >(base.size()); for (size_t k = 0; k < base.size(); k++) { rt[k] = new std.vector <size_t>(); for (size_t j = k + 1; j < base.size(); j++) { if (fill[j][k] < (size_t)pmatrix_cr <B, B_OPS, int_N> .constants_e.FILL_INFINITY) { rt[k].push_back(j); } } } std.vector <size_t> levGE = new std.vector <size_t>(base.size(), 0); size_t cl = 0; for (size_t k = 0; k < base.size(); k++) { if (levGE[k] >= cl) { std.vector <size_t> t = rt[k]; for (size_t j = k + 1; j < base.size(); j++) { bool overlap = false; // is there overlap if (plib.container.contains(t, j)) { overlap = true; } foreach (var x in rt[j]) { if (plib.container.contains(t, x)) { overlap = true; break; } } if (overlap) { levGE[j] = cl + 1; } else { t.push_back(j); foreach (var x in rt[j]) { t.push_back(x); } } } cl++; } } m_ge_par.clear(); m_ge_par.resize(cl + 1); m_ge_par.Fill(() => { return(new std.vector <size_t>()); }); for (size_t k = 0; k < base.size(); k++) { m_ge_par[levGE[k]].push_back(k); } //for (std::size_t k = 0; k < m_ge_par.size(); k++) // printf("%d %d\n", (int) k, (int) m_ge_par[k].size()); }
// audit operations //------------------------------------------------- // audit_media - audit the media described by the // currently-enumerated driver //------------------------------------------------- public summary audit_media(string validation = AUDIT_VALIDATE_FULL) { // start fresh m_record_list.clear(); // store validation for later m_validation = validation; // first walk the parent chain for required ROMs parent_rom_vector parentroms = new parent_rom_vector(); for (var drvindex = driver_list.find(m_enumerator.driver().parent); 0 <= drvindex; drvindex = driver_list.find(driver_list.driver((size_t)drvindex).parent)) //for (auto drvindex = m_enumerator.find(m_enumerator.driver().parent); 0 <= drvindex; drvindex = m_enumerator.find(m_enumerator.driver(drvindex).parent)) { game_driver parent = driver_list.driver((size_t)drvindex); LOG(null, "Checking parent {0} for ROM files\n", parent.type.shortname()); std.vector <rom_entry> roms = rom_build_entries(parent.rom); for (Pointer <rom_entry> region = rom_first_region(new Pointer <rom_entry>(roms)); region != null; region = rom_next_region(region)) //for (rom_entry const *region = rom_first_region(&roms.front()); region; region = rom_next_region(region)) { for (Pointer <rom_entry> rom = rom_first_file(region); rom != null; rom = rom_next_file(rom)) //for (rom_entry const *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { LOG(null, "Adding parent ROM {0}\n", rom.op.name()); parentroms.emplace_back(new parent_rom(parent.type, rom)); } } } parentroms.remove_redundant_parents(); // count ROMs required/found size_t found = 0; size_t required = 0; size_t shared_found = 0; size_t shared_required = 0; size_t parent_found = 0; // iterate over devices and regions std.vector <string> searchpath = new std.vector <string>(); foreach (device_t device in new device_enumerator(m_enumerator.config().root_device())) { searchpath.clear(); // now iterate over regions and ROMs within for (Pointer <rom_entry> region = rom_first_region(device); region != null; region = rom_next_region(region)) { for (Pointer <rom_entry> rom = rom_first_file(region); rom != null; rom = rom_next_file(rom)) { if (searchpath.empty()) { LOG(null, "Audit media for device {0}({1})\n", device.shortname(), device.tag()); searchpath = device.searchpath(); } // look for a matching parent or device ROM string name = rom.op.name(); util.hash_collection hashes = new util.hash_collection(rom.op.hashdata()); bool dumped = !hashes.flag(util.hash_collection.FLAG_NO_DUMP); device_type shared_device = parentroms.find_shared_device(device, name, hashes, rom_file_size(rom)); if (shared_device != null) { LOG(null, "File '{0}' {1}{2}dumped shared with {3}\n", name, ROM_ISOPTIONAL(rom.op) ? "optional " : "", dumped ? "" : "un", shared_device.shortname()); } else { LOG(null, "File '{0}' {1}{2}dumped\n", name, ROM_ISOPTIONAL(rom.op) ? "optional " : "", dumped ? "" : "un"); } // count the number of files with hashes if (dumped && !ROM_ISOPTIONAL(rom.op)) { required++; if (shared_device != null) { shared_required++; } } // audit a file audit_record record = null; if (ROMREGION_ISROMDATA(region.op)) { record = audit_one_rom(searchpath, rom); } // audit a disk else if (ROMREGION_ISDISKDATA(region.op)) { record = audit_one_disk(rom, device); } if (record != null) { // see if the actual content found belongs to a parent var matchesshared = parentroms.actual_matches_shared(device, record); if (matchesshared.first != null) { LOG(null, "Actual ROM file shared with {0}parent {1}\n", matchesshared.second ? "immediate " : "", matchesshared.first.shortname()); } // count the number of files that are found. if ((record.status() == audit_status.GOOD) || ((record.status() == audit_status.FOUND_INVALID) && (matchesshared.first == null))) { found++; if (shared_device != null) { shared_found++; } if (matchesshared.second) { parent_found++; } } record.set_shared_device(shared_device); } } } } if (!searchpath.empty()) { LOG(null, "Total required={0} (shared={1}) found={2} (shared={3} parent={4})\n", required, shared_required, found, shared_found, parent_found); } // if we only find files that are in the parent & either the set has no unique files or the parent is not found, then assume we don't have the set at all if ((found == shared_found) && required != 0 && ((required != shared_required) || parent_found == 0)) { m_record_list.clear(); return(summary.NOTFOUND); } // return a summary return(summarize(m_enumerator.driver().name)); }
protected override void populate(ref float customtop, ref float custombottom) { foreach (var icon in m_icons) // TODO: why is this here? maybe better on resize or setting change? { icon.second().texture = null; //icon.second().texture.reset(); } set_switch_image(); bool have_prev_selected = false; int old_item_selected = -1; if (!isfavorite()) { if (m_populated_favorites) { m_prev_selected = null; } m_populated_favorites = false; m_displaylist.clear(); machine_filter flt = m_persistent_data.filter_data().get_current_filter(); // if search is not empty, find approximate matches if (!string.IsNullOrEmpty(m_search)) { populate_search(); if (flt != null) { for (int i = 0; i < m_searchlist.Count && MAX_VISIBLE_SEARCH > m_displaylist.size(); i++) //for (auto it = m_searchlist.begin(); (m_searchlist.end() != it) && (MAX_VISIBLE_SEARCH > m_displaylist.size()); ++it) { var it = m_searchlist[i]; if (flt.apply(it.second)) { m_displaylist.emplace_back(it.second); } } } else { //std.transform( // m_searchlist.begin(), // std.next(m_searchlist.begin(), std.min(m_searchlist.size(), MAX_VISIBLE_SEARCH)), // std.back_inserter(m_displaylist), // [] (auto const &entry) { return entry.second; }); foreach (var it in m_searchlist) { m_displaylist.Add(it.second); } } } else { // if filter is set on category, build category list var sorted = m_persistent_data.sorted_list(); if (flt == null) { foreach (ui_system_info sysinfo in sorted) { m_displaylist.emplace_back(sysinfo); } } else { foreach (ui_system_info sysinfo in sorted) { if (flt.apply(sysinfo)) { m_displaylist.emplace_back(sysinfo); } } } } // iterate over entries int curitem = 0; foreach (ui_system_info elem in m_displaylist) { have_prev_selected = have_prev_selected || (elem == m_prev_selected); if ((old_item_selected == -1) && (elem.driver.name == reselect_last.driver())) { old_item_selected = curitem; } item_append(elem.description, elem.is_clone ? FLAG_INVERT : 0, elem); curitem++; } } else { // populate favorites list if (!m_populated_favorites) { m_prev_selected = null; } m_populated_favorites = true; m_search = ""; //m_search.clear(); int curitem = 0; mame_machine_manager.instance().favorite().apply_sorted( (info) => //[this, &have_prev_selected, &old_item_selected, curitem = 0] (ui_software_info const &info) mutable { have_prev_selected = have_prev_selected || (info == (ui_software_info)m_prev_selected); if (info.startempty != 0) { if (old_item_selected == -1 && info.shortname == reselect_last.driver()) { old_item_selected = curitem; } bool cloneof = std.strcmp(info.driver.parent, "0") != 0; if (cloneof) { int cx = driver_list.find(info.driver.parent); if ((0 <= cx) && ((driver_list.driver((size_t)cx).flags & machine_flags.type.IS_BIOS_ROOT) != 0)) { cloneof = false; } } item_append(info.longname, cloneof ? FLAG_INVERT : 0, info); } else { if (old_item_selected == -1 && info.shortname == reselect_last.driver()) { old_item_selected = curitem; } item_append(info.longname, info.devicetype, info.parentname.empty() ? 0 : FLAG_INVERT, info); } curitem++; }); } // add special items if (stack_has_special_main_menu()) { item_append(menu_item_type.SEPARATOR, 0); item_append(__("Configure Options"), 0, CONF_OPTS); item_append(__("Configure Machine"), 0, CONF_MACHINE); skip_main_items = 3; if (m_prev_selected != null && !have_prev_selected) { m_prev_selected = item(0).ref_(); } } else { skip_main_items = 0; } // configure the custom rendering customtop = 3.0f * ui().get_line_height() + 5.0f * ui().box_tb_border(); custombottom = 4.0f * ui().get_line_height() + 3.0f * ui().box_tb_border(); // reselect prior game launched, if any if (old_item_selected != -1) { set_selected_index(old_item_selected); if (ui_globals.visible_main_lines == 0) { top_line = (selected_index() != 0) ? selected_index() - 1 : 0; } else { top_line = selected_index() - (ui_globals.visible_main_lines / 2); } if (reselect_last.software().empty()) { reselect_last.reset(); } } else { reselect_last.reset(); } }