⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modes.c

📁 DC的SEGA_GG模拟器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define  INITGUID

#include <windows.h>
#include "shared.h"
#include "ddraw.h"
#include "d3d.h"
#include "dinput.h"
#include "main.h"
#include "input.h"
#include "registry.h"
#include "modes.h"

static LPDIRECTDRAW7						pDirectDraw		= NULL;
static LPDIRECTDRAWSURFACE7					pFrontSurface	= NULL;
static LPDIRECTDRAWSURFACE7					pBackSurface	= NULL;
static LPDIRECT3D7							pDirect3D		= NULL;
static LPDIRECT3DDEVICE7					p3DDevice		= NULL;
static LPDIRECTDRAWSURFACE7					pSystemTexture  = NULL;
static LPDIRECTDRAWSURFACE7					pVRAMTexture	= NULL;
static LPDIRECTDRAWPALETTE					pPalette		= NULL;
static LPDIRECTDRAWCLIPPER					pClipper		= NULL;
static MODE									Mode[MAX_MODES];
static int									NoOfModes;
static int									CurrentMode		= -1;
static BOOL									ModeIsFullScreen = FALSE;
static RECT									ViewportRect;
static RECT									ScreenRect;
static D3DTLVERTEX							Vertex[4];
static D3DTLVERTEX							ScanLine[2];
static BOOL									UseGDISurface = FALSE;
static HMODULE								hModule		  = NULL;

BOOL InitModes(void)
{
	int				i;
	int				Devices = 0;
	HRESULT		    (WINAPI *pDirectDrawCreateEx)(GUID FAR *, LPVOID *, REFIID, IUnknown FAR *);

	ModeIsFullScreen = FALSE;

	hModule = LoadLibrary("ddraw.dll");

	if (!hModule) 
	{
		FreeLibrary(hModule);
		hModule = NULL;
	
		return FALSE;
	}

	pDirectDrawCreateEx = (void *)GetProcAddress(hModule, "DirectDrawCreateEx");

	if (!pDirectDrawCreateEx) return FALSE;

	if (pDirectDrawCreateEx(NULL, &pDirectDraw, &IID_IDirectDraw7, NULL) != DD_OK) return FALSE;

	memset(Mode, 0, sizeof(MODE) * MAX_MODES);
	NoOfModes = 0;
	IDirectDraw7_EnumDisplayModes(pDirectDraw, DDEDM_REFRESHRATES, NULL, NULL, EnumModes);

	if (IDirectDraw7_QueryInterface(pDirectDraw, &IID_IDirect3D7, &pDirect3D) != DD_OK)
	{
		TidyModes();

		return FALSE;
	}

	memset(&Vertex, 0, sizeof(D3DTLVERTEX) * 4);
	memset(&ScanLine, 0, sizeof(D3DTLVERTEX) * 2);
	
	for (i = 0 ; i < 4 ; i++)
	{
		Vertex[i].rhw   = 1;
		Vertex[i].color	= 0xFFFFFFFF;
	}
	
	return TRUE;
}

HRESULT WINAPI EnumModes(LPDDSURFACEDESC2 pDesc, LPVOID pContext)
{
	if (pDesc->ddpfPixelFormat.dwRGBBitCount != 8 && pDesc->ddpfPixelFormat.dwRGBBitCount != 24)
	{
		Mode[NoOfModes].Width		= pDesc->dwWidth;
		Mode[NoOfModes].Height		= pDesc->dwHeight;
		Mode[NoOfModes].BitDepth	= pDesc->ddpfPixelFormat.dwRGBBitCount;

		NoOfModes++;

		if (NoOfModes == MAX_MODES) return DDENUMRET_CANCEL;
	}

	return DDENUMRET_OK;
}

void TidyModes(void)
{
	RestoreMode(GetSMShwnd());

	if (pDirect3D)
	{
		IDirect3D7_Release(pDirect3D);
		pDirect3D = NULL;
	}

	if (pDirectDraw) 
	{
		IDirectDraw7_Release(pDirectDraw);
		pDirectDraw = NULL;
	}

	if (hModule)
	{
		FreeLibrary(hModule);
		hModule = NULL;
	}
}

BOOL ChangeMode(int ModeIndex, BOOL FullScreen)
{
	HWND			hwnd = GetSMShwnd();
	DDSURFACEDESC2	Surface;
	DDSCAPS2		SurfaceCaps;

	RestoreMode(hwnd);

	memset(&Surface, 0, sizeof(DDSURFACEDESC2));
	Surface.dwSize = sizeof(DDSURFACEDESC2);

	if (FullScreen)
	{
		if (IDirectDraw7_SetCooperativeLevel(pDirectDraw, hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) != DD_OK) return FALSE;

		if (IDirectDraw7_SetDisplayMode(pDirectDraw, Mode[ModeIndex].Width, Mode[ModeIndex].Height, Mode[ModeIndex].BitDepth, 0, 0) != DD_OK)
		{
			RestoreMode(hwnd);

			return FALSE;
		}
	
		Surface.dwFlags			  = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		Surface.ddsCaps.dwCaps	  = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
		Surface.dwBackBufferCount = 1;

		if (IDirectDraw7_CreateSurface(pDirectDraw, &Surface, &pFrontSurface, NULL) != DD_OK)
		{
			RestoreMode(hwnd);

			return FALSE;
		}

		memset(&SurfaceCaps, 0, sizeof(DDSCAPS2));
        SurfaceCaps.dwCaps = DDSCAPS_BACKBUFFER;

		if (IDirectDrawSurface7_GetAttachedSurface(pFrontSurface, &SurfaceCaps, &pBackSurface) != DD_OK)
		{
			RestoreMode(hwnd);

			return FALSE;
		}

		while (ShowCursor(FALSE) >= 0);
	}
	else
	{
		RECT					Rect;
		int						Width;
		int						Height;
		
		if (IDirectDraw7_SetCooperativeLevel(pDirectDraw, hwnd, DDSCL_NORMAL) != DD_OK) return FALSE;

        Surface.dwFlags			  = DDSD_CAPS;
        Surface.ddsCaps.dwCaps	  = DDSCAPS_PRIMARYSURFACE;

		if (IDirectDraw7_CreateSurface(pDirectDraw, &Surface, &pFrontSurface, NULL) != DD_OK)
		{
			return FALSE;
		}

		if (IDirectDraw7_CreateClipper(pDirectDraw, 0, &pClipper, NULL) != DD_OK)
		{
			RestoreMode(hwnd);

			return FALSE;
		}

		IDirectDrawClipper_SetHWnd(pClipper, 0, hwnd);
		IDirectDrawSurface7_SetClipper(pFrontSurface, pClipper);

		GetConsoleScreenRect(&Rect);
		Width  = (Rect.right - Rect.left) * RegistryInfo.ScreenScale;
		Height = (Rect.bottom - Rect.top) * RegistryInfo.ScreenScale;

		Surface.dwFlags			= DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
		Surface.dwWidth			= Width;
		Surface.dwHeight		= Height;
		Surface.ddsCaps.dwCaps	= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;

		if (IDirectDraw7_CreateSurface(pDirectDraw, &Surface, &pBackSurface, NULL) != DD_OK)
		{
			RestoreMode(hwnd);

			return FALSE;
		}
	}

	ModeIsFullScreen = FullScreen;
	CurrentMode		 = ModeIndex;
	RegistryInfo.FullScreenMode = CurrentMode;

	if (!CreateTexture())
	{
		RestoreMode(hwnd);
		
		return FALSE;
	}

	if (IDirect3D7_CreateDevice(pDirect3D, &IID_IDirect3DHALDevice, pBackSurface, &p3DDevice) != D3D_OK)
	{
		RestoreMode(hwnd);

		return FALSE;
	}

	UpdateModeWindowCoords(hwnd);

	SetModeSmoothing(RegistryInfo.ScreenSmoothing);
	
	return TRUE;
}

void RestoreMode(HWND hwnd)
{
	while (ShowCursor(TRUE) < 0);

	DestroyTexture();
	
	if (p3DDevice)
	{
		IDirect3DDevice7_Release(p3DDevice);
		p3DDevice = NULL;
	}

	if (pBackSurface) 
	{
		IDirectDrawSurface7_Release(pBackSurface);
		pBackSurface = NULL;
	}

	if (pFrontSurface)
	{
		if (pClipper)
		{
			IDirectDrawSurface7_SetClipper(pFrontSurface, NULL);
			IDirectDrawClipper_Release(pClipper);
			pClipper = NULL;
		}

		IDirectDrawSurface7_Release(pFrontSurface);
		pFrontSurface = NULL;
	}

	if (ModeIsFullScreen)
	{
		IDirectDraw7_RestoreDisplayMode(pDirectDraw);
		IDirectDraw7_SetCooperativeLevel(pDirectDraw, GetSMShwnd(), DDSCL_NORMAL);
	}

	ModeIsFullScreen = FALSE;
}

void FlipScreens(void)
{
	if (UseGDISurface && ModeIsFullScreen) 
	{
		IDirectDrawSurface7_Blt(pFrontSurface, NULL, pBackSurface, NULL, DDBLT_WAIT, NULL);
	
		return;
	}
	
	while (1)
	{
		HRESULT		Result;

		if (ModeIsFullScreen)
		{
			Result = IDirectDrawSurface7_Flip(pFrontSurface, NULL, 0);
		}
		else
		{
			Result = IDirectDrawSurface7_Blt(pFrontSurface, &ScreenRect, pBackSurface, &ViewportRect, DDBLTFAST_WAIT, NULL);
		}

		if (Result == DD_OK) break;

		if (Result == DDERR_SURFACELOST)
		{
			Result = IDirectDrawSurface7_Restore(pFrontSurface);

			if (Result != DD_OK) break;
		}

		if (Result != DDERR_WASSTILLDRAWING) break;
	}
}

void UpdateModeWindowCoords(HWND hwnd)
{
	RECT			Rect;
	float			Top;
	float			Left;
	float			Right;
	float			Bottom;

	GetConsoleScreenRect(&Rect);

	if (ModeIsFullScreen)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -