map.c 8.0 KB

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