예제 #1
0
 public override std.error_condition read(PointerU8 buffer, size_t length, out size_t actual)  //virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override;
 {
     // since osd_file works like pread/pwrite, implement in terms of read_at
     // core_osd_file is delcared final, so a derived class can't interfere
     std.error_condition err = read_at(offset(), buffer, length, out actual);
     add_offset(actual);
     return(err);
 }
예제 #2
0
        //-------------------------------------------------
        //  load_samples - load all the samples in our
        //  attached interface
        //  Returns true when all samples were successfully read, else false
        //-------------------------------------------------
        bool load_samples()
        {
            bool ok = true;

            // if the user doesn't want to use samples, bail
            if (!machine().options().samples())
            {
                return(false);
            }

            // iterate over ourself
            string           basename    = machine().basename();
            samples_iterator iter        = new samples_iterator(this);
            string           altbasename = iter.altbasename();

            // pre-size the array
            m_sample.resize((size_t)iter.count());

            // load the samples
            int index = 0;

            for (string samplename = iter.first(); samplename != null; index++, samplename = iter.next())
            {
                // attempt to open as FLAC first
                emu_file            file   = new emu_file(machine().options().sample_path(), OPEN_FLAG_READ);
                std.error_condition filerr = file.open(util.string_format("{0}" + PATH_SEPARATOR + "{1}.flac", basename, samplename));
                if (filerr && !string.IsNullOrEmpty(altbasename))
                {
                    filerr = file.open(util.string_format("{0}" + PATH_SEPARATOR + "{1}.flac", altbasename, samplename));
                }

                // if not, try as WAV
                if (filerr)
                {
                    filerr = file.open(util.string_format("{0}" + PATH_SEPARATOR + "{1}.wav", basename, samplename));
                }

                if (filerr && !string.IsNullOrEmpty(altbasename))
                {
                    filerr = file.open(util.string_format("{0}" + PATH_SEPARATOR + "{1}.wav", altbasename, samplename));
                }

                // if opened, read it
                if (!filerr)
                {
                    read_sample(file, m_sample[index]);
                }
                else
                {
                    logerror("Error opening sample '{0}' ({1}:{2} {3})\n", samplename, filerr.category().name(), filerr.value(), filerr.message());
                    ok = false;
                }

                file.close();
            }

            return(ok);
        }
예제 #3
0
        // position

        //-------------------------------------------------
        //  seek - seek within a file
        //-------------------------------------------------
        public std.error_condition seek(s64 offset, int whence)
        {
            // load the ZIP file now if we haven't yet
            std.error_condition err = compressed_file_ready();
            if (err)
            {
                return(err);
            }

            // seek if we can
            if (m_file != null)
            {
                return(m_file.seek(offset, whence));
            }

            return(std.errc.bad_file_descriptor); // TODO: revisit this error condition
        }
예제 #4
0
            protected override std.error_condition truncate(uint64_t offset)
            {
                if (is_loaded())
                {
                    return(base.truncate(offset));
                }

                // truncate file
                std.error_condition err = m_file.truncate(offset);
                if (err)
                {
                    return(err);
                }

                // and adjust to new length and offset
                set_length(offset);
                return(new std.error_condition());
            }
예제 #5
0
            public std.error_condition initialize()
            {
#if false
                try
                {
                    if (m_utf16_buf.size() < 128)
                    {
                        m_utf16_buf.resize(128);
                    }
                    if (m_uchar_buf.size() < 128)
                    {
                        m_uchar_buf.resize(128);
                    }
                    m_utf8_buf.reserve(512);
                }
                catch (...)
                {
                    return(std::errc::not_enough_memory);
                }
#endif

                if (m_archive_stream.file == null)
                {
                    osd_file            file;                                                                                    //osd_file::ptr file;
                    std.error_condition err = m_osdfile.open(m_filename, OPEN_FLAG_READ, out file, out m_archive_stream.length); //std::error_condition const err = osd_file::open(m_filename, OPEN_FLAG_READ, file, m_archive_stream.length);
                    if (err)
                    {
                        return(err);
                    }

                    m_archive_stream.file = osd_file_read(file);  //m_archive_stream.file = osd_file_read(std::move(file));
                    //osd_printf_verbose("un7z: opened archive file %s\n", m_filename);
                }
                else if (m_archive_stream.length == 0)
                {
                    std.error_condition err = m_archive_stream.file.length(out m_archive_stream.length);  //std::error_condition const err = m_archive_stream.file->length(m_archive_stream.length);
                    if (err)
                    {
                        osd_printf_verbose(
                            "un7z: error getting length of archive file {0} ({1}:{2} {3})\n",
                            m_filename, err.category().name(), err.value(), err.message());
                        return(err);
                    }
                }
예제 #6
0
            /*-------------------------------------------------
            *   buffer - return a pointer to the file buffer;
            *   if it doesn't yet exist, load the file into
            *   RAM first
            *  -------------------------------------------------*/
            public override MemoryU8 buffer()  //void const *buffer()
            {
                // if we already have data, just return it
                if (!is_loaded() && length() != 0)
                {
                    // allocate some memory
                    MemoryU8 buf = allocate();  //void *const buf = allocate();
                    if (buf == null)
                    {
                        return(null);
                    }

                    // read the file
                    uint64_t  bytes_read = 0;
                    uint64_t  remaining  = length();
                    PointerU8 ptr        = new PointerU8(buf); //std::uint8_t *ptr = reinterpret_cast<std::uint8_t *>(buf);
                    while (remaining != 0)
                    {
                        uint32_t            chunk = std.min(uint32_t.MaxValue, (uint32_t)remaining); //std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), remaining);
                        uint32_t            read_length;
                        std.error_condition filerr = m_file.read(ptr, bytes_read, chunk, out read_length);
                        if (filerr || read_length == 0)
                        {
                            purge();
                            return(base.buffer());
                        }

                        bytes_read += read_length;
                        remaining  -= read_length;
                        ptr        += read_length;
                    }

                    m_file.Dispose();  //m_file.reset(); // close the file because we don't need it anymore
                    m_file = null;
                }

                return(base.buffer());
            }
예제 #7
0
            public override std.error_condition write_at(uint64_t offset, PointerU8 buffer, size_t length, out size_t actual)  //virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override;
            {
                // can't write to RAM-based stuff
                if (is_loaded())
                {
                    return(base.write_at(offset, buffer, length, out actual));
                }

                // flush any buffered char
                clear_putback();

                // invalidate any buffered data
                m_bufferbytes = 0U;

                // do the write - may need to split into chunks if size_t is larger than 32 bits
                actual = 0U;
                while (length != 0)
                {
                    // bytes written not valid on error
                    uint32_t            chunk = std.min(uint32_t.MaxValue, (uint32_t)length); //std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length);
                    uint32_t            bytes_written;
                    std.error_condition err = m_file.write(buffer, offset, chunk, out bytes_written);
                    if (err)
                    {
                        return(err);
                    }

                    assert(chunk >= bytes_written);

                    offset += bytes_written;
                    buffer  = buffer + bytes_written; //buffer = reinterpret_cast<std::uint8_t const *>(buffer) + bytes_written;
                    length -= bytes_written;
                    actual += bytes_written;
                    set_length(std.max(this.length(), offset));
                }

                return(new std.error_condition());
            }
예제 #8
0
        // INI parsing helper
        //-------------------------------------------------
        //  parse_one_ini - parse a single INI file
        //-------------------------------------------------
        static void parse_one_ini(emu_options options, string basename, int priority, ref string error_stream)
        {
            // don't parse if it has been disabled
            if (!options.read_config())
            {
                return;
            }

            // open the file; if we fail, that's ok
            emu_file file = new emu_file(options.ini_path(), OPEN_FLAG_READ);

            osd_printf_verbose("Attempting load of {0}.ini\n", basename);
            std.error_condition filerr = file.open(basename + ".ini");
            if (filerr)
            {
                return;
            }

            // parse the file
            osd_printf_verbose("Parsing {0}.ini\n", basename);
            try
            {
                options.parse_ini_file(file.core_file_get(), priority, priority < OPTION_PRIORITY_DRIVER_INI, false);
            }
            catch (options_exception ex)
            {
                if (error_stream != null)
                {
                    error_stream += string.Format("While parsing {0}:\n{1}\n", file.fullpath(), ex.message());
                }
                return;
            }
            finally
            {
                file.close();
            }
        }
예제 #9
0
        /*-------------------------------------------------
        *   write_config - emit current option statuses as
        *   INI files
        *  -------------------------------------------------*/
        int write_config(emu_options options, string filename, game_driver gamedrv)
        {
            string buffer;
            int    retval = 1;

            if (gamedrv != null)
            {
                sprintf(out buffer, "{0}.ini", gamedrv.name);
                filename = buffer;
            }

            emu_file file = new emu_file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);

            std.error_condition filerr = file.open(filename);
            if (!filerr)
            {
                string inistring = options.output_ini();
                file.puts(inistring);
                retval = 0;
            }
            file.close();

            return(retval);
        }
예제 #10
0
            public std.error_condition read_at(uint64_t offset, PointerU8 buffer, size_t length, out size_t actual)  //virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
            {
                // TODO: should the client have to deal with reading less than expected even if EOF isn't hit?
                if (uint32_t.MaxValue < length)  //if (std::numeric_limits<std::uint32_t>::max() < length)
                {
                    actual = 0U;
                    return(std.errc.invalid_argument);
                }

                // actual length not valid on error
                uint32_t count;

                std.error_condition err = file().read(buffer, offset, (uint32_t)length, out count);  //std::error_condition err = file().read(buffer, offset, std::uint32_t(length), count);
                if (!err)
                {
                    actual = (size_t)count;
                }
                else
                {
                    actual = 0U;
                }

                return(err);
            }
예제 #11
0
        //-------------------------------------------------
        //  start_luaengine
        //-------------------------------------------------
        public void start_luaengine()
        {
            if (options().plugins())
            {
                //throw new emu_unimplemented();
#if false
                // scan all plugin directories
                path_iterator iter = new path_iterator(options().plugins_path());
                string        pluginpath;
                while (iter.next(out pluginpath))
                {
                    // user may specify environment variables; subsitute them
                    m_osdcore.osd_subst_env(out pluginpath, pluginpath);

                    // and then scan the directory recursively
                    m_plugins.scan_directory(pluginpath, true);
                }

                {
                    // parse the file
                    // attempt to open the output file
                    emu_file file = new emu_file(options().ini_path(), OPEN_FLAG_READ);
                    if (file.open("plugin.ini") == osd_file.error.NONE)
                    {
                        try
                        {
                            m_plugins.parse_ini_file(file.core_file_get());  //(util::core_file&)file
                        }
                        catch (options_exception)
                        {
                            osd_printf_error("**Error loading plugin.ini**\n");
                        }

                        file.close();
                    }
                }

                // process includes
                foreach (string incl in split(options().plugin(), ','))
                {
                    plugin_options::plugin *p = m_plugins->find(incl);
                    if (!p)
                    {
                        fatalerror("Fatal error: Could not load plugin: %s\n", incl);
                    }
                    p.m_start = true;
                }

                // process excludes
                foreach (string excl in split(options().no_plugin(), ','))
                {
                    plugin_options::plugin *p = m_plugins->find(excl);
                    if (!p)
                    {
                        fatalerror("Fatal error: Unknown plugin: %s\n", excl);
                    }
                    p.m_start = false;
                }
#endif
            }

            // we have a special way to open the console plugin
            if (options().console())
            {
                plugin_options.plugin p = m_plugins.find(OPTION_CONSOLE);
                if (p == null)
                {
                    fatalerror("Fatal error: Console plugin not found.\n");
                }

                p.m_start = true;
            }

            m_lua.initialize();

            {
                emu_file            file   = new emu_file(options().plugins_path(), OPEN_FLAG_READ);
                std.error_condition filerr = file.open("boot.lua");
                if (!filerr)
                {
                    string exppath;
                    m_osdcore.osd_subst_env(out exppath, file.fullpath());
                    m_lua.load_script(file.fullpath());
                    file.close();
                }
            }
        }
예제 #12
0
        //-------------------------------------------------
        //  recompute_speed - recompute the current
        //  overall speed; we assume this is called only
        //  if we did not skip a frame
        //-------------------------------------------------
        void recompute_speed(attotime emutime)
        {
            // if we don't have a starting time yet, or if we're paused, reset our starting point
            if (m_speed_last_realtime == 0 || machine().paused())
            {
                m_speed_last_realtime = m_osdcore.osd_ticks();
                m_speed_last_emutime  = emutime;
            }

            // if it has been more than the update interval, update the time
            attotime delta_emutime = emutime - m_speed_last_emutime;

            if (delta_emutime > new attotime(0, ATTOSECONDS_PER_SPEED_UPDATE))
            {
                // convert from ticks to attoseconds
                osd_ticks_t realtime       = m_osdcore.osd_ticks();
                osd_ticks_t delta_realtime = realtime - m_speed_last_realtime;
                osd_ticks_t tps            = m_osdcore.osd_ticks_per_second();
                m_speed_percent = delta_emutime.as_double() * (double)tps / (double)delta_realtime;

                // remember the last times
                m_speed_last_realtime = realtime;
                m_speed_last_emutime  = emutime;

                // if we're throttled, this time period counts for overall speed; otherwise, we reset the counter
                if (!m_fastforward)
                {
                    m_overall_valid_counter++;
                }
                else
                {
                    m_overall_valid_counter = 0;
                }

                // if we've had at least 4 consecutive valid periods, accumulate stats
                if (m_overall_valid_counter >= 4)
                {
                    m_overall_real_ticks += delta_realtime;
                    while (m_overall_real_ticks >= tps)
                    {
                        m_overall_real_ticks -= tps;
                        m_overall_real_seconds++;
                    }
                    m_overall_emutime += delta_emutime;
                }
            }

            // if we're past the "time-to-execute" requested, signal an exit
            if (m_seconds_to_run != 0 && emutime.seconds() >= m_seconds_to_run)
            {
                // create a final screenshot
                emu_file            file   = new emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
                std.error_condition filerr = open_next(file, "png");
                if (!filerr)
                {
                    save_snapshot(null, file);
                }

                file.close();

                //printf("Scheduled exit at %f\n", emutime.as_double());

                // schedule our demise
                machine().schedule_exit();
            }
        }
예제 #13
0
        //-------------------------------------------------
        //  audit_samples - validate the samples for the
        //  currently-enumerated driver
        //-------------------------------------------------
        public summary audit_samples()
        {
            // start fresh
            m_record_list.clear();

            int required = 0;
            int found    = 0;

            // iterate over sample entries
            foreach (samples_device device in new samples_device_enumerator(m_enumerator.config().root_device()))
            {
                // by default we just search using the driver name
                string searchpath = m_enumerator.driver().name;

                // add the alternate path if present
                samples_iterator samplesiter = new samples_iterator(device);
                if (samplesiter.altbasename() != null)
                {
                    searchpath += ";" + samplesiter.altbasename();
                }

                // iterate over samples in this entry
                for (string samplename = samplesiter.first(); samplename != null; samplename = samplesiter.next())
                {
                    required++;

                    // create a new record
                    audit_record record = m_record_list.emplace_back(new audit_record(samplename, media_type.SAMPLE)).Value;  //audit_record &record = *m_record_list.emplace(m_record_list.end(), samplename, media_type::SAMPLE);

                    // look for the files
                    emu_file      file = new emu_file(m_enumerator.options().sample_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD);
                    path_iterator path = new path_iterator(searchpath);
                    string        curpath;
                    while (path.next(out curpath, samplename))
                    {
                        // attempt to access the file (.flac) or (.wav)
                        std.error_condition filerr = file.open(curpath + ".flac");
                        if (filerr)
                        {
                            filerr = file.open(curpath + ".wav");
                        }

                        if (!filerr)
                        {
                            record.set_status(audit_status.GOOD, audit_substatus.GOOD);
                            found++;
                        }
                        else
                        {
                            record.set_status(audit_status.NOT_FOUND, audit_substatus.NOT_FOUND);
                        }
                    }

                    file.close();
                }
            }

            if (found == 0 && required > 0)
            {
                m_record_list.clear();
                return(summary.NOTFOUND);
            }

            // return a summary
            return(summarize(m_enumerator.driver().name));
        }
예제 #14
0
        // fetch items by name
        //template <class DeviceClass> [[deprecated("absolute tag lookup; use subdevice or finder instead")]] inline DeviceClass *device(const char *tag) { return downcast<DeviceClass *>(root_device().subdevice(tag)); }


        // immediate operations

        //-------------------------------------------------
        //  run - execute the machine
        //-------------------------------------------------
        public int run(bool quiet)
        {
            int error = EMU_ERR_NONE;

            // use try/catch for deep error recovery
            try
            {
                m_manager.http().clear();

                // move to the init phase
                m_current_phase = machine_phase.INIT;

                // if we have a logfile, set up the callback
                if (options().log() && !quiet)
                {
                    m_logfile = new emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
                    std.error_condition filerr = m_logfile.open("error.log");
                    if (filerr)
                    {
                        throw new emu_fatalerror("running_machine::run: unable to open error.log file");
                    }

                    //using namespace std::placeholders;
                    add_logerror_callback(logfile_callback);
                }

                if (options().debug() && options().debuglog())
                {
                    m_debuglogfile = new emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
                    std.error_condition filerr = m_debuglogfile.open("debug.log");
                    if (filerr)
                    {
                        throw new emu_fatalerror("running_machine::run: unable to open debug.log file");
                    }
                }

                // then finish setting up our local machine
                start();

                // load the configuration settings
                manager().before_load_settings(this);
                m_configuration.load_settings();

                // disallow save state registrations starting here.
                // Don't do it earlier, config load can create network
                // devices with timers.
                m_save.allow_registration(false);

                // load the NVRAM
                nvram_load();

                // set the time on RTCs (this may overwrite parts of NVRAM)
                set_rtc_datetime(new system_time(m_base_time));

                sound().ui_mute(false);
                if (!quiet)
                {
                    sound().start_recording();
                }

                m_hard_reset_pending = false;

                // initialize ui lists
                // display the startup screens
                manager().ui_initialize(this);

                // perform a soft reset -- this takes us to the running phase
                soft_reset();

                // handle initial load
                if (m_saveload_schedule != saveload_schedule.NONE)
                {
                    handle_saveload();
                }

                export_http_api();

#if EMSCRIPTEN
                // break out to our async javascript loop and halt
                emscripten_set_running_machine(this);
#endif

                // run the CPUs until a reset or exit
                while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != saveload_schedule.NONE)
                {
                    g_profiler.start(profile_type.PROFILER_EXTRA);

                    // execute CPUs if not paused
                    if (!m_paused)
                    {
                        m_scheduler.timeslice();
                    }
                    // otherwise, just pump video updates through
                    else
                    {
                        m_video.frame_update();
                    }

                    // handle save/load
                    if (m_saveload_schedule != saveload_schedule.NONE)
                    {
                        handle_saveload();
                    }

                    g_profiler.stop();
                }

                m_manager.http().clear();

                // and out via the exit phase
                m_current_phase = machine_phase.EXIT;

                // save the NVRAM and configuration
                sound().ui_mute(true);
                if (options().nvram_save())
                {
                    nvram_save();
                }
                m_configuration.save_settings();
            }
#if false
            catch (emu_fatalerror fatal)
            {
                osd_printf_error("Fatal error: %s\n", fatal.what());
                error = EMU_ERR_FATALERROR;
                if (fatal.exitcode() != 0)
                {
                    error = fatal.exitcode();
                }
            }
            catch (emu_exception)
            {
                osd_printf_error("Caught unhandled emulator exception\n");
                error = machine_manager.MAMERR.MAMERR_FATALERROR;
            }
            catch (binding_type_exception)// btex)
            {
                osd_printf_error("Error performing a late bind of function expecting type %s to instance of type %s\n", btex.target_type().name(), btex.actual_type().name());
                error = machine_manager.MAMERR.MAMERR_FATALERROR;
            }
            catch (tag_add_exception&aex)
            {
                osd_printf_error("Tag '%s' already exists in tagged map\n", aex.tag());
                error = EMU_ERR_FATALERROR;
            }
예제 #15
0
        std.error_condition attempt_zipped()
        {
            //typedef std::error_condition (*open_func)(std::string_view filename, util::archive_file::ptr &result);
            //char const *const suffixes[] = { ".zip", ".7z" };
            //open_func const open_funcs[ARRAY_LENGTH(suffixes)] = { &util::archive_file::open_zip, &util::archive_file::open_7z };

            // loop over archive types
            string savepath = m_fullpath;
            string filename = "";

            for (unsigned i = 0; i < std.size(suffixes); i++, m_fullpath = savepath, filename = "")
            {
                // loop over directory parts up to the start of filename
                while (true)
                {
                    if (!part_of_mediapath(m_fullpath))
                    {
                        break;
                    }

                    // find the final path separator
                    //auto const dirsepiter(std::find_if(m_fullpath.rbegin(), m_fullpath.rend(), util::is_directory_separator));
                    //if (dirsepiter == m_fullpath.rend())
                    //    break;
                    //std::string::size_type const dirsep(std::distance(m_fullpath.begin(), dirsepiter.base()) - 1);
                    var dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
                    if (dirsep == npos)
                    {
                        break;
                    }

                    // insert the part from the right of the separator into the head of the filename
                    if (!filename.empty())
                    {
                        filename = filename.insert_(0, "/");
                    }
                    filename = filename.insert_(0, m_fullpath.substr(dirsep + 1));

                    // remove this part of the filename and append an archive extension
                    m_fullpath  = m_fullpath.Substring(0, (int)dirsep);
                    m_fullpath += suffixes[i];
                    LOG(null, "emu_file: looking for '{0}' in archive '{1}'\n", filename, m_fullpath);

                    // attempt to open the archive file
                    util.archive_file   zip;
                    std.error_condition ziperr = open_funcs[i](m_fullpath, out zip);

                    // chop the archive suffix back off the filename before continuing
                    m_fullpath = m_fullpath.substr(0, dirsep);

                    // if we failed to open this file, continue scanning
                    if (ziperr)
                    {
                        continue;
                    }

                    int header = -1;

                    // see if we can find a file with the right name and (if available) CRC
                    if ((m_openflags & OPEN_FLAG_HAS_CRC) != 0)
                    {
                        header = zip.search(m_crc, filename, false);
                    }
                    if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0))
                    {
                        header = zip.search(m_crc, filename, true);
                    }

                    // if that failed, look for a file with the right CRC, but the wrong filename
                    if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0))
                    {
                        header = zip.search(m_crc);
                    }

                    // if that failed, look for a file with the right name;
                    // reporting a bad checksum is more helpful and less confusing than reporting "ROM not found"
                    if (header < 0)
                    {
                        header = zip.search(filename, false);
                    }
                    if (header < 0)
                    {
                        header = zip.search(filename, true);
                    }

                    // if we got it, read the data
                    if (header >= 0)
                    {
                        m_zipfile   = zip;
                        m_ziplength = m_zipfile.current_uncompressed_length();

                        // build a hash with just the CRC
                        m_hashes.reset();
                        m_hashes.add_crc(m_zipfile.current_crc());
                        m_fullpath = savepath;
                        return((m_openflags & OPEN_FLAG_NO_PRELOAD) != 0 ? new std.error_condition() : load_zipped_file());
                    }

                    // close up the archive file and try the next level
                    zip.Dispose();
                    zip = null;  //.reset();
                }
            }

            return(std.errc.no_such_file_or_directory);
        }
예제 #16
0
        /*************************************
        *
        *  Settings save/load frontend
        *
        *************************************/
        public bool load_settings()
        {
            // loop over all registrants and call their init function
            foreach (var type in m_typelist)
            {
                type.load(config_type.INIT, config_level.DEFAULT, null);
            }

            // now load the controller file
            string controller = machine().options().ctrlr();

            if (!string.IsNullOrEmpty(controller))
            {
                // open the config file
                emu_file file = new emu_file(machine().options().ctrlr_path(), OPEN_FLAG_READ);
                osd_printf_verbose("Attempting to parse: {0}.cfg\n", controller);
                std.error_condition filerr = file.open(controller + ".cfg");
                if (filerr)
                {
                    throw new emu_fatalerror("Could not open controller file {0}.cfg ({1}:{2} {3})", controller, filerr.category().name(), filerr.value(), filerr.message());
                }

                // load the XML
                if (!load_xml(file, config_type.CONTROLLER))
                {
                    throw new emu_fatalerror("Could not load controller file {0}.cfg", controller);
                }

                file.close();
            }

            bool loaded;

            {
                // next load the defaults file
                emu_file            file   = new emu_file(machine().options().cfg_directory(), OPEN_FLAG_READ);
                std.error_condition filerr = file.open("default.cfg");
                osd_printf_verbose("Attempting to parse: default.cfg\n");
                if (!filerr)
                {
                    load_xml(file, config_type.DEFAULT);
                }

                // finally, load the game-specific file
                filerr = file.open(machine().basename() + ".cfg");
                osd_printf_verbose("Attempting to parse: {0}.cfg\n", machine().basename());
                loaded = !filerr && load_xml(file, config_type.SYSTEM);

                file.close();
            }

            // loop over all registrants and call their final function
            foreach (var type in m_typelist)
            {
                type.load(config_type.FINAL, config_level.DEFAULT, null);
            }

            // if we didn't find a saved config, return false so the main core knows that it
            // is the first time the game is run and it should display the disclaimer.
            return(loaded);
        }
예제 #17
0
        //-------------------------------------------------
        //  open_next - open the next file that matches
        //  the filename by iterating over paths
        //-------------------------------------------------
        public std.error_condition open_next()
        {
            // if we're open from a previous attempt, close up now
            if (m_file != null)
            {
                close();
            }

            // loop over paths
            LOG(null, "emu_file: open next '{0}'\n", m_filename);
            std.error_condition filerr = std.errc.no_such_file_or_directory;
            while (filerr)
            {
                if (m_first)
                {
                    m_first = false;
                    for (int iIdx = 0; iIdx < m_iterator.Count; iIdx++)  //for (searchpath_vector::value_type &i : m_iterator)
                    {
                        var i = m_iterator[iIdx];
                        i.first.reset();

                        //if (!i.first.next(i.second))
                        string next;
                        var    ret = i.first.next(out next);
                        m_iterator[iIdx] = new std.pair <path_iterator, string>(i.first, next);
                        if (!ret)
                        {
                            return(filerr);
                        }
                    }
                }
                else
                {
                    int iIdx = 0;                    //searchpath_vector::iterator i(m_iterator.begin());
                    while (iIdx != m_iterator.Count) //while (i != m_iterator.end())
                    {
                        var i = m_iterator[iIdx];

                        //if (i->first.next(i->second))
                        string next;
                        var    ret = i.first.next(out next);
                        m_iterator[iIdx] = new std.pair <path_iterator, string>(i.first, next);
                        i = m_iterator[iIdx];
                        if (ret)
                        {
                            LOG(null, "emu_file: next path {0} '{1}'\n", iIdx, i.second); //LOG("emu_file: next path %d '%s'\n", std::distance(m_iterator.begin(), i), i->second);
                            for (int jIdx = 0; iIdx != jIdx; ++jIdx)                      //for (searchpath_vector::iterator j = m_iterator.begin(); i != j; ++j)
                            {
                                var j = m_iterator[jIdx];
                                j.first.reset();

                                //j->first.next(j->second);
                                string jnext;
                                j.first.next(out jnext);
                                m_iterator[jIdx] = new std.pair <path_iterator, string>(j.first, jnext);
                            }
                            break;
                        }
                        ++iIdx;                   //++i;
                    }
                    if (m_iterator.Count == iIdx) //if (m_iterator.end() == i)
                    {
                        return(filerr);
                    }
                }

                // build full path
                m_fullpath = m_fullpath.clear_();
                foreach (var path in m_iterator)  //for (searchpath_vector::value_type const &path : m_iterator)
                {
                    m_fullpath = m_fullpath.append_(path.second);
                    if (!m_fullpath.empty() && !util.is_directory_separator(m_fullpath.back()))
                    {
                        m_fullpath = m_fullpath.append_(PATH_SEPARATOR);
                    }
                }
                m_fullpath = m_fullpath.append_(m_filename);

                // attempt to open the file directly
                LOG(null, "emu_file: attempting to open '{0}' directly\n", m_fullpath);
                filerr = util.core_file.open(m_fullpath, m_openflags, out m_file);

                // if we're opening for read-only we have other options
                if (filerr && ((m_openflags & (OPEN_FLAG_READ | OPEN_FLAG_WRITE)) == OPEN_FLAG_READ))
                {
                    LOG(null, "emu_file: attempting to open '{0}' from archives\n", m_fullpath);
                    filerr = attempt_zipped();
                }
            }

            return(filerr);
        }
예제 #18
0
        std.vector <u8> m_rawdata_cmd = new std.vector <u8>();       //std::vector<char>   m_rawdata_cmd;      // pointer to the raw data for the font


        // construction/destruction

        //-------------------------------------------------
        //  render_font - constructor
        //-------------------------------------------------
        public render_font(render_manager manager, string filename)
        {
            m_manager    = manager;
            m_format     = format.UNKNOWN;
            m_height     = 0;
            m_yoffs      = 0;
            m_defchar    = -1;
            m_scale      = 1.0f;
            m_rawsize    = 0;
            m_osdfont    = null;
            m_height_cmd = 0;
            m_yoffs_cmd  = 0;


            //memset(m_glyphs, 0, sizeof(m_glyphs));
            for (int i = 0; i < m_glyphs.Length; i++)
            {
                m_glyphs[i] = new List <glyph>();
            }

            //memset(m_glyphs_cmd, 0, sizeof(m_glyphs_cmd));
            //for (int i = 0; i < m_glyphs_cmd.Length; i++)
            //    m_glyphs_cmd[i] = new List<glyph>();


            // if this is an OSD font, we're done
            if (filename != null)
            {
                m_osdfont = manager.machine().osd().font_alloc();
                if (m_osdfont != null && m_osdfont.open(manager.machine().options().font_path(), filename, out m_height))
                {
                    m_scale  = 1.0f / (float)m_height;
                    m_format = format.OSD;

                    //mamep: allocate command glyph font
                    render_font_command_glyph();
                    return;
                }

                m_osdfont = null;  // m_osdfont.reset();
            }

            // if the filename is 'default' default to 'ui.bdf' for backwards compatibility
            if (filename != null && core_stricmp(filename, "default") == 0)
            {
                filename = "ui.bdf";
            }

            // attempt to load an external BDF font first
            if (filename != null && load_cached_bdf(filename))
            {
                //mamep: allocate command glyph font
                render_font_command_glyph();
                return;
            }

            // load the compiled in data instead
            emu_file ramfile = new emu_file(OPEN_FLAG_READ);

            std.error_condition filerr = ramfile.open_ram(new MemoryU8(font_uismall), (u32)font_uismall.Length);//, sizeof(font_uismall));
            if (!filerr)
            {
                load_cached(ramfile, 0, 0);
            }

            ramfile.close();

            render_font_command_glyph();
        }