/** * \brief Redux the Page file data. * \param[in] vsfname data file name. * \param[in] wallPath Path to save wall data. * \param[in] spritePath Path to save sprite data. * \param[in] soundPath Path to save sound data. * \param[in] palette Palette array. * \return On success true, otherwise false. * \note Caller is responsible for freeing allocated data by calling MM_FREE. */ PUBLIC wtBoolean PageFile_ReduxDecodePageData( const char *vsfname, const char *wallPath, const char *spritePath, const char *soundPath, W8 *palette ) { void *data; void *decdata; W32 length; char tempFileName[ 1024 ]; W32 i; W32 SpriteStart, NumBlocks, SoundStart; W32 soundBufferSize; W8 *soundBuffer; W32 totallength; printf( "Decoding Page Data..." ); if( ! PageFile_Setup( vsfname, &NumBlocks, &SpriteStart, &SoundStart ) ) { PageFile_Shutdown(); return false; } // //////////////////////////////////////////////////////////////////////// // Decode Walls for( i = 0 ; i < SpriteStart ; ++i ) { data = PageFile_getPage( i, &length ); if( data == NULL ) { continue; } decdata = PageFile_decodeWall_RGB32( (PW8)data, palette ); if( decdata == NULL ) { fprintf( stderr, "[PageFile_ReduxDecodePageData]: Unable to decode wall (%d).\n", i ); MM_FREE( data ); continue; } if( _filterScale > 0 ) { void *scaledImgBuf; scaledImgBuf = (void *) MM_MALLOC( 128 * 128 * 4 ); if( NULL == scaledImgBuf ) { MM_FREE( data ); MM_FREE( decdata ); continue; } // Scale2x if( _filterScale == 1 ) { scale( 2, (void *)scaledImgBuf, 128 * 4, decdata, 64 * 4, 4, 64, 64 ); RGB32toRGB24( (const PW8)scaledImgBuf, (PW8)scaledImgBuf, 128 * 128 * 4 ); } else { // hq2x RGB32toRGB24( (const PW8)decdata, (PW8)decdata, 64 * 64 * 4 ); RGB24toBGR565( decdata, decdata, 64 * 64 * 3 ); hq2x_32( (PW8)decdata, (PW8)scaledImgBuf, 64, 64, 64 * 2 * 4 ); RGB32toRGB24( (const PW8)scaledImgBuf, (PW8)scaledImgBuf, 128 * 128 * 4 ); } wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%.3d.tga", wallPath, PATH_SEP, GetWallMappedIndex( i ) ); TGA_write( tempFileName, 24, 128, 128, scaledImgBuf, 0, 1 ); MM_FREE( scaledImgBuf ); } else { wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%.3d.tga", wallPath, PATH_SEP, GetWallMappedIndex( i ) ); RGB32toRGB24( (const PW8)decdata, (PW8)decdata, 64 * 64 * 4 ); TGA_write( tempFileName, 24, 64, 64, decdata, 0, 1 ); } MM_FREE( data ); MM_FREE( decdata ); } // //////////////////////////////////////////////////////////////////////// // Decode Sprites for( i = SpriteStart ; i < SoundStart ; ++i ) { data = PageFile_getPage( i, &length ); if( data == NULL ) { continue; } decdata = PageFile_decodeSprite_RGB32( (PW8)data, palette ); if( decdata == NULL ) { MM_FREE( data ); continue; } if( _filterScale_Sprites > 0 ) { W8 *scaledImgBuf; scaledImgBuf = (PW8) MM_MALLOC( 128 * 128 * 4 ); if( NULL == scaledImgBuf ) { MM_FREE( data ); MM_FREE( decdata ); continue; } if( _filterScale_Sprites == 1 ) { scale( 2, (void *)scaledImgBuf, 128 * 4, decdata, 64 * 4, 4, 64, 64 ); } else { // hq2x RGB32toRGB24( (const PW8)decdata, (PW8)decdata, 64 * 64 * 4 ); RGB24toBGR565( decdata, decdata, 64 * 64 * 3 ); hq2x_32( (PW8)decdata, (PW8)scaledImgBuf, 64, 64, 64 * 2 * 4 ); ReduxAlphaChannel_hq2x( scaledImgBuf, 128, 128 ); } wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%.3d.tga", spritePath, PATH_SEP, GetSpriteMappedIndex( i - SpriteStart ) ); TGA_write( tempFileName, 32, 128, 128, scaledImgBuf, 0, 1 ); MM_FREE( scaledImgBuf ); } else { wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%.3d.tga", spritePath, PATH_SEP, GetSpriteMappedIndex( i - SpriteStart ) ); TGA_write( tempFileName, 32, 64, 64, decdata, 0, 1 ); } MM_FREE( data ); MM_FREE( decdata ); } // //////////////////////////////////////////////////////////////////////// // Decode SFX soundBufferSize = 20 * 4096; soundBuffer = (PW8) MM_MALLOC( soundBufferSize ); if( soundBuffer == NULL ) { PageFile_Shutdown(); return false; } totallength = 0; for( i = SoundStart ; i < NumBlocks ; ++i ) { data = PageFile_getPage( i, &length ); if( data == NULL ) { continue; } if( (totallength + length) > soundBufferSize ) { fprintf( stderr, "[PageFile_ReduxDecodePageData]: Buffer not large enough to hold sound data!\n" ); MM_FREE( data ); MM_FREE( soundBuffer ); return false; } MM_MEMCPY( soundBuffer + totallength, data, length ); totallength += length; if( length < 4096 ) { wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%.3d.wav", soundPath, PATH_SEP, i - SoundStart ); wav_write( tempFileName, soundBuffer, totallength, 1, SAMPLERATE, 1 ); totallength = 0; } MM_FREE( data ); } MM_FREE( soundBuffer ); PageFile_Shutdown(); MM_FREE( data ); printf( "Done\n" ); return true; }
/* ----------------------------------------------------------------------------- Function: SavePic() -Save graphic lump in targa image format. Parameters: chunk -[in] Chunk number to save. version -[in] extension version. 1 -WL6 2 -SOD Returns: Nothing. Notes: ----------------------------------------------------------------------------- */ PRIVATE void SavePic( W32 chunknum, W16 version, W8 *buffer, W8 *buffer2 ) { W16 i; W16 temp; char filename[32]; char *fname; W8 *ptr; W8 *pic; W32 picnum; W16 width, height; W16 linewidth, plane, sx, sy; W8 r,g,b; W16 rgb; W8 *tpalette = gamepal; static W16 offset = 0; if( ( (chunknum == WL1_N_BLANKPIC || chunknum == WL1_NOKEYPIC ) && (version & WL1_PAK) ) ) { return; } if( ( (chunknum == N_BLANKPIC || chunknum == NOKEYPIC ) && (version & WL6_PAK) ) ) { return; } if( ( (chunknum == SDM_N_BLANKPIC || chunknum == SDM_NOKEYPIC ) && (version & SDM_PAK) ) ) { return; } if( ( (chunknum == SOD_N_BLANKPIC || chunknum == SOD_NOKEYPIC ) && (version & SOD_PAK) ) ) { return; } // Spear used multiple palettes, so // pull out the one we need. if( version & SDM_PAK ) { switch( chunknum ) { case SDM_TITLE1PIC: case SDM_TITLE2PIC: CA_CacheGrChunk( SDM_TITLEPALETTE, version ); tpalette = grsegs[ SDM_TITLEPALETTE ]; break; default: tpalette = gamepal; break; } } if( version & SOD_PAK ) { switch( chunknum ) { case SOD_IDGUYS1PIC: case SOD_IDGUYS2PIC: CA_CacheGrChunk( SOD_IDGUYSPALETTE, version ); tpalette = grsegs[ SOD_IDGUYSPALETTE ]; break; case SOD_TITLE1PIC: case SOD_TITLE2PIC: CA_CacheGrChunk( SOD_TITLEPALETTE, version ); tpalette = grsegs[ SOD_TITLEPALETTE ]; break; case SOD_ENDSCREEN11PIC: CA_CacheGrChunk( SOD_END1PALETTE, version ); tpalette = grsegs[ SOD_END1PALETTE ]; break; case SOD_ENDSCREEN12PIC: CA_CacheGrChunk( SOD_END2PALETTE, version ); tpalette = grsegs[ SOD_END2PALETTE ]; break; case SOD_ENDSCREEN3PIC: CA_CacheGrChunk( SOD_END3PALETTE, version ); tpalette = grsegs[ SOD_END3PALETTE ]; break; case SOD_ENDSCREEN4PIC: CA_CacheGrChunk( SOD_END4PALETTE, version ); tpalette = grsegs[ SOD_END4PALETTE ]; break; case SOD_ENDSCREEN5PIC: CA_CacheGrChunk( SOD_END5PALETTE, version ); tpalette = grsegs[ SOD_END5PALETTE ]; break; case SOD_ENDSCREEN6PIC: CA_CacheGrChunk( SOD_END6PALETTE, version ); tpalette = grsegs[ SOD_END6PALETTE ]; break; case SOD_ENDSCREEN7PIC: CA_CacheGrChunk( SOD_END7PALETTE, version ); tpalette = grsegs[ SOD_END7PALETTE ]; break; case SOD_ENDSCREEN8PIC: CA_CacheGrChunk( SOD_END8PALETTE, version ); tpalette = grsegs[ SOD_END8PALETTE ]; break; case SOD_ENDSCREEN9PIC: CA_CacheGrChunk( SOD_END9PALETTE, version ); tpalette = grsegs[ SOD_END9PALETTE ]; break; default: tpalette = gamepal; break; } // End switch chunknum } // End if version & SOD_PAK STATUSBARHACK: picnum = chunknum - STARTPICS; pic = grsegs[ chunknum ]; width = pictable[ picnum ].width; height= pictable[ picnum ].height; linewidth = width / 4; for( i = 0; i < ( width * height ); ++i, pic++ ) { plane = i / ( (width * height) / 4 ); sx = ( ( i % ( linewidth ) ) * 4 ) + plane; sy = ( ( i / linewidth ) % height ); ptr = buffer + ( (sx*2) + (sy * width)*2); temp = (*pic) * 3; r = tpalette[ temp ] >> 1; g = tpalette[ temp+1 ]; b = tpalette[ temp+2 ] >> 1; rgb = (b << 11) | (g << 5) | r; ptr[ 0 ] = rgb & 0xff; ptr[ 1 ] = rgb >> 8; } // // Hacks to reassemble images // if( version & WL1_PAK ) { if( chunknum == WL1_STATUSBARPIC ) { memcpy( buffer2, buffer, width * height * 2 ); // Save Status bar pic CA_CacheGrChunk( WL1_NOKEYPIC, version ); // cache NOKEYPIC chunknum = WL1_NOKEYPIC; goto STATUSBARHACK; } else if( chunknum == WL1_H_BOTTOMINFOPIC ) { MergeImages( buffer, 2, 304, 91, 16, 24, 4, buffer2, 2, 91, 91, 16, 0, 0 ); MergeImages( buffer, 2, 304, 91, 16, 192, 4, buffer2, 2, 91, 91, 16, 0, 16 ); hq2x_32( buffer2, buffer, 91, 16, (91*2)*4 ); RGB32toRGB24( buffer, buffer, 182*32*4 ); cs_snprintf( filename, sizeof( filename ), "%s/%s.tga", LGFXDIR, "PLAQUE_PAGE" ); WriteTGA( filename, 24, 182, 32, buffer, 0, 0 ); hq2x_32( buffer2 + (16 * 91 * 2), buffer, 91, 16, (91*2)*4 ); RGB32toRGB24( buffer, buffer, 182*32*4 ); cs_snprintf( filename, sizeof( filename ), "%s/%s.tga", LGFXDIR, "PLAQUE_BLANK" ); WriteTGA( filename, 24, 182, 32, buffer, 0, 1 ); return; } else if( chunknum == WL1_NOKEYPIC ) { chunknum = WL1_STATUSBARPIC; MergePics( buffer, buffer2, width, height, 2, 320, 240, 4 ); MergePics( buffer, buffer2, width, height, 2, 320, 240, 4+height ); memcpy( buffer, buffer2, 320 * 40 * 2 ); width = 320; height = 40; } else if( chunknum == WL1_L_COLONPIC ) { memset( buffer2, 0, 256*64*2 ); MergePics( buffer, buffer2, width, height, 2, 256, 160, 16 ); return; } else if( chunknum == WL1_L_EXPOINTPIC ) { MergePics( buffer, buffer2, width, height, 2, 256, 16, 0 ); return; } else if( chunknum == WL1_L_APOSTROPHEPIC ) { W16 i; MergePics( buffer, buffer2, width, height, 2, 256, 112, 0 ); memcpy( buffer, buffer2, 256 * 64 * 2 ); for( i = 0 ; i < 256 * 64 * 2 ; i += 2 ) { if( buffer[ i ] == 0 && buffer[ i + 1 ] == 0 ) { buffer[ i + 1 ] = 66; } } offset = 0; width = 256; height = 64; } else if( chunknum == WL1_L_PERCENTPIC ) { offset = 16; // this is for L_APIC... MergePics( buffer, buffer2, width, height, 2, 256, 80, 0 ); return; } else if( chunknum >= WL1_L_NUM0PIC && chunknum <= WL1_L_NUM9PIC ) { MergePics( buffer, buffer2, width, height, 2, 256, offset, 16 ); offset += width; return; } else if( chunknum >= WL1_N_0PIC && chunknum < WL1_N_9PIC ) { MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); offset += width + 1; return; } else if( chunknum == WL1_N_9PIC ) { W32 i; MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); memcpy( buffer, buffer2, 90 * height * 2 ); for( i = 0 ; i < 90 * 16 * 2 ; i += 2 ) { if( ! (i % 9) && i != 0 ) { buffer[ i - 2 ] = 0; buffer[ i - 1 ] = 160; } } width = 90; offset = 0; } else if( chunknum >= WL1_L_APIC && chunknum <= WL1_L_ZPIC ) { static W32 yoffset = 32; MergePics( buffer, buffer2, width, height, 2, 256, offset, yoffset ); offset += width; if( offset >= 256 ) { offset = 0; yoffset += 16; } return; } else if( chunknum == WL1_FACE5CPIC ) { // hmmm... Why is this one messed up? MergeImages( buffer, 2, 24, 18, height-2, 8, 2, buffer2, 2, 24, 18, height-2, 0, 0 ); MergeImages( buffer, 2, 24, 8, height-3, 0, 3, buffer2, 2, 24, 8, height-2, 16, 0 ); MergeImages( buffer, 2, 24, 18, 2, 9, 0, buffer2, 2, 24, 18, 2, 0, height-2 ); MergeImages( buffer, 2, 24, 7, 3, 1, 0, buffer2, 2, 24, 7, 3, 16, height-3 ); memcpy( buffer, buffer2, 24 * 32 * 2 ); buffer[ (30 * 24 * 2) + (3 * 2) ] = 73; buffer[ (30 * 24 * 2) + (3 * 2) + 1 ] = 74; buffer[ (31 * 24 * 2) + (3 * 2) ] = 73; buffer[ (31 * 24 * 2) + (3 * 2) + 1 ] = 74; buffer[ (29 * 24 * 2) + (23 * 2) ] = 73; buffer[ (29 * 24 * 2) + (23 * 2) + 1 ] = 74; buffer[ (30 * 24 * 2) + (23 * 2) ] = 73; buffer[ (30 * 24 * 2) + (23 * 2) + 1 ] = 74; buffer[ (31 * 24 * 2) + (23 * 2) ] = 73; buffer[ (31 * 24 * 2) + (23 * 2) + 1 ] = 74; buffer[ (29 * 24 * 2) + (19 * 2) ] = 255; buffer[ (29 * 24 * 2) + (19 * 2) + 1 ] = 100; buffer[ (30 * 24 * 2) + (19 * 2) ] = 63; buffer[ (30 * 24 * 2) + (19 * 2) + 1 ] = 117; buffer[ (31 * 24 * 2) + (19 * 2) ] = 52; buffer[ (31 * 24 * 2) + (19 * 2) + 1 ] = 59; buffer[ (30 * 24 * 2) + (7 * 2) ] = 19; buffer[ (30 * 24 * 2) + (7 * 2) + 1 ] = 59; buffer[ (31 * 24 * 2) + (7 * 2) ] = 19; buffer[ (31 * 24 * 2) + (7 * 2) + 1 ] = 59; buffer[ (30 * 24 * 2) + (11 * 2) ] = 91; buffer[ (30 * 24 * 2) + (11 * 2) + 1 ] = 84; buffer[ (31 * 24 * 2) + (11 * 2) ] = 190; buffer[ (31 * 24 * 2) + (11 * 2) + 1 ] = 92; buffer[ (30 * 24 * 2) + (15 * 2) ] = 249; buffer[ (30 * 24 * 2) + (15 * 2) + 1 ] = 75; buffer[ (31 * 24 * 2) + (15 * 2) ] = 190; buffer[ (31 * 24 * 2) + (15 * 2) + 1 ] = 92; } } else if( version & WL6_PAK ) { if( chunknum == STATUSBARPIC ) { memcpy( buffer2, buffer, width * height * 2 ); // Save Status bar pic CA_CacheGrChunk( NOKEYPIC, version ); // cache NOKEYPIC chunknum = NOKEYPIC; goto STATUSBARHACK; } else if( chunknum == H_BOTTOMINFOPIC ) { MergeImages( buffer, 2, 304, 91, 16, 24, 4, buffer2, 2, 91, 91, 16, 0, 0 ); MergeImages( buffer, 2, 304, 91, 16, 192, 4, buffer2, 2, 91, 91, 16, 0, 16 ); hq2x_32( buffer2, buffer, 91, 16, (91*2)*4 ); RGB32toRGB24( buffer, buffer, 182*32*4 ); cs_snprintf( filename, sizeof( filename ), "%s/%s.tga", LGFXDIR, "PLAQUE_PAGE" ); WriteTGA( filename, 24, 182, 32, buffer, 0, 0 ); hq2x_32( buffer2 + (16 * 91 * 2), buffer, 91, 16, (91*2)*4 ); RGB32toRGB24( buffer, buffer, 182*32*4 ); cs_snprintf( filename, sizeof( filename ), "%s/%s.tga", LGFXDIR, "PLAQUE_BLANK" ); WriteTGA( filename, 24, 182, 32, buffer, 0, 1 ); return; } else if( chunknum == NOKEYPIC ) { chunknum = STATUSBARPIC; MergePics( buffer, buffer2, width, height, 2, 320, 240, 4 ); MergePics( buffer, buffer2, width, height, 2, 320, 240, 4+height ); memcpy( buffer, buffer2, 320 * 40 * 2 ); width = 320; height = 40; } else if( chunknum == L_COLONPIC ) { memset( buffer2, 0, 256*64*2 ); MergePics( buffer, buffer2, width, height, 2, 256, 160, 16 ); return; } else if( chunknum == L_EXPOINTPIC ) { MergePics( buffer, buffer2, width, height, 2, 256, 16, 0 ); return; } else if( chunknum == L_APOSTROPHEPIC ) { W16 i; MergePics( buffer, buffer2, width, height, 2, 256, 112, 0 ); memcpy( buffer, buffer2, 256 * 64 * 2 ); for( i = 0 ; i < 256 * 64 * 2 ; i += 2 ) { if( buffer[ i ] == 0 && buffer[ i + 1 ] == 0 ) { buffer[ i + 1 ] = 66; } } offset = 0; width = 256; height = 64; } else if( chunknum == L_PERCENTPIC ) { offset = 16; // this is for L_APIC... MergePics( buffer, buffer2, width, height, 2, 256, 80, 0 ); return; } else if( chunknum >= L_NUM0PIC && chunknum <= L_NUM9PIC ) { MergePics( buffer, buffer2, width, height, 2, 256, offset, 16 ); offset += width; return; } else if( chunknum >= N_0PIC && chunknum < N_9PIC ) { MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); offset += width + 1; return; } else if( chunknum == N_9PIC ) { W32 i; MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); memcpy( buffer, buffer2, 90 * height * 2 ); for( i = 0 ; i < 90 * 16 * 2 ; i += 2 ) { if( ! (i % 9) && i != 0 ) { buffer[ i - 2 ] = 0; buffer[ i - 1 ] = 160; } } width = 90; offset = 0; } else if( chunknum >= L_APIC && chunknum <= L_ZPIC ) { static W32 yoffset = 32; MergePics( buffer, buffer2, width, height, 2, 256, offset, yoffset ); offset += width; if( offset >= 256 ) { offset = 0; yoffset += 16; } return; } } else if( version & SDM_PAK ) { if( chunknum == SDM_STATUSBARPIC ) { memcpy( buffer2, buffer, width * height * 2 ); // Save Status bar pic CA_CacheGrChunk( SDM_NOKEYPIC, version ); // cache SOD_NOKEYPIC chunknum = SDM_NOKEYPIC; goto STATUSBARHACK; } else if( chunknum == SDM_NOKEYPIC ) { chunknum = SDM_STATUSBARPIC; MergePics( buffer, buffer2, width, height, 2, 320, 240, 4 ); MergePics( buffer, buffer2, width, height, 2, 320, 240, 4+height ); memcpy( buffer, buffer2, 320 * 40 * 2 ); width = 320; height = 40; } else if( chunknum == SDM_L_COLONPIC ) { memset( buffer2, 0, 256*64*2 ); MergePics( buffer, buffer2, width, height, 2, 256, 160, 16 ); return; } else if( chunknum == SDM_L_EXPOINTPIC ) { MergePics( buffer, buffer2, width, height, 2, 256, 16, 0 ); return; } else if( chunknum == SDM_L_APOSTROPHEPIC ) { W16 i; MergePics( buffer, buffer2, width, height, 2, 256, 112, 0 ); memcpy( buffer, buffer2, 256 * 64 * 2 ); for( i = 0 ; i < 256 * 64 * 2 ; i += 2 ) { if( buffer[ i ] == 0 && buffer[ i + 1 ] == 0 ) { buffer[ i + 1 ] = 66; } } offset = 0; width = 256; height = 64; } else if( chunknum == SDM_L_PERCENTPIC ) { offset = 16; // this is for L_APIC... MergePics( buffer, buffer2, width, height, 2, 256, 80, 0 ); return; } else if( chunknum >= SDM_L_NUM0PIC && chunknum <= SDM_L_NUM9PIC ) { MergePics( buffer, buffer2, width, height, 2, 256, offset, 16 ); offset += width; return; } else if( chunknum >= SDM_N_0PIC && chunknum < SDM_N_9PIC ) { MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); offset += width + 1; return; } else if( chunknum == SDM_N_9PIC ) { W32 i; MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); memcpy( buffer, buffer2, 90 * height * 2 ); for( i = 0 ; i < 90 * 16 * 2 ; i += 2 ) { if( ! (i % 9) && i != 0 ) { buffer[ i - 2 ] = 0; buffer[ i - 1 ] = 160; } } width = 90; offset = 0; } else if( chunknum >= SDM_L_APIC && chunknum <= SDM_L_ZPIC ) { static W32 yoffset = 32; MergePics( buffer, buffer2, width, height, 2, 256, offset, yoffset ); offset += width; if( offset >= 256 ) { offset = 0; yoffset += 16; } return; } else if( chunknum == SDM_TITLE1PIC ) { memcpy( buffer2+offset, buffer, (width*height*2) ); offset += width*height*2; return; } else if( chunknum == SDM_TITLE2PIC ) { memcpy( buffer2+offset, buffer, (width*height*2) ); memcpy( buffer, buffer2, 320*200*2 ); height = 200; offset = 0; } } else if( version & SOD_PAK ) { if( chunknum == SOD_STATUSBARPIC ) { memcpy( buffer2, buffer, width * height * 2 ); // Save Status bar pic CA_CacheGrChunk( SOD_NOKEYPIC, version ); // cache SOD_NOKEYPIC chunknum = SOD_NOKEYPIC; goto STATUSBARHACK; } else if( chunknum == SOD_NOKEYPIC ) { chunknum = SOD_STATUSBARPIC; MergePics( buffer, buffer2, width, height, 2, 320, 240, 4 ); MergePics( buffer, buffer2, width, height, 2, 320, 240, 4+height ); memcpy( buffer, buffer2, 320 * 40 * 2 ); width = 320; height = 40; } else if( chunknum == SOD_L_COLONPIC ) { memset( buffer2, 0, 256*64*2 ); MergePics( buffer, buffer2, width, height, 2, 256, 160, 16 ); return; } else if( chunknum == SOD_L_EXPOINTPIC ) { MergePics( buffer, buffer2, width, height, 2, 256, 16, 0 ); return; } else if( chunknum == SOD_L_APOSTROPHEPIC ) { W16 i; MergePics( buffer, buffer2, width, height, 2, 256, 112, 0 ); memcpy( buffer, buffer2, 256 * 64 * 2 ); for( i = 0 ; i < 256 * 64 * 2 ; i += 2 ) { if( buffer[ i ] == 0 && buffer[ i + 1 ] == 0 ) { buffer[ i + 1 ] = 66; } } offset = 0; width = 256; height = 64; } else if( chunknum == SOD_L_PERCENTPIC ) { offset = 16; // this is for L_APIC... MergePics( buffer, buffer2, width, height, 2, 256, 80, 0 ); return; } else if( chunknum >= SOD_L_NUM0PIC && chunknum <= SOD_L_NUM9PIC ) { MergePics( buffer, buffer2, width, height, 2, 256, offset, 16 ); offset += width; return; } else if( chunknum >= SOD_N_0PIC && chunknum < SOD_N_9PIC ) { MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); offset += width + 1; return; } else if( chunknum == SOD_N_9PIC ) { W32 i; MergePics( buffer, buffer2, width, height, 2, 90, offset, 0 ); memcpy( buffer, buffer2, 90 * height * 2 ); for( i = 0 ; i < 90 * 16 * 2 ; i += 2 ) { if( ! (i % 9) && i != 0 ) { buffer[ i - 2 ] = 0; buffer[ i - 1 ] = 160; } } width = 90; offset = 0; } else if( chunknum >= SOD_L_APIC && chunknum <= SOD_L_ZPIC ) { static W32 yoffset = 32; MergePics( buffer, buffer2, width, height, 2, 256, offset, yoffset ); offset += width; if( offset >= 256 ) { offset = 0; yoffset += 16; } return; } else if( chunknum == SOD_IDGUYS1PIC ) { memcpy( buffer2+offset, buffer, (width*height*2) ); offset += width*height*2; return; } else if( chunknum == SOD_IDGUYS2PIC ) { memcpy( buffer2+offset, buffer, (width*height*2) ); memcpy( buffer, buffer2, 320*200*2 ); height = 200; offset = 0; } else if( chunknum == SOD_TITLE1PIC ) { memcpy( buffer2+offset, buffer, (width*height*2) ); offset += width*height*2; return; } else if( chunknum == SOD_TITLE2PIC ) { memcpy( buffer2+offset, buffer, (width*height*2) ); memcpy( buffer, buffer2, 320*200*2 ); height = 200; offset = 0; } } // // End of images hacks // if( version & WL1_PAK ) { fname = GetLumpFileName_WL1( chunknum ); } else if( version & WL6_PAK ) { fname = GetLumpFileName_WL6( chunknum ); } else if( version & SDM_PAK ) { fname = GetLumpFileName_SDM( chunknum ); } else if( version & SOD_PAK ) { fname = GetLumpFileName_SOD( chunknum ); } else { printf( "Unknown file extension!\n" ); return; } if( fname == NULL ) { printf( "File name not found for item: (%d)\n", chunknum ); return; } cs_snprintf( filename, sizeof( filename ), "%s/%s.tga", LGFXDIR, fname ); hq2x_32( buffer, buffer2, width, height, (width*2)*4 ); // Get rid of alpha channel RGB32toRGB24( buffer2, buffer2, (width*2)*(height*2)*4 ); WriteTGA( filename, 24, (width*2), (height*2), buffer2, 0, 1 ); return; }
/** * \brief Converts Wolf3D graphic data. * \param[in] dict Name of dictionary file to load. * \param[in] head Name of header file to load. * \param[in] graph Name of graphics file to load. * \param[in] start Offset to start of sprite data * \param[in] end Offset to end of sprite data * \param[in] picNum Pointer to picNum_t structure to * \param[in] GetReduxGFXFileName Call back function to get file names for graphics data. * \return On success true, otherwise false. */ PRIVATE wtBoolean wolf3d_gfx( char *dict, char *head, char *graph, W32 start, W32 end, picNum_t *picNum, char *(*GetReduxGFXFileName)( W32 ) ) { wtBoolean bRetVal; W32 width, height; void *data; W32 i; char tempFileName[ 1024 ]; printf( "\nDecoding GFX..." ); bRetVal = GFXFile_Setup( dict, head, graph ); if( ! bRetVal ) { printf( "Failed\n" ); return false; } for( i = 1; i < start; ++i ) { GFXFile_decodeFont( i, 256, 128, DIR_PICS ); } // Create directory for help scripts "gscripts/wolfhelp%.3d.txt" GFXFile_decodeScript( picNum->PN_HelpScript, picNum->PN_HelpScript+1, DIR_GSCRIPTS ); GFXFile_decodeScript( picNum->PN_ScriptStart, picNum->PN_ScriptEnd, DIR_GSCRIPTS ); for( i = start ; i < end ; ++i ) { GFXFile_cacheChunk( i ); data = GFXFile_decodeChunk_RGB32( i, &width, &height, wolf_gamepal ); if( NULL == data ) { continue; } if( _doRedux ) { W32 id; void *updata; id = 0; updata = wolfcore_ReduxGFX( i, data, &width, &height, &id, wolf_gamepal, picNum ); if( updata == NULL ) { MM_FREE( data ); continue; } wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%s.tga", DIR_PICS, PATH_SEP, GetReduxGFXFileName( i ) ); RGB32toRGB24( updata, updata, width * height * 4 ); TGA_write( tempFileName, 24, width, height, updata, 0, 1 ); // updata and data could point to the same memory block. if( updata == data) { MM_FREE( data ); } else { MM_FREE( data ); MM_FREE( updata ); } i += id; } else { wt_snprintf( tempFileName, sizeof( tempFileName ), "%s%c%.3d.tga", DIR_PICS, PATH_SEP, i ); RGB32toRGB24( data, data, width * height * 4 ); TGA_write( tempFileName, 24, width, height, data, 0, 1 ); MM_FREE( data ); } } GFXFile_Shutdown(); printf( "Done\n" ); return bRetVal; }