0001: // ----------------------------------------------------------------------------
0002: //
0003: // main.cpp - ウィンドウズメイン部分
0004: // 
0005: // Copyright (c) 2001 if (if@edokko.com)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: #define STRICT
0010: 
0011: #include <windows.h>
0012: #include <d3d8.h>
0013: #include <d3dx8.h>
0014: #include "main.h"
0015: #include "draw.h"
0016: 
0017: // ----------------------------------------------------------------------------
0018: // オブジェクト
0019: // ----------------------------------------------------------------------------
0020: static LPDIRECT3D8              s_lpD3D = NULL;
0021: static LPDIRECT3DDEVICE8        s_lpD3DDEV = NULL;
0022: static D3DPRESENT_PARAMETERS    s_d3dpp;
0023: 
0024: static bool                     s_end;      // 終了フラグ
0025: 
0026: // ----------------------------------------------------------------------------
0027: // プロトタイプ宣言
0028: // ----------------------------------------------------------------------------
0029: int PASCAL WinMain(HINSTANCE hInst,HINSTANCE hPrev,char *CmdLine,int CmdShow);
0030: LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
0031: HRESULT InitD3D( HWND hWnd );           // DirectX の初期化
0032: 
0033: // ----------------------------------------------------------------------------
0034: // 外部関数
0035: // ----------------------------------------------------------------------------
0036: 
0037: // ----------------------------------------------------------------------------
0038: // 関数
0039: // ----------------------------------------------------------------------------
0040: 
0041: #include <stdio.h>
0042: #include "font.h"
0043: static CMyFont sFont;
0044: // ----------------------------------------------------------------------------
0045: // Name: set_fps()
0046: // Desc: フレーム数の表示
0047: //-----------------------------------------------------------------------------
0048: static void fps_disp()
0049: {
0050:     static DWORD    last = timeGetTime();
0051:     static DWORD    frames = 0;
0052:     static char     buf[256] = "";
0053:     DWORD           current;
0054:     
0055:     current = timeGetTime();
0056:     frames++;
0057:     
0058:     if(500 <= current - last) {// 0.5秒後とに更新
0059:         float dt = (float)(current - last) / 1000.0f;
0060:         float fps = (float)frames / dt;
0061:         last = current;
0062:         frames = 0;
0063:         sprintf(buf, "%.02f fps", fps);
0064:     }
0065:     sFont.Print(buf, 0,0);
0066: }
0067: 
0068: 
0069: // ----------------------------------------------------------------------------
0070: // Name: WinMain()
0071: // Desc: Windows アプリケーションはここから始まる
0072: //-----------------------------------------------------------------------------
0073: int PASCAL WinMain(HINSTANCE hInst,HINSTANCE hPrev,char *CmdLine,int CmdShow)
0074: {
0075:     s_end = 0;
0076:     
0077:     // ウインドウの作成
0078:     RECT    rect;
0079:     SetRect(&rect, 0, 0, WIDTH, HEIGHT);
0080:     DWORD   style = (FULLSCREEN) ? WS_POPUP :(WS_CAPTION|WS_SYSMENU|WS_BORDER|WS_MINIMIZEBOX);
0081:     AdjustWindowRect(&rect, style, FALSE);  // ウィンドウスタイルを設定したときの、ウィンドウの大きさを調べる
0082:     int width  = rect.right - rect.left;
0083:     int height = rect.bottom - rect.top;    
0084:     
0085:     WNDCLASS wc;
0086:     ZeroMemory(&wc, sizeof(WNDCLASS));
0087:     wc.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
0088:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
0089:     wc.hInstance        = hInst;
0090:     wc.lpfnWndProc      = MsgProc;
0091:     wc.lpszClassName    = CAPTION;
0092:     if(RegisterClass(&wc) == 0) return 0; //ウィンドウ作成に使用できる新しいウィンドウクラスを作成する。
0093:     
0094:     HWND hWnd = CreateWindow(CAPTION        // 登録されているクラス名
0095:                             ,CAPTION        // ウィンドウ名
0096:                             ,style          // ウィンドウスタイル
0097:                             ,CW_USEDEFAULT  // ウィンドウの横方向の位置
0098:                             ,CW_USEDEFAULT  // ウィンドウの縦方向の位置
0099:                             ,width          // ウィンドウの幅
0100:                             ,height         // ウィンドウの高さ
0101:                             ,NULL           // 親ウィンドウまたはオーナーウィンドウのハンドル
0102:                             ,NULL           // メニューハンドルまたは子ウィンドウ ID
0103:                             ,hInst          // アプリケーションインスタンスのハンドル
0104:                             ,NULL           // ウィンドウ作成データ
0105:                             );
0106:     if(hWnd == NULL) return 0;
0107:     
0108:     // Direct3D の初期化
0109:     if(SUCCEEDED(InitD3D(hWnd))){
0110:         
0111:         sFont.Init(s_lpD3DDEV, 12, 24);
0112: 
0113:         if(FAILED(InitRender(s_lpD3DDEV))) s_end = true;
0114:         
0115:         ShowWindow(hWnd, SW_SHOW);
0116:         UpdateWindow(hWnd);
0117:     
0118:         // メインループ
0119:         MSG msg;
0120:         while (!s_end)
0121:         {
0122:             if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
0123:                 // メッセージの処理
0124:                 TranslateMessage(&msg);
0125:                 DispatchMessage(&msg);
0126:             }else{
0127:                 // Direct3D の描画
0128:                 // バックバッファと Z バッファをクリア
0129:                 s_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,32,32),1.0f,0);
0130:                 // シーン開始
0131:                 s_lpD3DDEV->BeginScene();
0132:                 
0133:                 // 描画などの処理
0134:                 Render(s_lpD3DDEV);
0135:                 fps_disp();         // fpsの描画
0136:                 
0137:                 // シーン終了
0138:                 s_lpD3DDEV->EndScene();
0139:                 if (FAILED(s_lpD3DDEV->Present(NULL,NULL,NULL,NULL)))
0140:                     s_lpD3DDEV->Reset(&s_d3dpp);// バックバッファをプライマリバッファにコピー
0141:             }
0142:         }
0143:     }
0144:     
0145:     // 終了
0146:     CleanRender(s_lpD3DDEV);
0147:     sFont.Clean();
0148:     RELEASE(s_lpD3DDEV);
0149:     RELEASE(s_lpD3D);
0150:     
0151:     return 0;
0152: }
0153: // ----------------------------------------------------------------------------
0154: // Name: MsgProc()
0155: // Desc: メインウインドウのイベントを処理する
0156: //-----------------------------------------------------------------------------
0157: LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
0158: {
0159:     switch (msg){
0160:     case WM_KEYDOWN:                // 何かキーが押された
0161:     case WM_CLOSE:                  // ×ボタンを押した
0162:         s_end = true;
0163:         return 1;
0164:         break;
0165:     default:
0166:         break;
0167:     }
0168:     return DefWindowProc(hWnd,msg,wParam,lParam);
0169: }
0170: //-----------------------------------------------------------------------------
0171: // Name: InitD3D()
0172: // Desc: Direct3D の初期化
0173: //-----------------------------------------------------------------------------
0174: HRESULT InitD3D( HWND hWnd )
0175: {
0176:     // Direct3D オブジェクトを作成
0177:     if (NULL == (s_lpD3D = Direct3DCreate8(D3D_SDK_VERSION))){
0178:         MessageBox(NULL,"Direct3D の作成に失敗しました。",CAPTION,MB_OK | MB_ICONSTOP);
0179:         return E_FAIL;
0180:     }
0181: 
0182:     // 現在の画面モードを取得
0183:     D3DDISPLAYMODE d3ddm;
0184:     if( FAILED( s_lpD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) ) return E_FAIL;
0185: 
0186:     // Direct3D 初期化パラメータの設定
0187:     ZeroMemory(&s_d3dpp, sizeof(D3DPRESENT_PARAMETERS));
0188: 
0189:     s_d3dpp.BackBufferCount = 1;
0190:     if (FULLSCREEN){
0191:         s_d3dpp.Windowed = FALSE;
0192:         s_d3dpp.BackBufferWidth = WIDTH;
0193:         s_d3dpp.BackBufferHeight = HEIGHT;
0194:     }else{
0195:         s_d3dpp.Windowed = TRUE;
0196:         s_d3dpp.BackBufferWidth = 0;
0197:         s_d3dpp.BackBufferHeight = 0;
0198:     }
0199:     // ウインドウ : 現在の画面モードを使用
0200:     s_d3dpp.BackBufferFormat = d3ddm.Format;
0201:     s_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
0202:     s_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
0203:     s_d3dpp.hDeviceWindow = hWnd;
0204:     // Z バッファの自動作成
0205:     s_d3dpp.EnableAutoDepthStencil = TRUE;
0206:     s_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
0207:  
0208:     D3DCAPS8 caps;
0209:     s_lpD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
0210:     if(caps.VertexShaderVersion < D3DVS_VERSION(1,0)){
0211:         //vertex shader 1.0 をhwサポートしない場合はD3DCREATE_SOFTWARE_VERTEXPROCESSINGする必要があります
0212:         if(FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0213:             if(FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,&s_d3dpp,&s_lpD3DDEV))){
0214:                 return FALSE;
0215:             }
0216:         }
0217:     }else{
0218:         // デバイスの作成 - T&L HAL
0219:         if (FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0220:             // 失敗したので HAL で試行
0221:             if (FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0222:                 // 失敗したので REF で試行
0223:                 if (FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0224:                     // 結局失敗した
0225:                     MessageBox(NULL,"Direct3D の初期化に失敗しました。",CAPTION,MB_OK | MB_ICONSTOP);
0226:                     return E_FAIL;
0227:                 }
0228:             }
0229:         }
0230:     }
0231:     return S_OK;
0232: }
0233: