www.gusucode.com > VC++游戏圣剑英雄传2双刃剑源程序+开发文档-源码程序 > VC++游戏圣剑英雄传2双刃剑源程序+开发文档-源码程序\code\source\GAMELIB\Gp_init.cpp
//Download by http://www.NewXing.com //******************************************** // 程序初始化相关处理函数 // softboy 创建于2000年1月25日 //******************************************** #include <stdlib.h> #include <crtdbg.h> #include <time.h> #include "..\resource.h" #include "gp_init.h" #include "gp_iniset.h" #include "gp_draw.h" #include "gp_input.h" #include "gp_sound.h" #include "gp_music.h" #include "gp_other.h" #define GameTitle "圣剑英雄传II" extern WORD *GraphBuffer; // 绘图缓冲区 extern WORD RMask, GMask, BMask; //16位色颜色遮罩 extern BYTE RMove, GMove; //移动到最右边的位数 extern DWORD rgbMask; //扩展为32位后的遮罩 HWND hWnd; //主窗口句柄 HINSTANCE hInst; //应用程序实例 BOOL bActive = TRUE; //应用程序是否活跃 BOOL g_bDebug = FALSE; //作弊模式 int RunGame=1; //0=退出 int WindowMode=1; //0=全屏 other=窗口 BOOL bSwitch = TRUE; //能否切换显示模式 //****************************************************************** //创建主窗口。 HWND InitWindow( HINSTANCE hInstance, int nCmdShow ) { HWND hwnd; WNDCLASS wc; //填充窗口类结构 wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WinProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON_Heroland) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL;//MAKEINTRESOURCE(IDR_MENU_Window); wc.lpszClassName = GameTitle; //注册窗口类 RegisterClass( &wc ); if( WindowMode == 0 ) { //创建主窗口-(全屏) hwnd = CreateWindowEx( WS_EX_TOPMOST, GameTitle, GameTitle, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); } else //创建主窗口-(窗口) { RectWindow.left=0; RectWindow.top=0; RectWindow.right=ScreenWidth; RectWindow.bottom=ScreenHeight; AdjustWindowRect(&RectWindow, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, false); g_pointClient.x = 0 - RectWindow.left; g_pointClient.y = 0 - RectWindow.top; int w = RectWindow.right-RectWindow.left; int h = RectWindow.bottom-RectWindow.top; hwnd = CreateWindowEx( 0, GameTitle, GameTitle, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, w, h, NULL, NULL, hInstance, NULL ); if( WindowMode != 0 ) //窗口 { int W=GetSystemMetrics(SM_CXSCREEN); int H=GetSystemMetrics(SM_CYSCREEN); int x1=(W-w)/2; int y1=(H-h)/2; SetWindowPos(hwnd, HWND_NOTOPMOST, x1, y1, w, h, SWP_SHOWWINDOW ); } } if( !hwnd ) return FALSE; //显示并更新窗口 ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); return hwnd; } //***************************************************** //释放系统的DirectDraw对象 HRESULT FreeDDraw() { if (lpDD != NULL) { //恢复协作级 lpDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); _RELEASE( lpDDSBack ); _RELEASE(lpDDSPrimary ); } return DD_OK; } //模式切换------------------------------------------------------------------------- HRESULT ChangeCoopLevel(HWND hWnd ) { HRESULT hRet; //释放DDraw if (FAILED(hRet = FreeDDraw())) { ShowMessage("ReleaseAllObjects FAILED"); return false; } if( WindowMode == 0 ) { SetWindowLong(hWnd, GWL_STYLE, WS_POPUP); } //获得窗口显示区域 if ( WindowMode != 0 ) { SetWindowLong(hWnd, GWL_STYLE,WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX); RectWindow.left=0; RectWindow.top=0; RectWindow.right=ScreenWidth; RectWindow.bottom=ScreenHeight; AdjustWindowRect(&RectWindow, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, false); g_pointClient.x = 0 - RectWindow.left; g_pointClient.y = 0 - RectWindow.top; int w = RectWindow.right-RectWindow.left; int h = RectWindow.bottom-RectWindow.top; int W=GetSystemMetrics(SM_CXSCREEN); int H=GetSystemMetrics(SM_CYSCREEN); int x1=(W-w)/2; int y1=(H-h)/2; SetWindowPos(hWnd, HWND_NOTOPMOST, x1, y1, w, h, SWP_SHOWWINDOW ); } //初始化DDraw hRet = InitDDraw(); return hRet; } //******************************************************************* //创建一个GDI裁减器 BOOL CreateClipper() { LPDIRECTDRAWCLIPPER lpClipper; HRESULT ddrval; //创建一个剪裁器对象 ddrval = lpDD->CreateClipper(0, &lpClipper, NULL); if ( ddrval != DD_OK) { ShowMessage("CreateClipper FAILED"); return FALSE; } //设置窗口句柄 ddrval = lpClipper->SetHWnd(0, hWnd); if ( ddrval != DD_OK) { ShowMessage("SetHWnd FAILED"); return FALSE; } //关联主页面,注意这个函数会增加引用计数 ddrval = lpDDSPrimary->SetClipper(lpClipper); if ( ddrval != DD_OK) { ShowMessage("SetClipper FAILED"); return FALSE; } //理所当然要减少引用计数 _RELEASE( lpClipper ); return TRUE; } //****************************************************************** //初始化DirectDraw环境 BOOL InitDDraw(void) { DWORD dwFlags; DDSURFACEDESC ddsd; HRESULT ddrval; if( WindowMode==0 ) //全屏 { //设置协作级别为全屏模式 dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT; //DDSCL_ALLOWMODEX | lpDD->SetCooperativeLevel(hWnd, dwFlags); //设置显示模式 lpDD->SetDisplayMode( ScreenWidth, ScreenHeight, ScreenColor); // 创建主页面 ZeroMemory( &ddsd, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ); if( ddrval != DD_OK ) { return false; } //创建一个后台表面 CreateBitmap(lpDDSBack, ScreenWidth, ScreenHeight); // 测试像素格式是555还是565 DDPIXELFORMAT DDPixelFormat; ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat)); DDPixelFormat.dwSize = sizeof(DDPixelFormat); if (lpDDSPrimary->GetPixelFormat(&DDPixelFormat) != DD_OK) return 1; RMask=(WORD)DDPixelFormat.dwRBitMask; GMask=(WORD)DDPixelFormat.dwGBitMask; BMask=(WORD)DDPixelFormat.dwBBitMask; //扩展为32位 00000gggggg00000rrrrr000000bbbbb rgbMask=((DWORD)GMask<<16)|RMask|BMask; //0x07e0 = 00000|11111|00000b 五位的绿色 if (GMask == 0x07e0 ) Is555 = 0; if( Is555 ) { ColorKey16=0x00007c1f; //00000|11111|00000|11111b (255,0,255) RMove=10; //R要向右10位 GMove=5; //G要向右5位 } else { ColorKey16=0x0000f81f; //0000|11111|000000|11111b (255,0,255) RMove=11; //R要向右11位 GMove=6; //注意这儿了,为什么是6呢?因为在进行灰度运算的时候, } //一个6位和两个五位运算会超出5位,所以……呵呵,soft //在这儿一句注释都没有,把我可想苦了:)这下改明白了吧 ShowWindow(hWnd, SW_SHOWMAXIMIZED); } else //窗口 { //设置协作级别为窗口模式 dwFlags = DDSCL_NORMAL; lpDD->SetCooperativeLevel(hWnd, dwFlags); // 创建主页面 ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ); if( ddrval != DD_OK ) { return false; } //生成剪裁器 CreateClipper(); //生成背景页面 CreateBitmap(lpDDSBack, ScreenWidth, ScreenHeight); // 测试像素格式是555还是565 DDPIXELFORMAT DDPixelFormat; ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat)); DDPixelFormat.dwSize = sizeof(DDPixelFormat); if (lpDDSPrimary->GetPixelFormat(&DDPixelFormat) != DD_OK) return 1; RMask=(WORD)DDPixelFormat.dwRBitMask; GMask=(WORD)DDPixelFormat.dwGBitMask; BMask=(WORD)DDPixelFormat.dwBBitMask; //扩展为32位 00000gggggg00000rrrrr000000bbbbb //下面的部分,看上面的注释好了,我就不再写了 rgbMask=((DWORD)GMask<<16)|RMask|BMask; if (GMask == 0x07e0 ) Is555 = 0; if( Is555 ) { ColorKey16=0x00007c1f; RMove=10; GMove=5; } else { ColorKey16=0x0000f81f; RMove=11; GMove=6; } } return TRUE; } //******************************************************************* //应用程序入口 int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // 检测内存泄漏 //读入游戏启动配置文件-(读取窗口模式) CIniSet Ini("ini\\setup.ini"); WindowMode=Ini.ReadInt("Setup", "WindowMode"); int w=GetSystemMetrics(SM_CXSCREEN); int h=GetSystemMetrics(SM_CYSCREEN); HDC hdc=GetDC(hWnd); int color=GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(hWnd,hdc); if( WindowMode != 0 && WindowMode != 1 ) { if( IDYES==MessageBox(hWnd, "使用窗口显示模式吗?\n[Alt+Enter] 切换全屏或窗口显示." , "注意", MB_YESNO)) WindowMode=1; else WindowMode=0; bSwitch=true; } //如果不是16位色,或者屏幕小于800*600则定为全屏模式 if( color != 16 || w < 800 ) { if( color != 16 ) MessageBox(hWnd, "注意:当前Windows不是16位色,如果希望在窗口模式运行游戏\ ,请把桌面设置为16位色!","注意",MB_OK); else MessageBox(hWnd, "注意:当前Windows屏幕小于800*600,如果希望在窗口模式运行\ 游戏,请把桌面设置为800*600以上,否则只能在全屏模式下运行!","注意",MB_OK); bSwitch=false; WindowMode=0; } //初始化主窗口 hWnd=InitWindow( hInstance, nCmdShow ) ; if (hWnd == NULL ) return FALSE; hInst=hInstance; //初始化DirectDraw环境,并实现DirectDraw功能 DirectDrawCreate(NULL, &lpDD, NULL); //创建DirectDraw对象 if (!InitDDraw()) { MessageBox(hWnd, "初始化DirectDraw过程中出错!请检查你是否正确的安装\ 了DirectX。", "Error", MB_OK ); FreeDDraw(); return FALSE; } //初始化DirectInput if( !InitInput() ) { MessageBox(hWnd, "初始化DirectInput过程出错!请检查你是否\ ` 正确的安装了DirectX 5.0以上版本。", "Error", MB_OK ); FreeInput(); return FALSE; } //初始化DirectInput_Mouse if( !Mouse.InitInput_Mouse(hWnd) ) { MessageBox(hWnd, "初始化DirectInput Mouse出错!请检查你是否正确的安装\ 了DirectX 5.0以上版本。", "Error", MB_OK ); Mouse.FreeInput_Mouse(); return FALSE; } //初始化DirectInput_Key if( !Key.InitInput_Key(hWnd) ) { MessageBox(hWnd, "初始化DirectInput Keyboard出错!请检查你是否正确的安装\ 了DirectX 5.0以上版本。", "Error", MB_OK ); Key.FreeInput_Key(); return FALSE; } //初始化DirectInput_Joystick if( !g_Joystick.InitInput_Joystick(hWnd) ) { g_Joystick.FreeInput_Joystick(); return FALSE; } //初始化DirectInput_Sound if( Ini.ReadInt("Setup","游戏音效") && !CSound::InitDirectSound(hWnd) ) { CSound::EnableSound(false); CSound::ReleaseDirectSound(); } //初始化DirectMusic音乐 if( Ini.ReadInt("Setup","背景音乐") ) { CMusic::InitMusic(); } //初始化随机指数 srand( (unsigned)time( NULL ) ); SetCursor(NULL); //读取数据等初始化操作 if( !InitGame() ) { MessageBox(hWnd, "初始化游戏数据过程出错!请检查你的文件", "Error", MB_OK ); FreeDDraw(); return FALSE; } while( RunGame ) //程序主循环 { if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage(&msg, NULL, 0, 0)) return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else if(bActive) { MainLoop(); //进入游戏主循环 } else WaitMessage(); //等待消息 } ReleaseGame(); //释放数据 CSound::ReleaseDirectSound(); //释放DirectSound对象 g_Joystick.FreeInput_Joystick(); Key.FreeInput_Key(); Mouse.FreeInput_Mouse(); FreeInput(); FreeDDraw(); //释放所有DirectDraw对象 //如果显示模式改变则记录到配置文件 if( bSwitch && WindowMode != Ini.ReadInt("Setup", "WindowMode") ) { Ini.WriteInt("Setup", "WindowMode", WindowMode); Ini.Save(); } return 1; }