Example #1
0
/**
 * gens_window_reinit(): Reinitialize the Gens window.
 */
void gens_window_reinit(void)
{
	// Determine the window size using the scaling factor.
	if (vdraw_scale <= 0)
		return;
	const int w = 320 * vdraw_scale;
	const int h = 240 * vdraw_scale;
	
	LONG_PTR lStyle;
	
	if (vdraw_get_fullscreen())
	{
		// Fullscreen. Hide the mouse cursor and the window borders.
		while (ShowCursor(TRUE) < 1) { }
		while (ShowCursor(FALSE) >= 0) { }
		
		// Hide the window borders.
		lStyle = GetWindowLongPtr(gens_window, GWL_STYLE);
		lStyle &= ~(WS_POPUPWINDOW | WS_OVERLAPPEDWINDOW);
		SetWindowLongPtr(gens_window, GWL_STYLE, lStyle);
		SetWindowPos(gens_window, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOACTIVATE);
	}
	else
	{
		// Windowed. Show the mouse cursor and the window borders.
		while (ShowCursor(FALSE) >= 0) { }
		while (ShowCursor(TRUE) < 1) { }
		
		// Adjust the window style.
		lStyle = GetWindowLongPtr(gens_window, GWL_STYLE);
		if (vdraw_cur_backend_flags & VDRAW_BACKEND_FLAG_WINRESIZE)
		{
			// Backend supports resizable windows.
			lStyle &= ~WS_POPUPWINDOW;
			lStyle |= WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE | WS_CLIPSIBLINGS;
		}
		else
		{
			// Backend does not support resizable windows.
			lStyle &= ~WS_OVERLAPPEDWINDOW;
			lStyle |= WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE | WS_CLIPSIBLINGS;
		}
		SetWindowLongPtr(gens_window, GWL_STYLE, lStyle);
		
		// Reposition the window.
		SetWindowPos(gens_window, NULL, Window_Pos.x, Window_Pos.y, 0, 0,
			     SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
	}
	
	// Rebuild the menu bar.
	// This is needed if the mode is switched from windowed to fullscreen, or vice-versa.
	gens_window_create_menubar();
	
	// Synchronize menus.
	Sync_Gens_Window();
}
Example #2
0
/**
 * create_gens_window_menubar(): Create the menu bar.
 */
void gens_window_create_menubar(void)
{
	if (gens_menu_bar != NULL)
	{
		// Menu bar already exists. Delete it.
		gtk_widget_destroy(gens_menu_bar);
		gens_menu_clear();
	}
	
	if (!vdraw_get_fullscreen() && Settings.showMenuBar)
	{
		// Create a menu bar.
		gens_menu_bar = gtk_menu_bar_new();
		gtk_widget_show(gens_menu_bar);
		gtk_box_pack_start(GTK_BOX(gens_vbox_main), gens_menu_bar, FALSE, FALSE, 0);
	}
	else
	{
		// Create a popup menu.
		gens_menu_bar = gtk_menu_new();
	}
	
	// Connect the menu "deactivate" signal.
	// For whatever reason, GtkMenuShell has a "deactivate" signal,
	// but not an "activate" signal.
	g_signal_connect((gpointer)gens_menu_bar, "deactivate",
			 G_CALLBACK(gens_menu_deactivate), NULL);
	
	// Accelerator Group.
	static GtkAccelGroup *gens_menu_accel_group = NULL;
	if (gens_menu_accel_group != NULL)
	{
		// Delete the accelerator group.
		gtk_window_remove_accel_group(GTK_WINDOW(gens_window), gens_menu_accel_group);
		g_object_unref(gens_menu_accel_group);
	}
	
	// Create an accelerator group.
	gens_menu_accel_group = gtk_accel_group_new();
	
	// Parse the menus.
	gens_menu_parse(&gmiMain[0], GTK_MENU_SHELL(gens_menu_bar), gens_menu_accel_group);
	
	// Add the accel group.
	gtk_window_add_accel_group(GTK_WINDOW(gens_window), gens_menu_accel_group);
	
	// Synchronize the menus.
	Sync_Gens_Window();
	
#ifdef GDK_WINDOWING_QUARTZ
	// Set the menu bar as the MacOS X menu bar.
	if (!vdraw_get_fullscreen() && Settings.showMenuBar)
		ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(gens_menu_bar));
#endif
}
Example #3
0
/**
 * create_gens_window_menubar(): Create the menu bar.
 */
void gens_window_create_menubar(void)
{
	if (gens_menu_bar != NULL)
	{
		// Menu bar already exists. Delete it.
		gtk_widget_destroy(gens_menu_bar);
		gens_menu_clear();
	}
	
	if (!vdraw_get_fullscreen() && Settings.showMenuBar)
	{
		// Create a menu bar.
		gens_menu_bar = gtk_menu_bar_new();
		gtk_widget_show(gens_menu_bar);
		gtk_box_pack_start(GTK_BOX(gens_vbox_main), gens_menu_bar, FALSE, FALSE, 0);
	}
	else
	{
		// Create a popup menu.
		gens_menu_bar = gtk_menu_new();
	}
	
	// Accelerator Group.
	static GtkAccelGroup *gens_menu_accel_group = NULL;
	if (gens_menu_accel_group != NULL)
	{
		// Delete the accelerator group.
		gtk_window_remove_accel_group(GTK_WINDOW(gens_window), gens_menu_accel_group);
		g_object_unref(gens_menu_accel_group);
	}
	
	// Create an accelerator group.
	gens_menu_accel_group = gtk_accel_group_new();
	
	// Parse the menus.
	gens_menu_parse(&gmiMain[0], gens_menu_bar, gens_menu_accel_group);
	
	// Add the accel group.
	gtk_window_add_accel_group(GTK_WINDOW(gens_window), gens_menu_accel_group);
	
	// Synchronize the menus.
	Sync_Gens_Window();
	
#ifdef GDK_WINDOWING_QUARTZ
	// Set the menu bar as the MacOS X menu bar.
	if (!vdraw_get_fullscreen() && Settings.showMenuBar)
		ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(gens_menu_bar));
#endif
}
Example #4
0
/**
 * gens_window_create_menubar(): Create the menu bar.
 */
void gens_window_create_menubar(void)
{
	if (MainMenu)
	{
		// Menu bar already exists. Delete it.
		DestroyMenu(MainMenu);
		gens_menu_clear();
	}
	
	DestroyMenu(MainMenu);
	
	// Create the main menu.
	if (!vdraw_get_fullscreen() && Settings.showMenuBar)
	{
		// Create a menu bar.
		MainMenu = CreateMenu();
	}
	else
	{
		// Create a popup menu.
		MainMenu = CreatePopupMenu();
	}
	
	// Parse the menus.
	gens_menu_parse(&gmiMain[0], MainMenu);
	
	// Synchronize the menus.
	Sync_Gens_Window();
	
	// Set the menu bar.
	if (!vdraw_get_fullscreen() && Settings.showMenuBar)
		SetMenu(gens_window, MainMenu);
	else
		SetMenu(gens_window, NULL);
	
	if (!vdraw_get_fullscreen())
	{
		// Resize the window after the menu bar is rebuilt.
		if (vdraw_scale <= 0)
			return;
		const int w = 320 * vdraw_scale;
		const int h = 240 * vdraw_scale;
		gsft_win32_set_actual_window_size(gens_window, w, h);
	}
}
/**
 * SelCD_Save(): Save the settings.
 * @return 1 if settings were saved; 0 on error.
 */
int SelCD_Save(void)
{
	// Save settings.
	int tmpDrive;
	bool restartCD = false;
	
	// CD-ROM drive
	tmpDrive = ComboBox_GetCurSel(SelCD_cdromDropdownBox);
	
	// Check if the drive ID was changed.
	if (tmpDrive == cdromDeviceID)
	{
		// Drive ID wasn't changed. Don't do anything.
		return 1;
	}
	
	// Drive ID was changed.
	// This will cause a reset of the ASPI subsystem.
	if (SegaCD_Started && (CD_Load_System == CDROM_))
	{
		// ASPI is currently in use. Ask the user if they want to restart emulation.
		GensUI::MsgBox_Response response;
		response = GensUI::msgBox(
			"The CD-ROM drive is currently in use.\n"
			"Chanigng the CD-ROM drive will force the emulator to reset.\n"
			"Are you sure you want to do this?",
			"CD-ROM Drive in Use",
			GensUI::MSGBOX_ICON_WARNING | GensUI::MSGBOX_BUTTONS_YES_NO,
			select_cdrom_window);
		
		if (response == GensUI::MSGBOX_RESPONSE_NO)
		{
			// Don't change anything.
			return 0;
		}
		
		// Stop SegaCD emulation.
		// TODO: Don't allow this if Netplay is enabled.
		restartCD = true;
		ROM::freeROM(Game);
	}
	
	// Stop ASPI.
	ASPI_End();
	
	cdromDeviceID = tmpDrive;
	
	// TODO: Drive speed (maybe)
	
	// Restart ASPI.
	ASPI_Init();
	
	if (restartCD)
	{
		// Restart SegaCD emulation.
		SegaCD_Started = Init_SegaCD(NULL);
		Sync_Gens_Window();
	}
	
	// Settings saved.
	return 1;
}
Example #6
0
/**
 * vdraw_ddraw_init(): Initialize the DirectDraw video subsystem.
 * @return 0 on success; non-zero on error.
 */
int vdraw_ddraw_init(void)
{
	DDSURFACEDESC2 ddsd;
	
	vdraw_ddraw_end();
	
	mdp_render_t *rendMode = get_mdp_render_t();
	const int scale = rendMode->scale;
	
	// Determine the window size using the scaling factor.
	if (scale <= 0)
		return -1;
	const int w = 320 * scale;
	const int h = 240 * scale;
	
	if (vdraw_get_fullscreen())
	{
		Res_X = w;
		Res_Y = h;
	}
	
	// Return value.
	int rval;
	
	// Initialize DirectDraw.
	// TODO: Initialize DirectDraw on the monitor with most of Gens/GS onscreen.
	LPDIRECTDRAW lpDD_Init;
	rval = DirectDrawCreate(NULL, &lpDD_Init, NULL);
	if (FAILED(rval))
	{
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"DirectDrawCreate() failed: 0x%08X", rval);
		return -2;
	}
	
	rval = lpDD_Init->QueryInterface(IID_IDirectDraw7, (LPVOID*)&lpDD);
	if (FAILED(rval))
	{
		if (lpDD_Init)
			lpDD_Init->Release();
		
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"lpDD_Init->QueryInterface(IID_IDirectDraw4) failed: 0x%08X", rval);
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"This can usually be fixed by upgrading DirectX.");
		return -3;
	}
	
	// Free the DirectDraw initialization object.
	lpDD_Init->Release();
	
	// Set the cooperative level.
	vdraw_ddraw_set_cooperative_level();
	
	// TODO: 15-bit color override. ("Force 555" or "Force 565" in the config file.)
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	// TODO: Figure out what FS_No_Res_Change is for.
	// TODO: Figure out if this is correct.
	if (vdraw_get_fullscreen() /* && !FS_No_Res_Change*/)
	{
		// Use the color depth setting.
		// NOTE: "15-bit" color requires 16-bit to be specified.
		rval = lpDD->SetDisplayMode(Res_X, Res_Y, (bppOut == 15 ? 16 : bppOut), 0, 0);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->SetDisplayMode() failed: 0x%08X", rval);
			
			// If render mode is set to Normal, try using Double instead.
			if (rendMode_FS == RenderMgr::begin() && rendMode_FS != RenderMgr::end())
			{
				LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
					"Renderer is set to Normal; attempting to use Double instead.");
				rendMode_FS++;
				vdraw_set_renderer(rendMode_FS);
				vdraw_text_write("Normal rendering failed. Using Double.", 1500);
				Sync_Gens_Window_GraphicsMenu();
			}
			
			return -4;
		}
	}
	
#if 0
	// Check the current color depth.
	unsigned char newBpp;
	lpDD->GetDisplayMode(&ddsd);
	switch (ddsd.ddpfPixelFormat.dwGBitMask)
	{
		case 0x03E0:
			// 15-bit color.
			newBpp = 15;
			break;
		case 0x07E0:
			// 16-bit color.
			newBpp = 16;
			break;
		case 0x00FF00:
		default:
			// 32-bit color.
			newBpp = 32;
			break;
	}
	
	if (newBpp != bppOut)
		vdraw_set_bpp(newBpp, false);
#endif
	
	// Clear ddsd.
	memset(&ddsd, 0x00, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	if (vdraw_get_fullscreen() && Video.VSync_FS)
	{
		ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
		ddsd.dwBackBufferCount = 2;
	}
	else
	{
		ddsd.dwFlags = DDSD_CAPS;
		ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	}
	
	// Create the primary surface.
	rval = lpDD->CreateSurface(&ddsd, &lpDDS_Primary, NULL);
	if (FAILED(rval))
	{
		vdraw_ddraw_free_all(false);
		LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
			"lpDD->CreateSurface(&lpDDS_Primary) failed: 0x%08X", rval);
		return -5;
	}
	
	if (vdraw_get_fullscreen())
	{
		if (Video.VSync_FS)
		{
			ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
			
			rval = lpDDS_Primary->GetAttachedSurface(&ddsd.ddsCaps, &lpDDS_Flip);
			if (FAILED(rval))
			{
				vdraw_ddraw_free_all(false);
				LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
					"lpDDS_Primary->GetAttachSurface() failed: 0x%08X", rval);
				return -6;
			}
			
			lpDDS_Blit = lpDDS_Flip;
		}
		else
		{
			lpDDS_Blit = lpDDS_Primary;
		}
	}
	else
	{
		rval = lpDD->CreateClipper(0, &lpDDC_Clipper, NULL);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->CreateClipper() failed: 0x%08X", rval);
			return -7;
		}
		
		rval = lpDDC_Clipper->SetHWnd(0, gens_window);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDC_Clipper->SetHWnd() failed: 0x%08X", rval);
			return -8;
		}
		
		rval = lpDDS_Primary->SetClipper(lpDDC_Clipper);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDC_Primary->SetClipper() failed: 0x%08X", rval);
			return -9;
		}
	}
	
	// Clear ddsd again.
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
	
	// Determine the width and height.
	// NOTE: For DirectDraw, the actual 336 width is used.
	if (vdraw_ddraw_is_hw_render())
	{
		// Normal render mode. 320x240 [336x240]
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
		ddsd.dwWidth = 336;
		ddsd.dwHeight = 240;
	}
	else
	{
		// Larger than 1x.
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
		ddsd.dwWidth = w;
		ddsd.dwHeight = h;
	}
	
	// Set the pixel format.
	ddsd.dwFlags |= DDSD_PIXELFORMAT;
	ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
	ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
	ddsd.ddpfPixelFormat.dwFourCC = 0; // RGB
	ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0;
	
	// Bits per component.
	switch (bppOut)
	{
		case 15:
			// 15-bit color. (555)
			ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
			ddsd.ddpfPixelFormat.dwRBitMask = 0x7C00;
			ddsd.ddpfPixelFormat.dwGBitMask = 0x03E0;
			ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
			break;
		
		case 16:
			// 16-bit color. (555)
			ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
			ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;
			ddsd.ddpfPixelFormat.dwGBitMask = 0x07E0;
			ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
			break;
		
		case 32:
		default:
			// 32-bit color.
			ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
			ddsd.ddpfPixelFormat.dwRBitMask = 0xFF0000;
			ddsd.ddpfPixelFormat.dwGBitMask = 0x00FF00;
			ddsd.ddpfPixelFormat.dwBBitMask = 0x0000FF;
			break;
	}
	
	// Create the back surface.
	rval = lpDD->CreateSurface(&ddsd, &lpDDS_Back, NULL);
	if (FAILED(rval))
	{
		// Failed to create the back surface.
		// If we attempted to create it in video memory, try system memory instead.
		if (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
		{
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->CreateSurface(&lpDDS_Back, DDSCAPS_VIDEOMEMORY) failed: 0x%08X", rval);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"Attempting to use DDSCAPS_SYSTEMMEMORY instead.");
			ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
			ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
			rval = lpDD->CreateSurface(&ddsd, &lpDDS_Back, NULL);
			if (FAILED(rval))
			{
				// Failed to create the back surface in system memory.
				vdraw_ddraw_free_all(false);
				LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
					"lpDD->CreateSurface(&lpDDS_Back, DDSCAPS_SYSTEMMEMORY) failed: 0x%08X", rval);
				return -10;
			}
		}
		else
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDD->CreateSurface(&lpDDS_Back, DDSCAPS_SYSTEMMEMORY) failed: 0x%08X", rval);
			return -11;
		}
	}
	
	// TODO: Check if this is right.
	// I think this might be causing the frame counter flicker in full screen mode.
	//if (!vdraw_get_fullscreen() || (rendMode >= 1 && (/*FS_No_Res_Change ||*/ Res_X != 640 || Res_Y != 480)))
	if (!vdraw_get_fullscreen() || !vdraw_ddraw_is_hw_render())
		lpDDS_Blit = lpDDS_Back;
	
	if (vdraw_ddraw_is_hw_render())
	{
		// Normal rendering mode uses MD_Screen directly.
		memset(&ddsd, 0, sizeof(ddsd));
		ddsd.dwSize = sizeof(ddsd);
		
		// TODO: This causes issues if the selected color depth isn't the
		// same as the desktop color depth. This only affects windowed mode,
		// since in fullscreen, the desktop color depth is changed.
		rval = lpDDS_Back->GetSurfaceDesc(&ddsd);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDS_Back->GetSurfaceDesc() failed: 0x%08X", rval);
			return -12;
		}
		
		ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE | DDSD_PIXELFORMAT;
		ddsd.dwWidth = 336;
		ddsd.dwHeight = 240;
		
		if (ddsd.ddpfPixelFormat.dwRGBBitCount > 16)
		{
			// 32-bit color.
			ddsd.lpSurface = MD_Screen.u32;
			ddsd.lPitch = 336 * 4;
		}
		else
		{
			// 15-bit or 16-bit color.
			ddsd.lpSurface = MD_Screen.u16;
			ddsd.lPitch = 336 * 2;
		}
		
		rval = lpDDS_Back->SetSurfaceDesc(&ddsd, 0);
		if (FAILED(rval))
		{
			vdraw_ddraw_free_all(false);
			LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
				"lpDDS_Back->SetSurfaceDesc() failed: 0x%08X", rval);
			return -13;
		}
	}
	
	// Initialize the destination rectangle.
	vdraw_ddraw_adjust_RectDest();
	
	// Reset the render mode.
	vdraw_reset_renderer(false);
	
	// Synchronize menus.
	Sync_Gens_Window();
	
	// vdraw_ddraw initialized.
	return 0;
}