Example #1
0
void timer_device::device_validity_check(validity_checker &valid) const
{
	// type based configuration
	switch (m_type)
	{
		case TIMER_TYPE_GENERIC:
			if (m_screen_tag != NULL || m_first_vpos != 0 || m_start_delay != attotime::zero)
				mame_printf_warning("Generic timer specified parameters for a scanline timer\n");
			if (m_period != attotime::zero || m_start_delay != attotime::zero)
				mame_printf_warning("Generic timer specified parameters for a periodic timer\n");
			break;

		case TIMER_TYPE_PERIODIC:
			if (m_screen_tag != NULL || m_first_vpos != 0)
				mame_printf_warning("Periodic timer specified parameters for a scanline timer\n");
			if (m_period <= attotime::zero)
				mame_printf_error("Periodic timer specified invalid period\n");
			break;

		case TIMER_TYPE_SCANLINE:
			if (m_period != attotime::zero || m_start_delay != attotime::zero)
				mame_printf_warning("Scanline timer specified parameters for a periodic timer\n");
			if (m_param != 0)
				mame_printf_warning("Scanline timer specified parameter which is ignored\n");
			if (m_first_vpos < 0)
				mame_printf_error("Scanline timer specified invalid initial position\n");
			if (m_increment < 0)
				mame_printf_error("Scanline timer specified invalid increment\n");
			break;

		default:
			mame_printf_error("Invalid type specified\n");
			break;
	}
}
Example #2
0
int options_parse_ini_file(mame_file *inifile)
{
	/* loop over data */
	while (mame_fgets(giant_string_buffer, GIANT_STRING_BUFFER_SIZE, inifile) != NULL)
	{
		char *optionname, *optiondata, *temp;
		options_data *data;
		int inquotes = FALSE;

		/* find the name */
		for (optionname = giant_string_buffer; *optionname != 0; optionname++)
			if (!isspace(*optionname))
				break;

		/* skip comments */
		if (*optionname == 0 || *optionname == '#')
			continue;

		/* scan forward to find the first space */
		for (temp = optionname; *temp != 0; temp++)
			if (isspace(*temp))
				break;

		/* if we hit the end early, print a warning and continue */
		if (*temp == 0)
		{
			mame_printf_warning("Warning: invalid line in INI: %s", giant_string_buffer);
			continue;
		}

		/* NULL-terminate */
		*temp++ = 0;
		optiondata = temp;

		/* scan the data, stopping when we hit a comment */
		for (temp = optiondata; *temp != 0; temp++)
		{
			if (*temp == '"')
				inquotes = !inquotes;
			if (*temp == '#' && !inquotes)
				break;
		}
		*temp = 0;

		/* find our entry */
		data = find_entry_data(optionname, FALSE);
		if (data == NULL)
		{
			mame_printf_warning("Warning: unknown option in INI: %s\n", optionname);
			continue;
		}
		if ((data->flags & (OPTION_DEPRECATED | OPTION_INTERNAL)) != 0)
			continue;

		/* allocate a new copy of data for this */
		update_data(data, optiondata);
	}
	return 0;
}
Example #3
0
static void extract_video_config(running_machine &machine)
{
	windows_options &options = downcast<windows_options &>(machine.options());
	const char *stemp;

	// global options: extract the data
	video_config.windowed      = options.window();
	video_config.prescale      = options.prescale();
	video_config.keepaspect    = options.keep_aspect();
	video_config.numscreens    = options.numscreens();

	// if we are in debug mode, never go full screen
	if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
		video_config.windowed = TRUE;

	// per-window options: extract the data
	const char *default_resolution = options.resolution();
	get_resolution(default_resolution, options.resolution(0), &video_config.window[0], TRUE);
	get_resolution(default_resolution, options.resolution(1), &video_config.window[1], TRUE);
	get_resolution(default_resolution, options.resolution(2), &video_config.window[2], TRUE);
	get_resolution(default_resolution, options.resolution(3), &video_config.window[3], TRUE);

	// video options: extract the data
	stemp = options.video();
	if (strcmp(stemp, "d3d") == 0)
		video_config.mode = VIDEO_MODE_D3D;
	else if (strcmp(stemp, "ddraw") == 0)
		video_config.mode = VIDEO_MODE_DDRAW;
	else if (strcmp(stemp, "gdi") == 0)
		video_config.mode = VIDEO_MODE_GDI;
	else if (strcmp(stemp, "none") == 0)
	{
		video_config.mode = VIDEO_MODE_NONE;
		if (options.seconds_to_run() == 0)
			mame_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
	}
	else
	{
		mame_printf_warning("Invalid video value %s; reverting to gdi\n", stemp);
		video_config.mode = VIDEO_MODE_GDI;
	}
	video_config.waitvsync     = options.wait_vsync();
	video_config.syncrefresh   = options.sync_refresh();
	video_config.triplebuf     = options.triple_buffer();
	video_config.switchres     = options.switch_res();

	// ddraw options: extract the data
	video_config.hwstretch     = options.hwstretch();

	// d3d options: extract the data
	video_config.filter        = options.filter();
	if (video_config.prescale == 0)
		video_config.prescale = 1;
}
Example #4
0
static DEVICE_IMAGE_DISPLAY_INFO(cdi_cdinfo)
{
	const char *compatibility = image.get_feature("compatibility");
	if (compatibility)
	{
		if (!mame_stricmp(compatibility, "DVC"))
		{
			mame_printf_warning("This software requires the Digital Video Cartridge to work.\n");
			mame_printf_warning("Therefore, it might not work in MESS at present.\n");
		}
	}
}
Example #5
0
void cheat_script::script_entry::execute(cheat_manager &manager, UINT64 &argindex)
{
	// evaluate the condition
	if (!m_condition.is_empty())
	{
		try
		{
			UINT64 result = m_condition.execute();
			if (result == 0)
				return;
		}
		catch (expression_error &err)
		{
			mame_printf_warning("Error executing conditional expression \"%s\": %s\n", m_condition.original_string(), err.code_string());
			return;
		}
	}

	// if there is an action, execute it
	if (!m_expression.is_empty())
	{
		try
		{
			m_expression.execute();
		}
		catch (expression_error &err)
		{
			mame_printf_warning("Error executing expression \"%s\": %s\n", m_expression.original_string(), err.code_string());
		}
	}

	// if there is a string to display, compute it
	if (m_format)
	{
		// iterate over arguments and evaluate them
		UINT64 params[MAX_ARGUMENTS];
		int curarg = 0;
		for (output_argument *arg = m_arglist.first(); arg != NULL; arg = arg->next())
			curarg += arg->values(argindex, &params[curarg]);

		// generate the astring
		manager.get_output_astring(m_line, m_justify).printf(m_format,
			(UINT32)params[0],  (UINT32)params[1],  (UINT32)params[2],  (UINT32)params[3],
			(UINT32)params[4],  (UINT32)params[5],  (UINT32)params[6],  (UINT32)params[7],
			(UINT32)params[8],  (UINT32)params[9],  (UINT32)params[10], (UINT32)params[11],
			(UINT32)params[12], (UINT32)params[13], (UINT32)params[14], (UINT32)params[15],
			(UINT32)params[16], (UINT32)params[17], (UINT32)params[18], (UINT32)params[19],
			(UINT32)params[20], (UINT32)params[21], (UINT32)params[22], (UINT32)params[23],
			(UINT32)params[24], (UINT32)params[25], (UINT32)params[26], (UINT32)params[27],
			(UINT32)params[28], (UINT32)params[29], (UINT32)params[30], (UINT32)params[31]);
	}
}
Example #6
0
bool timer_device_config::device_validity_check(const game_driver &driver) const
{
	bool error = false;

	// type based configuration
	switch (m_type)
	{
		case TIMER_TYPE_GENERIC:
			if (m_screen != NULL || m_first_vpos != 0 || m_start_delay != 0)
				mame_printf_warning("%s: %s generic timer '%s' specified parameters for a scanline timer\n", driver.source_file, driver.name, tag());
			if (m_period != 0 || m_start_delay != 0)
				mame_printf_warning("%s: %s generic timer '%s' specified parameters for a periodic timer\n", driver.source_file, driver.name, tag());
			break;

		case TIMER_TYPE_PERIODIC:
			if (m_screen != NULL || m_first_vpos != 0)
				mame_printf_warning("%s: %s periodic timer '%s' specified parameters for a scanline timer\n", driver.source_file, driver.name, tag());
			if (m_period <= 0)
			{
				mame_printf_error("%s: %s periodic timer '%s' specified invalid period\n", driver.source_file, driver.name, tag());
				error = true;
			}
			break;

		case TIMER_TYPE_SCANLINE:
			if (m_period != 0 || m_start_delay != 0)
				mame_printf_warning("%s: %s scanline timer '%s' specified parameters for a periodic timer\n", driver.source_file, driver.name, tag());
			if (m_param != 0)
				mame_printf_warning("%s: %s scanline timer '%s' specified parameter which is ignored\n", driver.source_file, driver.name, tag());
			if (m_first_vpos < 0)
			{
				mame_printf_error("%s: %s scanline timer '%s' specified invalid initial position\n", driver.source_file, driver.name, tag());
				error = true;
			}
			if (m_increment < 0)
			{
				mame_printf_error("%s: %s scanline timer '%s' specified invalid increment\n", driver.source_file, driver.name, tag());
				error = true;
			}
			break;

		default:
			mame_printf_error("%s: %s timer '%s' has an invalid type\n", driver.source_file, driver.name, tag());
			error = true;
			break;
	}

	return error;
}
Example #7
0
static void display_rom_load_results(rom_load_data *romdata)
{
	int region;

	/* final status display */
	display_loading_rom_message(NULL, romdata);

	/* if we had errors, they are fatal */
	if (romdata->errors != 0)
	{
		/* clean up any regions */
		for (region = 0; region < MAX_MEMORY_REGIONS; region++)
			free_memory_region(Machine, region);

		/* create the error message and exit fatally */
		strcat(romdata->errorbuf, "ERROR: required files are missing, the game cannot be run.");
		fatalerror_exitcode(MAMERR_MISSING_FILES, "%s", romdata->errorbuf);
	}

	/* if we had warnings, output them, but continue */
	if (romdata->warnings)
	{
		strcat(romdata->errorbuf, "WARNING: the game might not run correctly.");
		mame_printf_warning("%s\n", romdata->errorbuf);
	}
}
Example #8
0
void osd_init(running_machine *machine)
{
	int watchdog = options_get_int(mame_options(), WINOPTION_WATCHDOG);
	const char *stemp;

	// thread priority
	if (!(machine->debug_flags & DEBUG_FLAG_OSD_ENABLED))
		SetThreadPriority(GetCurrentThread(), options_get_int(mame_options(), WINOPTION_PRIORITY));

	// ensure we get called on the way out
	add_exit_callback(machine, osd_exit);

	// get number of processors
	stemp = options_get_string(mame_options(), WINOPTION_NUMPROCESSORS);

	osd_num_processors = 0;

	if (strcmp(stemp, "auto") != 0)
	{
		osd_num_processors = atoi(stemp);
		if (osd_num_processors < 1)
		{
			mame_printf_warning("Warning: numprocessors < 1 doesn't make much sense. Assuming auto ...\n");
			osd_num_processors = 0;
		}
	}

	// initialize the subsystems
	winvideo_init(machine);
	winsound_init(machine);
	wininput_init(machine);
	winoutput_init(machine);

	// hook up the debugger log
	if (options_get_bool(mame_options(), WINOPTION_OSLOG))
		add_logerror_callback(machine, output_oslog);

	// crank up the multimedia timer resolution to its max
	// this gives the system much finer timeslices
	timeresult = timeGetDevCaps(&caps, sizeof(caps));
	if (timeresult == TIMERR_NOERROR)
		timeBeginPeriod(caps.wPeriodMin);

	// set our multimedia tasks if we can
//      if (av_set_mm_thread_characteristics != NULL)
//          mm_task = (*av_set_mm_thread_characteristics)(TEXT("Playback"), &task_index);

	start_profiler();

	// if a watchdog thread is requested, create one
	if (watchdog != 0)
	{
		watchdog_reset_event = CreateEvent(NULL, FALSE, FALSE, NULL);
		assert_always(watchdog_reset_event != NULL, "Failed to create watchdog reset event");
		watchdog_exit_event = CreateEvent(NULL, TRUE, FALSE, NULL);
		assert_always(watchdog_exit_event != NULL, "Failed to create watchdog exit event");
		watchdog_thread = CreateThread(NULL, 0, watchdog_thread_entry, (LPVOID)(FPTR)watchdog, 0, NULL);
		assert_always(watchdog_thread != NULL, "Failed to create watchdog thread");
	}
}
Example #9
0
cheat_script::cheat_script(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &scriptnode)
	: m_state(SCRIPT_STATE_RUN)
{
	// read the core attributes
	const char *state = xml_get_attribute_string(&scriptnode, "state", "run");
	if (strcmp(state, "on") == 0)
		m_state = SCRIPT_STATE_ON;
	else if (strcmp(state, "off") == 0)
		m_state = SCRIPT_STATE_OFF;
	else if (strcmp(state, "change") == 0)
		m_state = SCRIPT_STATE_CHANGE;
	else if (strcmp(state, "run") != 0)
		throw emu_fatalerror("%s.xml(%d): invalid script state '%s'\n", filename, scriptnode.line, state);

	// iterate over nodes within the script
	for (xml_data_node *entrynode = scriptnode.child; entrynode != NULL; entrynode = entrynode->next)
	{
		// handle action nodes
		if (strcmp(entrynode->name, "action") == 0)
			m_entrylist.append(*global_alloc(script_entry(manager, symbols, filename, *entrynode, true)));

		// handle output nodes
		else if (strcmp(entrynode->name, "output") == 0)
			m_entrylist.append(*global_alloc(script_entry(manager, symbols, filename, *entrynode, false)));

		// anything else is ignored
		else
		{
			mame_printf_warning("%s.xml(%d): unknown script item '%s' will be lost if saved\n", filename, entrynode->line, entrynode->name);
			continue;
		}
	}
}
Example #10
0
File: window.c Project: clobber/UME
static void sdlwindow_sync(void)
{
	if (multithreading_enabled)
	{
		// Fallback
		while (!osd_work_queue_wait(work_queue, osd_ticks_per_second()*10))
		{
			mame_printf_warning("sdlwindow_sync: Sleeping...\n");
			osd_sleep(100000);
		}
	}
}
Example #11
0
device_t *machine_config::device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock)
{
	// find the original device by this name (must exist)
	assert(owner != NULL);
	device_t *device = owner->subdevice(tag);
	if (device == NULL)
	{
		mame_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag);
		return device_add(owner, tag, type, clock);
	}

	// let the device's owner do the work
	return device->owner()->replace_subdevice(*device, type, tag, clock);
}
Example #12
0
device_t *machine_config::device_remove(device_t *owner, const char *tag)
{
	// find the original device by this name (must exist)
	assert(owner != NULL);
	device_t *device = owner->subdevice(tag);
	if (device == NULL)
	{
		mame_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag);
		return NULL;
	}

	// let the device's owner do the work
	device->owner()->remove_subdevice(*device);
	return NULL;
}
Example #13
0
int cheat_script::script_entry::output_argument::values(UINT64 &argindex, UINT64 *result)
{
	for (argindex = 0; argindex < m_count; argindex++)
	{
		try
		{
			result[argindex] = m_expression.execute();
		}
		catch (expression_error &err)
		{
			mame_printf_warning("Error executing argument expression \"%s\": %s\n", m_expression.original_string(), err.code_string());
		}
	}
	return m_count;
}
Example #14
0
INLINE SDL_BlendMode map_blendmode(int blendmode)
{
	switch (blendmode)
	{
		case BLENDMODE_NONE:
			return SDL_BLENDMODE_NONE;
		case BLENDMODE_ALPHA:
			return SDL_BLENDMODE_BLEND;
		case BLENDMODE_RGB_MULTIPLY:
			return SDL_BLENDMODE_MOD;
		case BLENDMODE_ADD:
			return SDL_BLENDMODE_ADD;
		default:
			mame_printf_warning("Unknown Blendmode %d", blendmode);
	}
	return SDL_BLENDMODE_NONE;
}
Example #15
0
void *finder_base::find_memory(UINT8 width, size_t &bytes, bool required)
{
	// look up the share and return NULL if not found
	memory_share *share = m_base.memshare(m_tag);
	if (share == NULL)
		return NULL;

	// check the width and warn if not correct
	if (width != 0 && share->width() != width)
	{
		if (required)
			mame_printf_warning("Shared ptr '%s' found but is width %d, not %d as requested\n", m_tag, share->width(), width);
		return NULL;
	}

	// return results
	bytes = share->bytes();
	return share->ptr();
}
Example #16
0
static void display_rom_load_results(romload_private *romdata, bool from_list)
{
	/* final status display */
	display_loading_rom_message(romdata, NULL, from_list);

	/* if we had errors, they are fatal */
	if (romdata->errors != 0)
	{
		/* create the error message and exit fatally */
		mame_printf_error("%s", romdata->errorstring.cstr());
		fatalerror_exitcode(romdata->machine(), MAMERR_MISSING_FILES, "Required files are missing, the %s cannot be run.",emulator_info::get_gamenoun());
	}

	/* if we had warnings, output them, but continue */
	if ((romdata-> warnings) || (romdata->knownbad))
	{
		romdata->errorstring.cat("WARNING: the ");
		romdata->errorstring.cat(emulator_info::get_gamenoun());
		romdata->errorstring.cat(" might not run correctly.");
		mame_printf_warning("%s\n", romdata->errorstring.cstr());
	}
}
Example #17
0
osd_font sdl_osd_interface::font_open(const char *_name, int &height)
{
	TTF_Font *font = (TTF_Font *)NULL;
	bool bakedstyles = false;
	int style = 0;

	// accept qualifiers from the name
	astring name(_name);

	if (name == "default")
	{
		name = "Liberation Sans";
	}

	bool bold = (name.replace(0, "[B]", "") + name.replace(0, "[b]", "") > 0);
	bool italic = (name.replace(0, "[I]", "") + name.replace(0, "[i]", "") > 0);
	bool underline = (name.replace(0, "[U]", "") + name.replace(0, "[u]", "") > 0);
	bool strike = (name.replace(0, "[S]", "") + name.replace(0, "[s]", "") > 0);

	// first up, try it as a filename
	font = TTF_OpenFont_Magic(name, POINT_SIZE);

	// if no success, try the font path

	if (!font)
	{
		mame_printf_verbose("Searching font %s in -%s\n", name.cstr(), OPTION_FONTPATH);
		emu_file file(machine().options().font_path(), OPEN_FLAG_READ);
		if (file.open(name) == FILERR_NONE)
		{
			astring full_name = file.fullpath();
			font = TTF_OpenFont_Magic(full_name, POINT_SIZE);
			if (font)
				mame_printf_verbose("Found font %s\n", full_name.cstr());
		}
	}

	// if that didn't work, crank up the FontConfig database
#ifndef SDLMAME_HAIKU
	if (!font)
	{
		font = search_font_config(name, bold, italic, underline, bakedstyles);
	}
#endif

	if (!font)
	{
        if (!BDF_Check_Magic(name))
        {
            printf("WARNING: font %s, is not TrueType or BDF, using MAME default\n", name.cstr());
        }
		return NULL;
	}

	// apply styles
	if (!bakedstyles)
	{
		style |= bold ? TTF_STYLE_BOLD : 0;
		style |= italic ? TTF_STYLE_ITALIC : 0;
	}
	style |= underline ? TTF_STYLE_UNDERLINE : 0;
	// SDL_ttf 2.0.9 and earlier does not define TTF_STYLE_STRIKETHROUGH
#if SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) > SDL_VERSIONNUM(2,0,9)
	style |= strike ? TTF_STYLE_STRIKETHROUGH : 0;
#else
	if (strike)
		mame_printf_warning("Ignoring strikethrough for SDL_TTF with version less 2.0.10\n");
#endif // PATCHLEVEL
	TTF_SetFontStyle(font, style);

	height = TTF_FontLineSkip(font);

	return (osd_font)font;
}
Example #18
0
void driver_switch::assign_drivers(emu_options &opts)
{
	static const struct
	{
		const char *name;
		const game_driver * const *driver;
	} drivers_table[] =
	{
#ifndef TINY_BUILD
		{ "mame",		mamedrivers },
		{ "plus",		mameplusdrivers },
		{ "homebrew",	mamehbdrivers },
		{ "decrypted",	mamedecrypteddrivers },
#ifdef MAMEMESS
		{ "console",	messdrivers },
#endif /* MAMEMESS */
#else
		{ "mame",		tinydrivers },
#endif /* !TINY_BUILD */
		{ NULL }
	};

	UINT32 enabled = 0;
	int i, n;
	bool mechanical = opts.bool_value(OPTION_DISABLE_MECHANICAL_DRIVER);

#ifndef TINY_BUILD
	const char *drv_option = opts.value(OPTION_DRIVER_CONFIG);
	if (drv_option)
	{
		char *temp = mame_strdup(drv_option);
		if (temp)
		{
			char *p = strtok(temp, ",");
 			while (p)
			{
				char *s = core_strtrim(p);	//get individual driver name
				if (s[0])
				{
					if (mame_stricmp(s, "all") == 0)
					{
						enabled = (UINT32)-1;
						break;
					}

					for (i = 0; drivers_table[i].name; i++)
						if (mame_stricmp(s, drivers_table[i].name) == 0)
						{
							enabled |= 1 << i;
							break;
						}

					if (!drivers_table[i].name)
						mame_printf_warning(_("Illegal value for %s = %s\n"), OPTION_DRIVER_CONFIG, s);
				}
				osd_free(s);
 				p = strtok(NULL, ",");
			}
 			osd_free(temp);
		}
	}
#endif /* !TINY_BUILD */

	if (enabled == 0)
		enabled = 1;	// default to mamedrivers

	n = 0;
	for (i = 0; drivers_table[i].name; i++)
		if (enabled & (1 << i))
		{
			for (int c = 0; drivers_table[i].driver[c]; c++)
				if (mame_stricmp(drivers_table[i].driver[c]->name, "___empty"))
					if (!mechanical || !(drivers_table[i].driver[c]->flags & GAME_MECHANICAL))
						driver_list::s_drivers_sorted[n++] = drivers_table[i].driver[c];
		}

	// ___empty driver add once
	driver_list::s_drivers_sorted[n++] = &GAME_NAME(___empty);
	driver_list::s_driver_count = n;

	qsort(driver_list::s_drivers_sorted, n, sizeof(*driver_list::s_drivers_sorted), driver_list::driver_sort_callback);
}
Example #19
0
static int read_rom_data(romload_private *romdata, const rom_entry *parent_region, const rom_entry *romp)
{
	int datashift = ROM_GETBITSHIFT(romp);
	int datamask = ((1 << ROM_GETBITWIDTH(romp)) - 1) << datashift;
	int numbytes = ROM_GETLENGTH(romp);
	int groupsize = ROM_GETGROUPSIZE(romp);
	int skip = ROM_GETSKIPCOUNT(romp);
	int reversed = ROM_ISREVERSED(romp);
	int numgroups = (numbytes + groupsize - 1) / groupsize;
	UINT8 *base = romdata->region->base() + ROM_GETOFFSET(romp);
	UINT32 tempbufsize;
	int i;

	LOG(("Loading ROM data: offs=%X len=%X mask=%02X group=%d skip=%d reverse=%d\n", ROM_GETOFFSET(romp), numbytes, datamask, groupsize, skip, reversed));

	/* make sure the length was an even multiple of the group size */
	if (numbytes % groupsize != 0)
		mame_printf_warning("Warning in RomModule definition: %s length not an even multiple of group size\n", ROM_GETNAME(romp));

	/* make sure we only fill within the region space */
	if (ROM_GETOFFSET(romp) + numgroups * groupsize + (numgroups - 1) * skip > romdata->region->bytes())
		fatalerror("Error in RomModule definition: %s out of memory region space\n", ROM_GETNAME(romp));

	/* make sure the length was valid */
	if (numbytes == 0)
		fatalerror("Error in RomModule definition: %s has an invalid length\n", ROM_GETNAME(romp));

	/* special case for simple loads */
	if (datamask == 0xff && (groupsize == 1 || !reversed) && skip == 0)
		return rom_fread(romdata, base, numbytes, parent_region);

	/* use a temporary buffer for complex loads */
	tempbufsize = MIN(TEMPBUFFER_MAX_SIZE, numbytes);
	dynamic_buffer tempbuf(tempbufsize);

	/* chunky reads for complex loads */
	skip += groupsize;
	while (numbytes > 0)
	{
		int evengroupcount = (tempbufsize / groupsize) * groupsize;
		int bytesleft = (numbytes > evengroupcount) ? evengroupcount : numbytes;
		UINT8 *bufptr = tempbuf;

		/* read as much as we can */
		LOG(("  Reading %X bytes into buffer\n", bytesleft));
		if (rom_fread(romdata, bufptr, bytesleft, parent_region) != bytesleft)
			return 0;
		numbytes -= bytesleft;

		LOG(("  Copying to %p\n", base));

		/* unmasked cases */
		if (datamask == 0xff)
		{
			/* non-grouped data */
			if (groupsize == 1)
				for (i = 0; i < bytesleft; i++, base += skip)
					*base = *bufptr++;

			/* grouped data -- non-reversed case */
			else if (!reversed)
				while (bytesleft)
				{
					for (i = 0; i < groupsize && bytesleft; i++, bytesleft--)
						base[i] = *bufptr++;
					base += skip;
				}

			/* grouped data -- reversed case */
			else
				while (bytesleft)
				{
					for (i = groupsize - 1; i >= 0 && bytesleft; i--, bytesleft--)
						base[i] = *bufptr++;
					base += skip;
				}
		}

		/* masked cases */
		else
		{
			/* non-grouped data */
			if (groupsize == 1)
				for (i = 0; i < bytesleft; i++, base += skip)
					*base = (*base & ~datamask) | ((*bufptr++ << datashift) & datamask);

			/* grouped data -- non-reversed case */
			else if (!reversed)
				while (bytesleft)
				{
					for (i = 0; i < groupsize && bytesleft; i++, bytesleft--)
						base[i] = (base[i] & ~datamask) | ((*bufptr++ << datashift) & datamask);
					base += skip;
				}

			/* grouped data -- reversed case */
			else
				while (bytesleft)
				{
					for (i = groupsize - 1; i >= 0 && bytesleft; i--, bytesleft--)
						base[i] = (base[i] & ~datamask) | ((*bufptr++ << datashift) & datamask);
					base += skip;
				}
		}
	}

	LOG(("  All done\n"));
	return ROM_GETLENGTH(romp);
}
Example #20
0
static int ddraw_create_surfaces(win_window_info *window)
{
	dd_info *dd = window->drawdata;
	HRESULT result;

	// make a description of the primary surface
	memset(&dd->primarydesc, 0, sizeof(dd->primarydesc));
	dd->primarydesc.dwSize = sizeof(dd->primarydesc);
	dd->primarydesc.dwFlags = DDSD_CAPS;
	dd->primarydesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

	// for triple-buffered full screen mode, allocate flipping surfaces
	if (window->fullscreen && video_config.triplebuf)
	{
		dd->primarydesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
		dd->primarydesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
		dd->primarydesc.dwBackBufferCount = 2;
	}

	// create the primary surface and report errors
	result = create_surface(dd, &dd->primarydesc, &dd->primary, "primary");
	if (result != DD_OK) goto error;

	// full screen mode: get the back surface
	dd->back = NULL;
	if (window->fullscreen && video_config.triplebuf)
	{
		DDSCAPS2 caps = { DDSCAPS_BACKBUFFER };
		result = IDirectDrawSurface7_GetAttachedSurface(dd->primary, &caps, &dd->back);
		if (result != DD_OK)
		{
			mame_printf_verbose("DirectDraw: Error %08X getting attached back surface\n", (int)result);
			goto error;
		}
	}

	// now make a description of our blit surface, based on the primary surface
	if (dd->blitwidth == 0 || dd->blitheight == 0)
		compute_blit_surface_size(window);
	dd->blitdesc = dd->primarydesc;
	dd->blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
	dd->blitdesc.dwWidth = dd->blitwidth;
	dd->blitdesc.dwHeight = dd->blitheight;
	dd->blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;

	// then create the blit surface, fall back to system memory if video mem doesn't work
	result = create_surface(dd, &dd->blitdesc, &dd->blit, "blit");
	if (result != DD_OK)
	{
		dd->blitdesc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
		result = create_surface(dd, &dd->blitdesc, &dd->blit, "blit");
	}
	if (result != DD_OK) goto error;

	// create a memory buffer for offscreen drawing
	if (dd->membuffersize < dd->blitwidth * dd->blitheight * 4)
	{
		dd->membuffersize = dd->blitwidth * dd->blitheight * 4;
		dd->membuffer = realloc(dd->membuffer, dd->membuffersize);
	}
	if (dd->membuffer == NULL)
		goto error;

#ifdef MESS
	// create a clipper for all modes, since MESS has dialogs
	if (create_clipper(window))
		goto error;
#else
	// create a clipper for windowed mode
	if (!window->fullscreen && create_clipper(window))
		goto error;
#endif

	// full screen mode: set the gamma
	if (window->fullscreen)
	{
		// only set the gamma if it's not 1.0f
		float brightness = options_get_float(mame_options(), WINOPTION_FULLSCREENBRIGHTNESS);
		float contrast = options_get_float(mame_options(), WINOPTION_FULLLSCREENCONTRAST);
		float gamma = options_get_float(mame_options(), WINOPTION_FULLSCREENGAMMA);
		if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
		{
			// see if we can get a GammaControl object
			result = IDirectDrawSurface_QueryInterface(dd->primary, &IID_IDirectDrawGammaControl, (void **)&dd->gamma);
			if (result != DD_OK)
			{
				mame_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n");
				dd->gamma = NULL;
			}

			// proceed if we can
			if (dd->gamma != NULL)
			{
				DDGAMMARAMP ramp;
				int i;

				// create a standard ramp and set it
				for (i = 0; i < 256; i++)
					ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;

				// attempt to set it
				result = IDirectDrawGammaControl_SetGammaRamp(dd->gamma, 0, &ramp);
				if (result != DD_OK)
					mame_printf_verbose("DirectDraw: Error %08X attempting to set gamma correction.\n", (int)result);
			}
		}
	}

	// force some updates
	update_outer_rects(dd);
	return 0;

error:
	ddraw_delete_surfaces(window);
	return 1;
}
Example #21
0
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 != NULL)
		{
			int datawidth = spaceconfig->m_databus_width;
			int alignunit = datawidth / 8;

			// construct the maps
			::address_map *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() == NULL)
			{
				global_free(map);
				continue;
			}

			// validate the global map parameters
			if (map->m_spacenum != spacenum)
				mame_printf_error("Space %d has address space %d handlers!\n", spacenum, map->m_spacenum);
			if (map->m_databits != datawidth)
				mame_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 != 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 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)
					mame_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))
					mame_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 == NULL)
				{
					entry->m_region = device().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)
				{
					// make sure we can resolve the full path to the region
					bool found = false;
					astring entry_region;
					device().siblingtag(entry_region, entry->m_region);

					// look for the region
					device_iterator deviter(device().mconfig().root_device());
					for (device_t *device = deviter.first(); device != NULL; device = deviter.next())
						for (const rom_entry *romp = rom_first_region(*device); romp != NULL && !found; romp = rom_next_region(romp))
						{
							astring fulltag;
							rom_region_name(fulltag, *device, romp);
							if (fulltag == 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)
									mame_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)
						mame_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
				if (entry->m_read.m_type == AMH_DEVICE_DELEGATE && entry->m_read.m_tag != NULL)
				{
					astring temp(entry->m_read.m_tag);
					if (device().siblingdevice(temp) == NULL)
						mame_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 != NULL)
				{
					astring temp(entry->m_write.m_tag);
					if (device().siblingdevice(temp) == NULL)
						mame_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))
//                  mame_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 != NULL)
					valid.validate_tag(entry->m_share);
			}

			// release the address map
			global_free(map);
		}
	}
}
Example #22
0
static void extract_video_config(running_machine &machine)
{
	const char *stemp;
	sdl_options &options = downcast<sdl_options &>(machine.options());

	video_config.perftest    = options.video_fps();

	// global options: extract the data
	video_config.windowed      = options.window();
	video_config.keepaspect    = options.keep_aspect();
	video_config.numscreens    = options.numscreens();
	video_config.fullstretch   = options.uneven_stretch();
	#ifdef SDLMAME_X11
	video_config.restrictonemonitor = !options.use_all_heads();
	#endif


	if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
		video_config.windowed = TRUE;

	// default to working video please
	video_config.novideo = 0;

	// d3d options: extract the data
	stemp = options.video();
	if (strcmp(stemp, SDLOPTVAL_SOFT) == 0)
		video_config.mode = VIDEO_MODE_SOFT;
	else if (strcmp(stemp, SDLOPTVAL_NONE) == 0)
	{
		video_config.mode = VIDEO_MODE_SOFT;
		video_config.novideo = 1;

		if (options.seconds_to_run() == 0)
			mame_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
	}
	else if (USE_OPENGL && (strcmp(stemp, SDLOPTVAL_OPENGL) == 0))
		video_config.mode = VIDEO_MODE_OPENGL;
	else if (USE_OPENGL && (strcmp(stemp, SDLOPTVAL_OPENGL16) == 0))
	{
		video_config.mode = VIDEO_MODE_OPENGL;
		video_config.prefer16bpp_tex = 1;
	}
	else if (SDLMAME_SDL2 && (strcmp(stemp, SDLOPTVAL_SDL13) == 0))
	{
		video_config.mode = VIDEO_MODE_SDL13;
		video_config.prefer16bpp_tex = 1;
	}
	else
	{
		mame_printf_warning("Invalid video value %s; reverting to software\n", stemp);
		video_config.mode = VIDEO_MODE_SOFT;
	}

	video_config.switchres     = options.switch_res();
	video_config.centerh       = options.centerh();
	video_config.centerv       = options.centerv();
	video_config.waitvsync     = options.wait_vsync();
	video_config.syncrefresh   = options.sync_refresh();
	if (!video_config.waitvsync && video_config.syncrefresh)
	{
		mame_printf_warning("-syncrefresh specified without -waitsync. Reverting to -nosyncrefresh\n");
		video_config.syncrefresh = 0;
	}

	if (USE_OPENGL || SDLMAME_SDL2)
	{
		video_config.filter        = options.filter();
	}

	if (USE_OPENGL)
	{
		video_config.prescale      = options.prescale();
		if (video_config.prescale < 1 || video_config.prescale > 3)
		{
			mame_printf_warning("Invalid prescale option, reverting to '1'\n");
			video_config.prescale = 1;
		}
		// default to working video please
		video_config.prefer16bpp_tex = 0;
		video_config.forcepow2texture = options.gl_force_pow2_texture();
		video_config.allowtexturerect = !(options.gl_no_texture_rect());
		video_config.vbo         = options.gl_vbo();
		video_config.pbo         = options.gl_pbo();
		video_config.glsl        = options.gl_glsl();
		if ( video_config.glsl )
		{
			int i;

			video_config.glsl_filter = options.glsl_filter();

			video_config.glsl_shader_mamebm_num=0;

			for(i=0; i<GLSL_SHADER_MAX; i++)
			{
				stemp = options.shader_mame(i);
				if (stemp && strcmp(stemp, SDLOPTVAL_NONE) != 0 && strlen(stemp)>0)
				{
					video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
					strcpy(video_config.glsl_shader_mamebm[i], stemp);
					video_config.glsl_shader_mamebm_num++;
				} else {
					video_config.glsl_shader_mamebm[i] = NULL;
				}
			}

			video_config.glsl_shader_scrn_num=0;

			for(i=0; i<GLSL_SHADER_MAX; i++)
			{
				stemp = options.shader_screen(i);
				if (stemp && strcmp(stemp, SDLOPTVAL_NONE) != 0 && strlen(stemp)>0)
				{
					video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
					strcpy(video_config.glsl_shader_scrn[i], stemp);
					video_config.glsl_shader_scrn_num++;
				} else {
					video_config.glsl_shader_scrn[i] = NULL;
				}
			}

			video_config.glsl_vid_attributes = options.glsl_vid_attr();
			{
				// Disable feature: glsl_vid_attributes, as long we have the gamma calculation
				// disabled within the direct shaders .. -> too slow.
				// IMHO the gamma setting should be done global anyways, and for the whole system,
				// not just MAME ..
				float gamma = options.gamma();
				if (gamma != 1.0 && video_config.glsl_vid_attributes && video_config.glsl)
				{
					video_config.glsl_vid_attributes = FALSE;
					mame_printf_warning("OpenGL: GLSL - disable handling of brightness and contrast, gamma is set to %f\n", gamma);
				}
			}
		} else {
			int i;
			video_config.glsl_filter = 0;
			video_config.glsl_shader_mamebm_num=0;
			for(i=0; i<GLSL_SHADER_MAX; i++)
			{
				video_config.glsl_shader_mamebm[i] = NULL;
			}
			video_config.glsl_shader_scrn_num=0;
			for(i=0; i<GLSL_SHADER_MAX; i++)
			{
				video_config.glsl_shader_scrn[i] = NULL;
			}
			video_config.glsl_vid_attributes = 0;
		}

	}
	// misc options: sanity check values

	// global options: sanity check values
#if (!SDLMAME_SDL2)
	if (video_config.numscreens < 1 || video_config.numscreens > 1) //MAX_VIDEO_WINDOWS)
	{
		mame_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens);
		video_config.numscreens = 1;
	}
#else
	if (video_config.numscreens < 1 || video_config.numscreens > MAX_VIDEO_WINDOWS)
	{
		mame_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens);
		video_config.numscreens = 1;
	}
#endif
	// yuv settings ...
	stemp = options.scale_mode();
	video_config.scale_mode = drawsdl_scale_mode(stemp);
	if (video_config.scale_mode < 0)
	{
		mame_printf_warning("Invalid yuvmode value %s; reverting to none\n", stemp);
		video_config.scale_mode = VIDEO_SCALE_MODE_NONE;
	}
	if ( (video_config.mode != VIDEO_MODE_SOFT) && (video_config.scale_mode != VIDEO_SCALE_MODE_NONE) )
	{
		mame_printf_warning("scalemode is only for -video soft, overriding\n");
		video_config.scale_mode = VIDEO_SCALE_MODE_NONE;
	}
}
Example #23
0
static void mame_puts_warning(const char *s)
{
	mame_printf_warning("%s", s);
}
Example #24
0
void sdlvideo_monitor_refresh(sdl_monitor_info *monitor)
{
	#if (SDLMAME_SDL2)
	SDL_DisplayMode dmode;

	SDL_GetDesktopDisplayMode(monitor->handle, &dmode);
	monitor->monitor_width = dmode.w;
	monitor->monitor_height = dmode.h;
	monitor->center_width = dmode.w;
	monitor->center_height = dmode.h;
	#else
	#if defined(SDLMAME_WIN32)  // Win32 version
	MONITORINFOEX info;
	info.cbSize = sizeof(info);
	GetMonitorInfo((HMONITOR)monitor->handle, (LPMONITORINFO)&info);
	monitor->center_width = monitor->monitor_width = info.rcMonitor.right - info.rcMonitor.left;
	monitor->center_height = monitor->monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;
	char *temp = utf8_from_wstring(info.szDevice);
	strcpy(monitor->monitor_device, temp);
	osd_free(temp);
	#elif defined(SDLMAME_MACOSX)   // Mac OS X Core Imaging version
	CGDirectDisplayID primary;
	CGRect dbounds;

	// get the main display
	primary = CGMainDisplayID();
	dbounds = CGDisplayBounds(primary);

	monitor->center_width = monitor->monitor_width = dbounds.size.width - dbounds.origin.x;
	monitor->center_height = monitor->monitor_height = dbounds.size.height - dbounds.origin.y;
	strcpy(monitor->monitor_device, "Mac OS X display");
	#elif defined(SDLMAME_X11) || defined(SDLMAME_NO_X11)       // X11 version
	{
		#if defined(SDLMAME_X11)
		// X11 version
		int screen;
		SDL_SysWMinfo info;
		SDL_VERSION(&info.version);

		if ( SDL_GetWMInfo(&info) && (info.subsystem == SDL_SYSWM_X11) )
		{
			screen = DefaultScreen(info.info.x11.display);
			SDL_VideoDriverName(monitor->monitor_device, sizeof(monitor->monitor_device)-1);
			monitor->monitor_width = DisplayWidth(info.info.x11.display, screen);
			monitor->monitor_height = DisplayHeight(info.info.x11.display, screen);

			if ((XineramaIsActive(info.info.x11.display)) && video_config.restrictonemonitor)
			{
				XineramaScreenInfo *xineinfo;
				int numscreens;

					xineinfo = XineramaQueryScreens(info.info.x11.display, &numscreens);

				monitor->center_width = xineinfo[0].width;
				monitor->center_height = xineinfo[0].height;

				XFree(xineinfo);
			}
			else
			{
				monitor->center_width = monitor->monitor_width;
				monitor->center_height = monitor->monitor_height;
			}
		}
		else
		#endif // defined(SDLMAME_X11)
		{
			static int first_call=0;
			static int cw = 0, ch = 0;

			SDL_VideoDriverName(monitor->monitor_device, sizeof(monitor->monitor_device)-1);
			if (first_call==0)
			{
				char *dimstr = osd_getenv(SDLENV_DESKTOPDIM);
				const SDL_VideoInfo *sdl_vi;

				sdl_vi = SDL_GetVideoInfo();
				#if (SDL_VERSION_ATLEAST(1,2,10))
				cw = sdl_vi->current_w;
				ch = sdl_vi->current_h;
				#endif
				first_call=1;
				if ((cw==0) || (ch==0))
				{
					if (dimstr != NULL)
					{
						sscanf(dimstr, "%dx%d", &cw, &ch);
					}
					if ((cw==0) || (ch==0))
					{
						mame_printf_warning("WARNING: SDL_GetVideoInfo() for driver <%s> is broken.\n", monitor->monitor_device);
						mame_printf_warning("         You should set SDLMAME_DESKTOPDIM to your desktop size.\n");
						mame_printf_warning("            e.g. export SDLMAME_DESKTOPDIM=800x600\n");
						mame_printf_warning("         Assuming 1024x768 now!\n");
						cw=1024;
						ch=768;
					}
				}
			}
			monitor->monitor_width = cw;
			monitor->monitor_height = ch;
			monitor->center_width = cw;
			monitor->center_height = ch;
		}
	}
	#elif defined(SDLMAME_OS2)      // OS2 version
	monitor->center_width = monitor->monitor_width = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
	monitor->center_height = monitor->monitor_height = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
	strcpy(monitor->monitor_device, "OS/2 display");
	#else
	#error Unknown SDLMAME_xx OS type!
	#endif

	{
		static int info_shown=0;
		if (!info_shown)
		{
			mame_printf_verbose("SDL Device Driver     : %s\n", monitor->monitor_device);
			mame_printf_verbose("SDL Monitor Dimensions: %d x %d\n", monitor->monitor_width, monitor->monitor_height);
			info_shown = 1;
		}
	}
	#endif //  (SDLMAME_SDL2)
}
Example #25
0
void osd_init(running_machine *machine)
{
	const char *stemp;

	// Some driver options - must be before audio init!
	stemp = options_get_string(machine->options(), SDLOPTION_AUDIODRIVER);
	if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
	{
		mame_printf_verbose("Setting SDL audiodriver '%s' ...\n", stemp);
		osd_setenv(SDLENV_AUDIODRIVER, stemp, 1);
	}

	stemp = options_get_string(machine->options(), SDLOPTION_VIDEODRIVER);
	if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
	{
		mame_printf_verbose("Setting SDL videodriver '%s' ...\n", stemp);
		osd_setenv(SDLENV_VIDEODRIVER, stemp, 1);
	}

	if (SDL_VERSION_ATLEAST(1,3,0))
	{
		stemp = options_get_string(machine->options(), SDLOPTION_RENDERDRIVER);
		if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
		{
			mame_printf_verbose("Setting SDL renderdriver '%s' ...\n", stemp);
			osd_setenv(SDLENV_RENDERDRIVER, stemp, 1);
		}
	}

	/* Set the SDL environment variable for drivers wanting to load the
     * lib at startup.
     */
	/* FIXME: move lib loading code from drawogl.c here */

	stemp = options_get_string(machine->options(), SDLOPTION_GL_LIB);
	if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
	{
		osd_setenv("SDL_VIDEO_GL_DRIVER", stemp, 1);
		mame_printf_verbose("Setting SDL_VIDEO_GL_DRIVER = '%s' ...\n", stemp);
	}

	/* get number of processors */
	stemp = options_get_string(machine->options(), SDLOPTION_NUMPROCESSORS);

	sdl_num_processors = 0;

	if (strcmp(stemp, "auto") != 0)
	{
		sdl_num_processors = atoi(stemp);
		if (sdl_num_processors < 1)
		{
			mame_printf_warning("Warning: numprocessors < 1 doesn't make much sense. Assuming auto ...\n");
			sdl_num_processors = 0;
		}
	}

	/* Initialize SDL */

	if (!SDLMAME_INIT_IN_WORKER_THREAD)
	{
#if (SDL_VERSION_ATLEAST(1,3,0))
		if (SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_AUDIO| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
#else
		if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_AUDIO| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
#endif
			mame_printf_error("Could not initialize SDL %s\n", SDL_GetError());
			exit(-1);
		}
		osd_sdl_info();
	}
	// must be before sdlvideo_init!
	machine->add_notifier(MACHINE_NOTIFY_EXIT, osd_exit);

	defines_verbose();

	if (!SDLMAME_HAS_DEBUGGER)
		if (machine->debug_flags & DEBUG_FLAG_OSD_ENABLED)
		{
			mame_printf_error("sdlmame: -debug not supported on X11-less builds\n\n");
			osd_exit(*machine);
			exit(-1);
		}

	if (sdlvideo_init(machine))
	{
		osd_exit(*machine);
		mame_printf_error("sdlvideo_init: Initialization failed!\n\n\n");
		fflush(stderr);
		fflush(stdout);
		exit(-1);
	}

	sdlinput_init(machine);

	sdlaudio_init(machine);

	sdloutput_init(machine);

	if (options_get_bool(machine->options(), SDLOPTION_OSLOG))
		machine->add_logerror_callback(output_oslog);

#if (SDL_VERSION_ATLEAST(1,3,0))
	SDL_EventState(SDL_TEXTINPUT, SDL_TRUE);
#else
	SDL_EnableUNICODE(SDL_TRUE);
#endif
}
Example #26
0
void ram_device::device_validity_check(validity_checker &valid) const
{
	const char *ramsize_string = NULL;
	int is_valid = FALSE;
	UINT32 specified_ram = 0;
	const char *gamename_option = NULL;

	/* verify default ram value */
	if (default_size() == 0)
		mame_printf_error("Invalid default RAM option: %s\n", m_default_size);

	/* command line options are only parsed for the device named RAM_TAG */
	if (tag() != NULL && strcmp(tag(), ":" RAM_TAG) == 0)
	{
		/* verify command line ram option */
		ramsize_string = mconfig().options().ram_size();
		gamename_option = mconfig().options().system_name();

		if ((ramsize_string != NULL) && (ramsize_string[0] != '\0'))
		{
			specified_ram = parse_string(ramsize_string);

			if (specified_ram == 0)
				mame_printf_error("Cannot recognize the RAM option %s\n", ramsize_string);

			if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, mconfig().gamedrv().name) == 0)
			{
				/* compare command line option to default value */
				if (default_size() == specified_ram)
					is_valid = TRUE;

				/* verify extra ram options */
				if (m_extra_options != NULL)
				{
					int j;
					int size = strlen(m_extra_options);
					char * const s = mame_strdup(m_extra_options);
					char * const e = s + size;
					char *p = s;
					for (j=0;j<size;j++) {
						if (p[j]==',') p[j]=0;
					}

					/* try to parse each option */
					while(p <= e)
					{
						UINT32 option_ram_size = parse_string(p);

						if (option_ram_size == 0)
							mame_printf_error("Invalid RAM option: %s\n", p);

						if (option_ram_size == specified_ram)
							is_valid = TRUE;

						p += strlen(p);
						if (p == e)
							break;
						p += 1;
					}

					osd_free(s);
				}

			} else {
				/* if not for this driver then return ok */
				is_valid = TRUE;
			}
		}
		else
		{
			/* not specifying the ramsize on the command line is valid as well */
			is_valid = TRUE;
		}
	}
	else
		is_valid = TRUE;

	if (!is_valid)
	{
		astring output;
		output.catprintf("Cannot recognize the RAM option %s", ramsize_string);
		output.catprintf(" (valid options are %s", m_default_size);

		if (m_extra_options != NULL)
			output.catprintf(",%s).\n", m_extra_options);
		else
			output.catprintf(").\n");

		mame_printf_error("%s", output.cstr());

		mame_printf_warning("Setting value to default %s\n",m_default_size);
		astring error;
		mconfig().options().set_value(OPTION_RAMSIZE, m_default_size, OPTION_PRIORITY_CMDLINE, error);
		assert(!error);
	}
}
Example #27
0
void sdl_osd_interface::init(running_machine &machine)
{
	// call our parent
	osd_interface::init(machine);

	sdl_options &options = downcast<sdl_options &>(machine.options());
	const char *stemp;
	// Switchres
	if (machine.options().modeline())
		switchres_modeline_setup(machine);

	// determine if we are benchmarking, and adjust options appropriately
	int bench = options.bench();
	astring error_string;
	if (bench > 0)
	{
		options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM, error_string);
		options.set_value(OPTION_SOUND, false, OPTION_PRIORITY_MAXIMUM, error_string);
		options.set_value(SDLOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM, error_string);
		options.set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM, error_string);
		assert(!error_string);
	}

	// Some driver options - must be before audio init!
	stemp = options.audio_driver();
	if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
	{
		mame_printf_verbose("Setting SDL audiodriver '%s' ...\n", stemp);
		osd_setenv(SDLENV_AUDIODRIVER, stemp, 1);
	}

	stemp = options.video_driver();
	if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
	{
		mame_printf_verbose("Setting SDL videodriver '%s' ...\n", stemp);
		osd_setenv(SDLENV_VIDEODRIVER, stemp, 1);
	}

#if (SDLMAME_SDL2)
		stemp = options.render_driver();
		if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
		{
			mame_printf_verbose("Setting SDL renderdriver '%s' ...\n", stemp);
			//osd_setenv(SDLENV_RENDERDRIVER, stemp, 1);
			SDL_SetHint(SDL_HINT_RENDER_DRIVER, stemp);
		}
#endif

	/* Set the SDL environment variable for drivers wanting to load the
     * lib at startup.
     */
#if USE_OPENGL
	/* FIXME: move lib loading code from drawogl.c here */

	stemp = options.gl_lib();
	if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0)
	{
		osd_setenv("SDL_VIDEO_GL_DRIVER", stemp, 1);
		mame_printf_verbose("Setting SDL_VIDEO_GL_DRIVER = '%s' ...\n", stemp);
	}
#endif

	/* get number of processors */
	stemp = options.numprocessors();

    osd_num_processors = 0;

	if (strcmp(stemp, "auto") != 0)
	{
		osd_num_processors = atoi(stemp);
		if (osd_num_processors < 1)
		{
			mame_printf_warning("Warning: numprocessors < 1 doesn't make much sense. Assuming auto ...\n");
			osd_num_processors = 0;
		}
	}

	/* Initialize SDL */

	if (!SDLMAME_INIT_IN_WORKER_THREAD)
	{
#if (SDLMAME_SDL2)
		if (SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_AUDIO| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
#else
		if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_AUDIO| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
#endif
			mame_printf_error("Could not initialize SDL %s\n", SDL_GetError());
			exit(-1);
		}
		osd_sdl_info();
	}
	// must be before sdlvideo_init!
	machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(osd_exit), &machine));

	defines_verbose();

	if (!SDLMAME_HAS_DEBUGGER)
		if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
		{
			mame_printf_error("sdlmame: -debug not supported on X11-less builds\n\n");
			osd_exit(machine);
			exit(-1);
		}

	if (sdlvideo_init(machine))
	{
		osd_exit(machine);
		mame_printf_error("sdlvideo_init: Initialization failed!\n\n\n");
		fflush(stderr);
		fflush(stdout);
		exit(-1);
	}

	sdlinput_init(machine);
	sdlaudio_init(machine);
	sdloutput_init(machine);

#ifdef SDLMAME_NETWORK
	sdlnetdev_init(machine);
#endif

	if (options.oslog())
		machine.add_logerror_callback(output_oslog);

	/* now setup watchdog */

	int watchdog_timeout = options.watchdog();
	int str = options.seconds_to_run();

	/* only enable watchdog if seconds_to_run is enabled *and* relatively short (time taken from ui.c) */
	if ((watchdog_timeout != 0) && (str > 0) && (str < 60*5 ))
	{
		m_watchdog = auto_alloc(machine, watchdog);
		m_watchdog->setTimeout(watchdog_timeout);
	}

#if (SDLMAME_SDL2)
	SDL_EventState(SDL_TEXTINPUT, SDL_TRUE);
#else
	SDL_EnableUNICODE(SDL_TRUE);
#endif
}

#ifdef SDLMAME_UNIX
#define POINT_SIZE 144.0

#ifdef SDLMAME_MACOSX

#define EXTRA_HEIGHT 1.0
#define EXTRA_WIDTH 1.15

//-------------------------------------------------
//  font_open - attempt to "open" a handle to the
//  font with the given name
//-------------------------------------------------

osd_font sdl_osd_interface::font_open(const char *_name, int &height)
{
	CFStringRef font_name = NULL;
	CTFontRef ct_font = NULL;
	CTFontDescriptorRef font_descriptor;
	CGAffineTransform affine_transform = CGAffineTransformIdentity;

	astring name(_name);

	if (name == "default")
	{
		name = "LucidaGrande";
	}

	/* handle bdf fonts in the core */
	if (name.len() > 4)
		if (name.makeupper().substr(name.len()-4,4) == ".BDF" )
			return NULL;

	font_name = CFStringCreateWithCString( NULL, _name, kCFStringEncodingUTF8 );

	if( font_name != NULL )
	{
      font_descriptor = CTFontDescriptorCreateWithNameAndSize( font_name, POINT_SIZE );

      if( font_descriptor != NULL )
      {
         ct_font = CTFontCreateWithFontDescriptor( font_descriptor, POINT_SIZE, &affine_transform );

         CFRelease( font_descriptor );
      }
   }

   CFRelease( font_name );

   if (!ct_font)
	{
		printf("WARNING: Couldn't find/open font %s, using MAME default\n", name.cstr());
		return NULL;
	}

   CFStringRef real_name = CTFontCopyPostScriptName( ct_font );
   char real_name_c_string[255];
   CFStringGetCString ( real_name, real_name_c_string, 255, kCFStringEncodingUTF8 );
   mame_printf_verbose("Matching font: %s\n", real_name_c_string);
   CFRelease( real_name );

   CGFloat line_height = 0.0;
   line_height += CTFontGetAscent(ct_font);
   line_height += CTFontGetDescent(ct_font);
   line_height += CTFontGetLeading(ct_font);
   height = ceilf(line_height * EXTRA_HEIGHT);

   return (osd_font)ct_font;
}
Example #28
0
bool device_memory_interface::interface_validity_check(emu_options &options, const game_driver &driver) const
{
	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(device(), 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, device().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, device().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, device().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 = device().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(device().mconfig()); 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_c = ROMREGION_GETTAG(romp);
							if (regiontag_c != NULL)
							{
								astring fulltag;
								astring regiontag;

								// a leading : on a region name indicates an absolute region, so fix up accordingly
								if (entry->m_region[0] == ':')
								{
									regiontag = &entry->m_region[1];
								}
								else
								{
									if (strchr(entry->m_region,':')) {
										regiontag = entry->m_region;
									} else {
										device().siblingtag(regiontag, entry->m_region);
									}
								}
								rom_region_name(fulltag, &driver, source, romp);
								if (fulltag.cmp(regiontag) == 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, device().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, device().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 && device().mconfig().devicelist().find(entry->m_read.m_tag) == NULL) ||
					(entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag != NULL && device().mconfig().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, device().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, device().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;
}
Example #29
0
cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, const char *filename, xml_data_node &cheatnode)
	: m_manager(manager),
		m_next(NULL),
		m_on_script(NULL),
		m_off_script(NULL),
		m_change_script(NULL),
		m_run_script(NULL),
		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 = xml_get_attribute_int(&cheatnode, "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 = xml_get_attribute_string(&cheatnode, "desc", NULL);
		if (description == NULL || 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);
		astring tempname;
		for (int curtemp = 0; curtemp < tempcount; curtemp++)
			m_symbols.add(tempname.format("temp%d", curtemp), symbol_table::READ_WRITE);

		// read the first comment node
		xml_data_node *commentnode = xml_get_sibling(cheatnode.child, "comment");
		if (commentnode != NULL)
		{
			// set the value if not NULL
			if (commentnode->value != NULL && commentnode->value[0] != 0)
				m_comment.cpy(commentnode->value);

			// only one comment is kept
			commentnode = xml_get_sibling(commentnode->next, "comment");
			if (commentnode != NULL)
				mame_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 *paramnode = xml_get_sibling(cheatnode.child, "parameter");
		if (paramnode != NULL)
		{
			// load this parameter
			m_parameter.reset(global_alloc(cheat_parameter(manager, m_symbols, filename, *paramnode)));

			// only one parameter allowed
			paramnode = xml_get_sibling(paramnode->next, "parameter");
			if (paramnode != NULL)
				mame_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 *scriptnode = xml_get_sibling(cheatnode.child, "script"); scriptnode != NULL; scriptnode = xml_get_sibling(scriptnode->next, "script"))
		{
			// load this entry
			cheat_script *curscript = global_alloc(cheat_script(manager, m_symbols, filename, *scriptnode));

			// if we have a script already for this slot, it is an error
			auto_pointer<cheat_script> &slot = script_for_state(curscript->state());
			if (slot != NULL)
				mame_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;
	}
}
Example #30
0
// The command is written when the CMD pin is low
void okim9810_device::write_command(UINT8 data)
{
    const UINT8 cmd = (data & 0xf8) >> 3;
    const UINT8 channel = (data & 0x07);

    switch(cmd)
    {
        case 0x00:  // START
        {
            mame_printf_debug("START channel mask %02x\n", m_TMP_register);
            UINT8 channelMask = 0x01;
            for (int i = 0; i < OKIM9810_VOICES; i++, channelMask <<= 1)
            {
                if (channelMask & m_TMP_register)
                {
                    m_voice[i].m_playing = true;
                    mame_printf_debug("\t\tPlaying channel %d: encoder type %d @ %dhz (volume = %d %d).  From %08x for %d samples (looping=%d).\n",
                                        i,
                                        m_voice[i].m_playbackAlgo,
                                        m_voice[i].m_samplingFreq,
                                        m_voice[i].volume_scale(m_global_volume, m_voice[i].m_channel_volume, m_voice[i].m_pan_volume_left),
                                        m_voice[i].volume_scale(m_global_volume, m_voice[i].m_channel_volume, m_voice[i].m_pan_volume_right),
                                        m_voice[i].m_base_offset,
                                        m_voice[i].m_count,
                                        m_voice[i].m_looping);
                }
            }
            break;
        }
        case 0x01:  // STOP
        {
            mame_printf_debug("STOP  channel mask %02x\n", m_TMP_register);
            UINT8 channelMask = 0x01;
            for (int i = 0; i < OKIM9810_VOICES; i++, channelMask <<= 1)
            {
                if (channelMask & m_TMP_register)
                {
                    m_voice[i].m_playing = false;
                    mame_printf_debug("\tChannel %d stopping.\n", i);
                }
            }
            break;
        }
        case 0x02:  // LOOP
        {
            mame_printf_debug("LOOP  channel mask %02x\n", m_TMP_register);
            UINT8 channelMask = 0x01;
            for (int i = 0; i < OKIM9810_VOICES; i++, channelMask <<= 1)
            {
                if (channelMask & m_TMP_register)
                {
                    m_voice[i].m_looping = true;
                    mame_printf_debug("\tChannel %d looping.\n", i);
                }
                else
                {
                    m_voice[i].m_looping = false;
                    mame_printf_debug("\tChannel %d done looping.\n", i);
                }
            }
            break;
        }
        case 0x03:  // OPT (options)
        {
            mame_printf_debug("OPT   complex data %02x\n", m_TMP_register);
            m_global_volume = (m_TMP_register & 0x18) >> 3;
            m_filter_type =   (m_TMP_register & 0x06) >> 1;
            m_output_level =  (m_TMP_register & 0x01);
            mame_printf_debug("\tOPT setting main volume scale to Vdd/%d\n", m_global_volume+1);
            mame_printf_debug("\tOPT setting output filter type to %d\n", m_filter_type);
            mame_printf_debug("\tOPT setting output amp level to %d\n", m_output_level);
            break;
        }
        case 0x04:  // MUON (silence)
        {
            mame_printf_warning("MUON  channel %d length %02x\n", channel, m_TMP_register);
            mame_printf_warning("MSM9810: UNIMPLEMENTED COMMAND!\n");
            break;
        }

        case 0x05:  // FADR (phrase address)
        {
            const offs_t base = m_TMP_register * 8;

            offs_t startAddr;
            UINT8 startFlags = m_direct->read_raw_byte(base + 0);
            startAddr  = m_direct->read_raw_byte(base + 1) << 16;
            startAddr |= m_direct->read_raw_byte(base + 2) << 8;
            startAddr |= m_direct->read_raw_byte(base + 3) << 0;

            offs_t endAddr;
            UINT8 endFlags = m_direct->read_raw_byte(base + 4);
            endAddr  = m_direct->read_raw_byte(base + 5) << 16;
            endAddr |= m_direct->read_raw_byte(base + 6) << 8;
            endAddr |= m_direct->read_raw_byte(base + 7) << 0;

            // Sub-table
            if (startFlags & 0x80)
            {
                offs_t subTable = startAddr;
                // TODO: New startFlags &= 0x80.  Are there further subtables?
                startFlags = m_direct->read_raw_byte(subTable + 0);
                startAddr  = m_direct->read_raw_byte(subTable + 1) << 16;
                startAddr |= m_direct->read_raw_byte(subTable + 2) << 8;
                startAddr |= m_direct->read_raw_byte(subTable + 3) << 0;

                // TODO: What does byte (subTable + 4) refer to?
                endAddr  = m_direct->read_raw_byte(subTable + 5) << 16;
                endAddr |= m_direct->read_raw_byte(subTable + 6) << 8;
                endAddr |= m_direct->read_raw_byte(subTable + 7) << 0;
            }

            m_voice[channel].m_sample = 0;
            m_voice[channel].m_interpSampleNum = 0;
            m_voice[channel].m_startFlags = startFlags;
            m_voice[channel].m_base_offset = startAddr;
            m_voice[channel].m_endFlags = endFlags;
            m_voice[channel].m_count = (endAddr-startAddr) + 1;     // Is there yet another extra byte at the end?

            m_voice[channel].m_playbackAlgo = (startFlags & 0x30) >> 4;
            m_voice[channel].m_samplingFreq = s_sampling_freq_table[startFlags & 0x0f];
            if (m_voice[channel].m_playbackAlgo == OKIM9810_ADPCM_PLAYBACK ||
                m_voice[channel].m_playbackAlgo == OKIM9810_ADPCM2_PLAYBACK)
                m_voice[channel].m_count *= 2;
            else
                mame_printf_warning("MSM9810: UNIMPLEMENTED PLAYBACK METHOD %d\n", m_voice[channel].m_playbackAlgo);

            mame_printf_debug("FADR  channel %d phrase offset %02x => ", channel, m_TMP_register);
            mame_printf_debug("startFlags(%02x) startAddr(%06x) endFlags(%02x) endAddr(%06x) bytes(%d)\n", startFlags, startAddr, endFlags, endAddr, endAddr-startAddr);
            break;
        }

        case 0x06:  // DADR (direct address playback)
        {
            mame_printf_warning("DADR  channel %d complex data %02x\n", channel, m_TMP_register);
            mame_printf_warning("MSM9810: UNIMPLEMENTED COMMAND!\n");
            break;
        }
        case 0x07:  // CVOL (channel volume)
        {
            mame_printf_debug("CVOL  channel %d data %02x\n", channel, m_TMP_register);
            mame_printf_debug("\tChannel %d -> volume index %d.\n", channel, m_TMP_register & 0x0f);

            m_voice[channel].m_channel_volume = m_TMP_register & 0x0f;
            break;
        }
        case 0x08:  // PAN
        {
            const UINT8 leftVolIndex = (m_TMP_register & 0xf0) >> 4;
            const UINT8 rightVolIndex = m_TMP_register & 0x0f;
            mame_printf_debug("PAN   channel %d left index: %02x right index: %02x (%02x)\n", channel, leftVolIndex, rightVolIndex, m_TMP_register);
            mame_printf_debug("\tChannel %d left -> %d right -> %d\n", channel, leftVolIndex, rightVolIndex);
            m_voice[channel].m_pan_volume_left = leftVolIndex;
            m_voice[channel].m_pan_volume_right = rightVolIndex;
            break;
        }
        default:
        {
            mame_printf_warning("MSM9810: UNKNOWN COMMAND!\n");
            break;
        }
    }
}