ddraw.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/Library/DDRAW.CPP $*
  25. * *
  26. * $Author:: Greg_h $*
  27. * *
  28. * $Modtime:: 10/15/98 11:05a $*
  29. * *
  30. * $Revision:: 2 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * Set_Video_Mode -- Initializes Direct Draw and sets the required Video Mode *
  35. * Process_DD_Result -- Does a message box based on the result of a DD command *
  36. * Reset_Video_Mode -- Resets video mode and deletes Direct Draw Object *
  37. * Get_Free_Video_Memory -- returns amount of free video memory *
  38. * Get_Video_Hardware_Caps -- returns bitmask of direct draw video hardware support *
  39. * Wait_Vert_Blank -- Waits for the start (leading edge) of a vertical blank *
  40. * Set_Palette -- set a direct draw palette *
  41. * Check_Overlapped_Blit_Capability -- See if video driver supports blitting overlapped regions*
  42. * Wait_Blit -- waits for the DirectDraw blitter to become idle *
  43. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  44. #include "always.h"
  45. #include "misc.h"
  46. #include "dsurface.h"
  47. #include "data.h"
  48. #include "_timer.h"
  49. #include <assert.h>
  50. #include <stdio.h>
  51. LPDIRECTDRAW DirectDrawObject = NULL; // Pointer to the direct draw object
  52. LPDIRECTDRAW2 DirectDraw2Interface = NULL; // Pointer to direct draw 2 interface
  53. static PALETTEENTRY PaletteEntries[256]; // 256 windows palette entries
  54. static LPDIRECTDRAWPALETTE PalettePtr; // Pointer to direct draw palette object
  55. static bool FirstPaletteSet = false; // Is this the first time 'Set_Palette' has been called?
  56. LPDIRECTDRAWSURFACE PaletteSurface = NULL;
  57. bool SurfacesRestored = false;
  58. static bool CanVblankSync = true;
  59. unsigned char CurrentPalette[768];
  60. bool Debug_Windowed;
  61. int (*DirectDrawErrorHandler)(HRESULT error) = NULL;
  62. void Set_Palette(PaletteClass const & pal, int time, void (*callback)())
  63. {
  64. CDTimerClass<SystemTimerClass> timer = time;
  65. PaletteClass original;
  66. memcpy(&original, CurrentPalette, sizeof(CurrentPalette));
  67. PaletteClass newpal = pal;
  68. while (timer) {
  69. /*
  70. ** Build an intermediate palette that is as close to the destination palette
  71. ** as the current time is proportional to the ending time.
  72. */
  73. PaletteClass palette = original;
  74. int adjust = ((time - timer) * 256) / time;
  75. adjust = MIN(adjust, 255);
  76. palette.Adjust(adjust, newpal);
  77. /*
  78. ** Remember the current time so that multiple palette sets within the same game
  79. ** time tick won't occur. This is probably unnecessary since the palette setting
  80. ** code, at the time of this writing, delays at least one game tick in the process
  81. ** of setting the palette.
  82. */
  83. int holdtime = timer;
  84. /*
  85. ** Set the palette to this intermediate palette and then loop back
  86. ** to calculate and set a new intermediate palette.
  87. */
  88. Set_Palette((void*)&palette[0]);
  89. /*
  90. ** If the callback routine was specified, then call it once per palette
  91. ** setting loop.
  92. */
  93. if (callback) {
  94. callback();
  95. }
  96. /*
  97. ** This loop ensures that the palette won't be set more than once per game tick. Setting
  98. ** the palette more than once per game tick will have no effect since the calculation will
  99. ** result in the same intermediate palette that was previously calculated.
  100. */
  101. while (timer == holdtime && holdtime != 0) {
  102. if (callback) callback();
  103. }
  104. }
  105. /*
  106. ** Ensure that the final palette exactly matches the requested
  107. ** palette before exiting the fading routine.
  108. */
  109. Set_Palette((void*)&newpal[0]);
  110. }
  111. /***********************************************************************************************
  112. * Process_DD_Result -- Does a message box based on the result of a DD command *
  113. * *
  114. * INPUT: HRESULT result - the result returned from the direct draw command *
  115. * int display_ok_msg - should a message be displayed if command ok * *
  116. * *
  117. * OUTPUT: none *
  118. * *
  119. * HISTORY: *
  120. * 09/27/1995 PWG : Created. *
  121. *=============================================================================================*/
  122. void Process_DD_Result(HRESULT result, int display_ok_msg)
  123. {
  124. #ifdef _DEBUG
  125. static struct {
  126. HRESULT Error;
  127. char const * Message;
  128. } _errors[] = {
  129. {DDERR_ALREADYINITIALIZED, "This object is already initialized"},
  130. {DDERR_BLTFASTCANTCLIP, "Return if a clipper object is attached to the source surface passed into a BltFast call."},
  131. {DDERR_CANNOTATTACHSURFACE, "This surface can not be attached to the requested surface."},
  132. {DDERR_CANNOTDETACHSURFACE, "This surface can not be detached from the requested surface."},
  133. {DDERR_CANTCREATEDC, "Windows can not create any more DCs"},
  134. {DDERR_CANTDUPLICATE, "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created."},
  135. {DDERR_CANTLOCKSURFACE, "Unable to lock surface because no driver exists which can supply a pointer to the surface."},
  136. {DDERR_CLIPPERISUSINGHWND, "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd."},
  137. {DDERR_COLORKEYNOTSET, "No src color key specified for this operation."},
  138. {DDERR_CURRENTLYNOTAVAIL, "Support is currently not available."},
  139. {DDERR_DIRECTDRAWALREADYCREATED, "A DirectDraw object representing this driver has already been created for this process."},
  140. {DDERR_EXCEPTION, "An exception was encountered while performing the requested operation."},
  141. {DDERR_EXCLUSIVEMODEALREADYSET, "An attempt was made to set the cooperative level when it was already set to exclusive."},
  142. {DDERR_GENERIC, "Generic failure."},
  143. {DDERR_HEIGHTALIGN, "Height of rectangle provided is not a multiple of reqd alignment."},
  144. {DDERR_HWNDALREADYSET, "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created."},
  145. {DDERR_HWNDSUBCLASSED, "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state."},
  146. {DDERR_IMPLICITLYCREATED, "This surface can not be restored because it is an implicitly created surface."},
  147. {DDERR_INCOMPATIBLEPRIMARY, "Unable to match primary surface creation request with existing primary surface."},
  148. {DDERR_INVALIDCAPS, "One or more of the caps bits passed to the callback are incorrect."},
  149. {DDERR_INVALIDCLIPLIST, "DirectDraw does not support the provided cliplist."},
  150. {DDERR_INVALIDDIRECTDRAWGUID, "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier."},
  151. {DDERR_INVALIDMODE, "DirectDraw does not support the requested mode."},
  152. {DDERR_INVALIDOBJECT, "DirectDraw received a pointer that was an invalid DIRECTDRAW object."},
  153. {DDERR_INVALIDPARAMS, "One or more of the parameters passed to the function are incorrect."},
  154. {DDERR_INVALIDPIXELFORMAT, "The pixel format was invalid as specified."},
  155. {DDERR_INVALIDPOSITION, "Returned when the position of the overlay on the destination is no longer legal for that destination."},
  156. {DDERR_INVALIDRECT, "Rectangle provided was invalid."},
  157. {DDERR_INVALIDSURFACETYPE, "The requested action could not be performed because the surface was of the wrong type."},
  158. {DDERR_LOCKEDSURFACES, "Operation could not be carried out because one or more surfaces are locked."},
  159. {DDERR_NO3D, "There is no 3D present."},
  160. {DDERR_NOALPHAHW, "Operation could not be carried out because there is no alpha accleration hardware present or available."},
  161. // {DDERR_NOANTITEARHW, "Operation could not be carried out because there is no hardware support for synchronizing blts to avoid tearing. "},
  162. {DDERR_NOBLTHW, "No blter hardware present."},
  163. // {DDERR_NOBLTQUEUEHW, "Operation could not be carried out because there is no hardware support for asynchronous blting."},
  164. {DDERR_NOCLIPLIST, "No cliplist available."},
  165. {DDERR_NOCLIPPERATTACHED, "No clipper object attached to surface object."},
  166. {DDERR_NOCOLORCONVHW, "Operation could not be carried out because there is no color conversion hardware present or available."},
  167. {DDERR_NOCOLORKEY, "Surface doesn't currently have a color key"},
  168. {DDERR_NOCOLORKEYHW, "Operation could not be carried out because there is no hardware support of the destination color key."},
  169. {DDERR_NOCOOPERATIVELEVELSET, "Create function called without DirectDraw object method SetCooperativeLevel being called."},
  170. {DDERR_NODC, "No DC was ever created for this surface."},
  171. {DDERR_NODDROPSHW, "No DirectDraw ROP hardware."},
  172. {DDERR_NODIRECTDRAWHW, "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware."},
  173. {DDERR_NODIRECTDRAWSUPPORT, "No DirectDraw support possible with current display driver."},
  174. {DDERR_NOEMULATION, "Software emulation not available."},
  175. {DDERR_NOEXCLUSIVEMODE, "Operation requires the application to have exclusive mode but the application does not have exclusive mode."},
  176. {DDERR_NOFLIPHW, "Flipping visible surfaces is not supported."},
  177. {DDERR_NOGDI, "There is no GDI present."},
  178. {DDERR_NOHWND, "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND."},
  179. {DDERR_NOMIRRORHW, "Operation could not be carried out because there is no hardware present or available."},
  180. {DDERR_NOOVERLAYDEST, "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination."},
  181. {DDERR_NOOVERLAYHW, "Operation could not be carried out because there is no overlay hardware present or available."},
  182. {DDERR_NOPALETTEATTACHED, "No palette object attached to this surface. "},
  183. {DDERR_NOPALETTEHW, "No hardware support for 16 or 256 color palettes."},
  184. {DDERR_NORASTEROPHW, "Operation could not be carried out because there is no appropriate raster op hardware present or available."},
  185. {DDERR_NOROTATIONHW, "Operation could not be carried out because there is no rotation hardware present or available."},
  186. {DDERR_NOSTRETCHHW, "Operation could not be carried out because there is no hardware support for stretching."},
  187. {DDERR_NOT4BITCOLOR, "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette."},
  188. {DDERR_NOT4BITCOLORINDEX, "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette."},
  189. {DDERR_NOT8BITCOLOR, "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color."},
  190. {DDERR_NOTAOVERLAYSURFACE, "Returned when an overlay member is called for a non-overlay surface."},
  191. {DDERR_NOTEXTUREHW, "Operation could not be carried out because there is no texture mapping hardware present or available."},
  192. {DDERR_NOTFLIPPABLE, "An attempt has been made to flip a surface that is not flippable."},
  193. {DDERR_NOTFOUND, "Requested item was not found."},
  194. {DDERR_NOTLOCKED, "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this process, has been attempted."},
  195. {DDERR_NOTPALETTIZED, "The surface being used is not a palette-based surface."},
  196. {DDERR_NOVSYNCHW, "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations."},
  197. {DDERR_NOZBUFFERHW, "Operation could not be carried out because there is no hardware support for zbuffer blting."},
  198. {DDERR_NOZOVERLAYHW, "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays."},
  199. {DDERR_OUTOFCAPS, "The hardware needed for the requested operation has already been allocated."},
  200. {DDERR_OUTOFMEMORY, "DirectDraw does not have enough memory to perform the operation."},
  201. {DDERR_OUTOFVIDEOMEMORY, "DirectDraw does not have enough memory to perform the operation."},
  202. {DDERR_OVERLAYCANTCLIP, "The hardware does not support clipped overlays."},
  203. {DDERR_OVERLAYCOLORKEYONLYONEACTIVE, "Can only have ony color key active at one time for overlays."},
  204. {DDERR_OVERLAYNOTVISIBLE, "Returned when GetOverlayPosition is called on a hidden overlay."},
  205. {DDERR_PALETTEBUSY, "Access to this palette is being refused because the palette is already locked by another thread."},
  206. {DDERR_PRIMARYSURFACEALREADYEXISTS, "This process already has created a primary surface."},
  207. {DDERR_REGIONTOOSMALL, "Region passed to Clipper::GetClipList is too small."},
  208. {DDERR_SURFACEALREADYATTACHED, "This surface is already attached to the surface it is being attached to."},
  209. {DDERR_SURFACEALREADYDEPENDENT, "This surface is already a dependency of the surface it is being made a dependency of."},
  210. {DDERR_SURFACEBUSY, "Access to this surface is being refused because the surface is already locked by another thread."},
  211. {DDERR_SURFACEISOBSCURED, "Access to surface refused because the surface is obscured."},
  212. {DDERR_SURFACELOST, "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it."},
  213. {DDERR_SURFACENOTATTACHED, "The requested surface is not attached."},
  214. {DDERR_TOOBIGHEIGHT, "Height requested by DirectDraw is too large."},
  215. {DDERR_TOOBIGSIZE, "Size requested by DirectDraw is too large -- the individual height and width are OK."},
  216. {DDERR_TOOBIGWIDTH, "Width requested by DirectDraw is too large."},
  217. {DDERR_UNSUPPORTED, "Action not supported."},
  218. {DDERR_UNSUPPORTEDFORMAT, "FOURCC format requested is unsupported by DirectDraw."},
  219. {DDERR_UNSUPPORTEDMASK, "Bitmask in the pixel format requested is unsupported by DirectDraw."},
  220. {DDERR_VERTICALBLANKINPROGRESS, "Vertical blank is in progress."},
  221. {DDERR_WASSTILLDRAWING, "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete."},
  222. {DDERR_WRONGMODE, "This surface can not be restored because it was created in a different mode."},
  223. {DDERR_XALIGN, "Rectangle provided was not horizontally aligned on required boundary."}
  224. };
  225. #endif
  226. /*
  227. ** If there iwas no error detected, then either bail out or display a message to
  228. ** this effect as indicated by the "display_ok_msg" parameter.
  229. */
  230. if (result == DD_OK) {
  231. if (display_ok_msg) {
  232. MessageBox(MainWindow, "Direct Draw operation processed without error", "Note", MB_OK);
  233. }
  234. return;
  235. }
  236. if (DirectDrawErrorHandler) {
  237. DirectDrawErrorHandler(result);
  238. return;
  239. }
  240. #ifdef _DEBUG
  241. /*
  242. ** Scan for a matching error code and display the appropriate message.
  243. */
  244. for (int index = 0; index < ARRAY_SIZE(_errors); index++) {
  245. if (_errors[index].Error == result) {
  246. MessageBox(MainWindow, _errors[index].Message, "Westwood Library Direct Draw Error", MB_ICONEXCLAMATION|MB_OK);
  247. return;
  248. }
  249. }
  250. #endif
  251. /*
  252. ** Since it fell out of the above loop, this must be an unrecognized error code.
  253. */
  254. char str[80];
  255. sprintf(str, "DDRAW.DLL Error code = %08X", result);
  256. MessageBox(MainWindow, str, "Direct X", MB_ICONEXCLAMATION|MB_OK);
  257. }
  258. /***********************************************************************************************
  259. * Check_Overlapped_Blit_Capability -- See if video driver supports blitting overlapped regions*
  260. * *
  261. * We will check for this by drawing something to a video page and blitting it over itself. *
  262. * If we end up with the top line repeating then overlapped region blits dont work. *
  263. * *
  264. * INPUT: Nothing *
  265. * *
  266. * OUTPUT: Nothing *
  267. * *
  268. * WARNINGS: None *
  269. * *
  270. * HISTORY: *
  271. * 6/7/96 5:06PM ST : Created *
  272. *=============================================================================================*/
  273. void Check_Overlapped_Blit_Capability(void)
  274. {
  275. // OverlappedVideoBlits = false;
  276. #ifdef NEVER
  277. /*
  278. ** Assume we can until we find out otherwise
  279. */
  280. OverlappedVideoBlits = true;
  281. GraphicBufferClass test_buffer;
  282. test_buffer.Init (64, 64, NULL, 0, (GBC_Enum)GBC_VIDEOMEM);
  283. test_buffer.Clear();
  284. /*
  285. ** Plot a pixel in the top left corner of the buffer.
  286. */
  287. test_buffer.Put_Pixel(0, 0, 255);
  288. /*
  289. ** Blit the buffer down by one line. If we end up with a vertical strip of pixel 255's then
  290. ** overlapped blits dont work
  291. */
  292. test_buffer.Blit(test_buffer, 0, 0, 0, 1, test_buffer.Get_Width(), test_buffer.Get_Height()-1);
  293. if (test_buffer.Get_Pixel(0, 5) == 255) OverlappedVideoBlits = false;
  294. #endif
  295. }
  296. void Prep_Direct_Draw(void)
  297. {
  298. //
  299. // If there is not currently a direct draw object then we need to define one.
  300. //
  301. if ( DirectDrawObject == NULL ) {
  302. HRESULT result = DirectDrawCreate(NULL, &DirectDrawObject, NULL);
  303. Process_DD_Result(result, false);
  304. if (result == DD_OK) {
  305. if (Debug_Windowed) {
  306. result = DirectDrawObject->SetCooperativeLevel(MainWindow, DDSCL_NORMAL);
  307. } else {
  308. result = DirectDrawObject->SetCooperativeLevel(MainWindow, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
  309. }
  310. Process_DD_Result(result, false);
  311. }
  312. }
  313. }
  314. /***********************************************************************************************
  315. * Set_Video_Mode -- Initializes Direct Draw and sets the required Video Mode *
  316. * *
  317. * INPUT: int width - the width of the video mode in pixels *
  318. * int height - the height of the video mode in pixels *
  319. * int bits_per_pixel - the number of bits per pixel the video mode supports *
  320. * *
  321. * OUTPUT: none *
  322. * *
  323. * HISTORY: *
  324. * 09/26/1995 PWG : Created. *
  325. *=============================================================================================*/
  326. bool Set_Video_Mode(HWND , int w, int h, int bits_per_pixel)
  327. {
  328. HRESULT result;
  329. Prep_Direct_Draw();
  330. //
  331. // Set the required display mode with 8 bits per pixel
  332. //
  333. //MessageBox(MainWindow, "In Set_Video_Mode. About to call call SetDisplayMode.","Note", MB_ICONEXCLAMATION|MB_OK);
  334. result = DirectDrawObject->SetDisplayMode(w, h, bits_per_pixel);
  335. if (result != DD_OK) {
  336. // Process_DD_Result(result, false);
  337. DirectDrawObject->Release();
  338. DirectDrawObject = NULL;
  339. return(false);
  340. }
  341. //
  342. // Create a direct draw palette object
  343. //
  344. //MessageBox(MainWindow, "In Set_Video_Mode. About to call CreatePalette.","Note", MB_ICONEXCLAMATION|MB_OK);
  345. result = DirectDrawObject->CreatePalette( DDPCAPS_8BIT | DDPCAPS_ALLOW256, &PaletteEntries[0], &PalettePtr, NULL);
  346. Process_DD_Result(result, false);
  347. if (result != DD_OK) {
  348. return (false);
  349. }
  350. Check_Overlapped_Blit_Capability();
  351. //MessageBox(MainWindow, "In Set_Video_Mode. About to return success.","Note", MB_ICONEXCLAMATION|MB_OK);
  352. #if (0)
  353. /*
  354. ** Find out if DirectX 2 extensions are available
  355. */
  356. result = DirectDrawObject->QueryInterface (IID_IDirectDraw2, (LPVOID*)&DirectDraw2Interface);
  357. SystemToVideoBlits = false;
  358. VideoToSystemBlits = false;
  359. SystemToSystemBlits= false;
  360. if (result != DD_OK) {
  361. DirectDraw2Interface = NULL;
  362. } else {
  363. DDCAPS capabilities;
  364. DDCAPS emulated_capabilities;
  365. memset ((char*)&capabilities, 0, sizeof(capabilities));
  366. memset ((char*)&emulated_capabilities, 0, sizeof(emulated_capabilities));
  367. capabilities.dwSize = sizeof (capabilities);
  368. emulated_capabilities.dwSize = sizeof (emulated_capabilities);
  369. DirectDrawObject->GetCaps (&capabilities, &emulated_capabilities);
  370. if (capabilities.dwCaps & DDCAPS_CANBLTSYSMEM) {
  371. SystemToVideoBlits = (capabilities.dwSVBCaps & DDCAPS_BLT) ? true : false;
  372. VideoToSystemBlits = (capabilities.dwVSBCaps & DDCAPS_BLT) ? true : false;
  373. SystemToSystemBlits = (capabilities.dwSSBCaps & DDCAPS_BLT) ? true : false;
  374. }
  375. }
  376. #endif //(0)
  377. //MessageBox(MainWindow, "In Set_Video_Mode. About to return success.","Note", MB_ICONEXCLAMATION|MB_OK);
  378. return (true);
  379. }
  380. /***********************************************************************************************
  381. * Reset_Video_Mode -- Resets video mode and deletes Direct Draw Object *
  382. * *
  383. * INPUT: none *
  384. * *
  385. * OUTPUT: none *
  386. * *
  387. * WARNINGS: *
  388. * *
  389. * HISTORY: *
  390. * 09/26/1995 PWG : Created. *
  391. *=============================================================================================*/
  392. void Reset_Video_Mode(void)
  393. {
  394. HRESULT result;
  395. //
  396. // If a direct draw object has been declared and a video mode has been set
  397. // then reset the video mode and release the direct draw object.
  398. //
  399. if ( DirectDrawObject ) {
  400. result = DirectDrawObject->RestoreDisplayMode();
  401. Process_DD_Result(result, false);
  402. result = DirectDrawObject->Release();
  403. Process_DD_Result(result, false);
  404. DirectDrawObject = NULL;
  405. }
  406. }
  407. /***********************************************************************************************
  408. * Get_Free_Video_Memory -- returns amount of free video memory *
  409. * *
  410. * *
  411. * *
  412. * INPUT: Nothing *
  413. * *
  414. * OUTPUT: bytes of available video RAM *
  415. * *
  416. * WARNINGS: None *
  417. * *
  418. * HISTORY: *
  419. * 11/29/95 12:52PM ST : Created *
  420. *=============================================================================================*/
  421. unsigned int Get_Free_Video_Memory(void)
  422. {
  423. DDCAPS video_capabilities;
  424. if (DirectDrawObject) {
  425. video_capabilities.dwSize = sizeof (video_capabilities);
  426. if (DD_OK == DirectDrawObject->GetCaps (&video_capabilities, NULL)) {
  427. char string [256];
  428. wsprintf (string, "In Get_Free_Video_Memory. About to return %d bytes",video_capabilities.dwVidMemFree);
  429. return (video_capabilities.dwVidMemFree);
  430. }
  431. }
  432. return (0);
  433. }
  434. /***********************************************************************************************
  435. * Get_Video_Hardware_Caps -- returns bitmask of direct draw video hardware support *
  436. * *
  437. * *
  438. * *
  439. * INPUT: Nothing *
  440. * *
  441. * OUTPUT: hardware flags *
  442. * *
  443. * WARNINGS: Must call Set_Video_Mode 1st to create the direct draw object *
  444. * *
  445. * HISTORY: *
  446. * 1/12/96 9:14AM ST : Created *
  447. *=============================================================================================*/
  448. unsigned Get_Video_Hardware_Capabilities(void)
  449. {
  450. DDCAPS video_capabilities;
  451. unsigned video;
  452. /*
  453. ** Fail if the direct draw object has not been initialised
  454. */
  455. if (!DirectDrawObject) return (0);
  456. /*
  457. ** Get the capabilities of the direct draw object
  458. */
  459. video_capabilities.dwSize = sizeof(video_capabilities);
  460. //MessageBox(MainWindow, "In Get_Video_Hardware_Capabilities. About to call GetCaps","Note", MB_ICONEXCLAMATION|MB_OK);
  461. HRESULT result = DirectDrawObject->GetCaps (&video_capabilities, NULL);
  462. if (result != DD_OK) {
  463. Process_DD_Result(result, false);
  464. return (0);
  465. }
  466. /*
  467. ** Set flags to indicate the presence of the features we are interested in
  468. */
  469. video = 0;
  470. /* Hardware blits supported? */
  471. if (video_capabilities.dwCaps & DDCAPS_BLT) video |= VIDEO_BLITTER;
  472. /* Hardware blits asyncronous? */
  473. if (video_capabilities.dwCaps & DDCAPS_BLTQUEUE) video |= VIDEO_BLITTER_ASYNC;
  474. /* Can palette changes be synced to vertical refresh? */
  475. if (video_capabilities.dwCaps & DDCAPS_PALETTEVSYNC) video |= VIDEO_SYNC_PALETTE;
  476. /* Is the video cards memory bank switched? */
  477. if (video_capabilities.dwCaps & DDCAPS_BANKSWITCHED) video |= VIDEO_BANK_SWITCHED;
  478. /* Can the blitter do filled rectangles? */
  479. if (video_capabilities.dwCaps & DDCAPS_BLTCOLORFILL) video |= VIDEO_COLOR_FILL;
  480. /* Is there no hardware assistance avaailable at all? */
  481. if (video_capabilities.dwCaps & DDCAPS_NOHARDWARE) video |= VIDEO_NO_HARDWARE_ASSIST;
  482. //MessageBox(MainWindow, "In Get_Video_Hardware_Capabilities. About to return success.","Note", MB_ICONEXCLAMATION|MB_OK);
  483. return (video);
  484. }
  485. /***********************************************************************************************
  486. * Wait_Vert_Blank -- Waits for the start (leading edge) of a vertical blank *
  487. * *
  488. * INPUT: *
  489. * *
  490. * OUTPUT: *
  491. * *
  492. * WARNINGS: *
  493. * *
  494. * HISTORY: *
  495. *=============================================================================================*/
  496. void Wait_Vert_Blank(void)
  497. {
  498. if (CanVblankSync) {
  499. HRESULT result = DirectDrawObject->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
  500. if (result == E_NOTIMPL) {
  501. CanVblankSync = false;
  502. return;
  503. }
  504. Process_DD_Result(result, false);
  505. }
  506. }
  507. /***********************************************************************************************
  508. * Set_Palette -- set a direct draw palette *
  509. * *
  510. * *
  511. * *
  512. * INPUT: ptr to 768 rgb palette bytes *
  513. * *
  514. * OUTPUT: Nothing *
  515. * *
  516. * WARNINGS: None *
  517. * *
  518. * HISTORY: *
  519. * 10/11/95 3:33PM ST : Created *
  520. *=============================================================================================*/
  521. void Set_Palette(void const * palette)
  522. {
  523. assert(palette != NULL);
  524. if (&CurrentPalette[0] != palette) {
  525. memmove(CurrentPalette, palette, sizeof(CurrentPalette));
  526. }
  527. if (DirectDrawObject != NULL && PaletteSurface != NULL) {
  528. unsigned char * palette_get = (unsigned char *)palette;
  529. for (int index = 0; index < 256; index++) {
  530. int red = *palette_get++;
  531. int green = *palette_get++;
  532. int blue = *palette_get++;
  533. PaletteEntries[index].peRed = (unsigned char)red;
  534. PaletteEntries[index].peGreen = (unsigned char)green;
  535. PaletteEntries[index].peBlue = (unsigned char)blue;
  536. }
  537. if (PalettePtr != NULL) {
  538. if (!FirstPaletteSet) {
  539. PaletteSurface->SetPalette(PalettePtr);
  540. FirstPaletteSet = true;
  541. }
  542. PalettePtr->SetEntries(0, 0, 256, &PaletteEntries[0]);
  543. }
  544. }
  545. }
  546. /***********************************************************************************************
  547. * Wait_Blit -- waits for the DirectDraw blitter to become idle *
  548. * *
  549. * *
  550. * *
  551. * INPUT: Nothing *
  552. * *
  553. * OUTPUT: Nothing *
  554. * *
  555. * WARNINGS: None *
  556. * *
  557. * HISTORY: *
  558. * 07-25-95 03:53pm ST : Created *
  559. *=============================================================================================*/
  560. void Wait_Blit (void)
  561. {
  562. HRESULT return_code;
  563. do {
  564. return_code=PaletteSurface->GetBltStatus (DDGBS_ISBLTDONE);
  565. } while (return_code != DD_OK && return_code != DDERR_SURFACELOST);
  566. }