dirdraw.cpp
Upload User: hukewei88
Upload Date: 2019-04-29
Package Size: 835k
Code Size: 14k
Category:

DirextX

Development Platform:

C/C++

  1. // dirdraw.cpp
  2. //******************************************
  3. // copyright 1998 Mickey Kawick
  4. // This file may be used anywhere for free, but this
  5. // comment info must be left here.
  6. // If you use this code in any shape or form or even
  7. // as a reference for profit send me a dollar. 
  8. // Not a dollar per copy, just a single US dollar. 
  9. // If you are not in the US, send me
  10. // a few different coins or the equivalent of a dollar.
  11. // I love foreign currency, and I have a little collection.
  12. // MKawick@sprintmail.com
  13. //******************************************
  14. #include "dirdraw.h"
  15. #include "asm.h"
  16.      //****************************
  17.      //****************************
  18. DIRECT_DRAW_MANAGER:: DIRECT_DRAW_MANAGER ()
  19. {
  20. // let's set all values to 0. This is a simple constructor that 
  21. // simply initializes all of the member variables.
  22.   WindowHandle = NULL;// pointers
  23.   DDObject     = NULL;
  24. DDObjectNew  = NULL;
  25.   Primary      = NULL;
  26.    BackBuffer   = NULL;
  27. AvailableVideoMemory = 0;// numbers
  28. TotalVideoMemory = 0;
  29. Width     = 0;
  30.    Height    = 0;
  31. WindowX   = 0;
  32. WindowY   = 0;
  33. FullScreenFlag = 0;
  34. NotInitializedFlag = true;
  35. //********* offscreen buffers for faster drawing, in video mem
  36. // we may use these later, but for now, let's just allocate them and 
  37. // leave them alone
  38. NumOffSurfaces = 0;
  39. for (int i=0; i<MAXOFFSURFACES; i++)
  40. {
  41. OffSurface[i] = NULL;
  42. OffWidth[MAXOFFSURFACES] = 0, OffHeight[MAXOFFSURFACES] = 0;
  43. }    
  44. }
  45.      //****************************
  46. DIRECT_DRAW_MANAGER:: ~ DIRECT_DRAW_MANAGER ()
  47. {
  48. if (DDObjectNew != NULL)
  49.     {
  50.         DDObjectNew->Release();// takes care of all underlying objects
  51. if (DDClipper != NULL) DDClipper->Release();
  52. if (Primary  != NULL) Primary->Release();// kills all associated surfaces
  53. if (BackBuffer  != NULL) BackBuffer->Release();
  54.     }
  55. }
  56.      //****************************
  57.      //****************************
  58. HWND DIRECT_DRAW_MANAGER:: CreateMainWindow (const int w, const int h, 
  59. const char* ClassName, 
  60. void* MessageLoop, 
  61. void* hInst,
  62. const bool FullScreen)
  63. {
  64. if (NotInitializedFlag == false) return NULL;// already initialized
  65. WNDCLASS    wc;
  66. FullScreenFlag = FullScreen;// store this value
  67. wc.style=           CS_HREDRAW | CS_VREDRAW;
  68.    wc.lpfnWndProc =    (long (__stdcall *)(void *,unsigned int,unsigned int,long)) MessageLoop;
  69. wc.cbClsExtra =     0;
  70.   wc.cbWndExtra =     0;
  71.   wc.hInstance =      hInst;
  72.   wc.hIcon =          LoadIcon (hInst, IDI_APPLICATION);
  73.   wc.hCursor =        LoadCursor(NULL, IDC_ARROW);
  74.   wc.hbrBackground =  NULL;
  75.   wc.lpszMenuName =   ClassName;//NULL;
  76.   wc.lpszClassName =  ClassName;
  77.   RegisterClass(&wc);
  78. if (FullScreen)// there are some slight differences between 
  79. //fullscreen and not
  80.     {
  81. WindowX = 0, WindowY = 0;
  82. WindowHandle = CreateWindowEx(
  83. WS_EX_TOPMOST,
  84. ClassName,
  85. ClassName,
  86. WS_POPUP,
  87. WindowX,
  88. WindowY,
  89. 640, ///GetSystemMetrics( SM_CXSCREEN ),// full screen dimensions
  90. 480,//GetSystemMetrics( SM_CYSCREEN ),
  91. NULL,
  92. NULL,
  93. hInst,
  94. NULL);
  95. }
  96. else
  97. {
  98. WindowX = GetSystemMetrics (SM_CXSCREEN)/2-w/2, // center the window
  99. WindowY = GetSystemMetrics (SM_CYSCREEN)/2-h/2;
  100. WindowHandle = CreateWindowEx( 
  101. 0, 
  102. ClassName, 
  103. ClassName,  
  104. WS_POPUP, 
  105. WindowX, 
  106. WindowY, 
  107. w, 
  108. h,
  109. NULL, 
  110. NULL, 
  111. hInst, 
  112. NULL);
  113. }
  114. // there is a problem creating the window
  115. if (WindowHandle ==  NULL) return NULL; 
  116. // we now have a real window and we are ready to proceed
  117. Width     = w;
  118.    Height    = h;
  119.     
  120.   ShowWindow (WindowHandle, 1);
  121.   UpdateWindow (WindowHandle);
  122.   SetFocus    (WindowHandle);
  123.   ShowCursor (FALSE);
  124. int err = CreateDirectDraw ();
  125. if (err == 0) return NULL;
  126. NotInitializedFlag = false;
  127. return WindowHandle;
  128. }
  129.      //****************************
  130. void  DIRECT_DRAW_MANAGER:: ErrorMessage (const char* str)
  131. {
  132. MessageBox (WindowHandle, str, "Error", MB_OK);
  133. DestroyWindow (WindowHandle);
  134. }
  135.      //****************************
  136. int  DIRECT_DRAW_MANAGER:: CreateDirectDraw ()
  137. {
  138.     HRESULT ddret = DirectDrawCreate (NULL, &DDObject, NULL);
  139.     if (ddret != DD_OK){ DestroyWindow (WindowHandle); return 0;}
  140.         //***************
  141.     ddret = DDObject->SetCooperativeLevel (WindowHandle,  
  142. (FullScreenFlag) ? (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) 
  143. : (DDSCL_NORMAL));
  144.     if (ddret != DD_OK){ ErrorMessage ("Cooperative level not set"); return 0;}
  145. #if defined (DDVER6)
  146. ddret = DDObject->QueryInterface (IID_IDirectDraw4, (LPVOID *) 
  147. &DDObjectNew);
  148. #else
  149. /* ddret = DDObject->QueryInterface (IID_IDirectDraw2, (LPVOID *) 
  150. &DDObjectNew);*/
  151. DDObjectNew = DDObject;// simplifies the cross-version code
  152. #endif
  153. if(ddret != DD_OK) 
  154. ErrorMessage ("Problem initializing IID_IDirectDraw"); 
  155. return 0;
  156. }
  157.         //***************
  158. if (FullScreenFlag)
  159. {
  160. // 16bit bit depth
  161. #if defined (DDVER6)
  162. ddret = DDObjectNew->SetDisplayMode (Width, Height, 16, 0, 0);
  163. #else
  164. ddret = DDObjectNew->SetDisplayMode (Width, Height, 16);
  165. #endif
  166. if (ddret != DD_OK){ ErrorMessage ("Display not set"); return 0;}
  167. }
  168.         //***************Get primary surface
  169. ZeroMemory (&Description, sizeof(Description));
  170.    ZeroMemory (&Description.ddpfPixelFormat, sizeof(DDPIXELFORMAT));
  171.   Description.dwSize = sizeof (Description);
  172.   Description.dwFlags = DDSD_CAPS;
  173.   Description.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  174. if (FullScreenFlag) 
  175. {
  176. Description.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  177. Description.dwFlags |= DDSD_BACKBUFFERCOUNT;
  178. }
  179. // we can specify more than one back buffer  
  180.     Description.dwBackBufferCount = 1;
  181.     ddret = DDObjectNew->CreateSurface (&Description, &Primary, NULL);
  182.     if (ddret != DD_OK) { ErrorMessage ("Surface not created"); return 0;}
  183. //***************Get pixel format
  184. Description.dwSize = sizeof (Description);
  185.    Description.dwFlags = DDSD_PIXELFORMAT;
  186. ddret = Primary->GetSurfaceDesc (&Description);
  187. if (ddret != DD_OK) 
  188. ErrorMessage ("pixel format not available");
  189. return 0;
  190. }
  191. //************* get our color type
  192. int g = Description.ddpfPixelFormat.dwGBitMask>>5;// assumes 5 for red
  193. if (g == 0x1F) ColorType = _5x5x5_;
  194. else if (g == 0x3F) ColorType = _5x6x5_;
  195. else { ErrorMessage ("color mode not supported"); return 0;}
  196. //*************** create clipper
  197. if (FullScreenFlag == false)
  198. {
  199. ddret = DDObjectNew->CreateClipper ( 0, &DDClipper, NULL);
  200. if (ddret != DD_OK){ ErrorMessage ("clipper not created"); return 0;}
  201. ddret = DDClipper->SetHWnd (0, WindowHandle);
  202. if (ddret != DD_OK)
  203. ErrorMessage ("Surface not assigned to hwnd"); 
  204. return 0;
  205. }
  206. ddret = Primary->SetClipper (DDClipper);
  207. if (ddret != DD_OK)
  208. ErrorMessage ("clipper not set on primary surface"); 
  209. return 0;
  210. }
  211. }
  212.         //*************** Get BackBuffer surface
  213. if (FullScreenFlag)
  214. {
  215. ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
  216. ddret = Primary->GetAttachedSurface(&ddsCaps, &BackBuffer);
  217. if (ddret != DD_OK)
  218. ErrorMessage ("primary surface not attached"); 
  219. return 0;
  220. }
  221. }
  222. else 
  223. {
  224. Description.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  225. Description.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  226. Description.dwWidth = Width;
  227. Description.dwHeight = Height;
  228. ddret = DDObjectNew->CreateSurface(&Description, &BackBuffer, NULL);
  229. if (ddret != DD_OK){ ErrorMessage ("back buffer not made"); return 0;}
  230. }
  231. #if defined (DDVER6)
  232. ZeroMemory (&ddsCaps, sizeof (DDSCAPS2));
  233. #else
  234. ZeroMemory (&ddsCaps, sizeof (DDSCAPS));
  235. #endif
  236. ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  237. #if defined (DDVER6)
  238. ddret = DDObjectNew->GetAvailableVidMem (&ddsCaps, &TotalVideoMemory, 
  239. &AvailableVideoMemory);
  240. #else
  241. TotalVideoMemory = 0, AvailableVideoMemory = 0;
  242. #endif
  243. if(ddret != DD_OK) return 0;
  244.     return 1;
  245. }
  246.      //****************************
  247.      //****************************
  248. int  DIRECT_DRAW_MANAGER:: CreateBlankOffSurface (const int w, const int h)
  249. {
  250. if (NotInitializedFlag == true) return -1;
  251. if (NumOffSurfaces >= MAXOFFSURFACES) return -1;
  252. int which = NumOffSurfaces;
  253. CreateOffSurface(which, w, h);
  254. OffWidth[which] = w; OffHeight[which] = h;
  255. U16ptr ptr = (U16ptr) GetOffSurface(which);
  256. if (ptr != NULL) Memset16Bit (ptr, 0, w*h);
  257. ReleaseOffSurface (which);
  258. NumOffSurfaces++;// increment our count
  259. return which;
  260. }
  261. //****************************
  262. void DIRECT_DRAW_MANAGER:: CreateOffSurface (const int which, const int w, const int h)
  263. {
  264. if (NotInitializedFlag == true) return;
  265. ZeroMemory (&OffSurfaceDescription, sizeof (DDSURFACEDESC));
  266.     
  267.     OffSurfaceDescription.dwSize = sizeof (DDSURFACEDESC);
  268.     OffSurfaceDescription.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  269.     OffSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  270.     OffSurfaceDescription.dwHeight = h;
  271.     OffSurfaceDescription.dwWidth = w;
  272.     DDObjectNew->CreateSurface (&OffSurfaceDescription, 
  273. &OffSurface[which], NULL);  
  274. }
  275. //****************************
  276. void DIRECT_DRAW_MANAGER:: DrawOffSurface (const int x, const int y, const int which)
  277. {
  278. if (NotInitializedFlag == true) return;
  279. if (Screen.Screen == NULL) return;
  280.     
  281. BackBuffer->Unlock (NULL);   // first unlock the back buffer
  282.     
  283.     RECT rect = {0, 0, OffWidth[which], OffHeight[which]};// draw
  284.     BackBuffer->BltFast(x, y, OffSurface[which], &rect, 
  285. DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
  286.         
  287.     if (Screen.Screen != NULL)// then, restore the lock
  288.     {
  289.         int ret;
  290. // keep going until it get it right
  291.         do{
  292.             ret = BackBuffer->Lock(NULL, &Description, 
  293. DDLOCK_SURFACEMEMORYPTR, NULL);
  294.         }while(ret!=DD_OK);
  295.     }
  296. Screen.Width = Width, Screen.Height = Height;
  297.     Screen.Screen = (U16ptr) Description.lpSurface;
  298. Screen.RealWidth = Description.lPitch/2;
  299. }
  300.      //****************************
  301.      //****************************
  302. // this function call must be followed by a call to "ReleasePointerToOffSurface"
  303. SCREEN_STRUCT* 
  304. DIRECT_DRAW_MANAGER:: GetOffSurface (const int which)// must exist first
  305. {  
  306. if (NotInitializedFlag == true) return NULL;
  307. if (which >= NumOffSurfaces || which<0 || NumOffSurfaces<1) return NULL;
  308. ZeroMemory(&OffSurfaceDescription, sizeof (DDSURFACEDESC));
  309. OffSurfaceDescription.dwSize = sizeof (DDSURFACEDESC);
  310. if (OffSurface[which]->IsLost()) OffSurface[which]->Restore();
  311. HRESULT rval = OffSurface[which]->Lock(NULL, &OffSurfaceDescription, 
  312. 0, NULL);
  313. if(rval != DD_OK) return NULL;
  314. Screen.Width = OffWidth[which], Screen.Height = OffHeight[which], 
  315. Screen.Screen = (U16ptr) OffSurfaceDescription.lpSurface;
  316. Screen.RealWidth = OffSurfaceDescription.lPitch/2;
  317.   return &Screen; 
  318. }
  319.      //****************************
  320. void DIRECT_DRAW_MANAGER:: ReleaseOffSurface (const int which)
  321. {
  322. if (NotInitializedFlag == true) return;
  323. if (which >= NumOffSurfaces || which<0 || NumOffSurfaces<1) return;
  324. OffSurface[which]->Unlock(NULL);
  325. }
  326.      //****************************
  327.      //****************************
  328. void __fastcall DIRECT_DRAW_MANAGER:: ClearBackBuffer ()
  329. {
  330. if (NotInitializedFlag == true) return;
  331. PrepFrame();
  332. Memset16Bit (Screen.Screen, 0, Screen.Width*Screen.Height);
  333. }
  334.      //****************************
  335. SCREEN_STRUCT*
  336.  DIRECT_DRAW_MANAGER:: PrepFrame ()
  337. {
  338. if (NotInitializedFlag == true) return NULL;
  339.   ZeroMemory (&Description, sizeof (DDSURFACEDESC));
  340.   Description.dwSize = sizeof (Description);
  341.   int ret;
  342.   do{
  343.     ret = BackBuffer->Lock (NULL, &Description, 
  344. DDLOCK_SURFACEMEMORYPTR, NULL);
  345.     }while(ret!=DD_OK);
  346. BackBuffer->Unlock (NULL);
  347. Screen.Width = Width;
  348. Screen.Height = Height;
  349. Screen.Screen = (U16ptr) Description.lpSurface;
  350. Screen.RealWidth = Description.lPitch/2;
  351. return &Screen;
  352. }
  353.      //****************************
  354. void DIRECT_DRAW_MANAGER:: InterruptFrame ()
  355. {    
  356. if (NotInitializedFlag == true) return;
  357.     BackBuffer->Unlock (NULL);
  358.     Screen.Screen = NULL;
  359. }
  360.      //****************************
  361. int DIRECT_DRAW_MANAGER:: DrawFrame ()// swap
  362. {
  363. if (NotInitializedFlag == true) return 0;
  364. POINT pt = {0, 0};
  365. ClientToScreen (WindowHandle, &pt);
  366. RECT BuffRect = {pt.x, pt.y, pt.x+Width, pt.y+Height};
  367. RECT DRect = {0, 0, Width, Height};
  368. int pass = 0;//DDFLIP_WAIT;
  369. if (FullScreenFlag)
  370. {
  371. int ret = BackBuffer->GetFlipStatus (DDGFS_ISFLIPDONE);
  372. if (ret == DDERR_WASSTILLDRAWING) return 1;
  373. ret = Primary->Flip(NULL, pass);// too slow
  374. //int ret = Primary->Blt (&BuffRect, BackBuffer, &DRect, 
  375. //pass, NULL);
  376. if (ret == DDERR_SURFACELOST)
  377. {
  378. #if defined (DDVER6)
  379. ret = DDObjectNew->RestoreAllSurfaces ();
  380. #else
  381. ret = Primary->Restore ();
  382. if (ret != DD_OK){ErrorMessage ("Surfaces lost"); return 1;}
  383. ret = BackBuffer->Restore ();
  384. #endif
  385. if (ret != DD_OK){ErrorMessage ("Surfaces lost"); return 1;}
  386. }
  387. }
  388.     else
  389. {
  390. int ret = Primary->Blt (&BuffRect, BackBuffer, &DRect, pass, NULL);
  391. if (ret == DDERR_SURFACELOST)
  392. {
  393. #if defined (DDVER6)
  394. ret = DDObjectNew->RestoreAllSurfaces ();
  395. #else
  396. ret = Primary->Restore ();
  397. if (ret != DD_OK){ErrorMessage ("Surfaces lost"); return 1;}
  398. ret = BackBuffer->Restore ();
  399. #endif
  400. if (ret != DD_OK){ErrorMessage ("Surfaces lost"); return 1;}
  401. }
  402. }
  403. Screen.Screen = NULL;
  404. //DDObjectNew->WaitForVerticalBlank(DDWAITVB_BLOCKEND , NULL);
  405. return 0;
  406. }
  407.      //****************************
  408.      //****************************
  409. void DIRECT_DRAW_MANAGER:: PaintText (const int x, const int y, const char* string)
  410. {
  411. if (NotInitializedFlag == true) return;
  412.     HDC hdc;
  413.     BackBuffer->Unlock (NULL);
  414.     
  415.     BackBuffer-> GetDC(&hdc);
  416.     SetBkMode (hdc, TRANSPARENT);
  417.     SetTextColor (hdc, RGB(255, 255, 255));
  418.     TextOut (hdc, x, y, string, strlen(string));
  419.     BackBuffer->ReleaseDC (hdc);
  420.     int ret;
  421.     do{
  422.         ret = BackBuffer->Lock (NULL, &Description, 
  423. DDLOCK_SURFACEMEMORYPTR, NULL);
  424.     }while (ret!=DD_OK);
  425. /* an older way to accomplish the same thing
  426. if (lpDDSBack->GetDC(&hdc) == DD_OK) // must be locked
  427.     SetBkColor(hdc, RGB(0, 0, 255)); 
  428.     SetTextColor(hdc, RGB(255, 255, 0)); 
  429.     TextOut(hdc, 0, 0, szBackMsg, lstrlen(szBackMsg)); 
  430.     lpDDSBack->ReleaseDC(hdc); 
  431. */
  432. }
  433.      //****************************
  434.      //****************************
  435.      //****************************