01.#pragma comment(lib,"dxguid.lib")
02.#include <windows.h>
03.#include <windowsx.h>
04.#include <mmsystem.h>
05.#include <iostream.h>
06.#include <conio.h>
07.#include <stdlib.h>
08.#include <malloc.h>
09.#include <memory.h>
10.#include <string.h>
11.#include <stdarg.h>
12.#include <stdio.h>
13.#include <math.h>
14.#include <io.h>
15.#include <fcntl.h>
16.#include <ddraw.h>
17.
18.#define KEYDOWN(key) ((GetAsyncKeyState(key) & 0x8000) ? 1 : 0)
19.#define KEYUP(key) ((GetAsyncKeyState(key) & 0x8000) ? 0 : 1)
20.#define DD_INIT_STRUCT(ddstruct){memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize=sizeof(ddstruct);}
21.#define SCREEN_WIDTH 640
22.#define SCREEN_HEIGHT 480
23.#define SCREEN_BPP 8
24.#define SPEED_X 3
25.#define SPEED_Y 3
26.#define ANINUM 50
27.#define BITMAP_ID 0x4D42
28.#define MAX_COLORS_PALETTE 256
29.
30.//图片结构体
31.typedef struct BITMAP_FILE_TAG
32.{
33. BITMAPFILEHEADER bitmapfileheader;
34. BITMAPINFOHEADER bitmapinfoheader;
35. PALETTEENTRY palette[256];
36. UCHAR *buffer;
37.} BITMAP_FILE, *BITMAP_FILE_PTR;
38.
39.typedef struct ALIEN_OBJ_TYP
40.{
41. LPDIRECTDRAWSURFACE7 frames[3];
42. int x,y;
43. int velocity;
44. int current_frame;
45. int counter;
46.} ALIEN_OBJ, *ALIEN_OBJ_PTR;
47.
48.LPDIRECTDRAW7 lpdd = NULL; // dd4 object
49.LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface
50.LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface
51.LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
52.LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
53.PALETTEENTRY palette[256]; // color palette
54.PALETTEENTRY save_palette[256]; // used to save palettes
55.DDSURFACEDESC2 ddsd; // a direct draw surface description struct
56.DDBLTFX ddbltfx; // used to fill
57.DDSCAPS2 ddscaps; // a direct draw surface capabilities struct
58.HRESULT ddrval; // result back from dd calls
59.DWORD start_clock_count = 0; // used for timing
60.BITMAP_FILE bitmap; // holds the bitmap
61.ALIEN_OBJ aliens[3]; // 3 aliens, one on each level
62.LPDIRECTDRAWSURFACE7 lpddsbackground = NULL;// this will hold the background image
63.int window_closed=0;
64.
65.#define _RGB16BIT555(r,g,b) ((b&31)+((g&31)<<5)+((r&31)<<10))
66.#define _RGB16BIT565(r,g,b) ((b&31)+((g&63)<<5)+((r&31)<<11))
67.#define _RGB32BIT(a,r,g,b) ((b)+((g)<<8)+((r)<<16)+((a)<<24))
68.
69.
70.int gwidth = -1;
71.int gheight = -1;
72.
73.//从源表面拷贝一个矩形到桌面显示
74.int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source,int x, int y,int width,int height,LPDIRECTDRAWSURFACE7 dest,int transparent=1)
75.{
76. RECT dest_rect,source_rect;
77. dest_rect.left=x;
78. dest_rect.top=y;
79. dest_rect.right=x+width-1;
80. dest_rect.bottom=y+height-1;
81. source_rect.left=0;
82. source_rect.top=0;
83. source_rect.right=width-1;
84. source_rect.bottom=height-1;
85. if (transparent)
86. {
87. if (FAILED(dest->Blt(&dest_rect,source,&source_rect,(DDBLT_WAIT|DDBLT_KEYSRC),NULL)))
88. return(0);
89. }
90. else
91. {
92. if (FAILED(dest->Blt(&dest_rect,source,&source_rect,(DDBLT_WAIT),NULL)))
93. return(0);
94. }
95. return(1);
96.}
97.
98.//得到一个包含所有目标矩形的剪贴板
99.LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,int num_rects,LPRECT clip_list)
100.{
101. int index;
102. LPDIRECTDRAWCLIPPER lpddclipper;
103. LPRGNDATA region_data;
104. if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
105. return(NULL);
106. region_data=(LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));
107. memcpy(region_data->Buffer,clip_list,sizeof(RECT)*num_rects);
108. region_data->rdh.dwSize=sizeof(RGNDATAHEADER);
109. region_data->rdh.iType=RDH_RECTANGLES;
110. region_data->rdh.nCount=num_rects;
111. region_data->rdh.nRgnSize=num_rects*sizeof(RECT);
112. region_data->rdh.rcBound.left=64000;
113. region_data->rdh.rcBound.top=64000;
114. region_data->rdh.rcBound.right=-64000;
115. region_data->rdh.rcBound.bottom=-64000;
116. for(index=0;index<num_rects;index++)
117. {
118. if (clip_list[index].left<region_data->rdh.rcBound.left)
119. region_data->rdh.rcBound.left=clip_list[index].left;
120. if (clip_list[index].right>region_data->rdh.rcBound.right)
121. region_data->rdh.rcBound.right=clip_list[index].right;
122. if (clip_list[index].top<region_data->rdh.rcBound.top)
123. region_data->rdh.rcBound.top=clip_list[index].top;
124. if (clip_list[index].bottom>region_data->rdh.rcBound.bottom)
125. region_data->rdh.rcBound.bottom=clip_list[index].bottom;
126. }
127. if(FAILED(lpddclipper->SetClipList(region_data, 0)))
128. {
129. free(region_data);
130. return(NULL);
131. }
132. if(FAILED(lpdds->SetClipper(lpddclipper)))
133. {
134. free(region_data);
135. return(NULL);
136. }
137. free(region_data);
138. return(lpddclipper);
139.}
140.
141.//加载一副图片,图片路径:filename
142.int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
143.{
144. UCHAR *buffer;
145. int index;
146. if(!(buffer=(UCHAR*)malloc(bytes_per_line*height)))
147. return 0;
148. memcpy(buffer,image,bytes_per_line*height);
149. for(index=0;index<height;index++)
150. memcpy(&image[((height-1)-index)*bytes_per_line],&buffer[index*bytes_per_line],bytes_per_line);
151. free(buffer);
152. return(1);
153.}
154.
155.int Load_Bitmap_File(BITMAP_FILE_PTR bitmap,char *filename)
156.{
157. int file_handle,index;
158. UCHAR *temp_buffer=NULL;
159. OFSTRUCT file_data;
160. if((file_handle=OpenFile(filename,&file_data,OF_READ))==-1)
161. return(0);
162. _lread(file_handle,&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
163. if(bitmap->bitmapfileheader.bfType!=BITMAP_ID)
164. {
165. _lclose(file_handle);
166. return(0);
167. }
168. _lread(file_handle,&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
169. if (bitmap->bitmapinfoheader.biBitCount==8)
170. {
171. _lread(file_handle,&bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
172. for (index=0;index<MAX_COLORS_PALETTE;index++)
173. {
174. int temp_color=bitmap->palette[index].peRed;
175. bitmap->palette[index].peRed=bitmap->palette[index].peBlue;
176. bitmap->palette[index].peBlue=temp_color;
177. bitmap->palette[index].peFlags=PC_NOCOLLAPSE;
178. }
179. }
180. _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
181. if (bitmap->bitmapinfoheader.biBitCount==8||bitmap->bitmapinfoheader.biBitCount==16||bitmap->bitmapinfoheader.biBitCount==24)
182. {
183. if(bitmap->buffer)
184. free(bitmap->buffer);
185. if(!(bitmap->buffer=(UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
186. {
187. _lclose(file_handle);
188. return(0);
189. }
190. _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
191. }
192. else
193. {
194. return(0);
195. }
196.#if 0
197. printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
198. filename,
199. bitmap->bitmapinfoheader.biSizeImage,
200. bitmap->bitmapinfoheader.biWidth,
201. bitmap->bitmapinfoheader.biHeight,
202. bitmap->bitmapinfoheader.biBitCount,
203. bitmap->bitmapinfoheader.biClrUsed,
204. bitmap->bitmapinfoheader.biClrImportant);
205.#endif
206. _lclose(file_handle);
207. Flip_Bitmap(bitmap->buffer,
208. bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
209. bitmap->bitmapinfoheader.biHeight);
210. return(1);
211.}
212.
213.//用调色板编号为color的颜色填充整个屏幕
214.int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color)
215.{
216. DDBLTFX ddbltfx;
217. DD_INIT_STRUCT(ddbltfx);
218. ddbltfx.dwFillColor=color;
219. lpdds->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx);
220. return(1);
221.}
222.
223.//创建一个可以过滤颜色的表面
224.LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width,int height,int mem_flags,int color_key=0)
225.{
226. DDSURFACEDESC2 ddsd;
227. LPDIRECTDRAWSURFACE7 lpdds;
228. memset(&ddsd,0,sizeof(ddsd));
229. ddsd.dwSize=sizeof(ddsd);
230. ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
231. ddsd.dwWidth=width;
232. ddsd.dwHeight=height;
233. ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|mem_flags;
234. if(FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
235. return(NULL);
236. if(color_key>=0)
237. {
238. DDCOLORKEY color_key;
239. color_key.dwColorSpaceLowValue=0;
240. color_key.dwColorSpaceHighValue=0;
241. lpdds->SetColorKey(DDCKEY_SRCBLT,&color_key);
242. }
243. return(lpdds);
244.}
245.
246.//释放图片内存
247.int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
248.{
249. if (bitmap->buffer)
250. {
251. free(bitmap->buffer);
252. bitmap->buffer=NULL;
253. }
254. return(1);
255.}
256.
257.//显示一张图片
258.int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,LPDIRECTDRAWSURFACE7 lpdds,int cx,int cy)
259.{
260. UCHAR *source_ptr,*dest_ptr;
261. DDSURFACEDESC2 ddsd;
262. ddsd.dwSize=sizeof(ddsd);
263. lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR,NULL);
264. cx=cx*(ddsd.dwWidth+1)+1;
265. cy=cy*(ddsd.dwHeight+1)+1;
266. gwidth=ddsd.dwWidth;
267. gheight=ddsd.dwHeight;
268. source_ptr=bitmap->buffer+cy*bitmap->bitmapinfoheader.biWidth+cx;
269. dest_ptr=(UCHAR *)ddsd.lpSurface;
270. for (int index_y=0;index_y<ddsd.dwHeight;index_y++)
271. {
272. memcpy(dest_ptr,source_ptr,ddsd.dwWidth);
273. dest_ptr+=(ddsd.lPitch);
274. source_ptr+=bitmap->bitmapinfoheader.biWidth;
275. }
276. lpdds->Unlock(NULL);
277. return(1);
278.}
279.
280.void Plot_Pixel_Faster32(int x,int y,int a,int r,int g,int b,UINT *video_buffer,int lpitch32)
281.{
282. UINT color;
283. color=_RGB32BIT(a,r,g,b);
284. video_buffer[x+y*lpitch32]=color;
285.}
286.
287.HWND hwd;
288.HINSTANCE hIns;
289.HDC hdc;
290.
291.LRESULT CALLBACK WinSunProc(
292. HWND hwnd,
293. UINT uMsg,
294. WPARAM wParam,
295. LPARAM lParam
296.)
297.{
298. HDC hdc;
299. PAINTSTRUCT ps;
300. switch(uMsg)
301. {
302. case WM_PAINT:
303. hdc=BeginPaint(hwnd,&ps);
304.
305. EndPaint(hwnd,&ps);
306. break;
307. case WM_DESTROY:
308. PostQuitMessage(0);
309. break;
310. default:
311. break;
312. }
313. return DefWindowProc(hwnd,uMsg,wParam,lParam);
314.}
315.
316.void Blt_Clip(int x,int y,int width,int height,UCHAR *bitmap,UCHAR *video_buffer,int mempitch)
317.{
318. if((x>=SCREEN_WIDTH)||(y>=SCREEN_HEIGHT)||((x+width)<=0)||((y+height)<=0))
319. return;
320. int x1=x;
321. int y1=y;
322. int x2=x+width-1;
323. int y2=y+height-1;
324. if(x1<0)
325. x1=0;
326. if(y1<0)
327. y1=0;
328. if(x2>SCREEN_WIDTH)
329. x2=SCREEN_WIDTH;
330. if(y2>SCREEN_HEIGHT)
331. y2=SCREEN_HEIGHT;
332. int x_off=x-x1;
333. int y_off=y-y1;
334. int dx=x2-x1+1;
335. int dy=y2-y1+1;
336. video_buffer=video_buffer+(x1+y1*mempitch);
337. bitmap=bitmap+(x_off+y_off*width);
338. int i,j;
339. UCHAR pixel;
340. for(j=0;j<dy;j++)
341. {
342. for(i=0;i<dx;i++)
343. {
344. pixel=bitmap;
345. video_buffer=pixel;
346. }
347. video_buffer=video_buffer+mempitch;
348. bitmap=bitmap+width;
349. }
350.}
351.
352.void Game_Init()
353.{
354. if(FAILED(DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL)))
355. return;
356. if(FAILED(lpdd->SetCooperativeLevel(hwd,DDSCL_FULLSCREEN|DDSCL_ALLOWMODEX|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT)))
357. return;
358. if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)))
359. return;
360. DD_INIT_STRUCT(ddsd);
361. ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
362. ddsd.dwBackBufferCount=1;
363. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
364. if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)))
365. return;
366. ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
367. if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback)))
368. return;
369. int i;
370. for(i=1;i<=254;i++)
371. {
372. palette.peRed=rand()%256;
373. palette.peGreen=rand()%256;
374. palette.peBlue=rand()%256;
375. palette.peFlags=PC_NOCOLLAPSE;
376. }
377. palette[0].peRed=0;
378. palette[0].peGreen=0;
379. palette[0].peBlue=0;
380. palette[0].peFlags=PC_NOCOLLAPSE;
381. palette[255].peRed=255;
382. palette[255].peGreen=255;
383. palette[255].peBlue=255;
384. palette[255].peFlags=PC_NOCOLLAPSE;
385. if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT|DDPCAPS_ALLOW256|DDPCAPS_INITIALIZE,palette,&lpddpal, NULL)))
386. return;
387. if(FAILED(lpddsprimary->SetPalette(lpddpal)))
388. return;
389. RECT screen_rect={0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1};
390. lpddclipper=DDraw_Attach_Clipper(lpddsback,1,&screen_rect);
391. if(!Load_Bitmap_File(&bitmap,"alley8.bmp"))
392. return;
393. if(FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette)))
394. return;
395. DDraw_Fill_Surface(lpddsback,0);
396. DDraw_Fill_Surface(lpddsprimary,0);
397. lpddsbackground=DDraw_Create_Surface(SCREEN_WIDTH,SCREEN_HEIGHT,0,-1);
398. lpddsbackground->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
399. UCHAR* image_buffer=(UCHAR*)ddsd.lpSurface;
400. if(ddsd.lPitch==SCREEN_WIDTH)
401. {
402. memcpy((void*)image_buffer,(void*)bitmap.buffer,SCREEN_WIDTH*SCREEN_HEIGHT);
403. }
404. else
405. {
406. UCHAR *dest=image_buffer;
407. UCHAR *scr=bitmap.buffer;
408. for(i=0;i<SCREEN_HEIGHT;i++)
409. {
410. memcpy((void*)dest,(void*)scr,SCREEN_WIDTH);
411. dest=dest+ddsd.lPitch;
412. scr=scr+SCREEN_WIDTH;
413. }
414. }
415. if(FAILED(lpddsbackground->Unlock(NULL)))
416. return;
417. Unload_Bitmap_File(&bitmap);
418. srand(GetTickCount());
419. aliens[0].x=rand()%SCREEN_WIDTH;
420. aliens[0].y=116-72;
421. aliens[0].velocity=2+rand()%4;
422. aliens[0].current_frame=0;
423. aliens[0].counter=0;
424.
425. aliens[1].x=rand()%SCREEN_WIDTH;
426. aliens[1].y=246-72;
427. aliens[1].velocity=2+rand()%4;
428. aliens[1].current_frame=0;
429. aliens[1].counter=0;
430.
431. aliens[2].x=rand()%SCREEN_WIDTH;
432. aliens[2].y=382-72;
433. aliens[2].velocity=2+rand()%4;
434. aliens[2].current_frame=0;
435. aliens[2].counter=0;
436.
437. if(!Load_Bitmap_File(&bitmap,"dedsp0.bmp"))
438. return;
439.
440. for(i=0;i<3;i++)
441. {
442. aliens[0].frames=DDraw_Create_Surface(72,80,0);
443. Scan_Image_Bitmap(&bitmap,aliens[0].frames,i,0);
444. }
445.
446. Unload_Bitmap_File(&bitmap);
447. for(i=0;i<3;i++)
448. aliens[1].frames=aliens[2].frames=aliens[0].frames;
449. return;
450.}
451.
452.void Game_Main()
453.{
454. static int animation_seq[4]={0,1,0,2};
455. if(window_closed)
456. return;
457. if(KEYDOWN(VK_ESCAPE))
458. {
459. PostMessage(hwd,WM_CLOSE,0,0);
460. window_closed=1;
461. }
462. DDraw_Draw_Surface(lpddsbackground,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,lpddsback,0);
463. int i;
464. for(i=0;i<3;i++)
465. {
466. aliens.x++;
467. if(aliens.x>SCREEN_WIDTH)
468. aliens.x=-80;
469. if(++aliens.counter>=(8-aliens.velocity))
470. {
471. aliens.counter=0;
472. if(++aliens.current_frame>3)
473. aliens.current_frame=0;
474. }
475. }
476. for(i=0;i<3;i++)
477. {
478. DDraw_Draw_Surface(aliens.frames[animation_seq[aliens.current_frame]],
479. aliens.x,aliens.y,
480. 72,80,
481. lpddsback);
482. }
483.
484. while(FAILED(lpddsprimary->Flip(NULL,DDFLIP_WAIT)));
485. Sleep(30);
486. return;
487.}
488.
489.void Game_Shut()
490.{
491. if(lpddpal)
492. {
493. lpddpal->Release();
494. lpddpal=NULL;
495. }
496. if(lpddsprimary)
497. {
498. lpddsprimary->Release();
499. lpddsprimary=NULL;
500. }
501. if(lpdd)
502. {
503. lpdd->Release();
504. lpdd=NULL;
505. }
506.}
507.
508.int WINAPI WinMain(
509. HINSTANCE hInstance,
510. HINSTANCE hPrevInstance,
511. LPSTR lpCmdline,
512. int nShowCmd
513.)
514.{
515. WNDCLASS wndclass;
516. wndclass.cbClsExtra=0;
517. wndclass.cbWndExtra=0;
518. wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
519. wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
520. wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
521. wndclass.hInstance=hInstance;
522. wndclass.lpfnWndProc=WinSunProc;
523. wndclass.lpszClassName="bingshen";
524. wndclass.lpszMenuName=NULL;
525. wndclass.style=CS_HREDRAW|CS_VREDRAW;
526.
527. ShowCursor(FALSE);
528. HWND hwnd;
529. RegisterClass(&wndclass);
530. hwnd=CreateWindow("bingshen","-------bingshen",WS_POPUP|WS_VISIBLE,
531. 0,0,SCREEN_WIDTH,SCREEN_HEIGHT,
532. NULL,NULL,hInstance,NULL);
533. hwd=hwnd;
534. hdc=GetDC(hwnd);
535.
536. hIns=hInstance;
537.
538. Game_Init();
539. MSG msg;
540. while(true)
541. {
542. if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
543. {
544. if(msg.message==WM_QUIT)
545. break;
546. TranslateMessage(&msg);
547. DispatchMessage(&msg);
548. }
549. Game_Main();
550. }
551. Game_Shut();
552. ReleaseDC(hwnd,hdc);
553. return msg.wParam;
554.}
有运行环境的可以试试效果