video.c 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  4. // All rights reserved.
  5. //
  6. // This file is part of SDLPAL.
  7. //
  8. // SDLPAL is free software: you can redistribute it and/or modify
  9. // it under the terms of the GNU General Public License as published by
  10. // the Free Software Foundation, either version 3 of the License, or
  11. // (at your option) any later version.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU General Public License
  19. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. //
  21. #include "main.h"
  22. // Screen buffer
  23. SDL_Surface *gpScreen = NULL;
  24. // Backup screen buffer
  25. SDL_Surface *gpScreenBak = NULL;
  26. // The real screen surface
  27. #if SDL_VERSION_ATLEAST(2,0,0)
  28. static SDL_Window *gpWindow = NULL;
  29. static SDL_Renderer *gpRenderer = NULL;
  30. #else
  31. static SDL_Surface *gpScreenReal = NULL;
  32. #endif
  33. #if (defined (__SYMBIAN32__) && !defined (__S60_5X__)) || defined (PSP) || defined (GEKKO)
  34. static BOOL bScaleScreen = FALSE;
  35. #else
  36. static BOOL bScaleScreen = TRUE;
  37. #endif
  38. // Initial screen size
  39. static WORD g_wInitialWidth = 640;
  40. static WORD g_wInitialHeight = 400;
  41. // Shake times and level
  42. static WORD g_wShakeTime = 0;
  43. static WORD g_wShakeLevel = 0;
  44. INT
  45. #ifdef GEKKO // Rikku2000: Crash on compile, allready define on WIISDK
  46. VIDEO_Init_GEKKO(
  47. #else
  48. VIDEO_Init(
  49. #endif
  50. WORD wScreenWidth,
  51. WORD wScreenHeight,
  52. BOOL fFullScreen
  53. )
  54. /*++
  55. Purpose:
  56. Initialze the video subsystem.
  57. Parameters:
  58. [IN] wScreenWidth - width of the screen.
  59. [IN] wScreenHeight - height of the screen.
  60. [IN] fFullScreen - TRUE to use full screen mode, FALSE to use windowed mode.
  61. Return value:
  62. 0 = success, -1 = fail to create the screen surface,
  63. -2 = fail to create screen buffer.
  64. --*/
  65. {
  66. g_wInitialWidth = wScreenWidth;
  67. g_wInitialHeight = wScreenHeight;
  68. #if SDL_VERSION_ATLEAST(2,0,0)
  69. //
  70. // Before we can render anything, we need a window and a renderer.
  71. //
  72. gpWindow = SDL_CreateWindow("Pal",
  73. SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 400,
  74. SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
  75. if (gpWindow == NULL)
  76. {
  77. return -1;
  78. }
  79. gpRenderer = SDL_CreateRenderer(gpWindow, -1, SDL_RENDERER_ACCELERATED);
  80. if (gpRenderer == NULL)
  81. {
  82. return -1;
  83. }
  84. //
  85. // Create the screen buffer and the backup screen buffer.
  86. //
  87. gpScreen = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 200, 8, 0, 0, 0, 0);
  88. gpScreenBak = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 200, 8, 0, 0, 0, 0);
  89. //
  90. // Failed?
  91. //
  92. if (gpScreen == NULL || gpScreenBak == NULL)
  93. {
  94. if (gpScreen != NULL)
  95. {
  96. SDL_FreeSurface(gpScreen);
  97. gpScreen = NULL;
  98. }
  99. if (gpScreenBak != NULL)
  100. {
  101. SDL_FreeSurface(gpScreenBak);
  102. gpScreenBak = NULL;
  103. }
  104. SDL_DestroyRenderer(gpRenderer);
  105. gpRenderer = NULL;
  106. SDL_DestroyWindow(gpWindow);
  107. gpWindow = NULL;
  108. return -2;
  109. }
  110. #else
  111. //
  112. // Create the screen surface.
  113. //
  114. #if defined (NDS)
  115. gpScreenReal = SDL_SetVideoMode(293, 196, 8, SDL_SWSURFACE | SDL_FULLSCREEN);
  116. #elif defined (__SYMBIAN32__)
  117. #ifdef __S60_5X__
  118. gpScreenReal = SDL_SetVideoMode(640, 360, 8,
  119. SDL_SWSURFACE | (fFullScreen ? SDL_FULLSCREEN : 0));
  120. #else
  121. gpScreenReal = SDL_SetVideoMode(320, 240, 8,
  122. SDL_SWSURFACE | (fFullScreen ? SDL_FULLSCREEN : 0));
  123. #endif
  124. #elif defined (GEKKO)
  125. gpScreenReal = SDL_SetVideoMode(640, 480, 8,
  126. SDL_SWSURFACE | (fFullScreen ? SDL_FULLSCREEN : 0));
  127. #elif defined (PSP)
  128. gpScreenReal = SDL_SetVideoMode(320, 240, 8, SDL_SWSURFACE | SDL_FULLSCREEN);
  129. #else
  130. gpScreenReal = SDL_SetVideoMode(wScreenWidth, wScreenHeight, 8,
  131. SDL_HWSURFACE | SDL_RESIZABLE | (fFullScreen ? SDL_FULLSCREEN : 0));
  132. #endif
  133. if (gpScreenReal == NULL)
  134. {
  135. //
  136. // Fall back to 640x480 software mode.
  137. //
  138. gpScreenReal = SDL_SetVideoMode(640, 480, 8,
  139. SDL_SWSURFACE | (fFullScreen ? SDL_FULLSCREEN : 0));
  140. }
  141. //
  142. // Still fail?
  143. //
  144. if (gpScreenReal == NULL)
  145. {
  146. return -1;
  147. }
  148. //
  149. // Create the screen buffer and the backup screen buffer.
  150. //
  151. gpScreen = SDL_CreateRGBSurface(gpScreenReal->flags & ~SDL_HWSURFACE, 320, 200, 8,
  152. gpScreenReal->format->Rmask, gpScreenReal->format->Gmask,
  153. gpScreenReal->format->Bmask, gpScreenReal->format->Amask);
  154. gpScreenBak = SDL_CreateRGBSurface(gpScreenReal->flags & ~SDL_HWSURFACE, 320, 200, 8,
  155. gpScreenReal->format->Rmask, gpScreenReal->format->Gmask,
  156. gpScreenReal->format->Bmask, gpScreenReal->format->Amask);
  157. //
  158. // Failed?
  159. //
  160. if (gpScreen == NULL || gpScreenBak == NULL)
  161. {
  162. if (gpScreen != NULL)
  163. {
  164. SDL_FreeSurface(gpScreen);
  165. gpScreen = NULL;
  166. }
  167. if (gpScreenBak != NULL)
  168. {
  169. SDL_FreeSurface(gpScreenBak);
  170. gpScreenBak = NULL;
  171. }
  172. SDL_FreeSurface(gpScreenReal);
  173. gpScreenReal = NULL;
  174. return -2;
  175. }
  176. #endif
  177. if (fFullScreen)
  178. {
  179. SDL_ShowCursor(FALSE);
  180. }
  181. return 0;
  182. }
  183. VOID
  184. VIDEO_Shutdown(
  185. VOID
  186. )
  187. /*++
  188. Purpose:
  189. Shutdown the video subsystem.
  190. Parameters:
  191. None.
  192. Return value:
  193. None.
  194. --*/
  195. {
  196. if (gpScreen != NULL)
  197. {
  198. SDL_FreeSurface(gpScreen);
  199. }
  200. gpScreen = NULL;
  201. if (gpScreenBak != NULL)
  202. {
  203. SDL_FreeSurface(gpScreenBak);
  204. }
  205. gpScreenBak = NULL;
  206. #if SDL_VERSION_ATLEAST(2,0,0)
  207. if (gpRenderer)
  208. {
  209. SDL_DestroyRenderer(gpRenderer);
  210. }
  211. gpRenderer = NULL;
  212. if (gpWindow)
  213. {
  214. SDL_DestroyWindow(gpWindow);
  215. }
  216. gpWindow = NULL;
  217. #else
  218. if (gpScreenReal != NULL)
  219. {
  220. SDL_FreeSurface(gpScreenReal);
  221. }
  222. gpScreenReal = NULL;
  223. #endif
  224. }
  225. VOID
  226. VIDEO_UpdateScreen(
  227. const SDL_Rect *lpRect
  228. )
  229. /*++
  230. Purpose:
  231. Update the screen area specified by lpRect.
  232. Parameters:
  233. [IN] lpRect - Screen area to update.
  234. Return value:
  235. None.
  236. --*/
  237. {
  238. #if SDL_VERSION_ATLEAST(2,0,0)
  239. // TODO
  240. SDL_Texture *pTexture = SDL_CreateTextureFromSurface(gpRenderer, gpScreen);
  241. SDL_RenderClear(gpRenderer);
  242. SDL_RenderCopy(gpRenderer, pTexture, NULL/*srcrect*/, NULL/*dstrect*/);
  243. SDL_RenderPresent(gpRenderer);
  244. SDL_DestroyTexture(pTexture);
  245. #else
  246. SDL_Rect srcrect, dstrect;
  247. short offset = 240 - 200;
  248. short screenRealHeight = gpScreenReal->h;
  249. short screenRealY = 0;
  250. //
  251. // Lock surface if needed
  252. //
  253. if (SDL_MUSTLOCK(gpScreenReal))
  254. {
  255. if (SDL_LockSurface(gpScreenReal) < 0)
  256. return;
  257. }
  258. if (!bScaleScreen)
  259. {
  260. screenRealHeight -= offset;
  261. screenRealY = offset / 2;
  262. }
  263. if (lpRect != NULL)
  264. {
  265. dstrect.x = (SHORT)((INT)(lpRect->x) * gpScreenReal->w / gpScreen->w);
  266. dstrect.y = (SHORT)((INT)(screenRealY + lpRect->y) * screenRealHeight / gpScreen->h);
  267. dstrect.w = (WORD)((DWORD)(lpRect->w) * gpScreenReal->w / gpScreen->w);
  268. dstrect.h = (WORD)((DWORD)(lpRect->h) * screenRealHeight / gpScreen->h);
  269. SDL_SoftStretch(gpScreen, (SDL_Rect *)lpRect, gpScreenReal, &dstrect);
  270. if (SDL_MUSTLOCK(gpScreenReal))
  271. {
  272. SDL_UnlockSurface(gpScreenReal);
  273. }
  274. SDL_UpdateRect(gpScreenReal, dstrect.x, dstrect.y, dstrect.w, dstrect.h);
  275. }
  276. else if (g_wShakeTime != 0)
  277. {
  278. //
  279. // Shake the screen
  280. //
  281. srcrect.x = 0;
  282. srcrect.y = 0;
  283. srcrect.w = 320;
  284. srcrect.h = 200 - g_wShakeLevel;
  285. dstrect.x = 0;
  286. dstrect.y = screenRealY;
  287. dstrect.w = 320 * gpScreenReal->w / gpScreen->w;
  288. dstrect.h = (200 - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  289. if (g_wShakeTime & 1)
  290. {
  291. srcrect.y = g_wShakeLevel;
  292. }
  293. else
  294. {
  295. dstrect.y = (screenRealY + g_wShakeLevel) * screenRealHeight / gpScreen->h;
  296. }
  297. SDL_SoftStretch(gpScreen, &srcrect, gpScreenReal, &dstrect);
  298. if (g_wShakeTime & 1)
  299. {
  300. dstrect.y = (screenRealY + screenRealHeight - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  301. }
  302. else
  303. {
  304. dstrect.y = screenRealY;
  305. }
  306. dstrect.h = g_wShakeLevel * screenRealHeight / gpScreen->h;
  307. SDL_FillRect(gpScreenReal, &dstrect, 0);
  308. if (SDL_MUSTLOCK(gpScreenReal))
  309. {
  310. SDL_UnlockSurface(gpScreenReal);
  311. }
  312. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  313. g_wShakeTime--;
  314. }
  315. else
  316. {
  317. dstrect.x = 0;
  318. dstrect.y = screenRealY;
  319. dstrect.w = gpScreenReal->w;
  320. dstrect.h = screenRealHeight;
  321. SDL_SoftStretch(gpScreen, NULL, gpScreenReal, &dstrect);
  322. if (SDL_MUSTLOCK(gpScreenReal))
  323. {
  324. SDL_UnlockSurface(gpScreenReal);
  325. }
  326. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  327. }
  328. #endif
  329. }
  330. VOID
  331. VIDEO_SetPalette(
  332. SDL_Color rgPalette[256]
  333. )
  334. /*++
  335. Purpose:
  336. Set the palette of the screen.
  337. Parameters:
  338. [IN] rgPalette - array of 256 colors.
  339. Return value:
  340. None.
  341. --*/
  342. {
  343. #if SDL_VERSION_ATLEAST(2,0,0)
  344. int i;
  345. SDL_Palette *palette = SDL_AllocPalette(256);
  346. if (palette == NULL)
  347. {
  348. return;
  349. }
  350. for (i = 0; i < 256; i++)
  351. {
  352. palette->colors[i] = rgPalette[i];
  353. }
  354. SDL_SetSurfacePalette(gpScreen, palette);
  355. #else
  356. SDL_SetPalette(gpScreen, SDL_LOGPAL | SDL_PHYSPAL, rgPalette, 0, 256);
  357. SDL_SetPalette(gpScreenReal, SDL_LOGPAL | SDL_PHYSPAL, rgPalette, 0, 256);
  358. #if (defined (__SYMBIAN32__))
  359. {
  360. static UINT32 time = 0;
  361. if (SDL_GetTicks() - time > 50)
  362. {
  363. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  364. time = SDL_GetTicks();
  365. }
  366. }
  367. #endif
  368. #endif
  369. }
  370. VOID
  371. VIDEO_Resize(
  372. INT w,
  373. INT h
  374. )
  375. /*++
  376. Purpose:
  377. This function is called when user resized the window.
  378. Parameters:
  379. [IN] w - width of the window after resizing.
  380. [IN] h - height of the window after resizing.
  381. Return value:
  382. None.
  383. --*/
  384. {
  385. #if SDL_VERSION_ATLEAST(2,0,0)
  386. // TODO
  387. #else
  388. DWORD flags;
  389. PAL_LARGE SDL_Color palette[256];
  390. int i;
  391. //
  392. // Get the original palette.
  393. //
  394. for (i = 0; i < gpScreenReal->format->palette->ncolors; i++)
  395. {
  396. palette[i] = gpScreenReal->format->palette->colors[i];
  397. }
  398. //
  399. // Create the screen surface.
  400. //
  401. flags = gpScreenReal->flags;
  402. SDL_FreeSurface(gpScreenReal);
  403. gpScreenReal = SDL_SetVideoMode(w, h, 8, flags);
  404. if (gpScreenReal == NULL)
  405. {
  406. #ifdef __SYMBIAN32__
  407. #ifdef __S60_5X__
  408. gpScreenReal = SDL_SetVideoMode(640, 360, 8, SDL_SWSURFACE);
  409. #else
  410. gpScreenReal = SDL_SetVideoMode(320, 240, 8, SDL_SWSURFACE);
  411. #endif
  412. #else
  413. //
  414. // Fall back to 640x480 software windowed mode.
  415. //
  416. gpScreenReal = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
  417. #endif
  418. }
  419. SDL_SetPalette(gpScreenReal, SDL_PHYSPAL | SDL_LOGPAL, palette, 0, i);
  420. VIDEO_UpdateScreen(NULL);
  421. #endif
  422. }
  423. SDL_Color *
  424. VIDEO_GetPalette(
  425. VOID
  426. )
  427. /*++
  428. Purpose:
  429. Get the current palette of the screen.
  430. Parameters:
  431. None.
  432. Return value:
  433. Pointer to the current palette.
  434. --*/
  435. {
  436. #if SDL_VERSION_ATLEAST(2,0,0)
  437. return gpScreen->format->palette->colors;
  438. #else
  439. return gpScreenReal->format->palette->colors;
  440. #endif
  441. }
  442. VOID
  443. VIDEO_ToggleScaleScreen(
  444. VOID
  445. )
  446. /*++
  447. Purpose:
  448. Toggle scalescreen mode.
  449. Parameters:
  450. None.
  451. Return value:
  452. None.
  453. --*/
  454. {
  455. #ifdef __SYMBIAN32__
  456. bScaleScreen = !bScaleScreen;
  457. VIDEO_Resize(320, 240);
  458. VIDEO_UpdateScreen(NULL);
  459. #endif
  460. }
  461. VOID
  462. VIDEO_ToggleFullscreen(
  463. VOID
  464. )
  465. /*++
  466. Purpose:
  467. Toggle fullscreen mode.
  468. Parameters:
  469. None.
  470. Return value:
  471. None.
  472. --*/
  473. {
  474. #if SDL_VERSION_ATLEAST(2,0,0)
  475. // TODO
  476. #else
  477. DWORD flags;
  478. PAL_LARGE SDL_Color palette[256];
  479. int i;
  480. //
  481. // Get the original palette.
  482. //
  483. for (i = 0; i < gpScreenReal->format->palette->ncolors; i++)
  484. {
  485. palette[i] = gpScreenReal->format->palette->colors[i];
  486. }
  487. //
  488. // Get the flags of the original screen surface
  489. //
  490. flags = gpScreenReal->flags;
  491. if (flags & SDL_FULLSCREEN)
  492. {
  493. //
  494. // Already in fullscreen mode. Remove the fullscreen flag.
  495. //
  496. flags &= ~SDL_FULLSCREEN;
  497. flags |= SDL_RESIZABLE;
  498. SDL_ShowCursor(TRUE);
  499. }
  500. else
  501. {
  502. //
  503. // Not in fullscreen mode. Set the fullscreen flag.
  504. //
  505. flags |= SDL_FULLSCREEN;
  506. SDL_ShowCursor(FALSE);
  507. }
  508. //
  509. // Free the original screen surface
  510. //
  511. SDL_FreeSurface(gpScreenReal);
  512. //
  513. // ... and create a new one
  514. //
  515. if (g_wInitialWidth == 640 && g_wInitialHeight == 400 && (flags & SDL_FULLSCREEN))
  516. {
  517. gpScreenReal = SDL_SetVideoMode(640, 480, 8, flags);
  518. }
  519. else if (g_wInitialWidth == 640 && g_wInitialHeight == 480 && !(flags & SDL_FULLSCREEN))
  520. {
  521. gpScreenReal = SDL_SetVideoMode(640, 400, 8, flags);
  522. }
  523. else
  524. {
  525. gpScreenReal = SDL_SetVideoMode(g_wInitialWidth, g_wInitialHeight, 8, flags);
  526. }
  527. VIDEO_SetPalette(palette);
  528. //
  529. // Update the screen
  530. //
  531. VIDEO_UpdateScreen(NULL);
  532. #endif
  533. }
  534. VOID
  535. VIDEO_SaveScreenshot(
  536. VOID
  537. )
  538. /*++
  539. Purpose:
  540. Save the screenshot of current screen to a BMP file.
  541. Parameters:
  542. None.
  543. Return value:
  544. None.
  545. --*/
  546. {
  547. int iNumBMP = 0;
  548. FILE *fp;
  549. //
  550. // Find a usable BMP filename.
  551. //
  552. for (iNumBMP = 0; iNumBMP <= 9999; iNumBMP++)
  553. {
  554. fp = fopen(va("%sscrn%.4d.bmp", PAL_PREFIX, iNumBMP), "rb");
  555. if (fp == NULL)
  556. {
  557. break;
  558. }
  559. fclose(fp);
  560. }
  561. if (iNumBMP > 9999)
  562. {
  563. return;
  564. }
  565. //
  566. // Save the screenshot.
  567. //
  568. #if SDL_VERSION_ATLEAST(2,0,0)
  569. SDL_SaveBMP(gpScreen, va("%sscrn%.4d.bmp", PAL_PREFIX, iNumBMP));
  570. #else
  571. SDL_SaveBMP(gpScreenReal, va("%sscrn%.4d.bmp", PAL_PREFIX, iNumBMP));
  572. #endif
  573. }
  574. VOID
  575. VIDEO_BackupScreen(
  576. VOID
  577. )
  578. /*++
  579. Purpose:
  580. Backup the screen buffer.
  581. Parameters:
  582. None.
  583. Return value:
  584. None.
  585. --*/
  586. {
  587. SDL_BlitSurface(gpScreen, NULL, gpScreenBak, NULL);
  588. }
  589. VOID
  590. VIDEO_RestoreScreen(
  591. VOID
  592. )
  593. /*++
  594. Purpose:
  595. Restore the screen buffer which has been saved with VIDEO_BackupScreen().
  596. Parameters:
  597. None.
  598. Return value:
  599. None.
  600. --*/
  601. {
  602. SDL_BlitSurface(gpScreenBak, NULL, gpScreen, NULL);
  603. }
  604. VOID
  605. VIDEO_ShakeScreen(
  606. WORD wShakeTime,
  607. WORD wShakeLevel
  608. )
  609. /*++
  610. Purpose:
  611. Set the screen shake time and level.
  612. Parameters:
  613. [IN] wShakeTime - how many times should we shake the screen.
  614. [IN] wShakeLevel - level of shaking.
  615. Return value:
  616. None.
  617. --*/
  618. {
  619. g_wShakeTime = wShakeTime;
  620. g_wShakeLevel = wShakeLevel;
  621. }
  622. VOID
  623. VIDEO_SwitchScreen(
  624. WORD wSpeed
  625. )
  626. /*++
  627. Purpose:
  628. Switch the screen from the backup screen buffer to the current screen buffer.
  629. NOTE: This will destroy the backup buffer.
  630. Parameters:
  631. [IN] wSpeed - speed of fading (the larger value, the slower).
  632. Return value:
  633. None.
  634. --*/
  635. {
  636. #if SDL_VERSION_ATLEAST(2,0,0)
  637. // TODO
  638. #else
  639. int i, j;
  640. const int rgIndex[6] = {0, 3, 1, 5, 2, 4};
  641. SDL_Rect dstrect;
  642. short offset = 240 - 200;
  643. short screenRealHeight = gpScreenReal->h;
  644. short screenRealY = 0;
  645. if (!bScaleScreen)
  646. {
  647. screenRealHeight -= offset;
  648. screenRealY = offset / 2;
  649. }
  650. wSpeed++;
  651. wSpeed *= 10;
  652. for (i = 0; i < 6; i++)
  653. {
  654. for (j = rgIndex[i]; j < gpScreen->pitch * gpScreen->h; j += 6)
  655. {
  656. ((LPBYTE)(gpScreenBak->pixels))[j] = ((LPBYTE)(gpScreen->pixels))[j];
  657. }
  658. //
  659. // Draw the backup buffer to the screen
  660. //
  661. dstrect.x = 0;
  662. dstrect.y = screenRealY;
  663. dstrect.w = gpScreenReal->w;
  664. dstrect.h = screenRealHeight;
  665. SDL_SoftStretch(gpScreenBak, NULL, gpScreenReal, &dstrect);
  666. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  667. UTIL_Delay(wSpeed);
  668. }
  669. #endif
  670. }
  671. VOID
  672. VIDEO_FadeScreen(
  673. WORD wSpeed
  674. )
  675. /*++
  676. Purpose:
  677. Fade from the backup screen buffer to the current screen buffer.
  678. NOTE: This will destroy the backup buffer.
  679. Parameters:
  680. [IN] wSpeed - speed of fading (the larger value, the slower).
  681. Return value:
  682. None.
  683. --*/
  684. {
  685. #if SDL_VERSION_ATLEAST(2,0,0)
  686. // TODO
  687. #else
  688. int i, j, k;
  689. DWORD time;
  690. BYTE a, b;
  691. const int rgIndex[6] = {0, 3, 1, 5, 2, 4};
  692. SDL_Rect dstrect;
  693. short offset = 240 - 200;
  694. short screenRealHeight = gpScreenReal->h;
  695. short screenRealY = 0;
  696. //
  697. // Lock surface if needed
  698. //
  699. if (SDL_MUSTLOCK(gpScreenReal))
  700. {
  701. if (SDL_LockSurface(gpScreenReal) < 0)
  702. return;
  703. }
  704. if (!bScaleScreen)
  705. {
  706. screenRealHeight -= offset;
  707. screenRealY = offset / 2;
  708. }
  709. time = SDL_GetTicks();
  710. wSpeed++;
  711. wSpeed *= 10;
  712. for (i = 0; i < 12; i++)
  713. {
  714. for (j = 0; j < 6; j++)
  715. {
  716. PAL_ProcessEvent();
  717. while (SDL_GetTicks() <= time)
  718. {
  719. PAL_ProcessEvent();
  720. SDL_Delay(5);
  721. }
  722. time = SDL_GetTicks() + wSpeed;
  723. //
  724. // Blend the pixels in the 2 buffers, and put the result into the
  725. // backup buffer
  726. //
  727. for (k = rgIndex[j]; k < gpScreen->pitch * gpScreen->h; k += 6)
  728. {
  729. a = ((LPBYTE)(gpScreen->pixels))[k];
  730. b = ((LPBYTE)(gpScreenBak->pixels))[k];
  731. if (i > 0)
  732. {
  733. if ((a & 0x0F) > (b & 0x0F))
  734. {
  735. b++;
  736. }
  737. else if ((a & 0x0F) < (b & 0x0F))
  738. {
  739. b--;
  740. }
  741. }
  742. ((LPBYTE)(gpScreenBak->pixels))[k] = ((a & 0xF0) | (b & 0x0F));
  743. }
  744. //
  745. // Draw the backup buffer to the screen
  746. //
  747. if (g_wShakeTime != 0)
  748. {
  749. //
  750. // Shake the screen
  751. //
  752. SDL_Rect srcrect, dstrect;
  753. srcrect.x = 0;
  754. srcrect.y = 0;
  755. srcrect.w = 320;
  756. srcrect.h = 200 - g_wShakeLevel;
  757. dstrect.x = 0;
  758. dstrect.y = screenRealY;
  759. dstrect.w = 320 * gpScreenReal->w / gpScreen->w;
  760. dstrect.h = (200 - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  761. if (g_wShakeTime & 1)
  762. {
  763. srcrect.y = g_wShakeLevel;
  764. }
  765. else
  766. {
  767. dstrect.y = (screenRealY + g_wShakeLevel) * screenRealHeight / gpScreen->h;
  768. }
  769. SDL_SoftStretch(gpScreenBak, &srcrect, gpScreenReal, &dstrect);
  770. if (g_wShakeTime & 1)
  771. {
  772. dstrect.y = (screenRealY + screenRealHeight - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  773. }
  774. else
  775. {
  776. dstrect.y = screenRealY;
  777. }
  778. dstrect.h = g_wShakeLevel * screenRealHeight / gpScreen->h;
  779. SDL_FillRect(gpScreenReal, &dstrect, 0);
  780. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  781. g_wShakeTime--;
  782. }
  783. else
  784. {
  785. dstrect.x = 0;
  786. dstrect.y = screenRealY;
  787. dstrect.w = gpScreenReal->w;
  788. dstrect.h = screenRealHeight;
  789. SDL_SoftStretch(gpScreenBak, NULL, gpScreenReal, &dstrect);
  790. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  791. }
  792. }
  793. }
  794. if (SDL_MUSTLOCK(gpScreenReal))
  795. {
  796. SDL_UnlockSurface(gpScreenReal);
  797. }
  798. //
  799. // Draw the result buffer to the screen as the final step
  800. //
  801. VIDEO_UpdateScreen(NULL);
  802. #endif
  803. }
  804. #if SDL_VERSION_ATLEAST(2,0,0)
  805. /*++
  806. Purpose:
  807. Set the caption of the window. For compatibility with SDL2 only.
  808. Parameters:
  809. [IN] lpszCaption - the new caption of the window.
  810. [IN] lpReserved - not used, for compatibility only.
  811. Return value:
  812. None.
  813. --*/
  814. VOID
  815. SDL_WM_SetCaption(
  816. LPCSTR lpszCaption,
  817. LPVOID lpReserved
  818. )
  819. {
  820. if (gpWindow != NULL)
  821. {
  822. SDL_SetWindowTitle(gpWindow, lpszCaption);
  823. }
  824. }
  825. #endif