mac.c 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. /*
  2. Copyright (C) 2004-2005 Michael Liebscher <johnnycanuck@users.sourceforge.net>
  3. Copyright (C) 2000 Steven Fuller <relnev@atdot.org>
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. /*
  17. * mac.c: This module is used to extract data from the Macintosh
  18. * version of Wolfenstein 3-D.
  19. *
  20. * Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
  21. *
  22. * Acknowledgement:
  23. * Portion of this code was derived from code that was originally
  24. * written by Steven Fuller.
  25. *
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include "mac.h"
  30. #include "../wolf/wolf_def.h"
  31. #include "../../../common/arch.h"
  32. #include "../../../common/common_utils.h"
  33. #include "../loaders/tga.h"
  34. #include "../memory/memory.h"
  35. #include "../string/com_string.h"
  36. #include "../filesys/file.h"
  37. /* Resource file Palette offsets */
  38. #define MACPAL 898370L
  39. #define IDPAL 899142L
  40. #define GAMEPAL 946811L
  41. #define INTERPAL 997211L
  42. #define YUMMYPAL 1011345L
  43. #define TITLEPAL 2235007L
  44. #define PALETTE_SIZE 768
  45. #define MACBINFILENAME "Wolfenstein 3D"
  46. #define FILETYPECREATOR "APPLWOLF"
  47. #define DATAFORKLENGTH 105754L
  48. #define RESFORKLENGTH 2424697L
  49. PRIVATE W8 *macPalette;
  50. PRIVATE FILE *fResHandle;
  51. /*
  52. -----------------------------------------------------------------------------
  53. Function: getResourceBlock -Get block of resource data.
  54. Parameters: offset -[in] Number of bytes from start of file.
  55. length -[in] Length of resource block.
  56. glen -[out] next four bytes after block.
  57. Returns: NULL on error, otherwise pointer to block of memory.
  58. Notes: Caller is responsible for freeing memory block.
  59. -----------------------------------------------------------------------------
  60. */
  61. PRIVATE W8 *getResourceBlock( W32 offset, W32 length, W32 *glen )
  62. {
  63. W8 *buf;
  64. fseek( fResHandle, offset, SEEK_SET );
  65. buf = (PW8)MM_MALLOC( length );
  66. if( buf == NULL )
  67. {
  68. printf( "could not malloc data\n" );
  69. return NULL;
  70. }
  71. if( fread( buf, 1, length, fResHandle ) != length )
  72. {
  73. printf( "read error on resource file\n" );
  74. return NULL;
  75. }
  76. if( fread( glen, 1, 4, fResHandle ) != 4 )
  77. {
  78. printf( "read error on resource file\n" );
  79. return NULL;
  80. }
  81. *glen = BigLong( *glen );
  82. return buf;
  83. }
  84. /*
  85. -----------------------------------------------------------------------------
  86. Function:
  87. Parameters:
  88. Returns:
  89. Notes:
  90. -----------------------------------------------------------------------------
  91. */
  92. PRIVATE void Decode_LZSS( W8 *dst, const W8 *src, W32 Length )
  93. {
  94. W32 bitBucket;
  95. W32 runCount;
  96. W32 Fun;
  97. W8 *ptrBack;
  98. if( ! Length )
  99. {
  100. return;
  101. }
  102. bitBucket = (W32) src[ 0 ] | 0x100;
  103. ++src;
  104. do
  105. {
  106. if( bitBucket & 1 )
  107. {
  108. dst[ 0 ] = src[ 0 ];
  109. ++src;
  110. ++dst;
  111. --Length;
  112. }
  113. else
  114. {
  115. runCount = (W32) src[ 0 ] | ((W32) src[ 1 ] << 8);
  116. Fun = 0x1000 - (runCount & 0xFFF);
  117. ptrBack = dst - Fun;
  118. runCount = ((runCount >> 12) & 0x0F) + 3;
  119. if( Length >= runCount )
  120. {
  121. Length -= runCount;
  122. }
  123. else
  124. {
  125. runCount = Length;
  126. Length = 0;
  127. }
  128. while( runCount-- )
  129. {
  130. *dst++ = *ptrBack++;
  131. }
  132. src += 2;
  133. }
  134. bitBucket >>= 1;
  135. if( bitBucket == 1 )
  136. {
  137. bitBucket = (W32) src[ 0 ] | 0x100;
  138. ++src;
  139. }
  140. } while( Length );
  141. }
  142. ///////////////////////////////////////////////////////////////////////////////
  143. //
  144. // Palette Routines
  145. //
  146. ///////////////////////////////////////////////////////////////////////////////
  147. /*
  148. -----------------------------------------------------------------------------
  149. Function: ConvertPaletteToRGB -Convert 256 palette data to RGB.
  150. Parameters: dst -[in/out] Destination for RGB raw image data.
  151. src -[in] 256 palette data.
  152. length -[in] length of source data.
  153. palette -[in] Pointer to 256*3 array.
  154. Returns: Nothing.
  155. Notes:
  156. -----------------------------------------------------------------------------
  157. */
  158. PRIVATE void ConvertPaletteToRGB( W8 *dst, W8 *src, W32 length, W8 *palette )
  159. {
  160. W32 i;
  161. for( i = 0 ; i < length ; ++i )
  162. {
  163. dst[ i * 3 ] = palette[ src[ i ] * 3 ];
  164. dst[ i * 3 + 1 ] = palette[ src[ i ] * 3 + 1 ];
  165. dst[ i * 3 + 2 ] = palette[ src[ i ] * 3 + 2 ];
  166. }
  167. }
  168. /*
  169. -----------------------------------------------------------------------------
  170. Function: setPalette -Set global palette.
  171. Parameters: offset -[in] offset of palette in resource file.
  172. Returns: Nothing.
  173. Notes:
  174. -----------------------------------------------------------------------------
  175. */
  176. PRIVATE void setPalette( W32 offset )
  177. {
  178. W32 junk;
  179. if( macPalette )
  180. {
  181. MM_FREE( macPalette );
  182. }
  183. macPalette = getResourceBlock( offset, PALETTE_SIZE, &junk );
  184. }
  185. ///////////////////////////////////////////////////////////////////////////////
  186. //
  187. // Screen Routines
  188. //
  189. ///////////////////////////////////////////////////////////////////////////////
  190. PRIVATE void DecodeBJMapImage( W32 offset, W32 length )
  191. {
  192. W8 *ptrResource;
  193. W8 *buffer;
  194. char filename[ 32 ];
  195. W32 junk;
  196. ptrResource = (PW8)getResourceBlock( offset, length, &junk );
  197. if( ! ptrResource )
  198. {
  199. return;
  200. }
  201. buffer = (PW8) MM_MALLOC( 16 * 16 * 3 );
  202. ConvertPaletteToRGB( buffer, ptrResource, 16 * 16, macPalette );
  203. cs_snprintf( filename, sizeof( filename ), "%s/bjautomap.tga", DIRPATHPICS );
  204. WriteTGA( filename, 24, 16, 16, buffer, 0, 1 );
  205. MM_FREE( buffer );
  206. }
  207. PRIVATE void DecodeBJIntermImages( W32 offset, W32 length )
  208. {
  209. W32 *ptrResource;
  210. W32 uncomprLength;
  211. W8 *uncompr, *buffer;
  212. W32 indexs[3];
  213. W16 *ptr;
  214. int width, height, i;
  215. W32 junk;
  216. char filename[ 32 ];
  217. ptrResource = (PW32)getResourceBlock( offset, length, &junk );
  218. if( ! ptrResource )
  219. {
  220. return;
  221. }
  222. uncomprLength = BigLong( ptrResource[ 0 ] );
  223. uncompr = (PW8)MM_MALLOC( uncomprLength );
  224. Decode_LZSS( uncompr, (PW8)&ptrResource[ 1 ], uncomprLength );
  225. MM_FREE( ptrResource );
  226. memcpy( indexs, uncompr, 12 );
  227. indexs[ 0 ] = BigLong( indexs[ 0 ] );
  228. indexs[ 1 ] = BigLong( indexs[ 1 ] );
  229. indexs[ 2 ] = BigLong( indexs[ 2 ] );
  230. buffer = MM_MALLOC( 256 * 256 * 3 );
  231. for( i = 0 ; i < 3 ; ++i )
  232. {
  233. ptr = (PW16)&uncompr[ indexs[ i ] ];
  234. width = BigShort( ptr[ 0 ] );
  235. height = BigShort( ptr[ 1 ] );
  236. ConvertPaletteToRGB( buffer, (PW8)&ptr[ 2 ], width * height, macPalette );
  237. cs_snprintf( filename, sizeof( filename ), "%s/bj%d.tga", DIRPATHPICS, i );
  238. WriteTGA( filename, 24, width, height, buffer, 0, 1 );
  239. }
  240. MM_FREE( buffer );
  241. MM_FREE( uncompr );
  242. }
  243. /*
  244. -----------------------------------------------------------------------------
  245. Function: DecodeScreen -Decode screen from Macintosh resource fork.
  246. Parameters:
  247. offset -[in] offset in resource file.
  248. length -[in] length of data.
  249. filename -[in] Name of file to save as.
  250. Returns: Nothing.
  251. Notes:
  252. -----------------------------------------------------------------------------
  253. */
  254. PRIVATE void DecodeScreen( W32 offset, W32 length, const char *filename )
  255. {
  256. W8 *ptrResource;
  257. W32 uncomprLength;
  258. W16 *uncompr;
  259. W16 width, height;
  260. W8 *buffer;
  261. W32 junk;
  262. ptrResource = getResourceBlock( offset, length, &junk );
  263. if( ! ptrResource )
  264. {
  265. return;
  266. }
  267. uncomprLength = BigLong( *((PW32)ptrResource) );
  268. uncompr = (PW16)MM_MALLOC( uncomprLength );
  269. Decode_LZSS( (PW8)uncompr, ptrResource+4, uncomprLength );
  270. width = BigShort( uncompr[ 0 ] );
  271. height = BigShort( uncompr[ 1 ] );
  272. buffer = MM_MALLOC( width * height * 3 );
  273. ConvertPaletteToRGB( buffer, (PW8)&uncompr[ 2 ], width * height, macPalette );
  274. WriteTGA( filename, 24, width, height, buffer, 0, 1 );
  275. MM_FREE( buffer );
  276. MM_FREE( uncompr );
  277. MM_FREE( ptrResource );
  278. }
  279. /*
  280. -----------------------------------------------------------------------------
  281. Function: RipScreens -Extract screens from Macintosh resource fork.
  282. Parameters: Nothing.
  283. Returns: Nothing.
  284. Notes:
  285. -----------------------------------------------------------------------------
  286. */
  287. PRIVATE void RipScreens( void )
  288. {
  289. char path[ 256 ];
  290. setPalette( MACPAL );
  291. cs_snprintf( path, sizeof( path ), "%s/macplaypic.tga", DIRPATHPICS );
  292. DecodeScreen( 899914, 46893, path );
  293. setPalette( IDPAL );
  294. cs_snprintf( path, sizeof( path ), "%s/idpic.tga", DIRPATHPICS );
  295. DecodeScreen( 899914, 46893, path );
  296. setPalette( INTERPAL );
  297. cs_snprintf( path, sizeof( path ), "%s/intermissionpic.tga", DIRPATHPICS );
  298. DecodeScreen( 947583, 49624, path );
  299. DecodeBJIntermImages( 1018931, 20766 );
  300. setPalette( GAMEPAL );
  301. cs_snprintf( path, sizeof( path ), "%s/getpsychedpic.tga", DIRPATHPICS );
  302. DecodeScreen( 997983, 3256, path );
  303. DecodeBJMapImage( 2391746, 1281 );
  304. setPalette( YUMMYPAL );
  305. cs_snprintf( path, sizeof( path ), "%s/yummypic.tga", DIRPATHPICS );
  306. DecodeScreen( 1002299, 9042, path );
  307. setPalette( TITLEPAL );
  308. cs_snprintf( path, sizeof( path ), "%s/titlepic.tga", DIRPATHPICS );
  309. DecodeScreen( 2067971, 167032, path );
  310. }
  311. ///////////////////////////////////////////////////////////////////////////////
  312. //
  313. // Wall Routines
  314. //
  315. ///////////////////////////////////////////////////////////////////////////////
  316. /*
  317. -----------------------------------------------------------------------------
  318. Function: obverseWall -Realign wall image.
  319. Parameters:
  320. src -[in] source data.
  321. width -[in] width of wall image.
  322. height -[in] height of wall image.
  323. Returns: NULL on error, otherwise pointer to memory block with realigned
  324. wall image data.
  325. Notes: Caller is responsible for freeing returned memory block.
  326. -----------------------------------------------------------------------------
  327. */
  328. PRIVATE W8 *obverseWall( const W8 *src, W16 width, W16 height )
  329. {
  330. W8 *target;
  331. W16 w, h;
  332. target = MM_MALLOC( width * height );
  333. for( h = 0; h < height; ++h )
  334. for( w = 0; w < width; ++w )
  335. {
  336. target[ h + width * w ] = src[ h * width + w ];
  337. }
  338. return target;
  339. }
  340. /*
  341. -----------------------------------------------------------------------------
  342. Function: DecodeWall -Decode then save wall data as TARGA image file.
  343. Parameters:
  344. offet -[in] offset in resource file.
  345. length -[in] length of data.
  346. retval -[out] Length of next block.
  347. filename -[in] Name of file to save as.
  348. Returns: Nothing.
  349. Notes:
  350. -----------------------------------------------------------------------------
  351. */
  352. PRIVATE void DecodeWall( W32 offset, W32 length, W32 *retval, const char *filename )
  353. {
  354. W8 *ptrResource;
  355. W8 *uncompr;
  356. W8 *buffer;
  357. W8 *newwall;
  358. ptrResource = getResourceBlock( offset, length, retval );
  359. if( ! ptrResource )
  360. {
  361. return;
  362. }
  363. uncompr = (PW8)MM_MALLOC( 128 * 128 );
  364. Decode_LZSS( uncompr, ptrResource, 128 * 128 );
  365. newwall = obverseWall( uncompr, 128, 128 );
  366. buffer = MM_MALLOC( 128 * 128 * 3 );
  367. ConvertPaletteToRGB( buffer, newwall, 128 * 128, macPalette );
  368. WriteTGA( filename, 24, 128, 128, buffer, 0, 1 );
  369. MM_FREE( buffer );
  370. MM_FREE( newwall );
  371. MM_FREE( uncompr );
  372. MM_FREE( ptrResource );
  373. }
  374. /*
  375. -----------------------------------------------------------------------------
  376. Function: RipWalls -Extract wall image data from resource fork.
  377. Parameters: Nothing.
  378. Returns: Nothing.
  379. Notes:
  380. -----------------------------------------------------------------------------
  381. */
  382. PRIVATE void RipWalls( void )
  383. {
  384. int i;
  385. W32 noffset = 702256;
  386. W32 length = 6277;
  387. W32 retval;
  388. char name[ 256 ];
  389. for( i = 0 ; i < 35 ; ++i )
  390. {
  391. cs_snprintf( name, sizeof( name ), "%s/%.3d.tga", DIRPATHWALLS, i );
  392. DecodeWall( noffset, length, &retval, name );
  393. noffset += length + 4;
  394. length = retval;
  395. }
  396. }
  397. ///////////////////////////////////////////////////////////////////////////////
  398. //
  399. // Sprite Routines
  400. //
  401. ///////////////////////////////////////////////////////////////////////////////
  402. typedef struct
  403. {
  404. W16 Topy;
  405. W16 Boty;
  406. W16 Shape;
  407. } spriteRun;
  408. /*
  409. -----------------------------------------------------------------------------
  410. Function: DecodeSprite -Decode then save sprite data as TARGA image file.
  411. Parameters:
  412. offet -[in] offset in resource file.
  413. length -[in] length of data.
  414. retval -[out] Length of next block.
  415. filename -[in] Name of file to save as.
  416. Returns: Nothing.
  417. Notes:
  418. -----------------------------------------------------------------------------
  419. */
  420. PRIVATE void DecodeSprite( W32 offset, W32 length, W32 *retval, const char *filename )
  421. {
  422. W8 *ptrResource;
  423. W32 uncomprLength;
  424. W8 *uncompr;
  425. W8 *buffer;
  426. W16 *ptr;
  427. int i, x, width, noffset;
  428. ptrResource = getResourceBlock( offset, length, retval );
  429. if( ! ptrResource )
  430. {
  431. return;
  432. }
  433. uncomprLength = ptrResource[ 0 ];
  434. uncomprLength |= ptrResource[ 1 ] << 8;
  435. uncompr = (PW8)MM_MALLOC( uncomprLength );
  436. Decode_LZSS( uncompr, ptrResource+2, uncomprLength );
  437. buffer = (W8 *)MM_MALLOC(128 * 128 * 4);
  438. memset( buffer, 0, 128 * 128 * 4 );
  439. ptr = (PW16)uncompr;
  440. width = BigShort( ptr[ 0 ] );
  441. noffset = 64 - width / 2;
  442. for( x = 0 ; x < width ; ++x )
  443. {
  444. spriteRun *p = (spriteRun *)&ptr[ BigShort( ptr[ x + 1 ] ) / 2 ];
  445. while( p->Topy != 0xFFFF )
  446. {
  447. for( i = BigShort( p->Topy ) / 2; i < BigShort( p->Boty ) / 2; ++i )
  448. {
  449. *(buffer + (i * 128 + x + noffset) * 4 + 0) = macPalette[ uncompr[ BigShort( p->Shape ) + BigShort( p->Topy ) / 2 + (i - BigShort( p->Topy ) / 2) ] * 3 + 0 ];
  450. *(buffer + (i * 128 + x + noffset) * 4 + 1) = macPalette[ uncompr[ BigShort( p->Shape ) + BigShort( p->Topy ) / 2 + (i - BigShort( p->Topy ) / 2) ] * 3 + 1 ];
  451. *(buffer + (i * 128 + x + noffset) * 4 + 2) = macPalette[ uncompr[ BigShort( p->Shape ) + BigShort( p->Topy ) / 2 + (i - BigShort( p->Topy ) / 2) ] * 3 + 2 ];
  452. *(buffer + (i * 128 + x + noffset) * 4 + 3) = 255;
  453. }
  454. p++;
  455. }
  456. }
  457. WriteTGA( filename, 32, 128, 128, buffer, 0, 1 );
  458. MM_FREE( buffer );
  459. MM_FREE( uncompr );
  460. MM_FREE( ptrResource );
  461. }
  462. /*
  463. -----------------------------------------------------------------------------
  464. Function: RipSprites -Extract sprites from resource fork.
  465. Parameters: Nothing.
  466. Returns: Nothing.
  467. Notes:
  468. -----------------------------------------------------------------------------
  469. */
  470. PRIVATE void RipSprites( void )
  471. {
  472. int i;
  473. W32 offset = 106345;
  474. W32 length = 524;
  475. W32 retval;
  476. char name[ 256 ];
  477. for( i = 0 ; i < 163 ; ++i )
  478. {
  479. cs_snprintf( name, sizeof( name ), "%s/%.3d.tga", DIRPATHSPRITES, i );
  480. DecodeSprite( offset, length, &retval, name );
  481. offset += length + 4;
  482. length = retval;
  483. }
  484. offset = 579104;
  485. length = 868;
  486. for( i = 163 ; i < 171 ; ++i )
  487. {
  488. cs_snprintf( name, sizeof( name ), "%s/%.3d.tga", DIRPATHSPRITES, i );
  489. DecodeSprite( offset, length, &retval, name );
  490. offset += length + 4;
  491. length = retval;
  492. }
  493. offset = 2356530;
  494. length = 7153;
  495. for( i = 171 ; i < 175 ; ++i )
  496. {
  497. cs_snprintf( name, sizeof( name ), "%s/%.3d.tga", DIRPATHSPRITES, i );
  498. DecodeSprite( offset, length, &retval, name );
  499. offset += length + 4;
  500. length = retval;
  501. }
  502. }
  503. ///////////////////////////////////////////////////////////////////////////////
  504. //
  505. // Item Routines
  506. //
  507. ///////////////////////////////////////////////////////////////////////////////
  508. /*
  509. -----------------------------------------------------------------------------
  510. Function: DecodeItem -Convert item data into RGB raw data.
  511. Parameters: data -[in] data chunk to decode.
  512. pal -[in] palette.
  513. Returns: On success pointer to RGB data, otherwise NULL.
  514. Notes:
  515. -----------------------------------------------------------------------------
  516. */
  517. PRIVATE W8 *DecodeItem( W8 *data, W8 *pal )
  518. {
  519. W8 *buffer, *mask, *ptr;
  520. int x, y, w, h;
  521. buffer = (W8 *)MM_MALLOC( 128 * 128 * 4 );
  522. memset( buffer, 0, 128 * 128 * 4 );
  523. x = data[ 0 ] << 8 | data[ 1 ];
  524. y = data[ 2 ] << 8 | data[ 3 ];
  525. w = data[ 4 ] << 8 | data[ 5 ];
  526. h = data[ 6 ] << 8 | data[ 7 ];
  527. data += 8;
  528. mask = data + w * h;
  529. ptr = buffer + 512 * y + x * 4;
  530. do
  531. {
  532. int w2 = w;
  533. do
  534. {
  535. if( *mask == 0 )
  536. {
  537. ptr[ 0 ] = pal[ data[ 0 ] * 3 ];
  538. ptr[ 1 ] = pal[ data[ 0 ] * 3 + 1 ];
  539. ptr[ 2 ] = pal[ data[ 0 ] * 3 + 2 ];
  540. ptr[ 3 ] = 255;
  541. }
  542. ptr += 4;
  543. data++;
  544. mask++;
  545. } while( --w2 );
  546. ptr += 4 * (128 - w);
  547. } while( --h );
  548. return buffer;
  549. }
  550. /*
  551. -----------------------------------------------------------------------------
  552. Function: RipItems -Extract pic images from resource file.
  553. Parameters: Nothing.
  554. Returns: Nothing.
  555. Notes:
  556. -----------------------------------------------------------------------------
  557. */
  558. PRIVATE void RipItems( void )
  559. {
  560. W8 *ptrResource;
  561. W8 *ptrDst;
  562. W32 *ptrLong;
  563. W8 *buffer;
  564. W8 **gameItems;
  565. W32 junk;
  566. W32 uncomprLength;
  567. int i;
  568. char name[ 256 ];
  569. W16 *ptrShape1;
  570. W8 *ptrShape2;
  571. W16 width, height;
  572. W32 offset = 634799L;
  573. W32 length = 67453L;
  574. ptrResource = (PW8)getResourceBlock( offset, length, &junk );
  575. uncomprLength = BigLong( *((PW32)ptrResource) );
  576. gameItems = (W8 **)MM_MALLOC( uncomprLength );
  577. Decode_LZSS( (PW8)gameItems, ptrResource+4, uncomprLength );
  578. MM_FREE( ptrResource );
  579. ptrLong = (PW32)gameItems;
  580. ptrDst = (PW8)gameItems;
  581. for( i = 0; i < 47; ++i )
  582. {
  583. uncomprLength = BigLong( ptrLong[ i ] );
  584. gameItems[ i ] = ptrDst + uncomprLength;
  585. }
  586. for( i = 0 ; i < 6 * 4 ; ++i )
  587. {
  588. cs_snprintf( name, sizeof( name ), "%s/weapon%.2d.tga", DIRPATHPICS, i );
  589. buffer = DecodeItem( gameItems[ 12 + i ], macPalette );
  590. WriteTGA( name, 32, 128, 128, buffer, 0, 1 );
  591. MM_FREE( buffer );
  592. }
  593. for( i = 0 ; i < 47 ; ++i )
  594. {
  595. ptrShape1 = (PW16)gameItems[ i ];
  596. width = BigShort( ptrShape1[ 0 ] );
  597. height = BigShort( ptrShape1[ 1 ] );
  598. ptrShape2 = (PW8)&ptrShape1[ 2 ];
  599. buffer = MM_MALLOC( width * height * 3 );
  600. ConvertPaletteToRGB( buffer, ptrShape2, width * height, macPalette );
  601. cs_snprintf( name, sizeof( name ), "%s/%.2d.tga", DIRPATHPICS, i );
  602. WriteTGA( name, 24, width, height, buffer, 0, 1 );
  603. MM_FREE( buffer );
  604. // Skip over weapon frames
  605. if( 11 == i )
  606. {
  607. i = 35;
  608. }
  609. }
  610. MM_FREE( gameItems );
  611. }
  612. ///////////////////////////////////////////////////////////////////////////////
  613. //
  614. // Midi Routines
  615. //
  616. ///////////////////////////////////////////////////////////////////////////////
  617. /*
  618. -----------------------------------------------------------------------------
  619. Function: RipMidi -Extract midi files from resource fork.
  620. Parameters: Nothing.
  621. Returns: Nothing.
  622. Notes:
  623. -----------------------------------------------------------------------------
  624. */
  625. PRIVATE void RipMidi( void )
  626. {
  627. W8 *ptrResource;
  628. W32 retval;
  629. FILE *fhandle;
  630. char name[ 256 ];
  631. int i;
  632. W32 offset = 1899536L;
  633. W32 length = 8215L;
  634. for( i = 0 ; i < 8 ; ++i )
  635. {
  636. ptrResource = getResourceBlock( offset, length, &retval );
  637. if( ! ptrResource )
  638. {
  639. continue;
  640. }
  641. cs_snprintf( name, sizeof( name ), "%s/%d.mid", DIRPATHMIDI, i );
  642. fhandle = fopen( name, "wb" );
  643. if( ! fhandle )
  644. {
  645. continue;
  646. }
  647. fwrite( ptrResource, 1, length, fhandle );
  648. fclose( fhandle );
  649. MM_FREE( ptrResource );
  650. offset += length + 4;
  651. length = retval;
  652. }
  653. }
  654. ///////////////////////////////////////////////////////////////////////////////
  655. //
  656. // PICT image
  657. //
  658. ///////////////////////////////////////////////////////////////////////////////
  659. #if 0
  660. PRIVATE void DecodePICTimage( W32 offset, W32 length )
  661. {
  662. FILE *hfOut;
  663. W8 *ptrResource;
  664. W32 junk;
  665. int i;
  666. ptrResource = getResourceBlock( offset, length, &junk );
  667. if( ! ptrResource )
  668. {
  669. return;
  670. }
  671. hfOut = fopen( "pict.pct", "wb" );
  672. if( ! hfOut )
  673. {
  674. return;
  675. }
  676. for( i ; i < 512 ; ++i )
  677. {
  678. fwrite( ptrResource, 1, 0, hfOut );
  679. }
  680. fwrite( ptrResource, 1, length, hfOut );
  681. fclose( hfOut );
  682. }
  683. #endif
  684. ///////////////////////////////////////////////////////////////////////////////
  685. //
  686. // Parse MacBinary Header
  687. //
  688. ///////////////////////////////////////////////////////////////////////////////
  689. /*
  690. -----------------------------------------------------------------------------
  691. Function: parseMacBinaryHead -Parse mac binary header.
  692. Parameters: Nothing.
  693. Returns: true if this is Wolfenstein Mac binary file, otherwise false.
  694. Notes:
  695. -----------------------------------------------------------------------------
  696. */
  697. PRIVATE _boolean parseMacBinaryHead( void )
  698. {
  699. W32 temp32 = 0;
  700. char name[ 64 ];
  701. //
  702. // Check file name
  703. //
  704. fseek( fResHandle, 1, SEEK_SET );
  705. // get file name length (range is 1 to 31)
  706. fread( &temp32, 1, 1, fResHandle );
  707. if( temp32 < 1 || temp32 > 31 )
  708. {
  709. return false;
  710. }
  711. fread( name, 1, temp32, fResHandle );
  712. name[ temp32 - 1 ] = '\0';
  713. if( strcmp( name, MACBINFILENAME ) != 0 )
  714. {
  715. return false;
  716. }
  717. //
  718. // Check file type / creator
  719. //
  720. fseek( fResHandle, 65, SEEK_SET );
  721. fread( &name, 1, 8, fResHandle );
  722. name[ 8 ] = '\0';
  723. if( strcmp( name, FILETYPECREATOR ) != 0 )
  724. {
  725. return false;
  726. }
  727. //
  728. // Check Data Fork length
  729. //
  730. fseek( fResHandle, 83, SEEK_SET );
  731. fread( &temp32, 1, 4, fResHandle );
  732. temp32 = BigLong( temp32 );
  733. if( temp32 != DATAFORKLENGTH )
  734. {
  735. return false;
  736. }
  737. //
  738. // Check Resource Fork length
  739. //
  740. fread( &temp32, 1, 4, fResHandle );
  741. temp32 = BigLong( temp32 );
  742. if( temp32 != RESFORKLENGTH )
  743. {
  744. return false;
  745. }
  746. return true;
  747. }
  748. ///////////////////////////////////////////////////////////////////////////////
  749. //
  750. // Interface
  751. //
  752. ///////////////////////////////////////////////////////////////////////////////
  753. /*
  754. -----------------------------------------------------------------------------
  755. Function: ripMac -Interface to Macintosh data extractor.
  756. Parameters: Nothing.
  757. Returns: Nothing.
  758. Notes:
  759. -----------------------------------------------------------------------------
  760. */
  761. PUBLIC void ripMac( void )
  762. {
  763. char *fname;
  764. char ext[ 256 ];
  765. cs_strlcpy( ext, MAC_FEXT, sizeof( ext ) );
  766. fname = FS_FindFirst( ext, 0, FA_DIR );
  767. FS_FindClose();
  768. if( fname == NULL )
  769. {
  770. // try again with lower case
  771. fname = FS_FindFirst( cs_strlwr( ext ), 0, FA_DIR );
  772. FS_FindClose();
  773. if( fname == NULL )
  774. {
  775. printf( "Could not find any mac files for read\n" );
  776. return;
  777. }
  778. }
  779. fResHandle = fopen( fname, "rb" );
  780. if( fResHandle == NULL )
  781. {
  782. printf( "Could not open file (%s) for read\n", fname );
  783. return;
  784. }
  785. if( ! parseMacBinaryHead() )
  786. {
  787. printf( "Unknown MacBinary file\n" );
  788. fclose( fResHandle );
  789. return;
  790. }
  791. FS_Mkdir( DIRPATHPICS );
  792. FS_Mkdir( DIRPATHSPRITES );
  793. FS_Mkdir( DIRPATHWALLS );
  794. FS_Mkdir( DIRPATHMIDI );
  795. printf( "Extracting Midi data...\n" );
  796. RipMidi();
  797. printf( "Decoding Screen data...\n" );
  798. RipScreens();
  799. setPalette( GAMEPAL );
  800. printf( "Decoding Wall data...\n" );
  801. RipWalls();
  802. printf( "Decoding Sprite data...\n" );
  803. RipSprites();
  804. printf( "Decoding Item data...\n" );
  805. RipItems();
  806. fclose( fResHandle );
  807. }