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

📄 main.c

📁 DC的SEGA_GG模拟器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		Frame		  = 0;
		LastTickCount = 0;

		if (UseDirectDraw && RegistryInfo.EnableDirectDraw && FullScreenMode()) FlipToGDISurface(FALSE);
		break;

	case WM_PAINT:
		if (UseDirectDraw && RegistryInfo.EnableDirectDraw)
		{
			PAINTSTRUCT			PaintStruct;

			BeginPaint(hwnd, &PaintStruct);
			EndPaint(hwnd, &PaintStruct);

			UpdateTexture();
			DrawTexture();
			FlipScreens();
		}
		else
		{
			HDC					hDC;
			HDRAWDIB			hDrawDib;
			PAINTSTRUCT			PaintStruct;
			int					Scale = RegistryInfo.ScreenScale;

			BeginPaint(hwnd, &PaintStruct);
			EndPaint(hwnd, &PaintStruct);

			hDC = GetDC(hwnd);
			hDrawDib = DrawDibOpen();
			if (cart.type == TYPE_GG)
			{
				DrawDibBegin(hDrawDib, hDC, Bmp.BitmapInfoHeader.biWidth - 96, Bmp.BitmapInfoHeader.biHeight - 48, &Bmp.BitmapInfoHeader, 
							 Bmp.BitmapInfoHeader.biWidth, Bmp.BitmapInfoHeader.biHeight, DDF_BACKGROUNDPAL);
				DrawDibDraw(hDrawDib, hDC, 0, 0, (Bmp.BitmapInfoHeader.biWidth - 96) * Scale, (Bmp.BitmapInfoHeader.biHeight - 48) * Scale,
							&Bmp.BitmapInfoHeader, &BitmapData[0], 48, 24, Bmp.BitmapInfoHeader.biWidth - 96, Bmp.BitmapInfoHeader.biHeight - 48, DDF_BACKGROUNDPAL);
			}
			else
			{
				DrawDibBegin(hDrawDib, hDC, Bmp.BitmapInfoHeader.biWidth, Bmp.BitmapInfoHeader.biHeight, &Bmp.BitmapInfoHeader, 
							 Bmp.BitmapInfoHeader.biWidth, Bmp.BitmapInfoHeader.biHeight, DDF_BACKGROUNDPAL);
				DrawDibDraw(hDrawDib, hDC, 0, 0, Bmp.BitmapInfoHeader.biWidth * Scale, Bmp.BitmapInfoHeader.biHeight * Scale,
							&Bmp.BitmapInfoHeader, &BitmapData[0], 0, 0, Bmp.BitmapInfoHeader.biWidth, Bmp.BitmapInfoHeader.biHeight, DDF_BACKGROUNDPAL);
			}
			DrawDibEnd(hDrawDib);
			DrawDibClose(hDrawDib);
			ReleaseDC(hwnd, hDC);
		}
		break;

	case WM_CLOSE:
		DeleteObject(hBitmap);
		DestroyWindow(hwnd);
		break;

	case WM_DESTROY:
	    SaveSRAM();
        PostQuitMessage(0);
		break;

	default:
		if (msg == USER_MESSAGE)
		{
		    SaveSRAM();
			OpenROM((char *)lParam);
			SendMessage(hwnd, WM_ACTIVATE, WA_CLICKACTIVE, (long)hwnd);
			SendMessage(hwnd, WM_NCACTIVATE, TRUE, 0);
			break;
		}
		else
		{
			return DefWindowProc(hwnd, msg, wParam, lParam);
		}
	}

	return FALSE;
}

void AdjustWindowSize(void)
{
	if (!FullScreenMode())
	{
		RECT		Rect;

		GetConsoleScreenRect(&Rect);

		Rect.right  = (Rect.right - Rect.left) * RegistryInfo.ScreenScale;
		Rect.bottom = (Rect.bottom - Rect.top) * RegistryInfo.ScreenScale;
		Rect.top	= 0;
		Rect.left	= 0;

		AdjustWindowRect(&Rect, GetWindowLong(hwnd, GWL_STYLE), GetMenu(hwnd)? TRUE : FALSE);
		SetWindowPos(hwnd, NULL, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
	}

	if (UseDirectDraw && RegistryInfo.EnableDirectDraw) UpdateModeWindowCoords(hwnd);
}

void InitVRAM(void)
{
     /* Initialize display bitmap */
    memset(&bitmap, 0, sizeof(t_bitmap));
    bitmap.width  = 256;
    bitmap.height = 192;
    bitmap.depth  = 8;
    bitmap.pitch  = (bitmap.width * (bitmap.depth >> 3));
    bitmap.data   = (unsigned char *)&BitmapData[0];
}

void UpdatePalette(void)
{
    unsigned char	r, g, b;
    int				index;

    if (bitmap.pal.update == 0) return;

    for (index = 0; index < 32; index++)
    {
        if(bitmap.pal.color[index])
        {
			if (UseDirectDraw && RegistryInfo.EnableDirectDraw)
			{
	            b = bitmap.pal.color[index][0];
				g = bitmap.pal.color[index][1];
				r = bitmap.pal.color[index][2];
			}
			else
			{
	            r = bitmap.pal.color[index][0];
				g = bitmap.pal.color[index][1];
				b = bitmap.pal.color[index][2];
			}

			r = (unsigned char)(255.0f * pow((float)r / 255.0f, 1.0f / RegistryInfo.Gamma) + 0.5f);
			g = (unsigned char)(255.0f * pow((float)g / 255.0f, 1.0f / RegistryInfo.Gamma) + 0.5f);
			b = (unsigned char)(255.0f * pow((float)b / 255.0f, 1.0f / RegistryInfo.Gamma) + 0.5f);

			pixel[index] = MAKE_PIXEL(b, g, r);

			Bmp.Palette[0x00 | index].rgbRed	  = r;
			Bmp.Palette[0x00 | index].rgbGreen	  = g;
			Bmp.Palette[0x00 | index].rgbBlue	  = b;
			Bmp.Palette[0x20 | index].rgbRed	  = r;
			Bmp.Palette[0x20 | index].rgbGreen	  = g;
			Bmp.Palette[0x20 | index].rgbBlue	  = b;
			Bmp.Palette[0x40 | index].rgbRed	  = r;
			Bmp.Palette[0x40 | index].rgbGreen	  = g;
			Bmp.Palette[0x40 | index].rgbBlue	  = b;
        }
    }

    bitmap.pal.update = 0;
    memset(bitmap.pal.dirty, 0, 32);
}

void OpenROM(char *pROM)
{
	HANDLE			FileHandle;
	char			Filename[MAX_PATH] = "";
	int				FileSize;
	int				BytesRead;
	int				i;

	if (RecordingSound)
	{
		CloseSoundRecording();
		RecordSound    = FALSE;
		RecordingSound = FALSE;
		CheckMenuItem(hMenu, ID_MENU_CONFIG_SOUND_RECORD, MF_UNCHECKED);
	}
	
	if (pROM)
	{
		strcpy(Filename, pROM);
	}
	else
	{
		// Initialise the file dialog
		InitFileDialog(hwnd, RegistryInfo.ROMPath, "Roms (*.gg, *.sms, *.zip)\0*.gg;*.sms;*.zip\0All Files (*.*)\0*.*\0", 0); 

		// Show the dialog, and return if it is cancelled
		if (!GetLoadFileFromDialog(hwnd, "Open", Filename)) return;
	}

	if (!stricmp(&Filename[strlen(Filename) - 3], "zip"))
	{
		if (!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ZIP), hwnd, LoadZipProc, (long)Filename)) return;
		if (!LoadSelectedFileFromZip(Filename)) return;
	}
	else
	{
		FileHandle = CreateFile(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

		if (FileHandle == INVALID_HANDLE_VALUE) return;
		
		FileSize = GetFileSize(FileHandle, NULL);

		if (FileSize < 0x8000) 
		{
			CloseHandle(FileHandle);
			return;
		}

		if ((FileSize / 512) & 1)
		{
			SetFilePointer(FileHandle, 512, 0, FILE_CURRENT);
			FileSize -= 512;
		}

		if (!stricmp(&Filename[strlen(Filename) - 2], "gg"))
		{
			cart.type  = TYPE_GG;
		}
		else
		{
			cart.type  = TYPE_SMS;
		}

		cart.pages = (FileSize / 0x4000);
    
		if (cart.rom) free(cart.rom);
		cart.rom = malloc(FileSize);
    
		if (!cart.rom)
		{
			CloseHandle(FileHandle);
			return;
		}

		ReadFile(FileHandle, cart.rom, FileSize, &BytesRead, NULL); 

		CloseHandle(FileHandle);
	}

	system_init(RegistryInfo.SoundFrequency, RegistryInfo.UpdateFrequency);
	system_reset();
    sms.country  = RegistryInfo.Region;
    sms.use_fm   = RegistryInfo.EnableFMSound;
	snd.callback = UpdateSoundRecording;

	for (i = strlen(Filename) - 1 ; i >= 0 ; i--)
	{
		if (Filename[i] == '\\' || Filename[i] == '/') 
		{
			break;
		}
	}

    strcpy(GameName, &Filename[i + 1]);
    strcpy(strrchr(GameName, '.'), "");
    LoadSRAM();

	SetWindowText(hwnd, GameName);

	AdjustWindowSize();
	RunEmulation = TRUE;

	if (RecordSound) 
	{
		CreateSoundRecording();
		RecordingSound = TRUE;
	}
}

char *GetGameName(void)
{
	return GameName;
}

char *GetBitmapInfoHeader(void)
{
	return (char *)&Bmp;
}

char *GetBitmapData(void)
{
	return BitmapData;
}

void LoadSRAM(void)
{
	HANDLE		FileHandle;
	int			BytesRead;
	char		Filename[MAX_PATH];

	wsprintf(Filename, "%s%s.sav", RegistryInfo.SRAMPath, GameName);

    FileHandle = CreateFile(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if (FileHandle == INVALID_HANDLE_VALUE) return;

    ReadFile(FileHandle, sms.sram, 0x8000, &BytesRead, NULL); 

	CloseHandle(FileHandle);

	sms.save = 1;
}

void SaveSRAM(void)
{
    HANDLE		FileHandle;
    int			BytesWritten;
	char		Filename[MAX_PATH];

	wsprintf(Filename, "%s%s.sav", RegistryInfo.SRAMPath, GameName);

	if (sms.save && strlen(GameName))
	{
	    FileHandle = CreateFile(Filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	    if (FileHandle == INVALID_HANDLE_VALUE) return;

	    WriteFile(FileHandle, sms.sram, 0x8000, &BytesWritten, NULL); 

	    CloseHandle (FileHandle);
	}
}

LRESULT CALLBACK ConfigureControlsProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_INITDIALOG:
		{
			int			i;

			CenterWindowInParent(hwnd);

			PopulateJoystickCombo(hwnd, PLAYER_1);
			PopulateJoystickCombo(hwnd, PLAYER_2);
			PopulateConfigureControls(hwnd);

			CheckDlgButton(hwnd, IDC_P1_BUTTON1_RAPIDFIRE_CHECK, RegistryInfo.RapidFire[PLAYER_1][PAD_BUTTON1 - PAD_BUTTON1]? BST_CHECKED : BST_UNCHECKED);
			CheckDlgButton(hwnd, IDC_P1_BUTTON2_RAPIDFIRE_CHECK, RegistryInfo.RapidFire[PLAYER_1][PAD_BUTTON2 - PAD_BUTTON1]? BST_CHECKED : BST_UNCHECKED);
			CheckDlgButton(hwnd, IDC_P2_BUTTON1_RAPIDFIRE_CHECK, RegistryInfo.RapidFire[PLAYER_2][PAD_BUTTON1 - PAD_BUTTON1]? BST_CHECKED : BST_UNCHECKED);
			CheckDlgButton(hwnd, IDC_P2_BUTTON2_RAPIDFIRE_CHECK, RegistryInfo.RapidFire[PLAYER_2][PAD_BUTTON2 - PAD_BUTTON1]? BST_CHECKED : BST_UNCHECKED);

			CheckDlgButton(hwnd, IDC_P1_DISABLE_KEYS_CHECK, RegistryInfo.DisableKeys[PLAYER_1]? BST_CHECKED : BST_UNCHECKED);
			CheckDlgButton(hwnd, IDC_P2_DISABLE_KEYS_CHECK, RegistryInfo.DisableKeys[PLAYER_2]? BST_CHECKED : BST_UNCHECKED);

			EnableWindow(GetDlgItem(hwnd, IDC_P1_DISABLE_KEYS_CHECK), GetSelectedJoystick(PLAYER_1)? TRUE : FALSE);
			EnableWindow(GetDlgItem(hwnd, IDC_P2_DISABLE_KEYS_CHECK), GetSelectedJoystick(PLAYER_2)? TRUE : FALSE);

			for (i = 0 ; i < MAX_PLAYERS ; i++)
			{
				HWND		hCombo = (i == PLAYER_1)? GetDlgItem(hwnd, IDC_P1_RAPIDFIRE_COMBO) : GetDlgItem(hwnd, IDC_P2_RAPIDFIRE_COMBO);
				int			j;

				SendMessage(hCombo, CB_RESETCONTENT, 0, 0);
				
				for (j = 2 ; j <= 10 ; j++)
				{
					char	String[32];
					char	PostFix[4];

					if (j == 2) strcpy(PostFix, "nd");
					else if (j == 3) strcpy(PostFix, "rd");
					else strcpy(PostFix, "th");

					wsprintf(String, "Every %d%s frame", j, PostFix);
					SendMessage(hCombo, CB_ADDSTRING, 0, (long)String);
				}

				SendMessage(hCombo, CB_SETCURSEL, RegistryInfo.RapidFireRate[i] - 2, 0);
			}

			ShowWindow(hwnd, SW_SHOW);
		}
		break;

	case WM_COMMAND:
		{
			switch (HIWORD(wParam))
			{
			case BN_CLICKED:
				switch (LOWORD (wParam))
				{
				case IDC_P1_LEFT_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_LEFT, IDC_P1_LEFT, "'Player 1 Left'");
					break;

				case IDC_P1_RIGHT_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_RIGHT, IDC_P1_RIGHT, "'Player 1 Right'");
					break;

				case IDC_P1_UP_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_UP, IDC_P1_UP, "'Player 1 Up'");
					break;

				case IDC_P1_DOWN_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_DOWN, IDC_P1_DOWN, "'Player 1 Down'");
					break;

				case IDC_P1_BUTTON1_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_BUTTON1, IDC_P1_BUTTON1, "'Player 1 Button 1'");
					break;

				case IDC_P1_BUTTON2_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_BUTTON2, IDC_P1_BUTTON2, "'Player 1 Button 2'");
					break;

				case IDC_P1_START_BUTTON:
					ConfigureButton(hwnd, PLAYER_1, PAD_START, IDC_P1_START, "'Player 1 Start / Pause'");
					break;

				case IDC_P2_LEFT_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_LEFT, IDC_P2_LEFT, "'Player 2 Left'");
					break;

				case IDC_P2_RIGHT_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_RIGHT, IDC_P2_RIGHT, "'Player 2 Right'");
					break;

				case IDC_P2_UP_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_UP, IDC_P2_UP, "'Player 2 Up'");
					break;

				case IDC_P2_DOWN_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_DOWN, IDC_P2_DOWN, "'Player 2 Down'");
					break;

				case IDC_P2_BUTTON1_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_BUTTON1, IDC_P2_BUTTON1, "'Player 2 Button 1'");
					break;

				case IDC_P2_BUTTON2_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_BUTTON2, IDC_P2_BUTTON2, "'Player 2 Button 2'");
					break;

				case IDC_P2_START_BUTTON:
					ConfigureButton(hwnd, PLAYER_2, PAD_START, IDC_P2_START, "'Player 2 Start / Pause'");
					break;

				case IDC_P1_BUTTON1_RAPIDFIRE_CHECK:
					RegistryInfo.RapidFire[PLAYER_1][PAD_BUTTON1 - PAD_BUTTON1] ^= 1;
					break;

				case IDC_P1_BUTTON2_RAPIDFIRE_CHECK:

⌨️ 快捷键说明

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