OVGABUF.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OVGABUF.CPP
  21. //Description : OVGABUF direct draw surface class
  22. #include <ALL.h>
  23. #include <OMOUSE.h>
  24. #include <IMGFUN.h>
  25. #include <OSYS.h>
  26. #include <OWORLD.h>
  27. #include <OVGA.h>
  28. #include <OVGABUF.h>
  29. //-------- Begin of function VgaBuf::VgaBuf ----------//
  30. VgaBuf::VgaBuf()
  31. {
  32. memset( this, 0, sizeof(VgaBuf) );
  33. }
  34. //-------- End of function VgaBuf::VgaBuf ----------//
  35. //-------- Begin of function VgaBuf::~VgaBuf ----------//
  36. VgaBuf::~VgaBuf()
  37. {
  38. deinit();
  39. }
  40. //-------- End of function VgaBuf::~VgaBuf ----------//
  41. //-------- Begin of function VgaBuf::init_front ----------//
  42. //
  43. // Create a direct draw front buffer.
  44. //
  45. void VgaBuf::init_front(LPDIRECTDRAW2 ddPtr)
  46. {
  47. DDSURFACEDESC ddsd;
  48. HRESULT rc;
  49. DDCAPS ddcaps;
  50. //------ Get Direct Draw capacity info --------//
  51. ddcaps.dwSize = sizeof( ddcaps );
  52. if( ddPtr->GetCaps( &ddcaps, NULL ) != DD_OK )
  53. err.run( "Error creating Direct Draw front surface!" );
  54. //---------------------------------------------//
  55. // Create the Front Buffer
  56. //---------------------------------------------//
  57. ZeroMemory( &ddsd, sizeof(ddsd) );
  58. ddsd.dwSize = sizeof( ddsd );
  59. ddsd.dwFlags = DDSD_CAPS;
  60. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  61. LPDIRECTDRAWSURFACE dd1Buf;
  62. rc = ddPtr->CreateSurface( &ddsd, &dd1Buf, NULL );
  63. if( rc != DD_OK )
  64. err.run( "Error creating Direct Draw front surface!" );
  65. rc = dd1Buf->QueryInterface(IID_IDirectDrawSurface2, (void **)&dd_buf);
  66. if( rc != DD_OK )
  67. {
  68. dd1Buf->Release();
  69. err.run ( "Error creating Direct Draw front surface!!" );
  70. }
  71. dd1Buf->Release();
  72. is_front = 1;
  73. }
  74. //-------- End of function VgaBuf::init_front ----------//
  75. //-------- Begin of function VgaBuf::init_back ----------//
  76. //
  77. // Create a direct draw back buffer.
  78. //
  79. // [DWORD] w : width of the surface [default 0 : VGA_WIDTH]
  80. // [DWORD] h : height of the surface [default 0 : VGA_HEIGHT]
  81. //
  82. void VgaBuf::init_back( LPDIRECTDRAW2 ddPtr, DWORD w, DWORD h )
  83. {
  84. DDSURFACEDESC ddsd;
  85. HRESULT rc;
  86. //--------- fill in surface desc -----------//
  87. memset( &ddsd, 0, sizeof( ddsd ) );
  88. ddsd.dwSize = sizeof( ddsd );
  89. ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
  90. ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  91. ddsd.dwWidth = w ? w : VGA_WIDTH;
  92. ddsd.dwHeight = h ? h : VGA_HEIGHT;
  93. LPDIRECTDRAWSURFACE dd1Buf;
  94. rc = ddPtr->CreateSurface( &ddsd, &dd1Buf, NULL );
  95. if( rc != DD_OK )
  96. err.run( "Error creating direct draw back surface!" );
  97. rc = dd1Buf->QueryInterface(IID_IDirectDrawSurface2, (void **)&dd_buf);
  98. if( rc != DD_OK )
  99. {
  100. dd1Buf->Release();
  101. err.run( "Error creating direct draw back surface!!" );
  102. }
  103. dd1Buf->Release();
  104. }
  105. //-------- End of function VgaBuf::init_back ----------//
  106. //------ Begin of function VgaBuf::deinit --------//
  107. void VgaBuf::deinit()
  108. {
  109. if( dd_buf )
  110. {
  111. dd_buf->Release();
  112. dd_buf = NULL;
  113. }
  114. }
  115. //-------- End of function VgaBuf::deinit ----------//
  116. //-------- Begin of function VgaBuf::activate_pal ----------//
  117. //
  118. // Activate a palette to the current direct draw surface buffer.
  119. //
  120. void VgaBuf::activate_pal(LPDIRECTDRAWPALETTE ddPalPtr)
  121. {
  122. err_when(!ddPalPtr || !dd_buf);
  123. HRESULT rc = dd_buf->SetPalette(ddPalPtr);
  124. if( rc == DDERR_SURFACELOST )
  125. {
  126. dd_buf->Restore();
  127. rc = dd_buf->SetPalette(ddPalPtr);
  128. }
  129. #ifdef DEBUG
  130. if( rc != DD_OK )
  131. debug_msg( "VgaBuf::activate_pal(), failed activating the palette" );
  132. #endif
  133. }
  134. //--------- End of function VgaBuf::activate_pal ----------//
  135. //-------- Begin of function VgaBuf::color_match ----------//
  136. DWORD VgaBuf::color_match(COLORREF rgb)
  137. {
  138. COLORREF rgbT;
  139. HDC hdc;
  140. DWORD dw = CLR_INVALID;
  141. DDSURFACEDESC ddsd;
  142. HRESULT hres;
  143. if( dd_buf->GetDC(&hdc) == DD_OK )
  144. {
  145. rgbT = GetPixel(hdc, 0, 0);
  146. SetPixel(hdc, 0, 0, rgb);
  147. dd_buf->ReleaseDC(hdc);
  148. }
  149. ddsd.dwSize = sizeof(ddsd);
  150. hres = dd_buf->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
  151. if (hres == DD_OK)
  152. {
  153. dw = *(DWORD *)ddsd.lpSurface;
  154. dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;
  155. dd_buf->Unlock(NULL);
  156. }
  157. if (dd_buf->GetDC(&hdc) == DD_OK)
  158. {
  159. SetPixel(hdc, 0, 0, rgbT);
  160. dd_buf->ReleaseDC(hdc);
  161. }
  162. return dw;
  163. }
  164. //-------- End Endof function VgaBuf::color_match ----------//
  165. //-------- Begin of function VgaBuf::is_buf_lost ----------//
  166. //
  167. BOOL VgaBuf::is_buf_lost()
  168. {
  169. return dd_buf && dd_buf->IsLost() == DDERR_SURFACELOST;
  170. }
  171. //--------- End of function VgaBuf::is_buf_lost ----------//
  172. //-------- Begin of function VgaBuf::restore_buf ----------//
  173. //
  174. // Restore buffers that have been lost.
  175. //
  176. BOOL VgaBuf::restore_buf()
  177. {
  178. if( dd_buf == NULL || dd_buf->Restore() != DD_OK )
  179. {
  180. #ifdef DEBUG
  181. debug_msg("Error restoring direct draw buffer");
  182. #endif
  183. return FALSE;
  184. }
  185. return TRUE;
  186. }
  187. //--------- End of function VgaBuf::restore_buf ----------//
  188. //------------- Begin of function VgaBuf::lock_buf --------------//
  189. void VgaBuf::lock_buf()
  190. {
  191. err_if( buf_locked )
  192. err_now( "VgaBuf::lock_buf() error, buffer already locked." );
  193. memset( &buf_des, 0, sizeof(buf_des) );
  194. buf_des.dwSize = sizeof(buf_des);
  195. int rc = dd_buf->Lock(NULL, &buf_des, DDLOCK_WAIT, NULL);
  196. cur_buf_ptr = (char*) buf_des.lpSurface;
  197. //--------------------------------------//
  198. if( rc==DD_OK )
  199. buf_locked = TRUE;
  200. else
  201. {
  202. if( is_front )
  203. err_now( "VgaBuf::lock_buf() locking front buffer failed." );
  204. else
  205. err_now( "VgaBuf::lock_buf() locking back buffer failed." );
  206. #ifdef DEBUG
  207. debug_msg( "Failed to lock the buffer." );
  208. #endif
  209. }
  210. }
  211. //--------------- End of function VgaBuf::lock_buf --------------//
  212. //------------- Begin of function VgaBuf::unlock_buf --------------//
  213. void VgaBuf::unlock_buf()
  214. {
  215. // ####### begin Gilbert 16/9 #####//
  216. if( !dd_buf )
  217. return;
  218. // ####### end Gilbert 16/9 #####//
  219. err_when( !buf_locked );
  220. int rc = dd_buf->Unlock(NULL);
  221. if( rc==DD_OK )
  222. buf_locked = FALSE;
  223. else
  224. {
  225. switch(rc)
  226. {
  227. case DDERR_INVALIDOBJECT:
  228. err_now( "VgaBuf::unlock_buf error: DDERR_INVALIDOBJECT" );
  229. case DDERR_INVALIDPARAMS:
  230. err_now( "VgaBuf::unlock_buf error: DDERR_INVALIDPARAMS" );
  231. case DDERR_INVALIDRECT:
  232. err_now( "VgaBuf::unlock_buf error: DDERR_INVALIDRECT" );
  233. case DDERR_NOTLOCKED:
  234. err_now( "VgaBuf::unlock_buf error: DDERR_NOTLOCKED" );
  235. case DDERR_SURFACELOST:
  236. err_now( "VgaBuf::unlock_buf error: DDERR_SURFACELOST" );
  237. }
  238. if( is_front )
  239. err_now( "VgaBuf::unlock_buf() unlocking front buffer failed." );
  240. else
  241. err_now( "VgaBuf::unlock_buf() unlocking back buffer failed." );
  242. #ifdef DEBUG
  243. debug_msg( "Failed to unlock the buffer." );
  244. #endif
  245. }
  246. }
  247. //--------------- End of function VgaBuf::unlock_buf --------------//
  248. //------------- Begin of function VgaBuf::temp_unlock --------------//
  249. //
  250. // Unlock the Vga buffer temporarily.
  251. //
  252. void VgaBuf::temp_unlock()
  253. {
  254. // ######### begin Gilbert 16/9 ########//
  255. save_locked_flag = buf_locked;
  256. if( buf_locked )
  257. unlock_buf();
  258. // ######### end Gilbert 16/9 ########//
  259. }
  260. //--------------- End of function VgaBuf::temp_unlock --------------//
  261. //------------- Begin of function VgaBuf::temp_restore_lock --------------//
  262. //
  263. // Restore the previous lock stage.
  264. //
  265. void VgaBuf::temp_restore_lock()
  266. {
  267. if( save_locked_flag )
  268. lock_buf();
  269. }
  270. //--------------- End of function VgaBuf::temp_restore_lock --------------//
  271. //------------- Begin of function VgaBuf::put_bitmap --------------//
  272. //
  273. // Put a bitmap on the surface buffer
  274. //
  275. void VgaBuf::put_bitmap(int x,int y,char* bitmapPtr)
  276. {
  277. err_when( !buf_locked );
  278. if( is_front )
  279. mouse.hide_area( x, y, x+*((short*)bitmapPtr)-1, y+*(((short*)bitmapPtr)+1)-1 );
  280. IMGblt(buf_ptr(), buf_pitch(), x, y, bitmapPtr);
  281. if( is_front )
  282. mouse.show_area();
  283. }
  284. //--------------- End of function VgaBuf::put_bitmap --------------//
  285. //------- Begin of function VgaBuf::put_bitmap_trans --------//
  286. //
  287. // Put a bitmap on the surface buffer and hide the mouse cursor while displaying
  288. //
  289. void VgaBuf::put_bitmap_trans(int x,int y,char* bitmapPtr)
  290. {
  291. err_when( !buf_locked );
  292. if( is_front )
  293. mouse.hide_area( x, y, x+*((short*)bitmapPtr)-1, y+*(((short*)bitmapPtr)+1)-1 );
  294. IMGbltTrans(buf_ptr(), buf_pitch(), x, y, bitmapPtr);
  295. if( is_front )
  296. mouse.show_area();
  297. }
  298. //--------- End of function VgaBuf::put_bitmap_trans --------//
  299. //------- Begin of function VgaBuf::put_bitmap_remap --------//
  300. //
  301. // Put a bitmap on the surface buffer and hide the mouse cursor while displaying
  302. //
  303. void VgaBuf::put_bitmap_remap(int x,int y,char* bitmapPtr,char *colorTable)
  304. {
  305. err_when( !buf_locked );
  306. if( is_front )
  307. mouse.hide_area( x, y, x+*((short*)bitmapPtr)-1, y+*(((short*)bitmapPtr)+1)-1 );
  308. IMGbltRemap(buf_ptr(), buf_pitch(), x, y, bitmapPtr, colorTable);
  309. if( is_front )
  310. mouse.show_area();
  311. }
  312. //--------- End of function VgaBuf::put_bitmap_remap --------//
  313. //---------- Begin of function VgaBuf::save_area_common_buf ----------//
  314. //
  315. // Save screen area to sys.common_data_buf.
  316. //
  317. void VgaBuf::save_area_common_buf(int x1, int y1, int x2, int y2)
  318. {
  319. err_when( x1>x2 || y1>y2 || x1<0 || y1<0 || x2>=VGA_WIDTH || y2>=VGA_HEIGHT );
  320. long saveSize = sizeof(short)*6 + (x2-x1+1) * (y2-y1+1);
  321. err_if( saveSize > COMMON_DATA_BUF_SIZE )
  322. err_now( "VgaBuf::save_area_common_buf()" );
  323. short* shortPtr = (short*) sys.common_data_buf;
  324. *shortPtr++ = x1;
  325. *shortPtr++ = y1;
  326. *shortPtr++ = x2;
  327. *shortPtr++ = y2;
  328. //-------- read screen ---------//
  329. if( is_front )
  330. mouse.hide_area( x1,y1,x2,y2 ); // if the mouse cursor is in that area, hide it
  331. read_bitmap( x1,y1,x2,y2, (char*) shortPtr );
  332. if( is_front )
  333. mouse.show_area();
  334. }
  335. //------------ End of function VgaBuf::save_area_common_buf ----------//
  336. //---------- Begin of function VgaBuf::rest_area_common_buf ----------//
  337. //
  338. // Restore screen area to the screen from Vga image buffer.
  339. // This screen should be previously saved by save_area()
  340. //
  341. void VgaBuf::rest_area_common_buf()
  342. {
  343. short* shortPtr = (short*) sys.common_data_buf;
  344. int x1 = *shortPtr++;
  345. int y1 = *shortPtr++;
  346. int x2 = *shortPtr++;
  347. int y2 = *shortPtr++;
  348. put_bitmap( x1, y1, (char*) shortPtr );
  349. }
  350. //------------ End of function VgaBuf::rest_area_common_buf ----------//
  351. //---------- Begin of function VgaBuf::save_area ---------//
  352. //
  353. // save_area() differs from save_area() as :
  354. //
  355. // save_area() save the screen to a user-defined buffer.
  356. // save_area() save the screen to the global screen saving buffer in Vga object
  357. //
  358. // <int> x1,y1,x2,y2 = the area of the screen
  359. // [char*] saveScr = the pointer to the previous saved buffer
  360. // (default : initialize a new buffer)
  361. //
  362. char* VgaBuf::save_area(int x1, int y1, int x2, int y2, char* saveScr )
  363. {
  364. err_when( x1>x2 || y1>y2 || x1<0 || y1<0 || x2>=VGA_WIDTH || y2>=VGA_HEIGHT );
  365. long newSize = sizeof(short)*6 + (x2-x1+1) * (y2-y1+1);
  366. saveScr = mem_resize( saveScr, newSize );
  367. short* shortPtr = (short*) saveScr;
  368. *shortPtr++ = x1;
  369. *shortPtr++ = y1;
  370. *shortPtr++ = x2;
  371. *shortPtr++ = y2;
  372. if( is_front )
  373. mouse.hide_area( x1,y1,x2,y2 ); // if the mouse cursor is in that area, hide it
  374. read_bitmap( x1,y1,x2,y2, (char*) shortPtr );
  375. if( is_front )
  376. mouse.show_area();
  377. return saveScr;
  378. }
  379. //------------ End of function VgaBuf::save_area ---------//
  380. //----------- Begin of function VgaBuf::rest_area --------//
  381. //
  382. // Restore previously saved screen
  383. //
  384. // char* saveScr = the previously saved screen
  385. // [int] releaseFlag = whether release the buffer of the saved screen or not
  386. // (default : 1)
  387. //
  388. void VgaBuf::rest_area(char* saveScr, int releaseFlag)
  389. {
  390. int x1,y1,x2,y2;
  391. if( saveScr == NULL )
  392. return;
  393. short* shortPtr = (short*) saveScr;
  394. x1 = *shortPtr++;
  395. y1 = *shortPtr++;
  396. x2 = *shortPtr++;
  397. y2 = *shortPtr++;
  398. err_when( x1>x2 || y1>y2 || x1<0 || y1<0 || x2>=VGA_WIDTH || y2>=VGA_HEIGHT );
  399. put_bitmap( x1, y1, (char*) shortPtr );
  400. if( releaseFlag )
  401. mem_del( saveScr );
  402. }
  403. //------------ End of function VgaBuf::rest_area ----------//
  404. //------------ Begin of function VgaBuf::write_bmp_file --------------//
  405. //
  406. // Load a BMP file into the current VgaBuf DIB object.
  407. //
  408. // <char*> fileName - the name of the BMP file.
  409. //
  410. // return : <int> 1-succeeded, 0-failed.
  411. //
  412. int VgaBuf::write_bmp_file(char* fileName)
  413. {
  414. File bmpFile;
  415. bmpFile.file_create(fileName, 1, 0); // 1-handle error, 0-disable variable file size
  416. //------------ Write the file header ------------//
  417. BITMAPFILEHEADER bmpFileHdr;
  418. bmpFileHdr.bfType = 0x4D42; // set the type to "BM"
  419. bmpFileHdr.bfReserved1 = 0;
  420. bmpFileHdr.bfReserved2 = 0;
  421. bmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256;
  422. bmpFileHdr.bfSize = buf_size() + bmpFileHdr.bfOffBits;
  423. bmpFile.file_write(&bmpFileHdr, sizeof(bmpFileHdr));
  424. //------------ Write in the info header -----------//
  425. BITMAPINFOHEADER bmpInfoHdr;
  426. bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
  427. bmpInfoHdr.biWidth = buf_des.dwWidth;
  428. bmpInfoHdr.biHeight = buf_des.dwHeight;
  429. bmpInfoHdr.biPlanes = 1;
  430. bmpInfoHdr.biBitCount = 8;
  431. bmpInfoHdr.biCompression = BI_RGB;
  432. bmpInfoHdr.biSizeImage = buf_size();
  433. bmpInfoHdr.biXPelsPerMeter = 0;
  434. bmpInfoHdr.biYPelsPerMeter = 0;
  435. bmpInfoHdr.biClrUsed = 0;
  436. bmpInfoHdr.biClrImportant = 0;
  437. bmpFile.file_write(&bmpInfoHdr, sizeof(bmpInfoHdr));
  438. //------------ write the color table -----------//
  439. LPDIRECTDRAWPALETTE ddPalettePtr; // get the direct draw surface's palette
  440. dd_buf->GetPalette(&ddPalettePtr);
  441. PALETTEENTRY *palEntries = (PALETTEENTRY*) mem_add( sizeof(PALETTEENTRY)*256 );
  442. ddPalettePtr->GetEntries(0, 0, 256, palEntries);
  443. RGBQUAD *colorTable = (RGBQUAD*) mem_add( sizeof(RGBQUAD)*256 ); // allocate a color table with 256 entries
  444. for( int i=0 ; i<256 ; i++ )
  445. {
  446. colorTable[i].rgbBlue = palEntries[i].peBlue;
  447. colorTable[i].rgbGreen = palEntries[i].peGreen;
  448. colorTable[i].rgbRed = palEntries[i].peRed;
  449. colorTable[i].rgbReserved = 0;
  450. }
  451. bmpFile.file_write(colorTable, sizeof(RGBQUAD)*256);
  452. mem_del(palEntries);
  453. mem_del(colorTable);
  454. //----------- write the bitmap ----------//
  455. for( int y=buf_height()-1 ; y>=0 ; y-- ) // write in reversed order as DIB's vertical order is reversed
  456. bmpFile.file_write(buf_ptr(0,y), buf_width());
  457. //------------ close the file -----------//
  458. bmpFile.file_close();
  459. return 1;
  460. }
  461. //------------ End of function VgaBuf::write_bmp_file --------------//
  462. int VgaBuf::write_bmp_file(char * fileName, int offset_x, int offset_y, int width, int height)
  463. {
  464. if (!width || !height || !offset_x || !offset_y) return 0;
  465. if (offset_x + width > buf_des.dwWidth) return 0;
  466. if (offset_y + width > buf_des.dwHeight) return 0;
  467. File bmpFile;
  468. bmpFile.file_create(fileName, 1, 0); // 1-handle error, 0-disable variable file size
  469. //------------ Write the file header ------------//
  470. BITMAPFILEHEADER bmpFileHdr;
  471. bmpFileHdr.bfType = 0x4D42; // set the type to "BM"
  472. bmpFileHdr.bfReserved1 = 0;
  473. bmpFileHdr.bfReserved2 = 0;
  474. bmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256;
  475. bmpFileHdr.bfSize = bmpFileHdr.bfOffBits + width * height;
  476. bmpFile.file_write(&bmpFileHdr, sizeof(bmpFileHdr));
  477. //------------ Write in the info header -----------//
  478. BITMAPINFOHEADER bmpInfoHdr;
  479. bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
  480. bmpInfoHdr.biWidth = width;
  481. bmpInfoHdr.biHeight = height;
  482. bmpInfoHdr.biPlanes = 1;
  483. bmpInfoHdr.biBitCount = 8;
  484. bmpInfoHdr.biCompression = BI_RGB;
  485. bmpInfoHdr.biSizeImage = width * height;
  486. bmpInfoHdr.biXPelsPerMeter = 0;
  487. bmpInfoHdr.biYPelsPerMeter = 0;
  488. bmpInfoHdr.biClrUsed = 0;
  489. bmpInfoHdr.biClrImportant = 0;
  490. bmpFile.file_write(&bmpInfoHdr, sizeof(bmpInfoHdr));
  491. //------------ write the color table -----------//
  492. LPDIRECTDRAWPALETTE ddPalettePtr; // get the direct draw surface's palette
  493. dd_buf->GetPalette(&ddPalettePtr);
  494. PALETTEENTRY *palEntries = (PALETTEENTRY*) mem_add(sizeof(PALETTEENTRY) * 256);
  495. ddPalettePtr->GetEntries(0, 0, 256, palEntries);
  496. RGBQUAD *colorTable = (RGBQUAD*) mem_add(sizeof(RGBQUAD) * 256); // allocate a color table with 256 entries
  497. for (int i = 0; i < 256; i++)
  498. {
  499. colorTable[i].rgbBlue = palEntries[i].peBlue;
  500. colorTable[i].rgbGreen = palEntries[i].peGreen;
  501. colorTable[i].rgbRed = palEntries[i].peRed;
  502. colorTable[i].rgbReserved = 0;
  503. }
  504. bmpFile.file_write(colorTable, sizeof(RGBQUAD) * 256);
  505. mem_del(palEntries);
  506. mem_del(colorTable);
  507. //----------- write the bitmap ----------//
  508. char paddingBytes[4];
  509. for (int y = offset_y + height - 1; y >= offset_y; y--) // write in reversed order as DIB's vertical order is reversed
  510. {
  511. bmpFile.file_write(buf_ptr(offset_x, y), width);
  512. if (width % 4 != 0) bmpFile.file_write(paddingBytes, 4 - (width % 4));
  513. }
  514. //------------ close the file -----------//
  515. bmpFile.file_close();
  516. return 1;
  517. }
  518. //---------- Begin of function VgaBuf::put_large_bitmap ---------//
  519. //
  520. // Put a picture on the screen, when a picture's size is > 64K
  521. // Pass a file pointer to put_large_bitmap() for continously reading the file
  522. //
  523. // Syntax
  524. //
  525. // <int> x, y = the location of the picture on the screen
  526. // <FILE*> filePtr = pointer to the
  527. //
  528. //--------- Format of Picture buffer -------//
  529. //
  530. // int = whether this picture buffer contains the palette or not
  531. // -1 (0xFF) if has, otherwise not
  532. // char[256][3] = VGA color palette
  533. //
  534. // <int> = picture width
  535. // <int> = picture height
  536. //
  537. // char[...] = non-compressed flat picture bitmap
  538. //
  539. //---------------------------------------------//
  540. void VgaBuf::put_large_bitmap(int x1, int y1, File* filePtr)
  541. {
  542. if( filePtr == NULL )
  543. return;
  544. int pictWidth = filePtr->file_get_short();
  545. int hasPalette=0;
  546. //------- read in color palette if this picture has one -----//
  547. /*
  548. if( pictWidth == -1 ) // if the has palette in it
  549. {
  550. //------- set all palette to dark black ------//
  551. ColorPal colorPal;
  552. colorPal.red=0;
  553. colorPal.green=0;
  554. colorPal.blue=0;
  555. palette.set_single(colorPal);
  556. //-------- get the palette of the picture --------//
  557. ColorPal palBuf[256];
  558. filePtr->file_read( palBuf, sizeof(ColorPal)*256 );
  559. palette.set_fade_in(0, 255, palBuf, 15 ); // 15 steps for the whole fade in process, each step 0.01 seconds, 10 steps = 0.1 second
  560. hasPalette=1;
  561. pictWidth = filePtr->file_get_short();
  562. }
  563. */
  564. //------ read in bitmap and display it --------//
  565. int pictHeight = filePtr->file_get_short();
  566. int x2 = x1 + pictWidth - 1;
  567. int y2 = y1 + pictHeight - 1;
  568. long pictSize = (long) x2 * y2;
  569. err_when( x1>x2 || y1>y2 || x1<0 || y1<0 || x2>=VGA_WIDTH || y2>=VGA_HEIGHT );
  570. //---- if pict size less than 64K, read in the picture in one step ----//
  571. if( pictSize <= COMMON_DATA_BUF_SIZE )
  572. {
  573. filePtr->file_read( sys.common_data_buf, pictSize );
  574. if( is_front )
  575. mouse.hide_area( x1,y1,x2,y2 ); // if the mouse cursor is in that area, hide it
  576. put_bitmap2( x1, y1, pictWidth, pictHeight, sys.common_data_buf );
  577. if( is_front )
  578. mouse.show_area();
  579. }
  580. else //----- if the picture size > 64K, read in line by line -----//
  581. {
  582. int bufferLine = COMMON_DATA_BUF_SIZE / pictWidth; // max. no. of lines can be in the buffer
  583. int ty=y1+bufferLine-1;
  584. if( ty> y2 )
  585. ty=y2;
  586. while( y1<=y2 )
  587. {
  588. filePtr->file_read( sys.common_data_buf, (unsigned)pictWidth * (ty-y1+1) );
  589. if( is_front )
  590. mouse.hide_area( x1,y1,x2,ty ); // if the mouse cursor is in that area, hide it
  591. put_bitmap2( x1, y1, pictWidth, ty-y1+1, sys.common_data_buf );
  592. if( is_front )
  593. mouse.show_area();
  594. y1 += bufferLine;
  595. if( (ty+=bufferLine) > y2 )
  596. ty=y2;
  597. }
  598. }
  599. /*
  600. if( hasPalette )
  601. while( !palette.fade_in() );
  602. */
  603. }
  604. //----------- End of function VgaBuf::put_large_bitmap --------//
  605. //----------- Begin of function VgaBuf::convert_gray ----------//
  606. //
  607. // Convert an specified area of the bitmap from color to gray-scale.
  608. //
  609. void VgaBuf::convert_gray(int x1, int y1, int x2, int y2)
  610. {
  611. remap_bar(x1, y1, x2, y2, vga.gray_remap_table);
  612. }
  613. //--------- End of function VgaBuf::convert_gray -----------//