int running_machine::run(bool firstrun) { int error = MAMERR_NONE; // move to the init phase m_current_phase = MACHINE_PHASE_INIT; // if we have a logfile, set up the callback if (options().log()) { m_logfile.reset(global_alloc(emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS))); file_error filerr = m_logfile->open("error.log"); assert_always(filerr == FILERR_NONE, "unable to open log file"); add_logerror_callback(logfile_callback); } // then finish setting up our local machine start(); // load the configuration settings and NVRAM bool settingsloaded = config_load_settings(*this); //MKCHAMP - INITIALIZING THE HISCORE ENGINE if (! options().disable_hiscore_patch()) hiscore_init(*this); // disallow save state registrations starting here. // Don't do it earlier, config load can create network // devices with timers. m_save.allow_registration(false); nvram_load(); sound().ui_mute(false); // initialize ui lists ui().initialize(*this); // display the startup screens ui().display_startup_screens(firstrun, !options().skip_nagscreen()); // perform a soft reset -- this takes us to the running phase soft_reset(); // handle initial load if (m_saveload_schedule != SLS_NONE) handle_saveload(); // run the CPUs until a reset or exit m_hard_reset_pending = false; while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != SLS_NONE) return 0; // and out via the exit phase m_current_phase = MACHINE_PHASE_EXIT; // save the NVRAM and configuration sound().ui_mute(true); nvram_save(); config_save_settings(*this); // make sure our phase is set properly before cleaning up, // in case we got here via exception m_current_phase = MACHINE_PHASE_EXIT; // call all exit callbacks registered call_notifiers(MACHINE_NOTIFY_EXIT); zip_file_cache_clear(); // close the logfile m_logfile.reset(); return error; }
static void gfxset_update_bitmap(running_machine &machine, ui_gfx_state &state, int xcells, int ycells, gfx_element &gfx) { int dev = state.gfxset.devindex; int set = state.gfxset.set; ui_gfx_info &info = state.gfxdev[dev]; int cellxpix, cellypix; int x, y; // compute the number of source pixels in a cell cellxpix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width()); cellypix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height()); // realloc the bitmap if it is too small if (state.bitmap == nullptr || state.texture == nullptr || state.bitmap->bpp() != 32 || state.bitmap->width() != cellxpix * xcells || state.bitmap->height() != cellypix * ycells) { // free the old stuff machine.render().texture_free(state.texture); global_free(state.bitmap); // allocate new stuff state.bitmap = global_alloc(bitmap_rgb32(cellxpix * xcells, cellypix * ycells)); state.texture = machine.render().texture_alloc(); state.texture->set_bitmap(*state.bitmap, state.bitmap->cliprect(), TEXFORMAT_ARGB32); // force a redraw state.bitmap_dirty = true; } // handle the redraw if (state.bitmap_dirty) { // loop over rows for (y = 0; y < ycells; y++) { rectangle cellbounds; // make a rect that covers this row cellbounds.set(0, state.bitmap->width() - 1, y * cellypix, (y + 1) * cellypix - 1); // only display if there is data to show if (info.offset[set] + y * xcells < gfx.elements()) { // draw the individual cells for (x = 0; x < xcells; x++) { int index = info.offset[set] + y * xcells + x; // update the bounds for this cell cellbounds.min_x = x * cellxpix; cellbounds.max_x = (x + 1) * cellxpix - 1; // only render if there is data if (index < gfx.elements()) gfxset_draw_item(machine, gfx, index, *state.bitmap, cellbounds.min_x, cellbounds.min_y, info.color[set], info.rotate[set], info.palette[set]); // otherwise, fill with transparency else state.bitmap->fill(0, cellbounds); } } // otherwise, fill with transparency else state.bitmap->fill(0, cellbounds); } // reset the texture to force an update state.texture->set_bitmap(*state.bitmap, state.bitmap->cliprect(), TEXFORMAT_ARGB32); state.bitmap_dirty = false; } }
device_config *zx8301_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) { return global_alloc(zx8301_device_config(mconfig, tag, owner, clock)); }
void device_memory_interface::interface_validity_check(validity_checker &valid) const { bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true; // loop over all address spaces for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; ++spacenum) { const address_space_config *spaceconfig = space_config(spacenum); if (spaceconfig != nullptr) { int datawidth = spaceconfig->m_databus_width; int alignunit = datawidth / 8; // construct the maps auto map = global_alloc(::address_map(const_cast<device_t &>(device()), spacenum)); // if this is an empty map, just skip it if (map->m_entrylist.first() == nullptr) { global_free(map); continue; } // validate the global map parameters if (map->m_spacenum != spacenum) osd_printf_error("Space %d has address space %d handlers!\n", spacenum, map->m_spacenum); if (map->m_databits != datawidth) osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig->m_name, datawidth, map->m_databits); // loop over entries and look for errors for (address_map_entry *entry = map->m_entrylist.first(); entry != nullptr; entry = entry->next()) { UINT32 bytestart = spaceconfig->addr2byte(entry->m_addrstart); UINT32 byteend = spaceconfig->addr2byte_end(entry->m_addrend); // look for overlapping entries if (!detected_overlap) { address_map_entry *scan; for (scan = map->m_entrylist.first(); scan != entry; scan = scan->next()) if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart && ((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) || (entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE))) { osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type); detected_overlap = true; break; } } // look for inverted start/end pairs if (byteend < bytestart) osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend); // look for misaligned entries if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit); // if this is a program space, auto-assign implicit ROM entries if (entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr) { entry->m_region = device().tag(); entry->m_rgnoffs = entry->m_addrstart; } // if this entry references a memory region, validate it if (entry->m_region != nullptr && entry->m_share == nullptr) { // make sure we can resolve the full path to the region bool found = false; std::string entry_region = entry->m_devbase.subtag(entry->m_region); // look for the region device_iterator deviter(device().mconfig().root_device()); for (device_t *device = deviter.first(); device != nullptr; device = deviter.next()) for (const rom_entry *romp = rom_first_region(*device); romp != nullptr && !found; romp = rom_next_region(romp)) { if (rom_region_name(*device, romp) == entry_region) { // verify the address range is within the region's bounds offs_t length = ROMREGION_GETLENGTH(romp); if (entry->m_rgnoffs + (byteend - bytestart + 1) > length) osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length); found = true; } } // error if not found if (!found) osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); } // make sure all devices exist // FIXME: This doesn't work! AMH_DEVICE_DELEGATE entries don't even set m_tag, the device tag is inside the proto-delegate if (entry->m_read.m_type == AMH_DEVICE_DELEGATE && entry->m_read.m_tag != nullptr) { std::string temp(entry->m_read.m_tag); if (device().siblingdevice(temp.c_str()) == nullptr) osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_read.m_tag); } if (entry->m_write.m_type == AMH_DEVICE_DELEGATE && entry->m_write.m_tag != nullptr) { std::string temp(entry->m_write.m_tag); if (device().siblingdevice(temp.c_str()) == nullptr) osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_write.m_tag); } // make sure ports exist // if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) || // (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL)) // osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig->m_name, entry->m_read.m_tag); // validate bank and share tags if (entry->m_read.m_type == AMH_BANK) valid.validate_tag(entry->m_read.m_tag); if (entry->m_write.m_type == AMH_BANK) valid.validate_tag(entry->m_write.m_tag); if (entry->m_share != nullptr) valid.validate_tag(entry->m_share); } // release the address map global_free(map); } } }
cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, const char *filename, xml_data_node const &cheatnode) : m_manager(manager) , m_symbols(&manager.machine(), &globaltable) , m_state(SCRIPT_STATE_OFF) , m_numtemp(DEFAULT_TEMP_VARIABLES) , m_argindex(0) { // reset scripts try { // pull the variable count out ahead of things int tempcount = cheatnode.get_attribute_int("tempvariables", DEFAULT_TEMP_VARIABLES); if (tempcount < 1) throw emu_fatalerror("%s.xml(%d): invalid tempvariables attribute (%d)\n", filename, cheatnode.line, tempcount); // allocate memory for the cheat m_numtemp = tempcount; // get the description const char *description = cheatnode.get_attribute_string("desc", nullptr); if (description == nullptr || description[0] == 0) throw emu_fatalerror("%s.xml(%d): empty or missing desc attribute on cheat\n", filename, cheatnode.line); m_description = description; // create the symbol table m_symbols.add("argindex", symbol_table::READ_ONLY, &m_argindex); for (int curtemp = 0; curtemp < tempcount; curtemp++) { m_symbols.add(string_format("temp%d", curtemp).c_str(), symbol_table::READ_WRITE); } // read the first comment node xml_data_node const *commentnode = cheatnode.get_child("comment"); if (commentnode != nullptr) { // set the value if not nullptr if (commentnode->get_value() != nullptr && commentnode->get_value()[0] != 0) m_comment.assign(commentnode->get_value()); // only one comment is kept commentnode = commentnode->get_next_sibling("comment"); if (commentnode != nullptr) osd_printf_warning("%s.xml(%d): only one comment node is retained; ignoring additional nodes\n", filename, commentnode->line); } // read the first parameter node xml_data_node const *paramnode = cheatnode.get_child("parameter"); if (paramnode != nullptr) { // load this parameter m_parameter.reset(global_alloc(cheat_parameter(manager, m_symbols, filename, *paramnode))); // only one parameter allowed paramnode = paramnode->get_next_sibling("parameter"); if (paramnode != nullptr) osd_printf_warning("%s.xml(%d): only one parameter node allowed; ignoring additional nodes\n", filename, paramnode->line); } // read the script nodes for (xml_data_node const *scriptnode = cheatnode.get_child("script"); scriptnode != nullptr; scriptnode = scriptnode->get_next_sibling("script")) { // load this entry auto curscript = global_alloc(cheat_script(manager, m_symbols, filename, *scriptnode)); // if we have a script already for this slot, it is an error std::unique_ptr<cheat_script> &slot = script_for_state(curscript->state()); if (slot != nullptr) osd_printf_warning("%s.xml(%d): only one on script allowed; ignoring additional scripts\n", filename, scriptnode->line); else slot.reset(curscript); } } catch (emu_fatalerror &) { // call our destructor to clean up and re-throw this->~cheat_entry(); throw; } }
base *drawd3d9_init(void) { bool post_available = true; // dynamically grab the create function from d3d9.dll HINSTANCE dllhandle = LoadLibrary(TEXT("d3d9.dll")); if (dllhandle == NULL) { mame_printf_verbose("Direct3D: Unable to access d3d9.dll\n"); return NULL; } // import the create function direct3dcreate9_ptr direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9"); if (direct3dcreate9 == NULL) { mame_printf_verbose("Direct3D: Unable to find Direct3DCreate9\n"); FreeLibrary(dllhandle); dllhandle = NULL; return NULL; } // create our core direct 3d object IDirect3D9 *d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION); if (d3d9 == NULL) { mame_printf_verbose("Direct3D: Error attempting to initialize Direct3D9\n"); FreeLibrary(dllhandle); dllhandle = NULL; return NULL; } // dynamically grab the shader load function from d3dx9.dll HINSTANCE fxhandle = NULL; for (int idx = 99; idx >= 0; idx--) // a shameful moogle { wchar_t dllbuf[13]; wsprintf(dllbuf, TEXT("d3dx9_%d.dll"), idx); fxhandle = LoadLibrary(dllbuf); if (fxhandle != NULL) { break; } } if (fxhandle == NULL) { mame_printf_verbose("Direct3D: Warning - Unable find any D3D9 DLLs; disabling post-effect rendering\n"); post_available = false; } // allocate an object to hold our data base *d3dptr = global_alloc(base); d3dptr->version = 9; d3dptr->d3dobj = d3d9; d3dptr->dllhandle = dllhandle; d3dptr->post_fx_available = post_available; d3dptr->libhandle = fxhandle; set_interfaces(d3dptr); mame_printf_verbose("Direct3D: Using Direct3D 9\n"); return d3dptr; }
cheat_script::script_entry::script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &entrynode, bool isaction) : m_next(nullptr), m_condition(&symbols), m_expression(&symbols) { const char *expression = nullptr; try { // read the condition if present expression = xml_get_attribute_string(&entrynode, "condition", nullptr); if (expression != nullptr) m_condition.parse(expression); // if this is an action, parse the expression if (isaction) { expression = entrynode.value; if (expression == nullptr || expression[0] == 0) throw emu_fatalerror("%s.xml(%d): missing expression in action tag\n", filename, entrynode.line); m_expression.parse(expression); } // otherwise, parse the attributes and arguments else { // extract format const char *format = xml_get_attribute_string(&entrynode, "format", nullptr); if (format == nullptr || format[0] == 0) throw emu_fatalerror("%s.xml(%d): missing format in output tag\n", filename, entrynode.line); m_format.assign(format); // extract other attributes m_line = xml_get_attribute_int(&entrynode, "line", 0); m_justify = JUSTIFY_LEFT; const char *align = xml_get_attribute_string(&entrynode, "align", "left"); if (strcmp(align, "center") == 0) m_justify = JUSTIFY_CENTER; else if (strcmp(align, "right") == 0) m_justify = JUSTIFY_RIGHT; else if (strcmp(align, "left") != 0) throw emu_fatalerror("%s.xml(%d): invalid alignment '%s' specified\n", filename, entrynode.line, align); // then parse arguments int totalargs = 0; for (xml_data_node *argnode = xml_get_sibling(entrynode.child, "argument"); argnode != nullptr; argnode = xml_get_sibling(argnode->next, "argument")) { output_argument &curarg = m_arglist.append(*global_alloc(output_argument(manager, symbols, filename, *argnode))); // verify we didn't overrun the argument count totalargs += curarg.count(); if (totalargs > MAX_ARGUMENTS) throw emu_fatalerror("%s.xml(%d): too many arguments (found %d, max is %d)\n", filename, argnode->line, totalargs, MAX_ARGUMENTS); } // validate the format against the arguments validate_format(filename, entrynode.line); } } catch (expression_error &err) { throw emu_fatalerror("%s.xml(%d): error parsing cheat expression \"%s\" (%s)\n", filename, entrynode.line, expression, err.code_string()); } }
static osd_renderer *drawbgfx_create(osd_window *window) { return global_alloc(renderer_bgfx(window)); }
void pcd_state::machine_start() { m_gfxdecode->set_gfx(0, global_alloc(gfx_element(machine().device<palette_device>("palette"), pcd_charlayout, &m_charram[0], 0, 1, 0))); m_req_hack = timer_alloc(); }
consolewin_info::consolewin_info(debugger_windows_interface &debugger) : disasmbasewin_info(debugger, true, "Debug", NULL), m_devices_menu(NULL) { if ((window() == NULL) || (m_views[0] == NULL)) goto cleanup; // create the views m_views[1].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_STATE))); if (!m_views[1]->is_valid()) goto cleanup; m_views[2].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_CONSOLE))); if (!m_views[2]->is_valid()) goto cleanup; { // Add image menu only if image devices exist image_interface_iterator iter(machine().root_device()); device_image_interface *img = iter.first(); if (img != NULL) { m_devices_menu = CreatePopupMenu(); for ( ; img != NULL; img = iter.next()) { astring temp; temp.format("%s : %s", img->device().name(), img->exists() ? img->filename() : "[no image]"); TCHAR *tc_buf = tstring_from_utf8(temp.c_str()); if (tc_buf != NULL) { AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf); osd_free(tc_buf); } } AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)m_devices_menu, TEXT("Images")); } // get the work bounds RECT work_bounds, bounds; SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0); // adjust the min/max sizes for the window style bounds.top = bounds.left = 0; bounds.right = bounds.bottom = EDGE_WIDTH + m_views[1]->maxwidth() + (2 * EDGE_WIDTH) + 100 + EDGE_WIDTH; AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX); set_minwidth(bounds.right - bounds.left); bounds.top = bounds.left = 0; bounds.right = bounds.bottom = EDGE_WIDTH + m_views[1]->maxwidth() + (2 * EDGE_WIDTH) + MAX(m_views[0]->maxwidth(), m_views[2]->maxwidth()) + EDGE_WIDTH; AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX); set_maxwidth(bounds.right - bounds.left); // position the window at the bottom-right int const bestwidth = MIN(maxwidth(), work_bounds.right - work_bounds.left); int const bestheight = MIN(500, work_bounds.bottom - work_bounds.top); SetWindowPos(window(), HWND_TOP, work_bounds.right - bestwidth, work_bounds.bottom - bestheight, bestwidth, bestheight, SWP_SHOWWINDOW); } // recompute the children set_cpu(*debug_cpu_get_visible_cpu(machine())); // mark the edit box as the default focus and set it set_default_focus(); return; cleanup: m_views[2].reset(); m_views[1].reset(); m_views[0].reset(); }
void symcache_module_load(void *drcontext, const module_data_t *mod, bool loaded) { /* look for cache file for this module. * fill in hashtable: key is string, value is list of offsets */ mod_cache_t *modcache; const char *modname = dr_module_preferred_name(mod); file_t f; if (modname == NULL) return; /* don't support caching */ /* if smaller than threshold, not worth caching */ if (mod->end - mod->start < op_modsize_cache_threshold) { LOG(1, "%s: module %s too small to cache\n", __FUNCTION__, modname); return; } ASSERT(initialized, "symcache was not initialized"); /* support initializing prior to module events => called twice */ dr_mutex_lock(symcache_lock); modcache = (mod_cache_t *) hashtable_lookup(&symcache_table, (void *)mod->full_path); dr_mutex_unlock(symcache_lock); if (modcache != NULL) return; modcache = (mod_cache_t *) global_alloc(sizeof(*modcache), HEAPSTAT_HASHTABLE); memset(modcache, 0, sizeof(*modcache)); hashtable_init_ex(&modcache->table, SYMCACHE_MODULE_TABLE_HASH_BITS, HASH_STRING, true/*strdup*/, true/*synch*/, symcache_free_list, NULL, NULL); /* store consistency fields */ f = dr_open_file(mod->full_path, DR_FILE_READ); if (f != INVALID_FILE) { bool ok = dr_file_size(f, &modcache->module_file_size); if (!ok) WARN("WARNING: unable to determine size of %s\n", mod->full_path); dr_close_file(f); } else WARN("WARNING: unable to open %s\n", mod->full_path); #ifdef WINDOWS modcache->file_version = mod->file_version; modcache->product_version = mod->product_version; modcache->checksum = mod->checksum; modcache->timestamp = mod->timestamp; modcache->module_internal_size = mod->module_internal_size; #endif modcache->modname = drmem_strdup(modname, HEAPSTAT_HASHTABLE); modcache->from_file = symcache_read_symfile(mod, modname, modcache); dr_mutex_lock(symcache_lock); if (!hashtable_add(&symcache_table, (void *)mod->full_path, (void *)modcache)) { /* this should be really rare to have dup paths (xref i#729) -- and * actually we now have a lookup up above so we should only get here * on a race while we let go of the lock */ WARN("WARNING: duplicate module paths: only caching symbols from first\n"); hashtable_delete(&modcache->table); global_free(modcache, sizeof(*modcache), HEAPSTAT_HASHTABLE); } dr_mutex_unlock(symcache_lock); }
void debug_view_state::recompute() { const debug_view_state_source &source = downcast<const debug_view_state_source &>(*m_source); // start with a blank list reset(); // add a cycles entry: cycles:99999999 state_item **tailptr = &m_state_list; *tailptr = global_alloc(state_item(REG_CYCLES, "cycles", 8)); tailptr = &(*tailptr)->m_next; // add a beam entry: beamx:1234 *tailptr = global_alloc(state_item(REG_BEAMX, "beamx", 4)); tailptr = &(*tailptr)->m_next; // add a beam entry: beamy:5678 *tailptr = global_alloc(state_item(REG_BEAMY, "beamy", 4)); tailptr = &(*tailptr)->m_next; // add a beam entry: frame:123456 *tailptr = global_alloc(state_item(REG_FRAME, "frame", 6)); tailptr = &(*tailptr)->m_next; // add a flags entry: flags:xxxxxxxx *tailptr = global_alloc(state_item(STATE_GENFLAGS, "flags", source.m_stateintf->state_string_max_length(STATE_GENFLAGS))); tailptr = &(*tailptr)->m_next; // add a divider entry *tailptr = global_alloc(state_item(REG_DIVIDER, "", 0)); tailptr = &(*tailptr)->m_next; // add all registers into it for (const device_state_entry &entry : source.m_stateintf->state_entries()) if (entry.divider()) { *tailptr = global_alloc(state_item(REG_DIVIDER, "", 0)); tailptr = &(*tailptr)->m_next; } else if (entry.visible()) { *tailptr = global_alloc(state_item(entry.index(), entry.symbol(), source.m_stateintf->state_string_max_length(entry.index()))); tailptr = &(*tailptr)->m_next; } // count the entries and determine the maximum tag and value sizes int count = 0; int maxtaglen = 0; int maxvallen = 0; for (state_item *item = m_state_list; item != nullptr; item = item->m_next) { count++; maxtaglen = MAX(maxtaglen, item->m_symbol.length()); maxvallen = MAX(maxvallen, item->m_vallen); } // set the current divider and total cols m_divider = 1 + maxtaglen + 1; m_total.x = 1 + maxtaglen + 2 + maxvallen + 1; m_total.y = count; m_topleft.x = 0; m_topleft.y = 0; // no longer need to recompute m_recompute = false; }
d3d *drawd3d9_init(void) { direct3dcreate9_ptr direct3dcreate9; HINSTANCE dllhandle; IDirect3D9 *d3d9; d3d *d3dptr; bool post_available = true; // dynamically grab the create function from d3d9.dll dllhandle = LoadLibrary(TEXT("d3d9.dll")); if (dllhandle == NULL) { mame_printf_verbose(_WINDOWS("Direct3D: Unable to access d3d9.dll\n")); return NULL; } // import the create function direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9"); if (direct3dcreate9 == NULL) { mame_printf_verbose(_WINDOWS("Direct3D: Unable to find Direct3DCreate9\n")); FreeLibrary(dllhandle); dllhandle = NULL; return NULL; } // create our core direct 3d object d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION); if (d3d9 == NULL) { mame_printf_verbose(_WINDOWS("Direct3D: Error attempting to initialize Direct3D9\n")); FreeLibrary(dllhandle); dllhandle = NULL; return NULL; } // dynamically grab the shader load function from d3dx9.dll HINSTANCE fxhandle = LoadLibrary(TEXT("d3dx9_43.dll")); if (fxhandle == NULL) { post_available = false; mame_printf_verbose(_WINDOWS("Direct3D: Warning - Unable to access d3dx9_43.dll; disabling post-effect rendering\n")); } // import the create function if(post_available) { g_load_effect = (direct3dx9_loadeffect_ptr)GetProcAddress(fxhandle, "D3DXCreateEffectFromFileW"); if (g_load_effect == NULL) { printf("Direct3D: Unable to find D3DXCreateEffectFromFileW\n"); FreeLibrary(dllhandle); fxhandle = NULL; dllhandle = NULL; return NULL; } } else { g_load_effect = NULL; post_available = false; mame_printf_verbose(_WINDOWS("Direct3D: Warning - Unable to get a handle to D3DXCreateEffectFromFileW; disabling post-effect rendering\n")); } // allocate an object to hold our data d3dptr = global_alloc(d3d); d3dptr->version = 9; d3dptr->d3dobj = d3d9; d3dptr->dllhandle = dllhandle; d3dptr->post_fx_available = post_available; set_interfaces(d3dptr); mame_printf_verbose(_WINDOWS("Direct3D: Using Direct3D 9\n")); return d3dptr; }
void running_machine::add_logerror_callback(logerror_callback callback) { assert_always(m_current_phase == MACHINE_PHASE_INIT, "Can only call add_logerror_callback at init time!"); m_logerror_list.append(*global_alloc(logerror_callback_item(callback))); }
static CREATE_NETDEV(create_tap) { class netdev_tap *dev = global_alloc(netdev_tap(ifname, ifdev, rate)); return dynamic_cast<netdev *>(dev); }
static void process_disk_entries(rom_load_data *romdata, const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag) { /* loop until we hit the end of this region */ for ( ; !ROMENTRY_ISREGIONEND(romp); romp++) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { open_chd *chd = global_alloc(open_chd(regiontag)); hash_collection hashes(ROM_GETHASHDATA(romp)); chd_error err; /* make the filename of the source */ astring filename(ROM_GETNAME(romp), ".chd"); /* first open the source drive */ LOG(("Opening disk image: %s\n", filename.cstr())); err = chd_error(open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, chd->orig_chd(), locationtag)); if (err != CHDERR_NONE) { if (err == CHDERR_FILE_NOT_FOUND) romdata->errorstring.catprintf("%s NOT FOUND\n", filename.cstr()); else romdata->errorstring.catprintf("%s CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err)); /* if this is NO_DUMP, keep going, though the system may not be able to handle it */ if (hashes.flag(hash_collection::FLAG_NO_DUMP)) romdata->knownbad++; else if (DISK_ISOPTIONAL(romp)) romdata->warnings++; else romdata->errors++; global_free(chd); continue; } /* get the header and extract the SHA1 */ hash_collection acthashes; acthashes.add_sha1(chd->orig_chd().sha1()); /* verify the hash */ if (hashes != acthashes) { romdata->errorstring.catprintf("%s WRONG CHECKSUMS:\n", filename.cstr()); dump_wrong_and_correct_checksums(romdata, hashes, acthashes); romdata->warnings++; } else if (hashes.flag(hash_collection::FLAG_BAD_DUMP)) { romdata->errorstring.catprintf("%s CHD NEEDS REDUMP\n", filename.cstr()); romdata->knownbad++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* try to open or create the diff */ err = open_disk_diff(romdata->machine().options(), romp, chd->orig_chd(), chd->diff_chd()); if (err != CHDERR_NONE) { romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err)); romdata->errors++; global_free(chd); continue; } } /* we're okay, add to the list of disks */ LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp))); romdata->machine().romload_data->chd_list.append(*chd); } } }
address_map_entry32 *address_map::add(offs_t start, offs_t end, address_map_entry32 *ptr) { ptr = global_alloc(address_map_entry32(*this, start, end)); m_entrylist.append(*ptr); return ptr; }
void tc0080vco_device::device_start() { /* Is this endian-correct ??? */ #define XOR(a) WORD_XOR_BE(a) static const gfx_layout charlayout = { 8, 8, /* 8x8 pixels */ 256, /* 256 chars */ 3, /* 3 bits per pixel */ { 0x10000*8 + XOR(2)*4, XOR(0)*4, XOR(2)*4 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 16*0, 16*1, 16*2, 16*3, 16*4, 16*5, 16*6, 16*7 }, 16*8 }; if(!m_gfxdecode->started()) throw device_missing_dependencies(); m_tilemap[0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0080vco_device::get_bg0_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64); m_tilemap[1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0080vco_device::get_bg1_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64); m_tilemap[0]->set_transparent_pen(0); m_tilemap[1]->set_transparent_pen(0); m_tilemap[0]->set_scrolldx(m_bg_xoffs, 512); m_tilemap[1]->set_scrolldx(m_bg_xoffs, 512); m_tilemap[0]->set_scrolldy(m_bg_yoffs, m_bg_flip_yoffs); m_tilemap[1]->set_scrolldy(m_bg_yoffs, m_bg_flip_yoffs); /* bg0 tilemap scrollable per pixel row */ m_tilemap[0]->set_scroll_rows(512); /* Perform extra initialisations for text layer */ m_tilemap[2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0080vco_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_tilemap[2]->set_scrolldx(0, 0); m_tilemap[2]->set_scrolldy(48, -448); m_tilemap[2]->set_transparent_pen(0); m_ram = auto_alloc_array_clear(machine(), UINT16, TC0080VCO_RAM_SIZE / 2); m_char_ram = m_ram + 0x00000 / 2; /* continues at +0x10000 */ m_tx_ram_0 = m_ram + 0x01000 / 2; m_chain_ram_0 = m_ram + 0x00000 / 2; /* only used from +0x2000 */ m_bg0_ram_0 = m_ram + 0x0c000 / 2; m_bg1_ram_0 = m_ram + 0x0e000 / 2; m_tx_ram_1 = m_ram + 0x11000 / 2; m_chain_ram_1 = m_ram + 0x10000 / 2; /* only used from +0x12000 */ m_bg0_ram_1 = m_ram + 0x1c000 / 2; m_bg1_ram_1 = m_ram + 0x1e000 / 2; m_bgscroll_ram = m_ram + 0x20000 / 2; m_spriteram = m_ram + 0x20400 / 2; m_scroll_ram = m_ram + 0x20800 / 2; /* create the char set (gfx will then be updated dynamically from RAM) */ m_gfxdecode->set_gfx(m_txnum, global_alloc(gfx_element(m_palette, charlayout, (UINT8 *)m_char_ram, 0, 1, 512))); save_pointer(NAME(m_ram), TC0080VCO_RAM_SIZE / 2); machine().save().register_postload(save_prepost_delegate(FUNC(tc0080vco_device::postload), this)); }
void cheat_manager::load_cheats(const char *filename) { xml_data_node *rootnode = nullptr; emu_file cheatfile(machine().options().cheat_path(), OPEN_FLAG_READ); try { // open the file with the proper name file_error filerr = cheatfile.open(filename, ".xml"); // loop over all instrances of the files found in our search paths while (filerr == FILERR_NONE) { osd_printf_verbose("Loading cheats file from %s\n", cheatfile.fullpath()); // read the XML file into internal data structures xml_parse_options options = { nullptr }; xml_parse_error error; options.error = &error; rootnode = xml_file_read(cheatfile, &options); // if unable to parse the file, just bail if (rootnode == nullptr) throw emu_fatalerror("%s.xml(%d): error parsing XML (%s)\n", filename, error.error_line, error.error_message); // find the layout node xml_data_node *mamecheatnode = xml_get_sibling(rootnode->child, "mamecheat"); if (mamecheatnode == nullptr) throw emu_fatalerror("%s.xml: missing mamecheatnode node", filename); // validate the config data version int version = xml_get_attribute_int(mamecheatnode, "version", 0); if (version != CHEAT_VERSION) throw emu_fatalerror("%s.xml(%d): Invalid cheat XML file: unsupported version", filename, mamecheatnode->line); // parse all the elements for (xml_data_node *cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != nullptr; cheatnode = xml_get_sibling(cheatnode->next, "cheat")) { // load this entry auto curcheat = global_alloc(cheat_entry(*this, m_symtable, filename, *cheatnode)); // make sure we're not a duplicate cheat_entry *scannode = nullptr; if (REMOVE_DUPLICATE_CHEATS) for (scannode = m_cheatlist.first(); scannode != nullptr; scannode = scannode->next()) if (strcmp(scannode->description(), curcheat->description()) == 0) { osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); break; } // add to the end of the list if (scannode == nullptr) m_cheatlist.append(*curcheat); else global_free(curcheat); } // free the file and loop for the next one xml_file_free(rootnode); // open the next file in sequence filerr = cheatfile.open_next(); } } // handle errors cleanly catch (emu_fatalerror &err) { osd_printf_error("%s\n", err.string()); m_cheatlist.reset(); if (rootnode != nullptr) xml_file_free(rootnode); } }
address_map_entry &address_map::range(offs_t start, offs_t end) { address_map_entry *ptr = global_alloc(address_map_entry(*m_device, *this, start, end)); m_entrylist.append(*ptr); return *ptr; }
osd_midi_device *pm_module::create_midi_device() { return global_alloc(osd_midi_device_pm()); }
bool device_config_memory_interface::interface_validity_check(emu_options &options, const game_driver &driver) const { const device_config *devconfig = &m_device_config; bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true; bool error = false; // loop over all address spaces for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) { const address_space_config *spaceconfig = space_config(spacenum); if (spaceconfig != NULL) { int datawidth = spaceconfig->m_databus_width; int alignunit = datawidth / 8; // construct the maps ::address_map *map = global_alloc(::address_map(*devconfig, spacenum)); // if this is an empty map, just skip it if (map->m_entrylist.first() == NULL) { global_free(map); continue; } // validate the global map parameters if (map->m_spacenum != spacenum) { mame_printf_error("%s: %s device '%s' space %d has address space %d handlers!\n", driver.source_file, driver.name, devconfig->tag(), spacenum, map->m_spacenum); error = true; } if (map->m_databits != datawidth) { mame_printf_error("%s: %s device '%s' uses wrong memory handlers for %s space! (width = %d, memory = %08x)\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, datawidth, map->m_databits); error = true; } // loop over entries and look for errors for (address_map_entry *entry = map->m_entrylist.first(); entry != NULL; entry = entry->next()) { UINT32 bytestart = spaceconfig->addr2byte(entry->m_addrstart); UINT32 byteend = spaceconfig->addr2byte_end(entry->m_addrend); // look for overlapping entries if (!detected_overlap) { address_map_entry *scan; for (scan = map->m_entrylist.first(); scan != entry; scan = scan->next()) if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart && ((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) || (entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE))) { mame_printf_warning("%s: %s '%s' %s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type); detected_overlap = true; break; } } // look for inverted start/end pairs if (byteend < bytestart) { mame_printf_error("%s: %s wrong %s memory read handler start = %08x > end = %08x\n", driver.source_file, driver.name, spaceconfig->m_name, entry->m_addrstart, entry->m_addrend); error = true; } // look for misaligned entries if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) { mame_printf_error("%s: %s wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", driver.source_file, driver.name, spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit); error = true; } // if this is a program space, auto-assign implicit ROM entries if (entry->m_read.m_type == AMH_ROM && entry->m_region == NULL) { entry->m_region = devconfig->tag(); entry->m_rgnoffs = entry->m_addrstart; } // if this entry references a memory region, validate it if (entry->m_region != NULL && entry->m_share == 0) { // look for the region bool found = false; for (const rom_source *source = rom_first_source(m_machine_config); source != NULL && !found; source = rom_next_source(*source)) for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp) && !found; romp++) { const char *regiontag = ROMREGION_GETTAG(romp); if (regiontag != NULL) { astring fulltag; rom_region_name(fulltag, &driver, source, romp); if (fulltag.cmp(entry->m_region) == 0) { // verify the address range is within the region's bounds offs_t length = ROMREGION_GETLENGTH(romp); if (entry->m_rgnoffs + (byteend - bytestart + 1) > length) { mame_printf_error("%s: %s device '%s' %s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length); error = true; } found = true; } } } // error if not found if (!found) { mame_printf_error("%s: %s device '%s' %s space memory map entry %X-%X references non-existant region '%s'\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); error = true; } } // make sure all devices exist if ((entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag != NULL && m_machine_config.m_devicelist.find(entry->m_read.m_tag) == NULL) || (entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag != NULL && m_machine_config.m_devicelist.find(entry->m_write.m_tag) == NULL)) { mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant device '%s'\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_write.m_tag); error = true; } // make sure ports exist // if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) || // (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL)) // { // mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant port tag '%s'\n", driver.source_file, driver.name, devconfig->tag(), spaceconfig->m_name, entry->m_read.tag); // error = true; // } // validate bank and share tags if (entry->m_read.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_read.m_tag)) error = true ; if (entry->m_write.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_write.m_tag)) error = true; if (entry->m_share != NULL && !validate_tag(driver, "share", entry->m_share)) error = true; } // release the address map global_free(map); } } return error; }
osd_font *font_alloc() { return global_alloc(osd_font_windows); }
consolewin_info::consolewin_info(debugger_windows_interface &debugger) : disasmbasewin_info(debugger, true, "Debug", nullptr), m_devices_menu(nullptr) { if ((window() == nullptr) || (m_views[0] == nullptr)) goto cleanup; // create the views m_views[1].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_STATE))); if (!m_views[1]->is_valid()) goto cleanup; m_views[2].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_CONSOLE))); if (!m_views[2]->is_valid()) goto cleanup; { // Add image menu only if image devices exist image_interface_iterator iter(machine().root_device()); if (iter.first() != nullptr) { m_devices_menu = CreatePopupMenu(); for (device_image_interface &img : iter) { osd::text::tstring tc_buf = osd::text::to_tstring(string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[no image]")); AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf.c_str()); } AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)m_devices_menu, TEXT("Images")); } // get the work bounds RECT work_bounds, bounds; SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0); // adjust the min/max sizes for the window style bounds.top = bounds.left = 0; bounds.right = bounds.bottom = EDGE_WIDTH + m_views[1]->maxwidth() + (2 * EDGE_WIDTH) + 100 + EDGE_WIDTH; AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX); set_minwidth(bounds.right - bounds.left); bounds.top = bounds.left = 0; bounds.right = bounds.bottom = EDGE_WIDTH + m_views[1]->maxwidth() + (2 * EDGE_WIDTH) + std::max(m_views[0]->maxwidth(), m_views[2]->maxwidth()) + EDGE_WIDTH; AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX); set_maxwidth(bounds.right - bounds.left); // position the window at the bottom-right int const bestwidth = (std::min<uint32_t>)(maxwidth(), work_bounds.right - work_bounds.left); int const bestheight = (std::min<uint32_t>)(500, work_bounds.bottom - work_bounds.top); SetWindowPos(window(), HWND_TOP, work_bounds.right - bestwidth, work_bounds.bottom - bestheight, bestwidth, bestheight, SWP_SHOWWINDOW); } // recompute the children set_cpu(*machine().debugger().cpu().get_visible_cpu()); // mark the edit box as the default focus and set it editwin_info::set_default_focus(); return; cleanup: m_views[2].reset(); m_views[1].reset(); m_views[0].reset(); }
address_map_entry64 *address_map::add(device_t &device, offs_t start, offs_t end, address_map_entry64 *ptr) { ptr = global_alloc(address_map_entry64(device, *this, start, end)); m_entrylist.append(*ptr); return ptr; }
static void gfxset_update_bitmap(running_machine &machine, ui_gfx_state *state, int xcells, int ycells, gfx_element *gfx) { int set = state->gfxset.set; int cellxpix, cellypix; int x, y; /* compute the number of source pixels in a cell */ cellxpix = 1 + ((state->gfxset.rotate[set] & ORIENTATION_SWAP_XY) ? gfx->height() : gfx->width()); cellypix = 1 + ((state->gfxset.rotate[set] & ORIENTATION_SWAP_XY) ? gfx->width() : gfx->height()); /* realloc the bitmap if it is too small */ if (state->bitmap == NULL || state->texture == NULL || state->bitmap->bpp() != 32 || state->bitmap->width() != cellxpix * xcells || state->bitmap->height() != cellypix * ycells) { /* free the old stuff */ machine.render().texture_free(state->texture); global_free(state->bitmap); /* allocate new stuff */ state->bitmap = global_alloc(bitmap_rgb32(cellxpix * xcells, cellypix * ycells)); state->texture = machine.render().texture_alloc(); state->texture->set_bitmap(*state->bitmap, state->bitmap->cliprect(), TEXFORMAT_ARGB32); /* force a redraw */ state->bitmap_dirty = TRUE; } /* handle the redraw */ if (state->bitmap_dirty) { /* loop over rows */ for (y = 0; y < ycells; y++) { rectangle cellbounds; /* make a rect that covers this row */ cellbounds.set(0, state->bitmap->width() - 1, y * cellypix, (y + 1) * cellypix - 1); /* only display if there is data to show */ if (state->gfxset.offset[set] + y * xcells < gfx->elements()) { /* draw the individual cells */ for (x = 0; x < xcells; x++) { int index = state->gfxset.offset[set] + y * xcells + x; /* update the bounds for this cell */ cellbounds.min_x = x * cellxpix; cellbounds.max_x = (x + 1) * cellxpix - 1; /* only render if there is data */ if (index < gfx->elements()) gfxset_draw_item(machine, gfx, index, *state->bitmap, cellbounds.min_x, cellbounds.min_y, state->gfxset.color[set], state->gfxset.rotate[set]); /* otherwise, fill with transparency */ else state->bitmap->fill(0, cellbounds); } } /* otherwise, fill with transparency */ else state->bitmap->fill(0, cellbounds); } /* reset the texture to force an update */ state->texture->set_bitmap(*state->bitmap, state->bitmap->cliprect(), TEXFORMAT_ARGB32); state->bitmap_dirty = FALSE; } }
device_config *luxor_55_21046_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) { return global_alloc(luxor_55_21046_device_config(mconfig, tag, owner, clock)); }
void tc0100scn_device::device_start() { static const gfx_layout tc0100scn_charlayout = { 8,8, /* 8*8 characters */ 256, /* 256 characters */ 2, /* 2 bits per pixel */ { 0, 8 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, 16*8 /* every sprite takes 16 consecutive bytes */ }; if(!m_gfxdecode->started()) throw device_missing_dependencies(); int xd, yd; /* Set up clipping for multi-TC0100SCN games. We assume this code won't ever affect single screen games: Thundfox is the only one of those with two chips, and we're safe as it uses single width tilemaps. */ /* Single width versions */ m_tilemap[0][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_tilemap[1][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_tilemap[2][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); /* Double width versions */ m_tilemap[0][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); m_tilemap[1][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); m_tilemap[2][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32); m_tilemap[0][0]->set_transparent_pen(0); m_tilemap[1][0]->set_transparent_pen(0); m_tilemap[2][0]->set_transparent_pen(0); m_tilemap[0][1]->set_transparent_pen(0); m_tilemap[1][1]->set_transparent_pen(0); m_tilemap[2][1]->set_transparent_pen(0); /* Standard width tilemaps. I'm setting the optional chip #2 7 bits higher and 2 pixels to the left than chip #1 because that's how thundfox wants it. */ xd = (m_multiscrn_hack == 0) ? (-m_x_offset) : (-m_x_offset - 2); yd = (m_multiscrn_hack == 0) ? (8 - m_y_offset) : (1 - m_y_offset); m_tilemap[0][0]->set_scrolldx(xd - 16, -m_flip_xoffs - xd - 16); m_tilemap[0][0]->set_scrolldy(yd, -m_flip_yoffs - yd); m_tilemap[1][0]->set_scrolldx(xd - 16, -m_flip_xoffs - xd - 16); m_tilemap[1][0]->set_scrolldy(yd, -m_flip_yoffs - yd); m_tilemap[2][0]->set_scrolldx(xd - 16, -m_flip_text_xoffs - xd - 16 - 7); m_tilemap[2][0]->set_scrolldy(yd, -m_flip_text_yoffs - yd); /* Double width tilemaps. We must correct offsets for extra chips, as MAME sees offsets from LHS of whole display not from the edges of individual screens. NB flipscreen tilemap offsets are based on Cameltry */ xd = -m_x_offset - m_multiscrn_xoffs; yd = 8 - m_y_offset; m_tilemap[0][1]->set_scrolldx(xd - 16, -m_flip_xoffs - xd - 16); m_tilemap[0][1]->set_scrolldy(yd, -m_flip_yoffs - yd); m_tilemap[1][1]->set_scrolldx(xd - 16, -m_flip_xoffs - xd - 16); m_tilemap[1][1]->set_scrolldy(yd, -m_flip_yoffs - yd); m_tilemap[2][1]->set_scrolldx(xd - 16, -m_flip_text_xoffs - xd - 16 - 7); m_tilemap[2][1]->set_scrolldy(yd, -m_flip_text_yoffs - yd); m_tilemap[0][0]->set_scroll_rows(512); m_tilemap[1][0]->set_scroll_rows(512); m_tilemap[0][1]->set_scroll_rows(512); m_tilemap[1][1]->set_scroll_rows(512); m_bg_tilemask = 0xffff; /* Mjnquest has 0x7fff tilemask */ m_ram = auto_alloc_array_clear(machine(), UINT16, TC0100SCN_RAM_SIZE / 2); set_layer_ptrs(); /* create the char set (gfx will then be updated dynamically from RAM) */ m_gfxdecode->set_gfx(m_txnum, global_alloc(gfx_element(m_palette, tc0100scn_charlayout, (UINT8 *)m_char_ram, NATIVE_ENDIAN_VALUE_LE_BE(8,0), 256, 0))); gfx_element *gfx = m_gfxdecode->gfx(m_gfxnum); gfx_element *txt = m_gfxdecode->gfx(m_txnum); if (gfx->granularity() == 2) /* Yuyugogo, Yesnoj */ gfx->set_granularity(16); txt->set_granularity(gfx->granularity()); set_colbanks(0, 0, 0); /* standard values, only Wgp & multiscreen games change them */ /* we call this here, so that they can be modified at video_start*/ save_pointer(NAME(m_ram), TC0100SCN_RAM_SIZE / 2); save_item(NAME(m_ctrl)); save_item(NAME(m_dblwidth)); save_item(NAME(m_gfxbank)); machine().save().register_postload(save_prepost_delegate(FUNC(tc0100scn_device::postload), this)); }
bool floppy_image_device::call_create(int format_type, option_resolution *format_options) { image = global_alloc(floppy_image(tracks, sides, form_factor)); output_format = 0; return IMAGE_INIT_PASS; }
void running_machine::start() { // initialize basic can't-fail systems here config_init(*this); m_input.reset(global_alloc(input_manager(*this))); output_init(*this); m_render.reset(global_alloc(render_manager(*this))); generic_machine_init(*this); // allocate a soft_reset timer m_soft_reset_timer = m_scheduler.timer_alloc(timer_expired_delegate(FUNC(running_machine::soft_reset), this)); // init the osd layer m_manager.osd().init(*this); // create the video manager m_video.reset(global_alloc(video_manager(*this))); m_ui.reset(global_alloc(ui_manager(*this))); // initialize the base time (needed for doing record/playback) ::time(&m_base_time); // initialize the input system and input ports for the game // this must be done before memory_init in order to allow specifying // callbacks based on input port tags time_t newbase = m_ioport.initialize(); if (newbase != 0) m_base_time = newbase; // intialize UI input ui_input_init(*this); // initialize the streams engine before the sound devices start m_sound.reset(global_alloc(sound_manager(*this))); // first load ROMs, then populate memory, and finally initialize CPUs // these operations must proceed in this order rom_init(*this); m_memory.initialize(); // initialize the watchdog m_watchdog_timer = m_scheduler.timer_alloc(timer_expired_delegate(FUNC(running_machine::watchdog_fired), this)); if (config().m_watchdog_vblank_count != 0 && primary_screen != NULL) primary_screen->register_vblank_callback(vblank_state_delegate(FUNC(running_machine::watchdog_vblank), this)); save().save_item(NAME(m_watchdog_enabled)); save().save_item(NAME(m_watchdog_counter)); // save the random seed or save states might be broken in drivers that use the rand() method save().save_item(NAME(m_rand_seed)); // initialize image devices image_init(*this); m_tilemap.reset(global_alloc(tilemap_manager(*this))); crosshair_init(*this); network_init(*this); // initialize the debugger if ((debug_flags & DEBUG_FLAG_ENABLED) != 0) debugger_init(*this); // call the game driver's init function // this is where decryption is done and memory maps are altered // so this location in the init order is important ui().set_startup_text("Initializing...", true); // register callbacks for the devices, then start them add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(running_machine::reset_all_devices), this)); add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(running_machine::stop_all_devices), this)); save().register_presave(save_prepost_delegate(FUNC(running_machine::presave_all_devices), this)); start_all_devices(); save().register_postload(save_prepost_delegate(FUNC(running_machine::postload_all_devices), this)); // if we're coming in with a savegame request, process it now const char *savegame = options().state(); if (savegame[0] != 0) schedule_load(savegame); // if we're in autosave mode, schedule a load else if (options().autosave() && (m_system.flags & GAME_SUPPORTS_SAVE) != 0) schedule_load("auto"); // set up the cheat engine m_cheat.reset(global_alloc(cheat_manager(*this))); // allocate autoboot timer m_autoboot_timer = scheduler().timer_alloc(timer_expired_delegate(FUNC(running_machine::autoboot_callback), this)); manager().update_machine(); }