map.c 7.9 KB

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