// -------------------------------------------------------------------------
// 文件名 : 7_7.cpp
// 创建者 : 方煜宽
// 邮箱 : fangyukuan@gmail.com
// 创建时间 : 2010-12-18 17:04
// 功能描述 : 从一个表面向另一个表面复制位图
// 地址 : http://www.cnblogs.com/fangyukuan/archive/2011/06/08/2075907.html
// -------------------------------------------------------------------------
#define INITGUID
#include<windows.h>
#include <ddraw.h>
#pragma comment(lib, "ddraw.lib")
#pragma comment(lib, "Dxguid.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Gdi32.lib")
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND main_window_handle = NULL; // 全局的windows窗口句柄
int window_closed = 0; // 窗口关闭标志
LPDIRECTDRAW7 lpdd = NULL; // ddraw 接口指针
DDSURFACEDESC2 ddsd; // ddraw 显示表面 描述结构
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // ddraw 主显示表面
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // ddraw 从显示表面
#define SCREEN_WIDTH 640 // 屏幕宽
#define SCREEN_HEIGHT 480 // 屏幕高
#define SCREEN_BPP 16 // 深度
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
// this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct, 0, sizeof(ddstruct)); ddstruct.dwSize = sizeof(ddstruct);}
int InitGame()
{
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
return 0;
if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return 0;
if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
return 0;
DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // 增加DDSD_BACKBUFFERCOUNT 表明dwBackBufferCount有效
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // 多了| DDSCAPS_COMPLEX | DDSCAPS_FLIP
ddsd.dwBackBufferCount = 1; //
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
return 0;
// 请求一个后备缓冲
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
// 得到后备缓冲
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
return 0;
DDRAW_INIT_STRUCT(ddsd);
if (FAILED(lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
return 0;
USHORT *video_buffer = (USHORT *)ddsd.lpSurface;
for (int y = 0; y < SCREEN_HEIGHT; y++)
{
DWORD color = _RGB16BIT565(0,(y >> 3),0);
// 32位的颜色
color = (color) | (color << 16);
_asm
{
CLD ; clear direction of copy to forward
MOV EAX, color ; color goes here
MOV ECX, (SCREEN_WIDTH / 2) ; number of DWORDS goes here
MOV EDI, video_buffer ; address of line to move data
REP STOSD ; send the pentium X on its way
}
// 跟上面的汇编等效
// for (DWORD ecx = 0, *edi = (DWORD*)video_buffer; ecx < (SCREEN_WIDTH / 2); ecx++)
// edi[ecx]= color;
video_buffer += (ddsd.lPitch >> 1);
}
if (FAILED(lpddsback->Unlock(NULL)))
return 0;
return 1;
}
int TermGame()
{
if (lpddsback)
{
lpddsback->Release();
lpddsback = NULL;
}
if (lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
}
if (lpdd)
{
lpdd->Release();
lpdd = NULL;
}
return 1;
}
int MainGame()
{
if (window_closed)
return 0;
if (KEYDOWN(VK_ESCAPE))
{
PostMessage(main_window_handle,WM_CLOSE,0,0);
window_closed = 1;
}
// 随机生成一个源区域
RECT rectSrc;
rectSrc.left = rand()%SCREEN_WIDTH;
rectSrc.top = rand()%SCREEN_HEIGHT;
rectSrc.right = rand()%SCREEN_WIDTH;
rectSrc.bottom = rand()%SCREEN_HEIGHT;
// 随机生成一个目标区域
RECT rectDst;
rectDst.left = rand()%SCREEN_WIDTH;
rectDst.top = rand()%SCREEN_HEIGHT;
rectDst.right = rand()%SCREEN_WIDTH;
rectDst.bottom = rand()%SCREEN_HEIGHT;
// blitter
if (FAILED(lpddsprimary->Blt(&rectDst,
lpddsback,
&rectSrc,
DDBLT_WAIT,
NULL)))
{
return 0;
}
Sleep(500);
return 1;
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
HWND hwnd;
MSG msg;
TCHAR lpszClassName[] = TEXT("kuan");
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszClassName;
RegisterClass(&wc);
hwnd = CreateWindow(lpszClassName,
TEXT("fangyukuan"),
WS_POPUP | WS_VISIBLE,
0,0,SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
main_window_handle = hwnd;
InitGame();
while(TRUE)
{
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
MainGame();
}
TermGame();
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONDOWN:
{
::MessageBeep(0);
}
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
// 文件名 : 7_7.cpp
// 创建者 : 方煜宽
// 邮箱 : fangyukuan@gmail.com
// 创建时间 : 2010-12-18 17:04
// 功能描述 : 从一个表面向另一个表面复制位图
// 地址 : http://www.cnblogs.com/fangyukuan/archive/2011/06/08/2075907.html
// -------------------------------------------------------------------------
#define INITGUID
#include<windows.h>
#include <ddraw.h>
#pragma comment(lib, "ddraw.lib")
#pragma comment(lib, "Dxguid.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Gdi32.lib")
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND main_window_handle = NULL; // 全局的windows窗口句柄
int window_closed = 0; // 窗口关闭标志
LPDIRECTDRAW7 lpdd = NULL; // ddraw 接口指针
DDSURFACEDESC2 ddsd; // ddraw 显示表面 描述结构
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // ddraw 主显示表面
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // ddraw 从显示表面
#define SCREEN_WIDTH 640 // 屏幕宽
#define SCREEN_HEIGHT 480 // 屏幕高
#define SCREEN_BPP 16 // 深度
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
// this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct, 0, sizeof(ddstruct)); ddstruct.dwSize = sizeof(ddstruct);}
int InitGame()
{
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
return 0;
if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return 0;
if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
return 0;
DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // 增加DDSD_BACKBUFFERCOUNT 表明dwBackBufferCount有效
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // 多了| DDSCAPS_COMPLEX | DDSCAPS_FLIP
ddsd.dwBackBufferCount = 1; //
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
return 0;
// 请求一个后备缓冲
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
// 得到后备缓冲
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
return 0;
DDRAW_INIT_STRUCT(ddsd);
if (FAILED(lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
return 0;
USHORT *video_buffer = (USHORT *)ddsd.lpSurface;
for (int y = 0; y < SCREEN_HEIGHT; y++)
{
DWORD color = _RGB16BIT565(0,(y >> 3),0);
// 32位的颜色
color = (color) | (color << 16);
_asm
{
CLD ; clear direction of copy to forward
MOV EAX, color ; color goes here
MOV ECX, (SCREEN_WIDTH / 2) ; number of DWORDS goes here
MOV EDI, video_buffer ; address of line to move data
REP STOSD ; send the pentium X on its way
}
// 跟上面的汇编等效
// for (DWORD ecx = 0, *edi = (DWORD*)video_buffer; ecx < (SCREEN_WIDTH / 2); ecx++)
// edi[ecx]= color;
video_buffer += (ddsd.lPitch >> 1);
}
if (FAILED(lpddsback->Unlock(NULL)))
return 0;
return 1;
}
int TermGame()
{
if (lpddsback)
{
lpddsback->Release();
lpddsback = NULL;
}
if (lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
}
if (lpdd)
{
lpdd->Release();
lpdd = NULL;
}
return 1;
}
int MainGame()
{
if (window_closed)
return 0;
if (KEYDOWN(VK_ESCAPE))
{
PostMessage(main_window_handle,WM_CLOSE,0,0);
window_closed = 1;
}
// 随机生成一个源区域
RECT rectSrc;
rectSrc.left = rand()%SCREEN_WIDTH;
rectSrc.top = rand()%SCREEN_HEIGHT;
rectSrc.right = rand()%SCREEN_WIDTH;
rectSrc.bottom = rand()%SCREEN_HEIGHT;
// 随机生成一个目标区域
RECT rectDst;
rectDst.left = rand()%SCREEN_WIDTH;
rectDst.top = rand()%SCREEN_HEIGHT;
rectDst.right = rand()%SCREEN_WIDTH;
rectDst.bottom = rand()%SCREEN_HEIGHT;
// blitter
if (FAILED(lpddsprimary->Blt(&rectDst,
lpddsback,
&rectSrc,
DDBLT_WAIT,
NULL)))
{
return 0;
}
Sleep(500);
return 1;
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
HWND hwnd;
MSG msg;
TCHAR lpszClassName[] = TEXT("kuan");
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszClassName;
RegisterClass(&wc);
hwnd = CreateWindow(lpszClassName,
TEXT("fangyukuan"),
WS_POPUP | WS_VISIBLE,
0,0,SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
main_window_handle = hwnd;
InitGame();
while(TRUE)
{
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
MainGame();
}
TermGame();
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONDOWN:
{
::MessageBeep(0);
}
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}