/*    RPGへの道>コマンドダイアログ   1999/10/30 宍戸 輝光 */ #include #include #include #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MesProc (HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK CmdProc (HWND, UINT, WPARAM, LPARAM); void getKey(void); void scrollUp(void); void scrollRight(void); void scrollDown(void); void scrollLeft(void); void drawScreen(void); void drawChr(void); void drawMes(void); int getCmd(void); HWND hwMain,hwMes,hwCmd; LPBYTE lpBScreen,lpScreen,lpBG,lpChr,lpMChip[4]; LPTSTR lpMes; LPBITMAPINFO lpIScreen; RGBQUAD pal[256]; BYTE map[128][128]; HINSTANCE hInst; RECT recScreen={8,8,496,496}; HBITMAP hScreen; HDC hdcWin,hdcMem; HFONT hFMes,hCmd; int iCmd; struct { DWORD x,y; } game; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; int i,j; hInst=hInstance; 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,640,560, NULL,NULL,hInstance,NULL); lpScreen=GlobalAlloc(GPTR,sizeof(BITMAPINFO)+sizeof(RGBQUAD)*255); lpBG=GlobalAlloc(GPTR,512*480); lpChr=GlobalAlloc(GPTR,32*32); for (i=0;i<4;i++) { /* マップパーツ作成 */ lpMChip[i]=GlobalAlloc(GPTR,32*32); FillMemory(lpMChip[i],32*32,i); } pal[0].rgbRed=0; pal[0].rgbGreen=64; pal[0].rgbBlue=240; pal[1].rgbRed=48; pal[1].rgbGreen=240; pal[1].rgbBlue=32; pal[2].rgbRed=64; pal[2].rgbGreen=192; pal[2].rgbBlue=32; pal[3].rgbRed=224; pal[3].rgbGreen=240; pal[3].rgbBlue=200; pal[4].rgbRed=224; pal[4].rgbGreen=64; pal[4].rgbBlue=128; /* バックバッファ用DIBSectionヘッダ */ lpIScreen=(LPBITMAPINFO)lpScreen; lpIScreen->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpIScreen->bmiHeader.biWidth=480; lpIScreen->bmiHeader.biHeight=480; lpIScreen->bmiHeader.biPlanes=1; lpIScreen->bmiHeader.biBitCount=8; lpIScreen->bmiHeader.biCompression=BI_RGB; CopyMemory(lpIScreen->bmiColors,pal,sizeof(RGBQUAD)*256); hdcWin=GetDC(hwMain); /* DIB とウインドウのDC からDIBSection を作成 */ hScreen=CreateDIBSection(hdcWin,lpIScreen,DIB_RGB_COLORS,&lpBScreen,NULL,0); hdcMem=CreateCompatibleDC(hdcWin); /* メモリDC を作成 */ SelectObject(hdcMem,hScreen); /* メモリDC にDIBSection を選択 */ ReleaseDC(hwMain,hdcWin); /* 不要になったウインドウのDC を解放 */ for (i=0;i<128;i++) for (j=0;j<128;j++) map[j][i]=0; for (i=8;i<120;i++) for (j=8;j<120;j++) map[j][i]=(BYTE)(rand() % 3+1); game.x=64; game.y=64; for (i=1;i<10;i++) { FillMemory(lpChr+(i*2)*32+4,24,1); FillMemory(lpChr+(i*2+1)*32+4,24,5); } for (i=22;i<30;i++) FillMemory(lpChr+8+i*32,16,4); drawScreen(); drawChr(); hFMes=CreateFont((int)20,0,0,0,FW_NORMAL, /* メッセージ用フォント */ FALSE,FALSE,FALSE,SHIFTJIS_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE,NULL); hCmd=CreateFont((int)24,0,0,0,FW_NORMAL, /* メッセージ用フォント */ FALSE,FALSE,FALSE,SHIFTJIS_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE,NULL); lpMes=GlobalAlloc(GPTR,256); ShowWindow (hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwMain); while (1) { /* メインループ */ if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) /* メッセージ処理 */ return msg.wParam ; TranslateMessage(&msg); DispatchMessage(&msg); } else { getKey(); } Sleep(1); } } void getKey(void) { if (GetFocus()!=hwMain) /* 入力フォーカスがなければリターン */ return; if (GetAsyncKeyState(VK_UP)<0 && map[game.x][game.y-1]!=0) { scrollUp(); } if (GetAsyncKeyState(VK_RIGHT)<0 && map[game.x+1][game.y]!=0) { scrollRight(); } if (GetAsyncKeyState(VK_DOWN)<0 && map[game.x][game.y+1]!=0) { scrollDown(); } if (GetAsyncKeyState(VK_LEFT)<0 && map[game.x-1][game.y]!=0) { scrollLeft(); } if (GetAsyncKeyState(VK_RETURN)<0) { switch(getCmd()) { case 0: lpMes="攻撃を選択"; break; case 1: lpMes="回復を選択"; break; case 2: lpMes="道具を選択"; break; case 3: lpMes="逃走を選択"; break; } drawMes(); } Sleep(1); } void scrollUp() { /* 上スクロール */ int i,j,k; DWORD dwTime; for (i=0;i<16;i++) /* スクロールバッファにパーツ描画 */ for (j=0;j<15;j++) for (k=0;k<32;k++) CopyMemory(lpBG+j*32+(511-(i*32+k))*480, lpMChip[map[game.x-7+j][game.y-8+i]]+k*32,32); dwTime=timeGetTime(); for (i=1;i<16;i++) { /* スクロール表示 */ /* スクロールバッファをバックバッファにコピー */ CopyMemory(lpBScreen,lpBG+(i*2)*480,480*480); drawChr(); /* キャラクタ描画 */ while (i>1 && timeGetTime()dwTime) Sleep(1); dwTime=timeGetTime(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } game.y--; /* 座標更新 */ CopyMemory(lpBScreen,lpBG+32*480,480*480); drawChr(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } void scrollRight() { /* 右スクロール */ int i,j,k; DWORD dwTime; for (i=0;i<15;i++) for (j=0;j<16;j++) for (k=0;k<32;k++) CopyMemory(lpBG+j*32+(i*32+k)*512, lpMChip[map[game.x-7+j][game.y-7+i]]+k*32,32); dwTime=timeGetTime(); for (i=1;i<16;i++) { for (j=0;j<480;j++) CopyMemory(lpBScreen+(479-j)*480,lpBG+(i*2)+j*512,480); drawChr(); while (i>1 && timeGetTime()dwTime) Sleep(1); dwTime=timeGetTime(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } game.x++; for (i=0;i<480;i++) CopyMemory(lpBScreen+(479-i)*480,lpBG+32+i*512,480); drawChr(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } void scrollDown() { /* 下スクロール */ int i,j,k; DWORD dwTime; for (i=0;i<16;i++) for (j=0;j<15;j++) for (k=0;k<32;k++) CopyMemory(lpBG+j*32+(511-(i*32+k))*480, lpMChip[map[game.x-7+j][game.y-7+i]]+k*32,32); dwTime=timeGetTime(); for (i=15;i>=1;i--) { CopyMemory(lpBScreen,lpBG+(i*2)*480,480*480); drawChr(); while (i<15 && timeGetTime()dwTime) Sleep(1); dwTime=timeGetTime(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } game.y++; CopyMemory(lpBScreen,lpBG,480*480); drawChr(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } void scrollLeft() { /* 左スクロール */ int i,j,k; DWORD dwTime; for (i=0;i<15;i++) for (j=0;j<16;j++) for (k=0;k<32;k++) CopyMemory(lpBG+j*32+(i*32+k)*512, lpMChip[map[game.x-8+j][game.y-7+i]]+k*32,32); dwTime=timeGetTime(); for (i=15;i>=1;i--) { for (j=0;j<480;j++) CopyMemory(lpBScreen+(479-j)*480,lpBG+(i*2+1)+j*512,480); drawChr(); while (i<15 && timeGetTime()dwTime) Sleep(1); dwTime=timeGetTime(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } game.x--; for (j=0;i<480;i++) CopyMemory(lpBScreen+(479-i)*480,lpBG+i*512,480); drawChr(); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ } void drawScreen() { int i,j,k; for (i=0;i<15;i++) for (j=0;j<15;j++) for (k=0;k<32;k++) CopyMemory(lpBScreen+j*32+(479-(i*32+k))*480, lpMChip[map[game.x-7+j][game.y-7+i]]+k*32,32); } void drawChr() { /* キャラクタをスプライト描画 */ int i,j; for (i=0;i<32;i++) for (j=0;j<32;j++) if (lpChr[j+i*32]!=0) /* 抜き色判定 */ lpBScreen[224+j+(224+i)*480]=lpChr[j+i*32]; } void drawMes(void) { /* メッセージを出す */ MSG msg; ShowWindow(hwMes,SW_SHOW); /* メッセージウインドウ表示 */ InvalidateRect(hwMain,NULL,FALSE); UpdateWindow (hwMain); /* 再描画 */ Sleep(10); while(GetAsyncKeyState(VK_RETURN)<0); do { /* リターンキー入力を待つ */ if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) /* メッセージ処理 */ ExitProcess(msg.wParam); TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(1); } while(!(GetFocus()==hwMain && GetAsyncKeyState(VK_RETURN)<0)); ShowWindow(hwMes,SW_HIDE); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ while(GetAsyncKeyState(VK_RETURN)<0); } int getCmd(void) { /* コマンド選択 */ MSG msg; iCmd=0; /* コマンド0を選択状態に */ ShowWindow(hwCmd,SW_SHOW); /* コマンドダイアログ表示 */ InvalidateRect(hwCmd,NULL,FALSE); UpdateWindow (hwCmd); /* 再描画 */ Sleep(10); while(GetAsyncKeyState(VK_RETURN)<0); do { /* リターンキー入力を待つ */ if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) /* メッセージ処理 */ ExitProcess(msg.wParam); TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(1); if (GetFocus()==hwMain && GetAsyncKeyState(VK_UP)<0 && iCmd>0) { iCmd--; /* 選択コマンド変更 */ InvalidateRect(hwCmd,NULL,FALSE); UpdateWindow (hwCmd); /* 再描画 */ Sleep(150); } else if (GetFocus()==hwMain && GetAsyncKeyState(VK_DOWN)<0 && iCmd<3) { iCmd++; /* 選択コマンド変更 */ InvalidateRect(hwCmd,NULL,FALSE); UpdateWindow (hwCmd); /* 再描画 */ Sleep(150); } } while(!(GetFocus()==hwMain && GetAsyncKeyState(VK_RETURN)<0)); ShowWindow(hwCmd,SW_HIDE); InvalidateRect(hwMain,&recScreen,FALSE); UpdateWindow (hwMain); /* 再描画 */ while(GetAsyncKeyState(VK_RETURN)<0); return iCmd; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int i; WNDCLASSEX wndclass ; switch (iMsg) { case WM_CREATE: /* メッセージウインドウ作成 */ wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = MesProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInst; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "MesWin"; wndclass.hIconSm = NULL; RegisterClassEx(&wndclass); wndclass.lpfnWndProc=CmdProc; wndclass.lpszClassName="CmdWin"; RegisterClassEx(&wndclass); hwMes=CreateWindow("MesWin",hwMain,WS_CHILD|WS_VISIBLE, 48+8,272+8,384,192,hwnd,(HMENU)0,hInst,NULL); hwCmd=CreateWindow("CmdWin",hwMain,WS_CHILD|WS_VISIBLE, 500,340,128,148,hwnd,(HMENU)0,hInst,NULL); ShowWindow(hwMes,SW_HIDE); ShowWindow(hwCmd,SW_HIDE); case WM_PAINT: hdc=BeginPaint(hwnd,&ps); BitBlt(hdc,8,8,480,480,hdcMem,0,0,SRCCOPY); EndPaint(hwnd,&ps); break; case WM_DESTROY : /* 終了処理 */ DeleteDC(hdcMem); /* デバイスコンテキスト開放 */ DeleteObject(hScreen); /* ビットマップ開放 */ DeleteObject(hFMes); DeleteObject(hCmd); GlobalFree(lpScreen); GlobalFree(lpBG); GlobalFree(lpChr); for (i=0;i<4;i++) GlobalFree(lpMChip[i]); PostQuitMessage(0); break; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } LRESULT CALLBACK MesProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rec1={0,0,384,192},rec2={2,2,382,190},rec3={10,10,374,182}; switch (iMsg) { case WM_PAINT: /* メッセージウインドウ描画 */ hdc=BeginPaint(hwnd,&ps); FillRect(hdc,&rec1,GetStockObject(WHITE_BRUSH)); FillRect(hdc,&rec2,GetStockObject(BLACK_BRUSH)); SetTextColor(hdc,0x00ffffff); SetBkMode(hdc,TRANSPARENT); DrawText(hdc,lpMes,-1,&rec3,DT_EDITCONTROL|DT_WORDBREAK); EndPaint(hwnd,&ps); } return DefWindowProc(hwnd, iMsg, wParam, lParam) ; } LRESULT CALLBACK CmdProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rec3; LPCTSTR lpszCmd[4]={"攻 撃","回 復","道 具","逃 走"}; int i; switch (iMsg) { case WM_PAINT: /* メッセージウインドウ描画 */ hdc=BeginPaint(hwnd,&ps); SelectObject(hdc,GetStockObject(BLACK_BRUSH)); SelectObject(hdc,GetStockObject(WHITE_PEN)); /* 枠を描画 */ Rectangle(hdc,0,0,127,147); Rectangle(hdc,1,1,126,146); SelectObject(hdc,hCmd); SetBkMode(hdc,TRANSPARENT); for (i=0;i<4;i++) { /* コマンドの表示領域 */ rec3.top=2+i*36; rec3.left=2; rec3.bottom=38+i*36; rec3.right=126; if (iCmd==i) { /* 選択コマンドを強調 */ /* 背景を塗りつぶす */ FillRect(hdc,&rec3,GetStockObject(GRAY_BRUSH)); /* コマンドの描画色設定 */ SetTextColor(hdc,0x0000ffff); } else { /* 背景を塗りつぶす */ FillRect(hdc,&rec3,GetStockObject(BLACK_BRUSH)); /* コマンドの描画色設定 */ SetTextColor(hdc,0x00ffffff); } /* コマンド文字列描画 */ DrawText(hdc,lpszCmd[i],-1,&rec3,DT_CENTER|DT_SINGLELINE|DT_VCENTER); } EndPaint(hwnd,&ps); } return DefWindowProc(hwnd, iMsg, wParam, lParam) ; }