video.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  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. #else
  245. SDL_Rect srcrect, dstrect;
  246. short offset = 240 - 200;
  247. short screenRealHeight = gpScreenReal->h;
  248. short screenRealY = 0;
  249. //
  250. // Lock surface if needed
  251. //
  252. if (SDL_MUSTLOCK(gpScreenReal))
  253. {
  254. if (SDL_LockSurface(gpScreenReal) < 0)
  255. return;
  256. }
  257. if (!bScaleScreen)
  258. {
  259. screenRealHeight -= offset;
  260. screenRealY = offset / 2;
  261. }
  262. if (lpRect != NULL)
  263. {
  264. dstrect.x = (SHORT)((INT)(lpRect->x) * gpScreenReal->w / gpScreen->w);
  265. dstrect.y = (SHORT)((INT)(screenRealY + lpRect->y) * screenRealHeight / gpScreen->h);
  266. dstrect.w = (WORD)((DWORD)(lpRect->w) * gpScreenReal->w / gpScreen->w);
  267. dstrect.h = (WORD)((DWORD)(lpRect->h) * screenRealHeight / gpScreen->h);
  268. SDL_SoftStretch(gpScreen, (SDL_Rect *)lpRect, gpScreenReal, &dstrect);
  269. if (SDL_MUSTLOCK(gpScreenReal))
  270. {
  271. SDL_UnlockSurface(gpScreenReal);
  272. }
  273. SDL_UpdateRect(gpScreenReal, dstrect.x, dstrect.y, dstrect.w, dstrect.h);
  274. }
  275. else if (g_wShakeTime != 0)
  276. {
  277. //
  278. // Shake the screen
  279. //
  280. srcrect.x = 0;
  281. srcrect.y = 0;
  282. srcrect.w = 320;
  283. srcrect.h = 200 - g_wShakeLevel;
  284. dstrect.x = 0;
  285. dstrect.y = screenRealY;
  286. dstrect.w = 320 * gpScreenReal->w / gpScreen->w;
  287. dstrect.h = (200 - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  288. if (g_wShakeTime & 1)
  289. {
  290. srcrect.y = g_wShakeLevel;
  291. }
  292. else
  293. {
  294. dstrect.y = (screenRealY + g_wShakeLevel) * screenRealHeight / gpScreen->h;
  295. }
  296. SDL_SoftStretch(gpScreen, &srcrect, gpScreenReal, &dstrect);
  297. if (g_wShakeTime & 1)
  298. {
  299. dstrect.y = (screenRealY + screenRealHeight - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  300. }
  301. else
  302. {
  303. dstrect.y = screenRealY;
  304. }
  305. dstrect.h = g_wShakeLevel * screenRealHeight / gpScreen->h;
  306. SDL_FillRect(gpScreenReal, &dstrect, 0);
  307. if (SDL_MUSTLOCK(gpScreenReal))
  308. {
  309. SDL_UnlockSurface(gpScreenReal);
  310. }
  311. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  312. g_wShakeTime--;
  313. }
  314. else
  315. {
  316. dstrect.x = 0;
  317. dstrect.y = screenRealY;
  318. dstrect.w = gpScreenReal->w;
  319. dstrect.h = screenRealHeight;
  320. SDL_SoftStretch(gpScreen, NULL, gpScreenReal, &dstrect);
  321. if (SDL_MUSTLOCK(gpScreenReal))
  322. {
  323. SDL_UnlockSurface(gpScreenReal);
  324. }
  325. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  326. }
  327. #endif
  328. }
  329. VOID
  330. VIDEO_SetPalette(
  331. SDL_Color rgPalette[256]
  332. )
  333. /*++
  334. Purpose:
  335. Set the palette of the screen.
  336. Parameters:
  337. [IN] rgPalette - array of 256 colors.
  338. Return value:
  339. None.
  340. --*/
  341. {
  342. #if SDL_VERSION_ATLEAST(2,0,0)
  343. int i;
  344. SDL_Palette *palette = SDL_AllocPalette(256);
  345. if (palette == NULL)
  346. {
  347. return;
  348. }
  349. for (i = 0; i < 256; i++)
  350. {
  351. palette->colors[i] = rgPalette[i];
  352. }
  353. SDL_SetSurfacePalette(gpScreen, palette);
  354. #else
  355. SDL_SetPalette(gpScreen, SDL_LOGPAL | SDL_PHYSPAL, rgPalette, 0, 256);
  356. SDL_SetPalette(gpScreenReal, SDL_LOGPAL | SDL_PHYSPAL, rgPalette, 0, 256);
  357. #if (defined (__SYMBIAN32__))
  358. {
  359. static UINT32 time = 0;
  360. if (SDL_GetTicks() - time > 50)
  361. {
  362. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  363. time = SDL_GetTicks();
  364. }
  365. }
  366. #endif
  367. #endif
  368. }
  369. VOID
  370. VIDEO_Resize(
  371. INT w,
  372. INT h
  373. )
  374. /*++
  375. Purpose:
  376. This function is called when user resized the window.
  377. Parameters:
  378. [IN] w - width of the window after resizing.
  379. [IN] h - height of the window after resizing.
  380. Return value:
  381. None.
  382. --*/
  383. {
  384. #if SDL_VERSION_ATLEAST(2,0,0)
  385. // TODO
  386. #else
  387. DWORD flags;
  388. PAL_LARGE SDL_Color palette[256];
  389. int i;
  390. //
  391. // Get the original palette.
  392. //
  393. for (i = 0; i < gpScreenReal->format->palette->ncolors; i++)
  394. {
  395. palette[i] = gpScreenReal->format->palette->colors[i];
  396. }
  397. //
  398. // Create the screen surface.
  399. //
  400. flags = gpScreenReal->flags;
  401. SDL_FreeSurface(gpScreenReal);
  402. gpScreenReal = SDL_SetVideoMode(w, h, 8, flags);
  403. if (gpScreenReal == NULL)
  404. {
  405. #ifdef __SYMBIAN32__
  406. #ifdef __S60_5X__
  407. gpScreenReal = SDL_SetVideoMode(640, 360, 8, SDL_SWSURFACE);
  408. #else
  409. gpScreenReal = SDL_SetVideoMode(320, 240, 8, SDL_SWSURFACE);
  410. #endif
  411. #else
  412. //
  413. // Fall back to 640x480 software windowed mode.
  414. //
  415. gpScreenReal = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
  416. #endif
  417. }
  418. SDL_SetPalette(gpScreenReal, SDL_PHYSPAL | SDL_LOGPAL, palette, 0, i);
  419. VIDEO_UpdateScreen(NULL);
  420. #endif
  421. }
  422. SDL_Color *
  423. VIDEO_GetPalette(
  424. VOID
  425. )
  426. /*++
  427. Purpose:
  428. Get the current palette of the screen.
  429. Parameters:
  430. None.
  431. Return value:
  432. Pointer to the current palette.
  433. --*/
  434. {
  435. #if SDL_VERSION_ATLEAST(2,0,0)
  436. return gpScreen->format->palette->colors;
  437. #else
  438. return gpScreenReal->format->palette->colors;
  439. #endif
  440. }
  441. VOID
  442. VIDEO_ToggleScaleScreen(
  443. VOID
  444. )
  445. /*++
  446. Purpose:
  447. Toggle scalescreen mode.
  448. Parameters:
  449. None.
  450. Return value:
  451. None.
  452. --*/
  453. {
  454. #ifdef __SYMBIAN32__
  455. bScaleScreen = !bScaleScreen;
  456. VIDEO_Resize(320, 240);
  457. VIDEO_UpdateScreen(NULL);
  458. #endif
  459. }
  460. VOID
  461. VIDEO_ToggleFullscreen(
  462. VOID
  463. )
  464. /*++
  465. Purpose:
  466. Toggle fullscreen mode.
  467. Parameters:
  468. None.
  469. Return value:
  470. None.
  471. --*/
  472. {
  473. #if SDL_VERSION_ATLEAST(2,0,0)
  474. // TODO
  475. #else
  476. DWORD flags;
  477. PAL_LARGE SDL_Color palette[256];
  478. int i;
  479. //
  480. // Get the original palette.
  481. //
  482. for (i = 0; i < gpScreenReal->format->palette->ncolors; i++)
  483. {
  484. palette[i] = gpScreenReal->format->palette->colors[i];
  485. }
  486. //
  487. // Get the flags of the original screen surface
  488. //
  489. flags = gpScreenReal->flags;
  490. if (flags & SDL_FULLSCREEN)
  491. {
  492. //
  493. // Already in fullscreen mode. Remove the fullscreen flag.
  494. //
  495. flags &= ~SDL_FULLSCREEN;
  496. flags |= SDL_RESIZABLE;
  497. SDL_ShowCursor(TRUE);
  498. }
  499. else
  500. {
  501. //
  502. // Not in fullscreen mode. Set the fullscreen flag.
  503. //
  504. flags |= SDL_FULLSCREEN;
  505. SDL_ShowCursor(FALSE);
  506. }
  507. //
  508. // Free the original screen surface
  509. //
  510. SDL_FreeSurface(gpScreenReal);
  511. //
  512. // ... and create a new one
  513. //
  514. if (g_wInitialWidth == 640 && g_wInitialHeight == 400 && (flags & SDL_FULLSCREEN))
  515. {
  516. gpScreenReal = SDL_SetVideoMode(640, 480, 8, flags);
  517. }
  518. else if (g_wInitialWidth == 640 && g_wInitialHeight == 480 && !(flags & SDL_FULLSCREEN))
  519. {
  520. gpScreenReal = SDL_SetVideoMode(640, 400, 8, flags);
  521. }
  522. else
  523. {
  524. gpScreenReal = SDL_SetVideoMode(g_wInitialWidth, g_wInitialHeight, 8, flags);
  525. }
  526. VIDEO_SetPalette(palette);
  527. //
  528. // Update the screen
  529. //
  530. VIDEO_UpdateScreen(NULL);
  531. #endif
  532. }
  533. VOID
  534. VIDEO_SaveScreenshot(
  535. VOID
  536. )
  537. /*++
  538. Purpose:
  539. Save the screenshot of current screen to a BMP file.
  540. Parameters:
  541. None.
  542. Return value:
  543. None.
  544. --*/
  545. {
  546. int iNumBMP = 0;
  547. FILE *fp;
  548. //
  549. // Find a usable BMP filename.
  550. //
  551. for (iNumBMP = 0; iNumBMP <= 9999; iNumBMP++)
  552. {
  553. fp = fopen(va("%sscrn%.4d.bmp", PAL_PREFIX, iNumBMP), "rb");
  554. if (fp == NULL)
  555. {
  556. break;
  557. }
  558. fclose(fp);
  559. }
  560. if (iNumBMP > 9999)
  561. {
  562. return;
  563. }
  564. //
  565. // Save the screenshot.
  566. //
  567. #if SDL_VERSION_ATLEAST(2,0,0)
  568. SDL_SaveBMP(gpScreen, va("%sscrn%.4d.bmp", PAL_PREFIX, iNumBMP));
  569. #else
  570. SDL_SaveBMP(gpScreenReal, va("%sscrn%.4d.bmp", PAL_PREFIX, iNumBMP));
  571. #endif
  572. }
  573. VOID
  574. VIDEO_BackupScreen(
  575. VOID
  576. )
  577. /*++
  578. Purpose:
  579. Backup the screen buffer.
  580. Parameters:
  581. None.
  582. Return value:
  583. None.
  584. --*/
  585. {
  586. SDL_BlitSurface(gpScreen, NULL, gpScreenBak, NULL);
  587. }
  588. VOID
  589. VIDEO_RestoreScreen(
  590. VOID
  591. )
  592. /*++
  593. Purpose:
  594. Restore the screen buffer which has been saved with VIDEO_BackupScreen().
  595. Parameters:
  596. None.
  597. Return value:
  598. None.
  599. --*/
  600. {
  601. SDL_BlitSurface(gpScreenBak, NULL, gpScreen, NULL);
  602. }
  603. VOID
  604. VIDEO_ShakeScreen(
  605. WORD wShakeTime,
  606. WORD wShakeLevel
  607. )
  608. /*++
  609. Purpose:
  610. Set the screen shake time and level.
  611. Parameters:
  612. [IN] wShakeTime - how many times should we shake the screen.
  613. [IN] wShakeLevel - level of shaking.
  614. Return value:
  615. None.
  616. --*/
  617. {
  618. g_wShakeTime = wShakeTime;
  619. g_wShakeLevel = wShakeLevel;
  620. }
  621. VOID
  622. VIDEO_SwitchScreen(
  623. WORD wSpeed
  624. )
  625. /*++
  626. Purpose:
  627. Switch the screen from the backup screen buffer to the current screen buffer.
  628. NOTE: This will destroy the backup buffer.
  629. Parameters:
  630. [IN] wSpeed - speed of fading (the larger value, the slower).
  631. Return value:
  632. None.
  633. --*/
  634. {
  635. #if SDL_VERSION_ATLEAST(2,0,0)
  636. // TODO
  637. #else
  638. int i, j;
  639. const int rgIndex[6] = {0, 3, 1, 5, 2, 4};
  640. SDL_Rect dstrect;
  641. short offset = 240 - 200;
  642. short screenRealHeight = gpScreenReal->h;
  643. short screenRealY = 0;
  644. if (!bScaleScreen)
  645. {
  646. screenRealHeight -= offset;
  647. screenRealY = offset / 2;
  648. }
  649. wSpeed++;
  650. wSpeed *= 10;
  651. for (i = 0; i < 6; i++)
  652. {
  653. for (j = rgIndex[i]; j < gpScreen->pitch * gpScreen->h; j += 6)
  654. {
  655. ((LPBYTE)(gpScreenBak->pixels))[j] = ((LPBYTE)(gpScreen->pixels))[j];
  656. }
  657. //
  658. // Draw the backup buffer to the screen
  659. //
  660. dstrect.x = 0;
  661. dstrect.y = screenRealY;
  662. dstrect.w = gpScreenReal->w;
  663. dstrect.h = screenRealHeight;
  664. SDL_SoftStretch(gpScreenBak, NULL, gpScreenReal, &dstrect);
  665. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  666. UTIL_Delay(wSpeed);
  667. }
  668. #endif
  669. }
  670. VOID
  671. VIDEO_FadeScreen(
  672. WORD wSpeed
  673. )
  674. /*++
  675. Purpose:
  676. Fade from the backup screen buffer to the current screen buffer.
  677. NOTE: This will destroy the backup buffer.
  678. Parameters:
  679. [IN] wSpeed - speed of fading (the larger value, the slower).
  680. Return value:
  681. None.
  682. --*/
  683. {
  684. #if SDL_VERSION_ATLEAST(2,0,0)
  685. // TODO
  686. #else
  687. int i, j, k;
  688. DWORD time;
  689. BYTE a, b;
  690. const int rgIndex[6] = {0, 3, 1, 5, 2, 4};
  691. SDL_Rect dstrect;
  692. short offset = 240 - 200;
  693. short screenRealHeight = gpScreenReal->h;
  694. short screenRealY = 0;
  695. //
  696. // Lock surface if needed
  697. //
  698. if (SDL_MUSTLOCK(gpScreenReal))
  699. {
  700. if (SDL_LockSurface(gpScreenReal) < 0)
  701. return;
  702. }
  703. if (!bScaleScreen)
  704. {
  705. screenRealHeight -= offset;
  706. screenRealY = offset / 2;
  707. }
  708. time = SDL_GetTicks();
  709. wSpeed++;
  710. wSpeed *= 10;
  711. for (i = 0; i < 12; i++)
  712. {
  713. for (j = 0; j < 6; j++)
  714. {
  715. PAL_ProcessEvent();
  716. while (SDL_GetTicks() <= time)
  717. {
  718. PAL_ProcessEvent();
  719. SDL_Delay(5);
  720. }
  721. time = SDL_GetTicks() + wSpeed;
  722. //
  723. // Blend the pixels in the 2 buffers, and put the result into the
  724. // backup buffer
  725. //
  726. for (k = rgIndex[j]; k < gpScreen->pitch * gpScreen->h; k += 6)
  727. {
  728. a = ((LPBYTE)(gpScreen->pixels))[k];
  729. b = ((LPBYTE)(gpScreenBak->pixels))[k];
  730. if (i > 0)
  731. {
  732. if ((a & 0x0F) > (b & 0x0F))
  733. {
  734. b++;
  735. }
  736. else if ((a & 0x0F) < (b & 0x0F))
  737. {
  738. b--;
  739. }
  740. }
  741. ((LPBYTE)(gpScreenBak->pixels))[k] = ((a & 0xF0) | (b & 0x0F));
  742. }
  743. //
  744. // Draw the backup buffer to the screen
  745. //
  746. if (g_wShakeTime != 0)
  747. {
  748. //
  749. // Shake the screen
  750. //
  751. SDL_Rect srcrect, dstrect;
  752. srcrect.x = 0;
  753. srcrect.y = 0;
  754. srcrect.w = 320;
  755. srcrect.h = 200 - g_wShakeLevel;
  756. dstrect.x = 0;
  757. dstrect.y = screenRealY;
  758. dstrect.w = 320 * gpScreenReal->w / gpScreen->w;
  759. dstrect.h = (200 - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  760. if (g_wShakeTime & 1)
  761. {
  762. srcrect.y = g_wShakeLevel;
  763. }
  764. else
  765. {
  766. dstrect.y = (screenRealY + g_wShakeLevel) * screenRealHeight / gpScreen->h;
  767. }
  768. SDL_SoftStretch(gpScreenBak, &srcrect, gpScreenReal, &dstrect);
  769. if (g_wShakeTime & 1)
  770. {
  771. dstrect.y = (screenRealY + screenRealHeight - g_wShakeLevel) * screenRealHeight / gpScreen->h;
  772. }
  773. else
  774. {
  775. dstrect.y = screenRealY;
  776. }
  777. dstrect.h = g_wShakeLevel * screenRealHeight / gpScreen->h;
  778. SDL_FillRect(gpScreenReal, &dstrect, 0);
  779. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  780. g_wShakeTime--;
  781. }
  782. else
  783. {
  784. dstrect.x = 0;
  785. dstrect.y = screenRealY;
  786. dstrect.w = gpScreenReal->w;
  787. dstrect.h = screenRealHeight;
  788. SDL_SoftStretch(gpScreenBak, NULL, gpScreenReal, &dstrect);
  789. SDL_UpdateRect(gpScreenReal, 0, 0, gpScreenReal->w, gpScreenReal->h);
  790. }
  791. }
  792. }
  793. if (SDL_MUSTLOCK(gpScreenReal))
  794. {
  795. SDL_UnlockSurface(gpScreenReal);
  796. }
  797. //
  798. // Draw the result buffer to the screen as the final step
  799. //
  800. VIDEO_UpdateScreen(NULL);
  801. #endif
  802. }
  803. #if SDL_VERSION_ATLEAST(2,0,0)
  804. /*++
  805. Purpose:
  806. Set the caption of the window. For compatibility with SDL2 only.
  807. Parameters:
  808. [IN] lpszCaption - the new caption of the window.
  809. [IN] lpReserved - not used, for compatibility only.
  810. Return value:
  811. None.
  812. --*/
  813. VOID
  814. SDL_WM_SetCaption(
  815. LPCSTR lpszCaption,
  816. LPVOID lpReserved
  817. )
  818. {
  819. if (gpWindow != NULL)
  820. {
  821. SDL_SetWindowTitle(gpWindow, lpszCaption);
  822. }
  823. }
  824. #endif