Exemple #1
0
int sound_sdl::init(const osd_options &options)
{
	int         n_channels = 2;
	int         audio_latency;
	SDL_AudioSpec   aspec, obtained;
	char audio_driver[16] = "";

	if (LOG_SOUND)
		sound_log = fopen(SDLMAME_SOUND_LOG, "w");

	// skip if sound disabled
	if (sample_rate() != 0)
	{
		if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
			osd_printf_error("Could not initialize SDL %s\n", SDL_GetError());
			return -1;
		}

		osd_printf_verbose("Audio: Start initialization\n");
	#if (SDLMAME_SDL2)
		strncpy(audio_driver, SDL_GetCurrentAudioDriver(), sizeof(audio_driver));
	#else
		SDL_AudioDriverName(audio_driver, sizeof(audio_driver));
	#endif
		osd_printf_verbose("Audio: Driver is %s\n", audio_driver);

		sdl_xfer_samples = SDL_XFER_SAMPLES;
		stream_in_initialized = 0;
		stream_loop = 0;

		// set up the audio specs
		aspec.freq = sample_rate();
		aspec.format = AUDIO_S16SYS;    // keep endian independent
		aspec.channels = n_channels;
		aspec.samples = sdl_xfer_samples;
		aspec.callback = sdl_callback;
		aspec.userdata = this;

		if (SDL_OpenAudio(&aspec, &obtained) < 0)
			goto cant_start_audio;

		osd_printf_verbose("Audio: frequency: %d, channels: %d, samples: %d\n",
							obtained.freq, obtained.channels, obtained.samples);

		sdl_xfer_samples = obtained.samples;

		// pin audio latency
		audio_latency = MAX(MIN(m_audio_latency, MAX_AUDIO_LATENCY), 1);

		// compute the buffer sizes
		stream_buffer_size = (sample_rate() * 2 * sizeof(INT16) * (2 + audio_latency)) / 30;
		stream_buffer_size = (stream_buffer_size / 1024) * 1024;
		if (stream_buffer_size < 1024)
			stream_buffer_size = 1024;

		// create the buffers
		if (sdl_create_buffers())
			goto cant_create_buffers;

		// set the startup volume
		set_mastervolume(attenuation);
		osd_printf_verbose("Audio: End initialization\n");
		return 0;

		// error handling
	cant_create_buffers:
	cant_start_audio:
		osd_printf_verbose("Audio: Initialization failed. SDL error: %s\n", SDL_GetError());

		return -1;
	}

	return 0;
}
Exemple #2
0
void m1comm_device::comm_tick()
{
	if (m_linkenable == 0x01)
	{
		int frameStart = 0x0010;
		int frameOffset = 0x0000;
		int frameSize = 0x01c4;
		int dataSize = frameSize + 1;
		int togo = 0;
		int recv = 0;
		int idx = 0;

		bool isMaster = (m_shared[1] == 0x01);
		bool isSlave = (m_shared[1] == 0x02);
		bool isRelay = (m_shared[1] == 0x00);

		// if link not yet established...
		if (m_linkalive == 0x00)
		{
			// waiting...
			m_shared[0] = 0x05;

			// check rx socket
			if (!m_line_rx.is_open())
			{
				osd_printf_verbose("M1COMM: listen on %s\n", m_localhost);
				m_line_rx.open(m_localhost);
			}

			// check tx socket
			if (!m_line_tx.is_open())
			{
				osd_printf_verbose("M1COMM: connect to %s\n", m_remotehost);
				m_line_tx.open(m_remotehost);
			}

			// if both sockets are there check ring
			if ((m_line_rx.is_open()) && (m_line_tx.is_open()))
			{
				// try to read one messages
				recv = m_line_rx.read(m_buffer, dataSize);
				while (recv != 0)
				{
					// check if complete message
					if (recv == dataSize)
					{
						// check if message id
						idx = m_buffer[0];

						// 0xFF - link id
						if (idx == 0xff)
						{
							if (isMaster)
							{
								// master gets first id and starts next state
								m_linkid = 0x01;
								m_linkcount = m_buffer[1];
								m_linktimer = 0x01;
							}
							else if (isSlave || isRelay)
							{
								// slave gets own id
								if (isSlave)
								{
									m_buffer[1]++;
									m_linkid = m_buffer[1];
								}

								// slave and relay forward message
								m_line_tx.write(m_buffer, dataSize);
							}
						}

						// 0xFE - link size
						else if (idx == 0xfe)
						{
							if (isSlave || isRelay)
							{
								m_linkcount = m_buffer[1];

								// slave and relay forward message
								m_line_tx.write(m_buffer, dataSize);
							}

							// consider it done
							osd_printf_verbose("M1COMM: link established - id %02x of %02x\n", m_linkid, m_linkcount);
							m_linkalive = 0x01;
							m_zfg = 0x01;

							// write to shared mem
							m_shared[0] = 0x01;
							m_shared[2] = m_linkid;
							m_shared[3] = m_linkcount;
						}
					}
					else
					{
						// got only part of a message - read the rest (and drop it)
						// TODO: combine parts and push to "ring buffer"
						togo = dataSize - recv;
						while (togo > 0){
							recv = m_line_rx.read(m_buffer, togo);
							togo -= recv;
						}
						osd_printf_verbose("M1COMM: dropped a message...\n");
					}

					if (m_linkalive == 0x00)
						recv = m_line_rx.read(m_buffer, dataSize);
					else
						recv = 0;
				}

				// if we are master and link is not yet established
				if (isMaster && (m_linkalive == 0x00))
				{
					// send first packet
					if (m_linktimer == 0x00)
					{
						m_buffer[0] = 0xff;
						m_buffer[1] = 0x01;
						m_line_tx.write(m_buffer, dataSize);
					}

					// send second packet
					else if (m_linktimer == 0x01)
					{
						m_buffer[0] = 0xfe;
						m_buffer[1] = m_linkcount;
						m_line_tx.write(m_buffer, dataSize);

						// consider it done
						osd_printf_verbose("M1COMM: link established - id %02x of %02x\n", m_linkid, m_linkcount);
						m_linkalive = 0x01;
						m_zfg = 0x01;

						// write to shared mem
						m_shared[0] = 0x01;
						m_shared[2] = m_linkid;
						m_shared[3] = m_linkcount;
					}

					else if (m_linktimer > 0x02)
					{
						// decrease delay timer
						m_linktimer--;
						if (m_linktimer == 0x02)
							m_linktimer = 0x00;
					}
				}
			}
		}

		// update "ring buffer" if link established
		if (m_linkalive == 0x01)
		{
			int togo = 0;
			// try to read one messages
			int recv = m_line_rx.read(m_buffer, dataSize);
			while (recv != 0)
			{
				// check if complete message
				if (recv == dataSize)
				{
					// check if valid id
					int idx = m_buffer[0];
					if (idx > 0 && idx <= m_linkcount) {
						// if not our own message
						if (idx != m_linkid)
						{
							// save message to "ring buffer"
							frameOffset = frameStart + (idx * frameSize);
							for (int j = 0x00 ; j < frameSize ; j++)
							{
								m_shared[frameOffset + j] = m_buffer[1 + j];
							}

							// forward message to other nodes
							m_line_tx.write(m_buffer, dataSize);
						}
					} else {
						if (!isMaster && idx == 0xf0){
							// 0xF0 - master addional bytes
							for (int j = 0x06 ; j < 0x10 ; j++)
							{
								m_shared[j] = m_buffer[1 + j];
							}

							// forward message to other nodes
							m_line_tx.write(m_buffer, dataSize);
						}
					}
				}
				else
				{
					// got only part of a message - read the rest (and drop it)
					// TODO: combine parts and push to "ring buffer"
					togo = dataSize - recv;
					while (togo > 0){
						recv = m_line_rx.read(m_buffer, togo);
						togo -= recv;
					}
					osd_printf_verbose("M1COMM: dropped a message...\n");
				}
				recv = m_line_rx.read(m_buffer, dataSize);
			}

			// update "ring buffer" if link established
			// live relay does not send data
			if (m_linkid != 0x00 && m_shared[5] != 0x00)
			{
				m_buffer[0] = m_linkid;
				frameOffset = frameStart + (m_linkid * frameSize);
				for (int j = 0x00 ; j < frameSize ; j++)
				{
					// push message to "ring buffer"
					m_shared[frameOffset + j] = m_shared[frameStart + j];
					m_buffer[1 + j] = m_shared[frameStart + j];
				}
				// push message to other nodes
				m_line_tx.write(m_buffer, dataSize);

				// master sends some additional status bytes
				if (isMaster){
					m_buffer[0] = 0xf0;
					for (int j = 0x00 ; j < frameSize ; j++)
					{
						m_buffer[1 + j] = 0x00;
					}
					for (int j = 0x06 ; j < 0x10 ; j++)
					{
						m_buffer[1 + j] = m_shared[j];
					}
					// push message to other nodes
					m_line_tx.write(m_buffer, dataSize);
				}
			}
			// clear 05
			m_shared[5] = 0x00;
		}
	}
}
Exemple #3
0
int sdl_window_info::complete_create()
{
	osd_dim temp(0,0);

	// clear out original mode. Needed on OSX
	if (fullscreen())
	{
		// default to the current mode exactly
		temp = monitor()->position_size().dim();

		// if we're allowed to switch resolutions, override with something better
		if (video_config.switchres)
			temp = pick_best_mode();
	}
	else if (m_windowed_dim.width() > 0)
	{
		// if we have a remembered size force the new window size to it
		temp = m_windowed_dim;
	}
	else if (m_startmaximized)
		temp = get_max_bounds(video_config.keepaspect );
	else
		temp = get_min_bounds(video_config.keepaspect );

	// create the window .....

	/* FIXME: On Ubuntu and potentially other Linux OS you should use
	 * to disable panning. This has to be done before every invocation of mame.
	 *
	 * xrandr --output HDMI-0 --panning 0x0+0+0 --fb 0x0
	 *
	 */
	osd_printf_verbose("Enter sdl_info::create\n");
	if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
	{
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

		/* FIXME: A reminder that gamma is wrong throughout MAME. Currently, SDL2.0 doesn't seem to
		    * support the following attribute although my hardware lists GL_ARB_framebuffer_sRGB as an extension.
		    *
		    * SDL_GL_SetAttribute( SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1 );
		    *
		    */
		m_extra_flags = SDL_WINDOW_OPENGL;
	}
	else
		m_extra_flags = 0;

#ifdef SDLMAME_MACOSX
	/* FIMXE: On OSX, SDL_WINDOW_FULLSCREEN_DESKTOP seems to be more reliable.
	 *        It however creates issues with white borders, i.e. the screen clear
	 *        does not work. This happens both with opengl and accel.
	 */
#endif

	// We need to workaround an issue in SDL 2.0.4 for OS X where setting the
	// relative mode on the mouse in fullscreen mode makes mouse events stop
	// It is fixed in the latest revisions so we'll assume it'll be fixed
	// in the next public SDL release as well
#if defined(SDLMAME_MACOSX) && SDL_VERSION_ATLEAST(2, 0, 2) // SDL_HINT_MOUSE_RELATIVE_MODE_WARP is introduced in 2.0.2
	SDL_version linked;
	SDL_GetVersion(&linked);
	int revision = SDL_GetRevisionNumber();

	// If we're running the exact version of SDL 2.0.4 (revision 10001) from the
	// SDL web site, we need to work around this issue and send the warp mode hint
	if (SDL_VERSION_EQUALS(linked, SDL_VERSIONNUM(2, 0, 4)) && revision == 10001)
	{
		osd_printf_verbose("Using warp mode for relative mouse in OS X SDL 2.0.4\n");
		SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
	}
#endif

	// create the SDL window
	// soft driver also used | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_MOUSE_FOCUS
	m_extra_flags |= (fullscreen() ?
			/*SDL_WINDOW_BORDERLESS |*/ SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE);

#if defined(SDLMAME_WIN32)
	SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
#endif

	// get monitor work area for centering
	osd_rect work = monitor()->usuable_position_size();

	// create the SDL window
	auto sdlwindow = SDL_CreateWindow(m_title,
			work.left() + (work.width() - temp.width()) / 2,
			work.top() + (work.height() - temp.height()) / 2,
			temp.width(), temp.height(), m_extra_flags);
	//window().sdl_window() = SDL_CreateWindow(window().m_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
	//      width, height, m_extra_flags);

	if  (sdlwindow == nullptr )
	{
		if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
			osd_printf_error("OpenGL not supported on this driver: %s\n", SDL_GetError());
		else
			osd_printf_error("Window creation failed: %s\n", SDL_GetError());
		return 1;
	}

	set_platform_window(sdlwindow);

	if (fullscreen() && video_config.switchres)
	{
		SDL_DisplayMode mode;
		//SDL_GetCurrentDisplayMode(window().monitor()->handle, &mode);
		SDL_GetWindowDisplayMode(platform_window(), &mode);
		m_original_mode->mode = mode;
		mode.w = temp.width();
		mode.h = temp.height();
		if (m_win_config.refresh)
			mode.refresh_rate = m_win_config.refresh;

		SDL_SetWindowDisplayMode(platform_window(), &mode);    // Try to set mode
#ifndef SDLMAME_WIN32
		/* FIXME: Warp the mouse to 0,0 in case a virtual desktop resolution
		 * is in place after the mode switch - which will most likely be the case
		 * This is a hack to work around a deficiency in SDL2
		 */
		SDL_WarpMouseInWindow(platform_window(), 1, 1);
#endif
	}
	else
	{
		//SDL_SetWindowDisplayMode(window().sdl_window(), nullptr); // Use desktop
	}

	// show window

	SDL_ShowWindow(platform_window());
	//SDL_SetWindowFullscreen(window->sdl_window(), 0);
	//SDL_SetWindowFullscreen(window->sdl_window(), window->fullscreen());
	SDL_RaiseWindow(platform_window());

#ifdef SDLMAME_WIN32
	if (fullscreen())
		SDL_SetWindowGrab(platform_window(), SDL_TRUE);
#endif

	// set main window
	if (m_index > 0)
	{
		for (auto w : osd_common_t::s_window_list)
		{
			if (w->m_index == 0)
			{
				set_main_window(std::dynamic_pointer_cast<osd_window>(w));
				break;
			}
		}
	}
	else
	{
		// We must be the main window
		set_main_window(shared_from_this());
	}

	// update monitor resolution after mode change to ensure proper pixel aspect
	monitor()->refresh();
	if (fullscreen() && video_config.switchres)
		monitor()->update_resolution(temp.width(), temp.height());

	// initialize the drawing backend
	if (renderer().create())
		return 1;

	// Make sure we have a consistent state
	SDL_ShowCursor(0);
	SDL_ShowCursor(1);

	return 0;
}
Exemple #4
0
bool sdl_osd_interface::window_init()
{
	osd_printf_verbose("Enter sdlwindow_init\n");
	// determine if we are using multithreading or not
	multithreading_enabled = options().multithreading();

	// get the main thread ID before anything else
	main_threadid = SDL_ThreadID();

	// if multithreading, create a thread to run the windows
	if (multithreading_enabled)
	{
		// create a thread to run the windows from
		work_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_IO);
		if (work_queue == NULL)
			return false;
		osd_work_item_queue(work_queue, &sdlwindow_thread_id, NULL, WORK_ITEM_FLAG_AUTO_RELEASE);
		sdlwindow_sync();
	}
	else
	{
		// otherwise, treat the window thread as the main thread
		//window_threadid = main_threadid;
		sdlwindow_thread_id(NULL, 0);
	}

	// initialize the drawers
#if USE_OPENGL
	if (video_config.mode == VIDEO_MODE_OPENGL)
	{
		if (drawogl_init(machine(), &draw))
			video_config.mode = VIDEO_MODE_SOFT;
	}
#endif
#if SDLMAME_SDL2
	if (video_config.mode == VIDEO_MODE_SDL2ACCEL)
	{
		if (drawsdl2_init(machine(), &draw))
			video_config.mode = VIDEO_MODE_SOFT;
	}
#endif
#ifdef USE_BGFX
	if (video_config.mode == VIDEO_MODE_BGFX)
	{
		if (drawbgfx_init(machine(), &draw))
			video_config.mode = VIDEO_MODE_SOFT;
	}
#endif
	if (video_config.mode == VIDEO_MODE_SOFT)
	{
		if (drawsdl_init(&draw))
			return false;
	}

#if SDLMAME_SDL2
	/* We may want to set a number of the hints SDL2 provides.
	 * The code below will document which hints were set.
	 */
	const char * hints[] = { SDL_HINT_FRAMEBUFFER_ACCELERATION,
			SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS,
			SDL_HINT_RENDER_SCALE_QUALITY,
			SDL_HINT_RENDER_VSYNC,
			SDL_HINT_VIDEO_X11_XVIDMODE, SDL_HINT_VIDEO_X11_XINERAMA,
			SDL_HINT_VIDEO_X11_XRANDR, SDL_HINT_GRAB_KEYBOARD,
			SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_HINT_IDLE_TIMER_DISABLED,
			SDL_HINT_ORIENTATIONS,
			SDL_HINT_XINPUT_ENABLED, SDL_HINT_GAMECONTROLLERCONFIG,
			SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_HINT_ALLOW_TOPMOST,
			SDL_HINT_TIMER_RESOLUTION,
#if SDL_VERSION_ATLEAST(2, 0, 2)
			SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_HINT_VIDEO_ALLOW_SCREENSAVER,
			SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK,
			SDL_HINT_VIDEO_WIN_D3DCOMPILER, SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT,
			SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_HINT_MOUSE_RELATIVE_MODE_WARP,
#endif
#if SDL_VERSION_ATLEAST(2, 0, 3)
			SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_HINT_VIDEO_HIGHDPI_DISABLED,
			SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL,
			SDL_HINT_WINRT_HANDLE_BACK_BUTTON,
#endif
			NULL
	};

	osd_printf_verbose("\nHints:\n");
	for (int i = 0; hints[i] != NULL; i++)
		osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i]));
#endif

	// set up the window list
	last_window_ptr = &sdl_window_list;
	osd_printf_verbose("Leave sdlwindow_init\n");
	return true;
}
Exemple #5
0
chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int current_cylinder, int current_head)
{
	if (TRACE_RWTRACK) osd_printf_verbose("%s: write back (c=%d,h=%d) to CHD\n", tag(), current_cylinder, current_head);

	uint8_t buffer[16384]; // for header or sector content

	int bytepos = 0;
	int state = SEARCH_A1;
	int count = 0;
	int pos = 0;
	uint16_t crc = 0;
	uint8_t byte;
	bool search_header = true;

	int ident = 0;
	int cylinder = 0;
	int head = 0;
	int sector = 0;
	int size = 0;

	int headerpos = 0;

	int interleave = 0;
	int interleave_prec = -1;
	bool check_interleave = true;
	bool check_skew = true;

	int gap1 = 0;
	int ecctype = 0;

	// if (current_cylinder==0 && current_head==0) showtrack(trackimage, tracksize);

	// If we want to detect gaps, we only do it on cylinder 0, head 0
	// This makes it safer to detect the header length
	// (There is indeed some chance that we falsely assume a header length of 4
	// because the two bytes behind happen to be a valid CRC value)
	if (save_param(MFMHD_GAP1) && current_cylinder==0 && current_head==0)
	{
		m_param.gap1 = 0;
		m_param.gap2 = 0;
		m_param.gap3 = 0;
		m_param.sync = 0;
		// 4-byte headers are used for the IBM-AT format
		// 5-byte headers are used in other formats
		m_param.headerlen = 4;
		m_param.ecctype = 0;
	}

	// AT format implies 512 bytes per sector
	int sector_length = 512;

	// Only check once
	bool countgap1 = (m_param.gap1==0);
	bool countgap2 = false;
	bool countgap3 = false;
	bool countsync = false;

	chd_error chdstate = CHDERR_NONE;

	if (TRACE_IMAGE)
	{
		for (int i=0; i < tracksize; i++)
		{
			if ((i % 16)==0) osd_printf_verbose("\n%04x: ", i);
			osd_printf_verbose("%02x ", (m_param.encoding==MFM_BITS || m_param.encoding==MFM_BYTE)? mfm_decode(trackimage[i]) : (trackimage[i]&0xff));
		}
		osd_printf_verbose("\n");
	}

	// We have to go through the bytes of the track and save a sector as soon as one shows up

	while (bytepos < tracksize)
	{
		// Decode the next 16 bits
		if (m_param.encoding==MFM_BITS || m_param.encoding==MFM_BYTE)
		{
			byte = mfm_decode(trackimage[bytepos]);
		}
		else byte = (trackimage[bytepos] & 0xff);

		switch (state)
		{
		case SEARCH_A1:
			// Counting gaps and sync
			if (countgap2)
			{
				if (byte == 0x4e) m_param.gap2++;
				else if (byte == 0) { countsync = true; countgap2 = false; }
			}

			if (countsync)
			{
				if (byte == 0) m_param.sync++;
				else countsync = false;
			}

			if (countgap3)
			{
				if (byte != 0x00 || m_param.gap3 < 4) m_param.gap3++;
				else countgap3 = false;
			}

			if (((m_param.encoding==MFM_BITS || m_param.encoding==MFM_BYTE) && trackimage[bytepos]==0x4489)
				|| (m_param.encoding==SEPARATED && trackimage[bytepos]==0x0aa1)
				|| (m_param.encoding==SEPARATED_SIMPLE && trackimage[bytepos]==0xffa1))
			{
				state = FOUND_A1;
				count = (search_header? m_param.headerlen : (sector_length+1)) + 2;
				crc = 0x443b; // init value with a1
				pos = 0;
			}
			bytepos++;
			break;

		case FOUND_A1:
			crc = ccitt_crc16_one(crc, byte);
			// osd_printf_verbose("%s: MFM HD: Byte = %02x, CRC=%04x\n", tag(), byte, crc);

			// Put byte into buffer
			// but not the data mark and the CRC
			if (search_header || (count > 2 &&  count < sector_length+3)) buffer[pos++] = byte;

			// Stop counting gap1
			if (search_header && countgap1)
			{
				gap1 = bytepos-1;
				countgap1 = false;
			}

			if (--count == 0)
			{
				if (crc==0)
				{
					if (search_header)
					{
						// Found a header
						ident = buffer[0];
						cylinder = buffer[1];
						// For non-PC-AT formats, highest three bits are in the head field
						if (m_param.headerlen == 5) cylinder |= ((buffer[2]&0x70)<<4);
						else
						{
							osd_printf_verbose("%s: Unexpected header size: %d, cylinder=%d, position=%04x\n", tag(), m_param.headerlen, cylinder, bytepos);
							showtrack(trackimage, tracksize);
						}

						head = buffer[2] & 0x0f;
						sector = buffer[3];
						int identexp = cylinder_to_ident(cylinder);

						if (identexp != ident)
						{
							osd_printf_verbose("%s: Field error; ident = %02x (expected %02x) for sector chs=(%d,%d,%d)\n", tag(), ident, identexp, cylinder, head, sector);
						}

						if (cylinder != current_cylinder)
						{
							osd_printf_verbose("%s: Sector header of sector %d defines cylinder = %02x (should be %02x)\n", tag(), sector, cylinder, current_cylinder);
						}

						if (head != current_head)
						{
							osd_printf_verbose("%s: Sector header of sector %d defines head = %02x (should be %02x)\n", tag(), sector, head, current_head);
						}

						// Check skew
						// We compare the beginning of this track with the track on the next head and the track on the next cylinder
						if (check_skew && cylinder < 2 && head < 2)
						{
							m_secnumber[cylinder*2 + head] = sector;
							check_skew=false;
						}

						// Count the sectors for the interleave
						if (check_interleave)
						{
							if (interleave_prec == -1) interleave_prec = sector;
							else
							{
								if (sector == interleave_prec+1) check_interleave = false;
								interleave++;
							}
						}

						if (interleave == 0) interleave = sector - buffer[3];

						// When we have 4-byte headers, the sector length is 512 bytes
						if (m_param.headerlen == 5)
						{
							size = buffer[4];
							sector_length = 128 << (size&0x07);
							ecctype = (size&0xf0)>>4;
						}

						search_header = false;
						if (TRACE_DETAIL) osd_printf_verbose("%s: Found sector chs=(%d,%d,%d)\n", tag(), cylinder, head, sector);
						headerpos = pos;
						// Start the GAP2 counter (if not already determined)
						if (m_param.gap2==0) countgap2 = true;
					}
					else
					{
						// Sector contents
						// Write the sectors to the CHD
						int lbaposition = chs_to_lba(cylinder, head, sector);
						if (lbaposition>=0)
						{
							if (TRACE_DETAIL) osd_printf_verbose("%s: Writing sector chs=(%d,%d,%d) to CHD\n", tag(), current_cylinder, current_head, sector);
							chdstate = chdfile->write_units(chs_to_lba(current_cylinder, current_head, sector), buffer);

							if (chdstate != CHDERR_NONE)
							{
								osd_printf_verbose("%s: Write error while writing sector chs=(%d,%d,%d)\n", tag(), cylinder, head, sector);
							}
						}
						else
						{
							osd_printf_verbose("%s: Invalid CHS data in track image: (%d,%d,%d); not saving to CHD\n", tag(), cylinder, head, sector);
						}
						if (m_param.gap3==0) countgap3 = true;
						search_header = true;
					}
				}
				else
				{
					// Let's test for a 5-byte header
					if (search_header && m_param.headerlen==4 && current_cylinder==0 && current_head==0)
					{
						if (TRACE_DETAIL) osd_printf_verbose("%s: CRC error for 4-byte header; trying 5 bytes\n", tag());
						m_param.headerlen=5;
						count = 1;
						bytepos++;
						break;
					}
					else
					{
						osd_printf_verbose("%s: CRC error in %s of (%d,%d,%d)\n", tag(), search_header? "header" : "data", cylinder, head, sector);
						search_header = true;
					}
				}
				// search next A1
				state = SEARCH_A1;

				if (!search_header && (pos - headerpos) > 30)
				{
					osd_printf_verbose("%s: Error; missing DAM; searching next header\n", tag());
					search_header = true;
				}
			}
Exemple #6
0
osd_dim sdl_window_info::pick_best_mode()
{
	int minimum_width, minimum_height, target_width, target_height;
	int i;
	float size_score, best_score = 0.0f;
	int best_width = 0, best_height = 0;
	SDL_Rect **modes;

	// determine the minimum width/height for the selected target
	m_target->compute_minimum_size(minimum_width, minimum_height);

	// use those as the target for now
	target_width = minimum_width * MAX(1, prescale());
	target_height = minimum_height * MAX(1, prescale());

	// if we're not stretching, allow some slop on the minimum since we can handle it
	{
		minimum_width -= 4;
		minimum_height -= 4;
	}

#if 1 // defined(SDLMAME_WIN32)
	/*
	 *  We need to do this here. If SDL_ListModes is
	 * called in init_monitors, the call will crash
	 * on win32
	 */
	modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_DOUBLEBUF);
#else
	modes = window->m_monitor->modes;
#endif

	if (modes == (SDL_Rect **)0)
	{
		osd_printf_error("SDL: No modes available?!\n");
		exit(-1);
	}
	else if (modes == (SDL_Rect **)-1)  // all modes are possible
	{
		return osd_dim(m_win_config.width, m_win_config.height);
	}
	else
	{
		for (i = 0; modes[i]; ++i)
		{
			// compute initial score based on difference between target and current
			size_score = 1.0f / (1.0f + fabsf((INT32)modes[i]->w - target_width) + fabsf((INT32)modes[i]->h - target_height));

			// if the mode is too small, give a big penalty
			if (modes[i]->w < minimum_width || modes[i]->h < minimum_height)
				size_score *= 0.01f;

			// if mode is smaller than we'd like, it only scores up to 0.1
			if (modes[i]->w < target_width || modes[i]->h < target_height)
				size_score *= 0.1f;

			// if we're looking for a particular mode, that's a winner
			if (modes[i]->w == m_win_config.width && modes[i]->h == m_win_config.height)
				size_score = 2.0f;

			osd_printf_verbose("%4dx%4d -> %f\n", (int)modes[i]->w, (int)modes[i]->h, size_score);

			// best so far?
			if (size_score > best_score)
			{
				best_score = size_score;
				best_width = modes[i]->w;
				best_height = modes[i]->h;
			}

		}
	}
	return osd_dim(best_width, best_height);
}
Exemple #7
0
//-------------------------------------------------
//  initialize story.dat index
//-------------------------------------------------
void datfile_manager::init_storyinfo()
{
	int swcount = 0;
	int count = index_datafile(m_storyidx, swcount);
	osd_printf_verbose("Story.dat games found = %i\n", count);
}
Exemple #8
0
void sdl_monitor_info::refresh()
{
	#if (SDLMAME_SDL2)
	SDL_DisplayMode dmode;

	#if defined(SDLMAME_WIN32)
	SDL_GetDesktopDisplayMode(m_handle, &dmode);
	#else
	SDL_GetCurrentDisplayMode(m_handle, &dmode);
	#endif
	SDL_Rect dimensions;
	SDL_GetDisplayBounds(m_handle, &dimensions);

	m_pos_size = SDL_Rect_to_osd_rect(dimensions);
	m_usuable_pos_size = SDL_Rect_to_osd_rect(dimensions);
	m_is_primary = (m_handle == 0);

	#else
	#if defined(SDLMAME_WIN32)  // Win32 version
	MONITORINFOEX info;
	info.cbSize = sizeof(info);
	GetMonitorInfo((HMONITOR)m_handle, (LPMONITORINFO)&info);
	m_pos_size = RECT_to_osd_rect(info.rcMonitor);
	m_usuable_pos_size = RECT_to_osd_rect(info.rcWork);
	m_is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) != 0);
	char *temp = utf8_from_wstring(info.szDevice);
	strncpy(m_name, temp, ARRAY_LENGTH(m_name) - 1);
	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);

	m_is_primary = (m_handle == 0);
	m_pos_size = osd_rect(0, 0, dbounds.size.width - dbounds.origin.x, dbounds.size.height - dbounds.origin.y);
	m_usuable_pos_size = m_pos_size;
	strncpy(m_name, "Mac OS X display", ARRAY_LENGTH(m_name) - 1);
	#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(m_name, ARRAY_LENGTH(m_name) - 1);
			m_pos_size = osd_rect(0, 0,
					DisplayWidth(info.info.x11.display, screen),
					DisplayHeight(info.info.x11.display, screen));

			/* FIXME: If Xinerame is used we should compile a list of monitors
			 * like we do for other targets and ignore SDL.
			 */
			if ((XineramaIsActive(info.info.x11.display)) && video_config.restrictonemonitor)
			{
				XineramaScreenInfo *xineinfo;
				int numscreens;

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

				m_pos_size = osd_rect(0, 0, xineinfo[0].width, xineinfo[0].height);

				XFree(xineinfo);
			}
			m_usuable_pos_size = m_pos_size;
			m_is_primary = (m_handle == 0);
		}
		else
		#endif // defined(SDLMAME_X11)
		{
			static int first_call=0;
			static int cw = 0, ch = 0;

			SDL_VideoDriverName(m_name, ARRAY_LENGTH(m_name) - 1);
			if (first_call==0)
			{
				const 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))
					{
						osd_printf_warning("WARNING: SDL_GetVideoInfo() for driver <%s> is broken.\n", m_name);
						osd_printf_warning("         You should set SDLMAME_DESKTOPDIM to your desktop size.\n");
						osd_printf_warning("            e.g. export SDLMAME_DESKTOPDIM=800x600\n");
						osd_printf_warning("         Assuming 1024x768 now!\n");
						cw=1024;
						ch=768;
					}
				}
			}
			m_pos_size = osd_rect(0, 0, cw, ch);
			m_usuable_pos_size = m_pos_size;
			m_is_primary = (m_handle == 0);
		}
	}
	#elif defined(SDLMAME_OS2)      // OS2 version
	m_pos_size = osd_rect(0, 0,
			WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ),
			WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) );
	m_usuable_pos_size = m_pos_size;
	m_is_primary = (m_handle == 0);
	strncpy(m_name, "OS/2 display", ARRAY_LENGTH(m_name) - 1);
	#else
	#error Unknown SDLMAME_xx OS type!
	#endif

	{
		static int info_shown=0;
		if (!info_shown)
		{
			osd_printf_verbose("SDL Device Driver     : %s\n", m_name);
			osd_printf_verbose("SDL Monitor Dimensions: %d x %d\n", m_pos_size.width(), m_pos_size.height());
			info_shown = 1;
		}
	}
	#endif //  (SDLMAME_SDL2)
}
Exemple #9
0
void cheat_manager::load_cheats(const char *filename)
{
	xml_data_node *rootnode = nullptr;
	std::string searchstr(machine().options().cheat_path());
	path_iterator path(searchstr.c_str());
	std::string curpath;
	while (path.next(curpath))
	{
		searchstr.append(";").append(curpath).append(PATH_SEPARATOR).append("cheat");
	}
	emu_file cheatfile(searchstr.c_str(), OPEN_FLAG_READ);
	try
	{
		// open the file with the proper name
		osd_file::error filerr = cheatfile.open(filename, ".xml");

		// loop over all instrances of the files found in our search paths
		while (filerr == osd_file::error::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 = std::make_unique<cheat_entry>(*this, m_symtable, filename, *cheatnode);

				// make sure we're not a duplicate
				if (REMOVE_DUPLICATE_CHEATS && curcheat->is_duplicate())
				{
					osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath());
				}
				else // add to the end of the list
					m_cheatlist.push_back(std::move(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.clear();
		if (rootnode != nullptr)
			xml_file_free(rootnode);
	}
}
Exemple #10
0
void renderer_dd::compute_blit_surface_size()
{
	INT32 newwidth, newheight;
	int xscale, yscale;
	RECT client;

	// start with the minimum size
	window().target()->compute_minimum_size(newwidth, newheight);

	// get the window's client rectangle
	GetClientRect(window().m_hwnd, &client);

	// hardware stretch case: apply prescale
	if (video_config.hwstretch)
	{
		int prescale = (window().prescale() < 1) ? 1 : window().prescale();

		// clamp the prescale to something smaller than the target bounds
		xscale = prescale;
		while (xscale > 1 && newwidth * xscale > rect_width(&client))
			xscale--;
		yscale = prescale;
		while (yscale > 1 && newheight * yscale > rect_height(&client))
			yscale--;
	}

	// non stretch case
	else
	{
		INT32 target_width = rect_width(&client);
		INT32 target_height = rect_height(&client);
		float desired_aspect = 1.0f;

		// compute the appropriate visible area if we're trying to keepaspect
		if (video_config.keepaspect)
		{
			osd_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
			window().target()->compute_visible_area(target_width, target_height, monitor->aspect(), window().target()->orientation(), target_width, target_height);
			desired_aspect = (float)target_width / (float)target_height;
		}

		// compute maximum integral scaling to fit the window
		xscale = (target_width + 2) / newwidth;
		yscale = (target_height + 2) / newheight;

		// try a little harder to keep the aspect ratio if desired
		if (video_config.keepaspect)
		{
			// if we could stretch more in the X direction, and that makes a better fit, bump the xscale
			while (newwidth * (xscale + 1) <= rect_width(&client) &&
				better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
				xscale++;

			// if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
			while (newheight * (yscale + 1) <= rect_height(&client) &&
				better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
				yscale++;

			// now that we've maxed out, see if backing off the maximally stretched one makes a better fit
			if (rect_width(&client) - newwidth * xscale < rect_height(&client) - newheight * yscale)
			{
				while (xscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect))
					xscale--;
			}
			else
			{
				while (yscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect))
					yscale--;
			}
		}
	}

	// ensure at least a scale factor of 1
	if (xscale == 0) xscale = 1;
	if (yscale == 0) yscale = 1;

	// apply the final scale
	newwidth *= xscale;
	newheight *= yscale;
	if (newwidth != blitwidth || newheight != blitheight)
	{
		// force some updates
		update_outer_rects();
		osd_printf_verbose("DirectDraw: New blit size = %dx%d\n", newwidth, newheight);
	}
	blitwidth = newwidth;
	blitheight = newheight;
}
Exemple #11
0
void renderer_dd::blit_to_primary(int srcwidth, int srcheight)
{
	IDirectDrawSurface7 *target = (back != NULL) ? back : primary;
	osd_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
	DDBLTFX blitfx = { sizeof(DDBLTFX) };
	RECT clear, outer, dest, source;
	INT32 dstwidth, dstheight;
	HRESULT result;

	// compute source rect
	source.left = source.top = 0;
	source.right = srcwidth;
	source.bottom = srcheight;

	// compute outer rect -- windowed version
	if (!window().fullscreen())
	{
		GetClientRect(window().m_hwnd, &outer);
		ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[0]);
		ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[1]);

		// adjust to be relative to the monitor
		osd_rect pos = monitor->position_size();
		outer.left -= pos.left();
		outer.right -= pos.left();
		outer.top -= pos.top();
		outer.bottom -= pos.top();
	}

	// compute outer rect -- full screen version
	else
	{
		calc_fullscreen_margins(primarydesc.dwWidth, primarydesc.dwHeight, &outer);
	}

	// if we're respecting the aspect ratio, we need to adjust to fit
	dstwidth = rect_width(&outer);
	dstheight = rect_height(&outer);
	if (!video_config.hwstretch)
	{
		// trim the source if necessary
		if (rect_width(&outer) < srcwidth)
		{
			source.left += (srcwidth - rect_width(&outer)) / 2;
			source.right = source.left + rect_width(&outer);
		}
		if (rect_height(&outer) < srcheight)
		{
			source.top += (srcheight - rect_height(&outer)) / 2;
			source.bottom = source.top + rect_height(&outer);
		}

		// match the destination and source sizes
		dstwidth = srcwidth = source.right - source.left;
		dstheight = srcheight = source.bottom - source.top;
	}
	else if (video_config.keepaspect)
	{
		// compute the appropriate visible area
		window().target()->compute_visible_area(rect_width(&outer), rect_height(&outer), monitor->aspect(), window().target()->orientation(), dstwidth, dstheight);
	}

	// center within
	dest.left = outer.left + (rect_width(&outer) - dstwidth) / 2;
	dest.right = dest.left + dstwidth;
	dest.top = outer.top + (rect_height(&outer) - dstheight) / 2;
	dest.bottom = dest.top + dstheight;

	// compare against last destination; if different, force a redraw
	if (dest.left != lastdest.left || dest.right != lastdest.right || dest.top != lastdest.top || dest.bottom != lastdest.bottom)
	{
		lastdest = dest;
		update_outer_rects();
	}

	// clear outer rects if we need to
	if (clearouter != 0)
	{
		clearouter--;

		// clear the left edge
		if (dest.left > outer.left)
		{
			clear = outer;
			clear.right = dest.left;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
		}

		// clear the right edge
		if (dest.right < outer.right)
		{
			clear = outer;
			clear.left = dest.right;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
		}

		// clear the top edge
		if (dest.top > outer.top)
		{
			clear = outer;
			clear.bottom = dest.top;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
		}

		// clear the bottom edge
		if (dest.bottom < outer.bottom)
		{
			clear = outer;
			clear.top = dest.bottom;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
		}
	}

	// do the blit
	result = IDirectDrawSurface7_Blt(target, &dest, blit, &source, DDBLT_WAIT, NULL);
	if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X blitting to the screen\n", (int)result);

	// page flip if triple buffered
	if (window().fullscreen() && back != NULL)
	{
		result = IDirectDrawSurface7_Flip(primary, NULL, DDFLIP_WAIT);
		if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
	}
}
Exemple #12
0
int renderer_dd::ddraw_create_surfaces()
{
	HRESULT result;

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

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

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

	// full screen mode: get the back surface
	back = NULL;
	if (window().fullscreen() && video_config.triplebuf)
	{
		DDSCAPS2 caps = { DDSCAPS_BACKBUFFER };
		result = IDirectDrawSurface7_GetAttachedSurface(primary, &caps, &back);
		if (result != DD_OK)
		{
			osd_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 (blitwidth == 0 || blitheight == 0)
		compute_blit_surface_size();
	blitdesc = primarydesc;
	blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
	blitdesc.dwWidth = blitwidth;
	blitdesc.dwHeight = blitheight;
	blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;

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

	// create a memory buffer for offscreen drawing
	if (membuffersize < blitwidth * blitheight * 4)
	{
		membuffersize = blitwidth * blitheight * 4;
		global_free_array(membuffer);
		membuffer = global_alloc_array_nothrow(UINT8, membuffersize);
	}
	if (membuffer == NULL)
		goto error;

	// create a clipper for windowed mode
	if (!window().fullscreen() && create_clipper())
		goto error;

	// full screen mode: set the gamma
	if (window().fullscreen())
	{
		// only set the gamma if it's not 1.0f
		windows_options &options = downcast<windows_options &>(window().machine().options());
		float brightness = options.full_screen_brightness();
		float contrast = options.full_screen_contrast();
		float fgamma = options.full_screen_gamma();
		if (brightness != 1.0f || contrast != 1.0f || fgamma != 1.0f)
		{
			// see if we can get a GammaControl object
			result = IDirectDrawSurface_QueryInterface(primary, WRAP_REFIID(IID_IDirectDrawGammaControl), (void **)&gamma);
			if (result != DD_OK)
			{
				osd_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n");
				this->gamma = NULL;
			}

			// proceed if we can
			if (this->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, fgamma) << 8;

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

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

error:
	ddraw_delete_surfaces();
	return 1;
}
Exemple #13
0
int renderer_dd::draw(const int update)
{
	render_primitive *prim;
	int usemembuffer = FALSE;
	HRESULT result;

	// if we're updating, remember to erase the outer stuff
	if (update)
		update_outer_rects();

	// if we have a ddraw object, check the cooperative level
	if (ddraw_test_cooperative())
		return 1;

	// get the size; if we're too small, delete the existing surfaces
	if (blitwidth > blitdesc.dwWidth || blitheight > blitdesc.dwHeight)
		ddraw_delete_surfaces();

	// if we need to create surfaces, do it now
	if (blit == NULL && ddraw_create_surfaces() != 0)
		return 1;

	// select our surface and lock it
	result = IDirectDrawSurface7_Lock(blit, NULL, &blitdesc, DDLOCK_WAIT, NULL);
	if (result == DDERR_SURFACELOST)
	{
		osd_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n");
		ddraw_delete_surfaces();
		return 1;
	}
	if (result != DD_OK)
	{
		osd_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result);
		return 1;
	}

	// render to it
	window().m_primlist->acquire_lock();

	// scan the list of primitives for tricky stuff
	for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
		if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
			(prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
		{
			usemembuffer = TRUE;
			break;
		}

	// if we're using the memory buffer, draw offscreen first and then copy
	if (usemembuffer)
	{
		int x, y;

		// based on the target format, use one of our standard renderers
		switch (blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			default:
				osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}

		// handle copying to both 16bpp and 32bpp destinations
		for (y = 0; y < blitheight; y++)
		{
			if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
			{
				UINT32 *src = (UINT32 *)membuffer + y * blitwidth;
				UINT32 *dst = (UINT32 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
				for (x = 0; x < blitwidth; x++)
					*dst++ = *src++;
			}
			else if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
			{
				UINT16 *src = (UINT16 *)membuffer + y * blitwidth;
				UINT16 *dst = (UINT16 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
				for (x = 0; x < blitwidth; x++)
					*dst++ = *src++;
			}
		}

	}

	// otherwise, draw directly
	else
	{
		// based on the target format, use one of our standard renderers
		switch (blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
			case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
			case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
			case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
			default:
				osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}
	}
	window().m_primlist->release_lock();

	// unlock and blit
	result = IDirectDrawSurface7_Unlock(blit, NULL);
	if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result);

	// sync to VBLANK
	if ((video_config.waitvsync || video_config.syncrefresh) && window().machine().video().throttled() && (!window().fullscreen() || back == NULL))
	{
		result = IDirectDraw7_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKBEGIN, NULL);
		if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
	}

	// complete the blitting
	blit_to_primary(blitwidth, blitheight);
	return 0;
}
Exemple #14
0
int renderer_dd::config_adapter_mode()
{
	DDDEVICEIDENTIFIER2 identifier;
	HRESULT result;

	// choose the monitor number
	get_adapter_for_monitor(window().monitor());

	// create a temporary DirectDraw object
	result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
	if (result != DD_OK)
	{
		osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
		return 1;
	}

	// get the identifier
	result = IDirectDraw7_GetDeviceIdentifier(ddraw, &identifier, 0);
	if (result != DD_OK)
	{
		osd_printf_error("Error getting identifier for device\n");
		return 1;
	}
	osd_printf_verbose("DirectDraw: Configuring device %s\n", identifier.szDescription);

	// get the current display mode
	memset(&origmode, 0, sizeof(origmode));
	origmode.dwSize = sizeof(origmode);
	result = IDirectDraw7_GetDisplayMode(ddraw, &origmode);
	if (result != DD_OK)
	{
		osd_printf_verbose("DirectDraw: Error %08X getting current display mode\n", (int)result);
		IDirectDraw7_Release(ddraw);
		return 1;
	}

	// choose a resolution: full screen mode case
	if (window().fullscreen())
	{
		// default to the current mode exactly
		width = origmode.dwWidth;
		height = origmode.dwHeight;
		refresh = origmode.dwRefreshRate;

		// if we're allowed to switch resolutions, override with something better
		if (video_config.switchres)
			pick_best_mode();
	}

	// release the DirectDraw object
	IDirectDraw7_Release(ddraw);
	ddraw = NULL;

	// if we're not changing resolutions, make sure we have a resolution we can handle
	if (!window().fullscreen() || !video_config.switchres)
	{
		switch (origmode.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:
			case 0x000000ff:
			case 0xf800:
			case 0x7c00:
				break;

			default:
				osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)origmode.ddpfPixelFormat.dwRBitMask, (int)origmode.ddpfPixelFormat.dwGBitMask, (int)origmode.ddpfPixelFormat.dwBBitMask);
				return 1;
		}
	}

	return 0;
}
Exemple #15
0
void menu_file_selector::populate(float &customtop, float &custombottom)
{
	const file_selector_entry *selected_entry = nullptr;


	// clear out the menu entries
	m_entrylist.clear();

	// open the directory
	util::zippath_directory::ptr directory;
	osd_file::error const err = util::zippath_directory::open(m_current_directory, directory);

	// add the "[empty slot]" entry if available
	if (m_has_empty)
		append_entry(SELECTOR_ENTRY_TYPE_EMPTY, "", "");

	// add the "[create]" entry
	if (m_has_create && !directory->is_archive())
		append_entry(SELECTOR_ENTRY_TYPE_CREATE, "", "");

	// add and select the "[software list]" entry if available
	if (m_has_softlist)
		selected_entry = &append_entry(SELECTOR_ENTRY_TYPE_SOFTWARE_LIST, "", "");

	// add the drives
	int i = 0;
	for (char const *volume_name = osd_get_volume_name(i); volume_name; volume_name = osd_get_volume_name(++i))
		append_entry(SELECTOR_ENTRY_TYPE_DRIVE, volume_name, volume_name);

	// mark first filename entry
	std::size_t const first = m_entrylist.size() + 1;

	// build the menu for each item
	if (osd_file::error::NONE != err)
	{
		osd_printf_verbose("menu_file_selector::populate: error opening directory '%s' (%d)\n", m_current_directory.c_str(), int(err));
	}
	else
	{
		for (osd::directory::entry const *dirent = directory->readdir(); dirent; dirent = directory->readdir())
		{
			// append a dirent entry
			file_selector_entry const *entry = append_dirent_entry(dirent);
			if (entry)
			{
				// set the selected item to be the first non-parent directory or file
				if (!selected_entry && strcmp(dirent->name, ".."))
					selected_entry = entry;

				// do we have to select this file?
				if (!core_stricmp(m_current_file.c_str(), dirent->name))
					selected_entry = entry;
			}
		}
	}
	directory.reset();

	// sort the menu entries
	const std::collate<wchar_t> &coll = std::use_facet<std::collate<wchar_t>>(std::locale());
	std::sort(
			m_entrylist.begin() + first,
			m_entrylist.end(),
			[&coll] (file_selector_entry const &x, file_selector_entry const &y)
			{
				std::wstring const xstr = wstring_from_utf8(x.basename);
				std::wstring const ystr = wstring_from_utf8(y.basename);
				return coll.compare(xstr.data(), xstr.data()+xstr.size(), ystr.data(), ystr.data()+ystr.size()) < 0;
			});

	// append all of the menu entries
	for (file_selector_entry const &entry : m_entrylist)
		append_entry_menu_item(&entry);

	// set the selection (if we have one)
	if (selected_entry)
		set_selection((void *)selected_entry);

	// set up custom render proc
	customtop = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
}
Exemple #16
0
void s32comm_device::comm_tick_15612()
{
	// m_shared[0] = node link status (5 = linking, 1 = online)
	// m_shared[1] = node mode (0 = relay, 1 = master, 2 = slave)
	// m_shared[2] = node id
	// m_shared[3] = node count
	// m_shared[4] = ready-to-send
	if (m_linkenable == 0x01)
	{
		int frameStart = 0x0010;
		int frameOffset = 0x0000;
		int frameSize = 0x00E0;
		int dataSize = frameSize + 1;
		int recv = 0;
		int idx = 0;

		bool isMaster = (m_shared[1] == 0x01);
		bool isSlave = (m_shared[1] == 0x02);
		bool isRelay = (m_shared[1] == 0x00);

		if (m_linkalive == 0x02)
		{
			// link failed...
			m_shared[0] = 0xff;
			return;
		}
		else if (m_linkalive == 0x00)
		{
			// link not yet established...
			m_shared[0] = 0x05;

			// check rx socket
			if (!m_line_rx)
			{
				osd_printf_verbose("S32COMM: listen on %s\n", m_localhost);
				uint64_t filesize; // unused
				osd_file::open(m_localhost, OPEN_FLAG_CREATE, m_line_rx, filesize);
			}

			// check tx socket
			if (!m_line_tx)
			{
				osd_printf_verbose("S32COMM: connect to %s\n", m_remotehost);
				uint64_t filesize; // unused
				osd_file::open(m_remotehost, 0, m_line_tx, filesize);
			}

			// if both sockets are there check ring
			if (m_line_rx && m_line_tx)
			{
				// try to read one message
				recv = read_frame(dataSize);
				while (recv > 0)
				{
					// check if message id
					idx = m_buffer0[0];

					// 0xFF - link id
					if (idx == 0xff)
					{
						if (isMaster)
						{
							// master gets first id and starts next state
							m_linkid = 0x01;
							m_linkcount = m_buffer0[1];
							m_linktimer = 0x00;
						}
						else if (isSlave || isRelay)
						{
							// slave gets own id
							if (isSlave)
							{
								m_buffer0[1]++;
								m_linkid = m_buffer0[1];
							}

							// slave and relay forward message
							send_frame(dataSize);
						}
					}

					// 0xFE - link size
					else if (idx == 0xfe)
					{
						if (isSlave || isRelay)
						{
							m_linkcount = m_buffer0[1];

							// slave and relay forward message
							send_frame(dataSize);
						}

						// consider it done
						osd_printf_verbose("S32COMM: link established - id %02x of %02x\n", m_linkid, m_linkcount);
						m_linkalive = 0x01;

						// write to shared mem
						m_shared[0] = 0x01;
						m_shared[2] = m_linkid;
						m_shared[3] = m_linkcount;
					}

					if (m_linkalive == 0x00)
						recv = read_frame(dataSize);
					else
						recv = 0;
				}

				// if we are master and link is not yet established
				if (isMaster && (m_linkalive == 0x00))
				{
					// send first packet
					if (m_linktimer == 0x01)
					{
						m_buffer0[0] = 0xFF;
						m_buffer0[1] = 0x01;
						send_frame(dataSize);
					}

					// send second packet
					else if (m_linktimer == 0x00)
					{
						m_buffer0[0] = 0xFE;
						m_buffer0[1] = m_linkcount;
						send_frame(dataSize);

						// consider it done
						osd_printf_verbose("S32COMM: link established - id %02x of %02x\n", m_linkid, m_linkcount);
						m_linkalive = 0x01;

						// write to shared mem
						m_shared[0] = 0x01;
						m_shared[2] = m_linkid;
						m_shared[3] = m_linkcount;
					}

					else if (m_linktimer > 0x01)
					{
						// decrease delay timer
						m_linktimer--;
					}
				}
			}
		}

		// update "ring buffer" if link established
		if (m_linkalive == 0x01)
		{
			do
			{
				// try to read a message
				recv = read_frame(dataSize);
				while (recv > 0)
				{
					// check if valid id
					idx = m_buffer0[0];
					if (idx > 0 && idx <= m_linkcount)
					{
						// if not own message
						if (idx != m_linkid)
						{
							// save message to "ring buffer"
							frameOffset = frameStart + (idx * frameSize);
							for (int j = 0x00 ; j < frameSize ; j++)
							{
								m_shared[frameOffset + j] = m_buffer0[1 + j];
							}

							// forward message to other nodes
							send_frame(dataSize);
						}
					}
					else
					{
						if (idx == 0xfc)
						{
							// 0xFC - VSYNC
							m_linktimer = 0x00;
							if (!isMaster)
								// forward message to other nodes
								send_frame(dataSize);
						}
						if (idx == 0xfd)
						{
							// 0xFD - master addional bytes
							if (!isMaster)
							{
								// save message to "ring buffer"
								frameOffset = 0x05;
								for (int j = 0x00 ; j < 0x0b ; j++)
								{
									m_shared[frameOffset + j] = m_buffer0[1 + j];
								}

								// forward message to other nodes
								send_frame(dataSize);
							}
						}
					}

					// try to read another message
					recv = read_frame(dataSize);
				}
			}
			while (m_linktimer == 0x01);

			// enable wait for vsync
			m_linktimer = m_framesync;

			// update "ring buffer" if link established
			// live relay does not send data
			if (m_linkid != 0x00)
			{
				// check ready-to-send flag
				if (m_shared[4] != 0x00)
				{
					send_data(m_linkid, frameStart, frameSize, dataSize);

					// save message to "ring buffer"
					frameOffset = frameStart + (m_linkid * frameSize);
					for (int j = 0x00 ; j < frameSize ; j++)
					{
						m_shared[frameOffset + j] = m_buffer0[1 + j];
					}
				}

				if (isMaster)
				{
					// master sends some additional status bytes
					// master sends additional status bytes
					send_data(0xfd, 0x05, 0x0b, dataSize);

					// send vsync
					m_buffer0[0] = 0xfc;
					m_buffer0[1] = 0x01;
					send_frame(dataSize);
				}
			}

			// clear 04
			m_shared[4] = 0x00;
		}
	}
}
Exemple #17
0
bool sdl_osd_interface::window_init()
{
	osd_printf_verbose("Enter sdlwindow_init\n");

	// get the main thread ID before anything else
	main_threadid = SDL_ThreadID();

	// otherwise, treat the window thread as the main thread
	//window_threadid = main_threadid;
	sdlwindow_thread_id(nullptr, 0);

	// initialize the drawers

	switch (video_config.mode)
	{
		case VIDEO_MODE_BGFX:
			renderer_bgfx::init(machine());
			break;
#if (USE_OPENGL)
		case VIDEO_MODE_OPENGL:
			renderer_ogl::init(machine());
			break;
#endif
		case VIDEO_MODE_SDL2ACCEL:
			renderer_sdl2::init(machine());
			break;
		case VIDEO_MODE_SOFT:
			renderer_sdl1::init(machine());
			break;
	}

	/* We may want to set a number of the hints SDL2 provides.
	 * The code below will document which hints were set.
	 */
	const char * hints[] = { SDL_HINT_FRAMEBUFFER_ACCELERATION,
			SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS,
			SDL_HINT_RENDER_SCALE_QUALITY,
			SDL_HINT_RENDER_VSYNC,
			SDL_HINT_VIDEO_X11_XVIDMODE, SDL_HINT_VIDEO_X11_XINERAMA,
			SDL_HINT_VIDEO_X11_XRANDR, SDL_HINT_GRAB_KEYBOARD,
			SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_HINT_IDLE_TIMER_DISABLED,
			SDL_HINT_ORIENTATIONS,
			SDL_HINT_XINPUT_ENABLED, SDL_HINT_GAMECONTROLLERCONFIG,
			SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_HINT_ALLOW_TOPMOST,
			SDL_HINT_TIMER_RESOLUTION,
#if SDL_VERSION_ATLEAST(2, 0, 2)
			SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_HINT_VIDEO_ALLOW_SCREENSAVER,
			SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK,
			SDL_HINT_VIDEO_WIN_D3DCOMPILER, SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT,
			SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_HINT_MOUSE_RELATIVE_MODE_WARP,
#endif
#if SDL_VERSION_ATLEAST(2, 0, 3)
			SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_HINT_VIDEO_HIGHDPI_DISABLED,
			SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL,
			SDL_HINT_WINRT_HANDLE_BACK_BUTTON,
#endif
			nullptr
	};

	osd_printf_verbose("\nHints:\n");
	for (int i = 0; hints[i] != nullptr; i++)
		osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i]));

	// set up the window list
	osd_printf_verbose("Leave sdlwindow_init\n");
	return true;
}
Exemple #18
0
static void defines_verbose(void)
{
	osd_printf_verbose("Build version:      %s\n", build_version);
	osd_printf_verbose("Build architecure:  ");
	MACRO_VERBOSE(SDLMAME_ARCH);
	osd_printf_verbose("\n");
	osd_printf_verbose("Build defines 1:    ");
	MACRO_VERBOSE(SDLMAME_UNIX);
	MACRO_VERBOSE(SDLMAME_X11);
	MACRO_VERBOSE(SDLMAME_WIN32);
	MACRO_VERBOSE(SDLMAME_MACOSX);
	MACRO_VERBOSE(SDLMAME_DARWIN);
	MACRO_VERBOSE(SDLMAME_LINUX);
	MACRO_VERBOSE(SDLMAME_SOLARIS);
	MACRO_VERBOSE(SDLMAME_IRIX);
	MACRO_VERBOSE(SDLMAME_BSD);
	osd_printf_verbose("\n");
	osd_printf_verbose("Build defines 1:    ");
	MACRO_VERBOSE(LSB_FIRST);
	MACRO_VERBOSE(PTR64);
	MACRO_VERBOSE(MAME_NOASM);
	MACRO_VERBOSE(MAME_DEBUG);
	MACRO_VERBOSE(BIGENDIAN);
	MACRO_VERBOSE(CPP_COMPILE);
	MACRO_VERBOSE(SYNC_IMPLEMENTATION);
	osd_printf_verbose("\n");
	osd_printf_verbose("SDL/OpenGL defines: ");
	osd_printf_verbose("SDL_COMPILEDVERSION=%d ", SDL_COMPILEDVERSION);
	MACRO_VERBOSE(USE_OPENGL);
	MACRO_VERBOSE(USE_DISPATCH_GL);
	osd_printf_verbose("\n");
	osd_printf_verbose("Compiler defines A: ");
	MACRO_VERBOSE(__GNUC__);
	MACRO_VERBOSE(__GNUC_MINOR__);
	MACRO_VERBOSE(__GNUC_PATCHLEVEL__);
	MACRO_VERBOSE(__VERSION__);
	osd_printf_verbose("\n");
	osd_printf_verbose("Compiler defines B: ");
	MACRO_VERBOSE(__amd64__);
	MACRO_VERBOSE(__x86_64__);
	MACRO_VERBOSE(__unix__);
	MACRO_VERBOSE(__i386__);
	MACRO_VERBOSE(__ppc__);
	MACRO_VERBOSE(__ppc64__);
	osd_printf_verbose("\n");
	osd_printf_verbose("Compiler defines C: ");
	MACRO_VERBOSE(_FORTIFY_SOURCE);
	MACRO_VERBOSE(__USE_FORTIFY_LEVEL);
	osd_printf_verbose("\n");
}
Exemple #19
0
base *drawd3d9_init(void)
{
	bool post_available = true;

	// dynamically grab the create function from d3d9.dll
	HINSTANCE dllhandle = LoadLibrary(TEXT("d3d9.dll"));
	if (dllhandle == nullptr)
	{
		osd_printf_verbose("Direct3D: Unable to access d3d9.dll\n");
		return nullptr;
	}

	// import the create function
	direct3dcreate9_ptr direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9");
	if (direct3dcreate9 == nullptr)
	{
		osd_printf_verbose("Direct3D: Unable to find Direct3DCreate9\n");
		FreeLibrary(dllhandle);
		return nullptr;
	}

	// create our core direct 3d object
	IDirect3D9 *d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION);
	if (d3d9 == nullptr)
	{
		osd_printf_verbose("Direct3D: Error attempting to initialize Direct3D9\n");
		FreeLibrary(dllhandle);
		return nullptr;
	}

	// dynamically grab the shader load function from d3dx9.dll
	HINSTANCE fxhandle = nullptr;
	for (int idx = 99; idx >= 0; idx--) // a shameful moogle
	{
		#ifdef UNICODE
		wchar_t dllbuf[13];
		wsprintf(dllbuf, TEXT("d3dx9_%d.dll"), idx);
		fxhandle = LoadLibrary(dllbuf);
		#else
		char dllbuf[13];
		sprintf(dllbuf, "d3dx9_%d.dll", idx);
		fxhandle = LoadLibraryA(dllbuf);
		#endif
		if (fxhandle != nullptr)
		{
			break;
		}
	}
	if (fxhandle == nullptr)
	{
		osd_printf_verbose("Direct3D: Warning - Unable find any D3D9 DLLs; disabling post-effect rendering\n");
		post_available = false;
	}

	// allocate an object to hold our data
	auto 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);

	osd_printf_verbose("Direct3D: Using Direct3D 9\n");
	return d3dptr;
}
Exemple #20
0
static void osd_sdl_info(void)
{
	int i, num = SDL_GetNumVideoDrivers();

	osd_printf_verbose("Available videodrivers: ");
	for (i=0;i<num;i++)
	{
		const char *name = SDL_GetVideoDriver(i);
		osd_printf_verbose("%s ", name);
	}
	osd_printf_verbose("\n");
	osd_printf_verbose("Current Videodriver: %s\n", SDL_GetCurrentVideoDriver());
	num = SDL_GetNumVideoDisplays();
	for (i=0;i<num;i++)
	{
		SDL_DisplayMode mode;
		int j;

		osd_printf_verbose("\tDisplay #%d\n", i);
		if (SDL_GetDesktopDisplayMode(i, &mode))
			osd_printf_verbose("\t\tDesktop Mode:         %dx%d-%d@%d\n", mode.w, mode.h, SDL_BITSPERPIXEL(mode.format), mode.refresh_rate);
		if (SDL_GetCurrentDisplayMode(i, &mode))
			osd_printf_verbose("\t\tCurrent Display Mode: %dx%d-%d@%d\n", mode.w, mode.h, SDL_BITSPERPIXEL(mode.format), mode.refresh_rate);
		osd_printf_verbose("\t\tRenderdrivers:\n");
		for (j=0; j<SDL_GetNumRenderDrivers(); j++)
		{
			SDL_RendererInfo info;
			SDL_GetRenderDriverInfo(j, &info);
			osd_printf_verbose("\t\t\t%10s (%dx%d)\n", info.name, info.max_texture_width, info.max_texture_height);
		}
	}

	osd_printf_verbose("Available audio drivers: \n");
	num = SDL_GetNumAudioDrivers();
	for (i=0;i<num;i++)
	{
		osd_printf_verbose("\t%-20s\n", SDL_GetAudioDriver(i));
	}
}
Exemple #21
0
//-------------------------------------------------
//  initialize command.dat index
//-------------------------------------------------
void datfile_manager::init_command()
{
	int swcount = 0;
	int count = index_datafile(m_cmdidx, swcount);
	osd_printf_verbose("Command.dat games found = %i\n", count);
}
Exemple #22
0
void sdl_osd_interface::init(running_machine &machine)
{
	// call our parent
	osd_common_t::init(machine);

	const char *stemp;

	// determine if we are benchmarking, and adjust options appropriately
	int bench = options().bench();
	std::string error_string;
	if (bench > 0)
	{
		options().set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM, error_string);
		options().set_value(OSDOPTION_SOUND, "none", OPTION_PRIORITY_MAXIMUM, error_string);
		options().set_value(OSDOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM, error_string);
		options().set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM, error_string);
		assert(error_string.c_str()[0] == 0);
	}

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

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

		stemp = options().render_driver();
		if (stemp != NULL)
		{
			if (strcmp(stemp, OSDOPTVAL_AUTO) != 0)
			{
				osd_printf_verbose("Setting SDL renderdriver '%s' ...\n", stemp);
				//osd_setenv(SDLENV_RENDERDRIVER, stemp, 1);
				SDL_SetHint(SDL_HINT_RENDER_DRIVER, stemp);
			}
			else
			{
#if defined(SDLMAME_WIN32)
				// OpenGL renderer has less issues with mode switching on windows
				osd_printf_verbose("Setting SDL renderdriver '%s' ...\n", "opengl");
				//osd_setenv(SDLENV_RENDERDRIVER, stemp, 1);
				SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
#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, OSDOPTVAL_AUTO) != 0)
	{
		osd_setenv("SDL_VIDEO_GL_DRIVER", stemp, 1);
		osd_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)
		{
			osd_printf_warning("numprocessors < 1 doesn't make much sense. Assuming auto ...\n");
			osd_num_processors = 0;
		}
	}

	/* Initialize SDL */

	if (!SDLMAME_INIT_IN_WORKER_THREAD)
	{
#ifdef SDLMAME_EMSCRIPTEN
		// timer brings in threads which are not supported in Emscripten
		if (SDL_InitSubSystem(SDL_INIT_VIDEO| SDL_INIT_GAMECONTROLLER|SDL_INIT_NOPARACHUTE)) {
#else
		if (SDL_InitSubSystem(SDL_INIT_TIMER| SDL_INIT_VIDEO| SDL_INIT_GAMECONTROLLER|SDL_INIT_NOPARACHUTE)) {
#endif
			osd_printf_error("Could not initialize SDL %s\n", SDL_GetError());
			exit(-1);
		}
		osd_sdl_info();
	}

	defines_verbose();

	osd_common_t::init_subsystems();

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

	/* now setup watchdog */

	int watchdog_timeout = options().watchdog();

	if (watchdog_timeout != 0)
	{
		m_watchdog = auto_alloc(machine, watchdog);
		m_watchdog->setTimeout(watchdog_timeout);
	}

#ifdef SDLMAME_EMSCRIPTEN
	SDL_EventState(SDL_TEXTINPUT, SDL_FALSE);
#else
	SDL_EventState(SDL_TEXTINPUT, SDL_TRUE);
#endif
}
Exemple #23
0
osd_dim sdl_window_info::pick_best_mode()
{
	int minimum_width, minimum_height, target_width, target_height;
	int i;
	int num;
	float size_score, best_score = 0.0f;
	osd_dim ret(0,0);

	// determine the minimum width/height for the selected target
	m_target->compute_minimum_size(minimum_width, minimum_height);

	// use those as the target for now
	target_width = minimum_width * MAX(1, prescale());
	target_height = minimum_height * MAX(1, prescale());

	// if we're not stretching, allow some slop on the minimum since we can handle it
	{
		minimum_width -= 4;
		minimum_height -= 4;
	}

	// FIXME: this should be provided by monitor !
	num = SDL_GetNumDisplayModes(*((UINT64 *)m_monitor->oshandle()));

	if (num == 0)
	{
		osd_printf_error("SDL: No modes available?!\n");
		exit(-1);
	}
	else
	{
		for (i = 0; i < num; ++i)
		{
			SDL_DisplayMode mode;
			SDL_GetDisplayMode(*((UINT64 *)m_monitor->oshandle()), i, &mode);

			// compute initial score based on difference between target and current
			size_score = 1.0f / (1.0f + abs((INT32)mode.w - target_width) + abs((INT32)mode.h - target_height));

			// if the mode is too small, give a big penalty
			if (mode.w < minimum_width || mode.h < minimum_height)
				size_score *= 0.01f;

			// if mode is smaller than we'd like, it only scores up to 0.1
			if (mode.w < target_width || mode.h < target_height)
				size_score *= 0.1f;

			// if we're looking for a particular mode, that's a winner
			if (mode.w == m_win_config.width && mode.h == m_win_config.height)
				size_score = 2.0f;

			// refresh adds some points
			if (m_win_config.refresh)
				size_score *= 1.0f / (1.0f + abs(m_win_config.refresh - mode.refresh_rate) / 10.0f);

			osd_printf_verbose("%4dx%4d@%2d -> %f\n", (int)mode.w, (int)mode.h, (int) mode.refresh_rate, (double) size_score);

			// best so far?
			if (size_score > best_score)
			{
				best_score = size_score;
				ret = osd_dim(mode.w, mode.h);
			}

		}
	}
	return ret;
}
Exemple #24
0
chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head)
{
	chd_error state = CHDERR_NONE;
	uint8_t sector_content[16384];

	int sectorcount = m_param.sectors_per_track;
	int size = m_param.sector_size;
	int position = 0; // will be incremented by each encode call
	int sec_number = 0;
	int identfield = 0;
	int cylfield = 0;
	int headfield = 0;
	int sizefield = (size >> 7)-1;

	// If we don't have interleave data in the CHD, take a default
	if (m_param.interleave==0)
	{
		m_param.interleave = get_default(MFMHD_IL);
		m_param.cylskew = get_default(MFMHD_CSKEW);
		m_param.headskew = get_default(MFMHD_HSKEW);
	}

	int sec_il_start = (m_param.cylskew * cylinder + m_param.headskew * head) % sectorcount;
	int delta = (sectorcount + m_param.interleave-1) / m_param.interleave;

	if (TRACE_RWTRACK) osd_printf_verbose("%s: Load track (c=%d,h=%d) from CHD, interleave=%d, cylskew=%d, headskew=%d\n", tag(), cylinder, head, m_param.interleave, m_param.cylskew, m_param.headskew);

	m_lastbit = false;

	if (m_param.sync==0)
	{
		m_param.gap1 = get_default(MFMHD_GAP1);
		m_param.gap2 = get_default(MFMHD_GAP2);
		m_param.gap3 = get_default(MFMHD_GAP3);
		m_param.sync = get_default(MFMHD_SYNC);
		m_param.headerlen = get_default(MFMHD_HLEN);
		m_param.ecctype = get_default(MFMHD_ECC);
	}

	// Gap 1
	mfm_encode(trackimage, position, 0x4e, m_param.gap1);

	if (TRACE_LAYOUT) osd_printf_verbose("%s: cyl=%d head=%d: sector sequence = ", tag(), cylinder, head);

	sec_number = sec_il_start;
	for (int sector = 0; sector < sectorcount; sector++)
	{
		if (TRACE_LAYOUT) osd_printf_verbose("%02d ", sec_number);

		// Sync gap
		mfm_encode(trackimage, position, 0x00, m_param.sync);

		// Write IDAM
		mfm_encode_a1(trackimage, position);

		// Write header
		identfield = cylinder_to_ident(cylinder);
		cylfield = cylinder & 0xff;
		headfield = head & 0x0f;
		if (m_param.headerlen==5)
			headfield |= ((cylinder & 0x700)>>4);

		mfm_encode(trackimage, position, identfield);
		mfm_encode(trackimage, position, cylfield);
		mfm_encode(trackimage, position, headfield);
		mfm_encode(trackimage, position, sec_number);
		if (m_param.headerlen==5)
			mfm_encode(trackimage, position, sizefield);

		// Write CRC for header.
		int crc = m_current_crc;
		mfm_encode(trackimage, position, (crc >> 8) & 0xff);
		mfm_encode(trackimage, position, crc & 0xff);

		// Gap 2
		mfm_encode(trackimage, position, 0x4e, m_param.gap2);

		// Sync
		mfm_encode(trackimage, position, 0x00, m_param.sync);

		// Write DAM
		mfm_encode_a1(trackimage, position);
		mfm_encode(trackimage, position, 0xfb);

		// Get sector content from CHD
		int lbaposition = chs_to_lba(cylinder, head, sec_number);
		if (lbaposition>=0)
		{
			chd_error state = chdfile->read_units(lbaposition, sector_content);
			if (state != CHDERR_NONE) break;
		}
		else
		{
			osd_printf_verbose("%s: Invalid CHS data (%d,%d,%d); not loading from CHD\n", tag(), cylinder, head, sector);
		}

		for (int i=0; i < size; i++)
			mfm_encode(trackimage, position, sector_content[i]);

		// Write CRC for content.
		crc = m_current_crc;
		mfm_encode(trackimage, position, (crc >> 8) & 0xff);
		mfm_encode(trackimage, position, crc & 0xff);

		// Gap 3
		mfm_encode(trackimage, position, 0x00, 3);
		mfm_encode(trackimage, position, 0x4e, m_param.gap3-3);

		// Calculate next sector number
		sec_number += delta;
		if (sec_number >= sectorcount)
		{
			sec_il_start = (sec_il_start+1) % delta;
			sec_number = sec_il_start;
		}
	}
	if (TRACE_LAYOUT) osd_printf_verbose("\n");

	// Gap 4
	if (state == CHDERR_NONE)
	{
		// Fill the rest with 0x4e
		mfm_encode(trackimage, position, 0x4e, tracksize-position);
		if (TRACE_IMAGE) showtrack(trackimage, tracksize);
	}
	return state;
}