map.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009-2011, Wei Mingzhi <whistler_wmz@users.sf.net>.
  4. // Copyright (c) 2011-2017, SDLPAL development team.
  5. // All rights reserved.
  6. //
  7. // This file is part of SDLPAL.
  8. //
  9. // SDLPAL is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation, either version 3 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. //
  22. #include "palcommon.h"
  23. #include "map.h"
  24. LPPALMAP
  25. PAL_LoadMap(
  26. INT iMapNum,
  27. FILE *fpMapMKF,
  28. FILE *fpGopMKF
  29. )
  30. /*++
  31. Purpose:
  32. Load the specified map from the MKF file, as well as the tile bitmaps.
  33. Parameters:
  34. [IN] iMapNum - Number of the map to load.
  35. [IN] fpMapMKF - Pointer to the fopen'ed map.mkf file, which
  36. contains the map tile data.
  37. [IN] fpGopMKF - Pointer to the fopen'ed gop.mkf file, which
  38. contains the tile bitmaps. The bitmap can be read
  39. by PAL_SpriteGetFrame() function.
  40. Return value:
  41. Pointer to the loaded map. NULL if failed.
  42. --*/
  43. {
  44. LPBYTE buf;
  45. INT size, i, j;
  46. LPPALMAP map;
  47. //
  48. // Check for invalid map number.
  49. //
  50. if (iMapNum >= PAL_MKFGetChunkCount(fpMapMKF) ||
  51. iMapNum >= PAL_MKFGetChunkCount(fpGopMKF) ||
  52. iMapNum <= 0)
  53. {
  54. return NULL;
  55. }
  56. //
  57. // Load the map tile data.
  58. //
  59. size = PAL_MKFGetChunkSize(iMapNum, fpMapMKF);
  60. //
  61. // Allocate a temporary buffer for the compressed data.
  62. //
  63. buf = (LPBYTE)malloc(size);
  64. if (buf == NULL)
  65. {
  66. return NULL;
  67. }
  68. //
  69. // Create the map instance.
  70. //
  71. map = (LPPALMAP)malloc(sizeof(PALMAP));
  72. if (map == NULL)
  73. {
  74. return NULL;
  75. }
  76. //
  77. // Read the map data.
  78. //
  79. if (PAL_MKFReadChunk(buf, size, iMapNum, fpMapMKF) < 0)
  80. {
  81. free(buf);
  82. free(map);
  83. return NULL;
  84. }
  85. //
  86. // Decompress the tile data.
  87. //
  88. if (Decompress(buf, (LPBYTE)(map->Tiles), sizeof(map->Tiles)) < 0)
  89. {
  90. free(map);
  91. free(buf);
  92. return NULL;
  93. }
  94. //
  95. // The compressed data is useless now; delete it.
  96. //
  97. free(buf);
  98. //
  99. // Adjust the endianness of the decompressed data.
  100. //
  101. for (i = 0; i < 128; i++)
  102. {
  103. for (j = 0; j < 64; j++)
  104. {
  105. map->Tiles[i][j][0] = SDL_SwapLE32(map->Tiles[i][j][0]);
  106. map->Tiles[i][j][1] = SDL_SwapLE32(map->Tiles[i][j][1]);
  107. }
  108. }
  109. //
  110. // Load the tile bitmaps.
  111. //
  112. size = PAL_MKFGetChunkSize(iMapNum, fpGopMKF);
  113. if (size <= 0)
  114. {
  115. free(map);
  116. return NULL;
  117. }
  118. map->pTileSprite = (LPSPRITE)malloc(size);
  119. if (map->pTileSprite == NULL)
  120. {
  121. free(map);
  122. return NULL;
  123. }
  124. if (PAL_MKFReadChunk(map->pTileSprite, size, iMapNum, fpGopMKF) < 0)
  125. {
  126. free(map);
  127. return NULL;
  128. }
  129. //
  130. // Done.
  131. //
  132. map->iMapNum = iMapNum;
  133. return map;
  134. }
  135. VOID
  136. PAL_FreeMap(
  137. LPPALMAP lpMap
  138. )
  139. /*++
  140. Purpose:
  141. Free a loaded map, as well as the tile bitmaps.
  142. Parameters:
  143. [IN] lpMap - Pointer to the loaded map structure.
  144. Return value:
  145. None.
  146. --*/
  147. {
  148. //
  149. // Check for NULL pointer.
  150. //
  151. if (lpMap == NULL)
  152. {
  153. return;
  154. }
  155. //
  156. // Free the tile bitmaps.
  157. //
  158. if (lpMap->pTileSprite != NULL)
  159. {
  160. free(lpMap->pTileSprite);
  161. }
  162. //
  163. // Delete the instance.
  164. //
  165. free(lpMap);
  166. }
  167. LPCBITMAPRLE
  168. PAL_MapGetTileBitmap(
  169. BYTE x,
  170. BYTE y,
  171. BYTE h,
  172. BYTE ucLayer,
  173. LPCPALMAP lpMap
  174. )
  175. /*++
  176. Purpose:
  177. Get the tile bitmap on the specified layer at the location (x, y, h).
  178. Parameters:
  179. [IN] x - Column number of the tile.
  180. [IN] y - Line number in the map.
  181. [IN] h - Each line in the map has two lines of tiles, 0 and 1.
  182. (See map.h for details.)
  183. [IN] ucLayer - The layer. 0 for bottom, 1 for top.
  184. [IN] lpMap - Pointer to the loaded map.
  185. Return value:
  186. Pointer to the bitmap. NULL if failed.
  187. --*/
  188. {
  189. DWORD d;
  190. //
  191. // Check for invalid parameters.
  192. //
  193. if (x >= 64 || y >= 128 || h > 1 || lpMap == NULL)
  194. {
  195. return NULL;
  196. }
  197. //
  198. // Get the tile data of the specified location.
  199. //
  200. d = lpMap->Tiles[y][x][h];
  201. if (ucLayer == 0)
  202. {
  203. //
  204. // Bottom layer
  205. //
  206. return PAL_SpriteGetFrame(lpMap->pTileSprite, (d & 0xFF) | ((d >> 4) & 0x100));
  207. }
  208. else
  209. {
  210. //
  211. // Top layer
  212. //
  213. d >>= 16;
  214. return PAL_SpriteGetFrame(lpMap->pTileSprite, ((d & 0xFF) | ((d >> 4) & 0x100)) - 1);
  215. }
  216. }
  217. BOOL
  218. PAL_MapTileIsBlocked(
  219. BYTE x,
  220. BYTE y,
  221. BYTE h,
  222. LPCPALMAP lpMap
  223. )
  224. /*++
  225. Purpose:
  226. Check if the tile at the specified location is blocked.
  227. Parameters:
  228. [IN] x - Column number of the tile.
  229. [IN] y - Line number in the map.
  230. [IN] h - Each line in the map has two lines of tiles, 0 and 1.
  231. (See map.h for details.)
  232. [IN] lpMap - Pointer to the loaded map.
  233. Return value:
  234. TRUE if the tile is blocked, FALSE if not.
  235. --*/
  236. {
  237. //
  238. // Check for invalid parameters.
  239. //
  240. if (x >= 64 || y >= 128 || h > 1 || lpMap == NULL)
  241. {
  242. return TRUE;
  243. }
  244. return (lpMap->Tiles[y][x][h] & 0x2000) >> 13;
  245. }
  246. BYTE
  247. PAL_MapGetTileHeight(
  248. BYTE x,
  249. BYTE y,
  250. BYTE h,
  251. BYTE ucLayer,
  252. LPCPALMAP lpMap
  253. )
  254. /*++
  255. Purpose:
  256. Get the logical height value of the specified tile. This value is used
  257. to judge whether the tile bitmap should cover the sprites or not.
  258. Parameters:
  259. [IN] x - Column number of the tile.
  260. [IN] y - Line number in the map.
  261. [IN] h - Each line in the map has two lines of tiles, 0 and 1.
  262. (See map.h for details.)
  263. [IN] ucLayer - The layer. 0 for bottom, 1 for top.
  264. [IN] lpMap - Pointer to the loaded map.
  265. Return value:
  266. The logical height value of the specified tile.
  267. --*/
  268. {
  269. DWORD d;
  270. //
  271. // Check for invalid parameters.
  272. //
  273. if (y >= 128 || x >= 64 || h > 1 || lpMap == NULL)
  274. {
  275. return 0;
  276. }
  277. d = lpMap->Tiles[y][x][h];
  278. if (ucLayer)
  279. {
  280. d >>= 16;
  281. }
  282. d >>= 8;
  283. return (BYTE)(d & 0xf);
  284. }
  285. VOID
  286. PAL_MapBlitToSurface(
  287. LPCPALMAP lpMap,
  288. SDL_Surface *lpSurface,
  289. const SDL_Rect *lpSrcRect,
  290. BYTE ucLayer
  291. )
  292. /*++
  293. Purpose:
  294. Blit the specified map area to a SDL Surface.
  295. Parameters:
  296. [IN] lpMap - Pointer to the map.
  297. [OUT] lpSurface - Pointer to the destination surface.
  298. [IN] lpSrcRect - Pointer to the source area.
  299. [IN] ucLayer - The layer. 0 for bottom, 1 for top.
  300. Return value:
  301. None.
  302. --*/
  303. {
  304. int sx, sy, dx, dy, x, y, h, xPos, yPos;
  305. LPCBITMAPRLE lpBitmap = NULL;
  306. //
  307. // Convert the coordinate
  308. //
  309. sy = lpSrcRect->y / 16 - 1;
  310. dy = (lpSrcRect->y + lpSrcRect->h) / 16 + 2;
  311. sx = lpSrcRect->x / 32 - 1;
  312. dx = (lpSrcRect->x + lpSrcRect->w) / 32 + 2;
  313. //
  314. // Do the drawing.
  315. //
  316. yPos = sy * 16 - 8 - lpSrcRect->y;
  317. for (y = sy; y < dy; y++)
  318. {
  319. for (h = 0; h < 2; h++, yPos += 8)
  320. {
  321. xPos = sx * 32 + h * 16 - 16 - lpSrcRect->x;
  322. for (x = sx; x < dx; x++, xPos += 32)
  323. {
  324. lpBitmap = PAL_MapGetTileBitmap((BYTE)x, (BYTE)y, (BYTE)h, ucLayer, lpMap);
  325. if (lpBitmap == NULL)
  326. {
  327. if (ucLayer)
  328. {
  329. continue;
  330. }
  331. lpBitmap = PAL_MapGetTileBitmap(0, 0, 0, ucLayer, lpMap);
  332. }
  333. PAL_RLEBlitToSurface(lpBitmap, lpSurface, PAL_XY(xPos, yPos));
  334. }
  335. }
  336. }
  337. }