/* DIBSectionによる4方向スクロールテスト 1999/ 6/14 宍戸 輝光 */ #include #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); void Loop(void); int scroll(void); LPBYTE lpBuf,lpScreen,lpParts[4]; LPBITMAPINFO lpScDIB,lpChDIB; RGBQUAD RGBs[256]; HDC hdcWin,hdcScMem,hdcPtMem[4]; HWND hwMain; HBITMAP hScBMP,hPtBMP[4]; BYTE map[64][64]; DWORD dwTime; RECT rec={8,8,488,488}; int iX=16,iY=8,iDx,iDy,iDdx,iDdy,iScd=2; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; int i,j,k; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = NULL; RegisterClassEx (&wndclass); hwMain=CreateWindow ("CWindow",NULL, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,560, NULL,NULL,hInstance,NULL); lpScDIB=(LPBITMAPINFO)GlobalAlloc /* DIBヘッダ用メモリ確保 */ (GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)); lpChDIB=(LPBITMAPINFO)GlobalAlloc (GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)); lpScDIB->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpScDIB->bmiHeader.biWidth=544; lpScDIB->bmiHeader.biHeight=544; lpScDIB->bmiHeader.biPlanes=1; lpScDIB->bmiHeader.biBitCount=8; lpScDIB->bmiHeader.biCompression=BI_RGB; lpChDIB->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpChDIB->bmiHeader.biWidth=32; lpChDIB->bmiHeader.biHeight=32; lpChDIB->bmiHeader.biPlanes=1; lpChDIB->bmiHeader.biBitCount=8; lpChDIB->bmiHeader.biCompression=BI_RGB; for (i=0;i<6;i++) /* カラーテーブル作成 */ for (j=0;j<6;j++) for (k=0;k<6;k++) { RGBs[i*36+j*6+k].rgbRed=i*51; RGBs[i*36+j*6+k].rgbGreen=j*51; RGBs[i*36+j*6+k].rgbBlue=k*51; } /* 作成したカラーテーブルをビットマップのカラーテーブルに設定 */ CopyMemory(lpScDIB->bmiColors,RGBs,256*sizeof(RGBQUAD)); CopyMemory(lpChDIB->bmiColors,RGBs,256*sizeof(RGBQUAD)); /* DIB とウインドウのDC からDIBSection を作成 */ hScBMP=CreateDIBSection (GetDC(hwMain),lpScDIB,DIB_RGB_COLORS,(void **)&lpScreen,NULL,0); hdcScMem=CreateCompatibleDC(GetDC(hwMain)); /* メモリDC を作成 */ SelectObject(hdcScMem,hScBMP); /* メモリDC にビットマップを選択 */ for (i=0;i<4;i++) { /* マップパーツ用ビットマップ作成 */ hPtBMP[i]=CreateDIBSection(GetDC(hwMain),lpChDIB,DIB_RGB_COLORS, (void **)&lpParts[i],NULL,0); hdcPtMem[i]=CreateCompatibleDC(GetDC(hwMain)); /* メモリDC を作成 */ SelectObject(hdcPtMem[i],hPtBMP[i]); /* メモリDC にビットマップを選択 */ } FillMemory(lpParts[0],32*32,5); for (i=0;i<48;i++) *(lpParts[0]+rand() % 1024)=173; FillMemory(lpParts[1],32*32,61); for (i=0;i<48;i++) *(lpParts[1]+rand() % 1024)=84; FillMemory(lpParts[2],32*32,172); for (i=0;i<32;i++) *(lpParts[2]+rand() % 1024)=215; FillMemory(lpParts[3],32*32,180); for (i=0;i<32;i++) *(lpParts[3]+rand() % 1024)=182; for (i=0;i<64;i++) /* マップ作成 */ for (j=0;j<64;j++) map[j][i]=rand() % 4; iX=32; iY=32; iDx=32; iDy=32; for (i=0;i<17;i++) for (j=0;j<17;j++) BitBlt(hdcScMem,j*32,i*32,32,32, hdcPtMem[map[iX-8+j][iY-8+i]],0,0,SRCCOPY); ShowWindow (hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwMain); dwTime=GetTickCount(); while (1) { /* メインループ */ if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) /* メッセージ処理 */ return msg.wParam ; TranslateMessage(&msg); DispatchMessage(&msg); } else Loop(); /* 描画処理 */ } } void Loop(void) { DWORD i; if (GetTickCount()>dwTime+20) dwTime=GetTickCount(); else /* 前回の処理から20ms 以上経ってなければ戻る */ return; iDx=32; iDy=32; iDdx=0; iDdy=0; /* カーソルキーで移動 */ if (GetAsyncKeyState(VK_UP)<0 && iY>8) { for (i=1;i<16;i++) BitBlt(hdcScMem,i*32,0,32,32,hdcPtMem[map[i+iX-8][iY-8]] ,0,0,SRCCOPY); iY--; /* 主人公の位置更新 */ iDdx=0; /* スクロール方向設定 */ iDdy=-iScd; scroll(); } else if (GetAsyncKeyState(VK_RIGHT)<0 && iX<55) { for (i=1;i<16;i++) BitBlt(hdcScMem,512,i*32,32,32,hdcPtMem[map[iX+8][iY+i-8]] ,0,0,SRCCOPY); iX++; iDdx=iScd; iDdy=0; scroll(); } else if (GetAsyncKeyState(VK_DOWN)<0 && iY<56) { for (i=1;i<16;i++) BitBlt(hdcScMem,i*32,512,32,32,hdcPtMem[map[iX+i-8][iY+8]] ,0,0,SRCCOPY); iY++; iDdx=0; iDdy=iScd; scroll(); } else if (GetAsyncKeyState(VK_LEFT)<0 && iX>8) { for (i=1;i<16;i++) BitBlt(hdcScMem,0,i*32,32,32,hdcPtMem[map[iX-8][iY+i-8]] ,0,0,SRCCOPY); iX--; iDdx=-iScd; iDdy=0; scroll(); } } int scroll(void) { /* スクロール処理 */ int iLeft,iTop; MSG msg; while(iDx!=iScd && iDy!=iScd && iDx!=64-iScd && iDy!=64-iScd) { if (GetTickCount()>dwTime+1) { dwTime=GetTickCount(); /* 表示開始位置をずらしてスクロール */ iDx+=iDdx; iDy+=iDdy; /* ウインドウを再描画 */ InvalidateRect(hwMain,&rec,FALSE); if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) /* メッセージ処理 */ return msg.wParam ; TranslateMessage(&msg); DispatchMessage(&msg); } } } /* 表示中マップの中央とスクロール用ビットマップの中央を合わせる */ if (iDdy<0) { /* 上スクロール時 */ iLeft=32; iTop=0; } else if (iDdx>0) { /* 右スクロール時 */ iLeft=64; iTop=32; } else if (iDdy>0) { /* 下スクロール時 */ iLeft=32; iTop=64; } else if (iDdx<0) { /* 左スクロール時 */ iLeft=0; iTop=32; } /* 表示中マップをスクロール用ビットマップ中央に描きなおす */ BitBlt(hdcScMem,32,32,480,480,hdcScMem,iLeft,iTop,SRCCOPY); iDx=32; iDy=32; InvalidateRect(hwMain,&rec,FALSE); } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int i; switch (iMsg) { case WM_PAINT: hdc=BeginPaint(hwnd,&ps); /* マップビットマップを描画 */ BitBlt(hdc,8,8,480,480,hdcScMem,iDx,iDy,SRCCOPY); break; case WM_DESTROY : /* 終了処理 */ DeleteDC(hdcScMem); DeleteObject(hScBMP); for (i=0;i<4;i++) { DeleteDC(hdcPtMem[i]); DeleteObject(hPtBMP[i]); } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }