/** * \brief Add directory to zip file. * \param[in] path Directory path that will be added to zip file. * \param[in,out] f File stream to write compressed files to. * \return On success true, otherwise false. */ PRIVATE wtBoolean Pak_addDirectoryToZipFile( const char *path, FILE *f ) { char temp[ 256 ]; char *ptr; zipHead_t *newZipNode = NULL; wt_strlcpy( temp, path, sizeof( temp ) ); if( strstr( temp, "*" ) == NULL ) { wt_strlcat( temp, "/*", sizeof( temp ) ); } // Look for files ptr = FS_FindFirst( temp ); do { wt_snprintf( temp, sizeof( temp ), "%s/%s", path, ptr ); if ( temp[strlen(temp)-1] == '.' ) { continue; } if( ! FS_CompareFileAttributes( temp, 0, FA_DIR ) ) { continue; } newZipNode = Pak_WriteLocalFileChunk( temp, f ); if( newZipNode == NULL ) { continue; } // add new zipHead_t to chain zipChainLast = linkList_addList( zipChainLast, newZipNode ); } while( (ptr = FS_FindNext()) != NULL ); FS_FindClose(); return true; }
/** * \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; }
/** * \brief Convert map to Redux file format. * \param[in] fmaphead Map header file name. * \param[in] fmap Map file name. * \param[in] path Path to save redux map to. * \param[in] palette Pointer to palette array. * \param[in] ceilingColour Array of ceiling colours. * \param[in] musicFileName Array of music titles. * \param[in] parTimes Struct with the parTimes. * \return On success true, otherwise false. * \note Caller must free allocated data. */ PUBLIC wtBoolean MapFile_ReduxDecodeMapData( const char *fmaphead, const char *fmap, const char *path, W8 *palette, const W32 *ceilingColour, char *musicFileName[], parTimes_t *parTimes, char *format ) { W16 Rtag; W32 totalMaps; W32 i; FILE *fout; char filename[ 256 ]; W32 offset[ 3 ]; W32 offsetin[ 3 ]; W16 length[ 3 ]; W8 sig[ 5 ]; W16 w, h; char name[ 32 ]; char musicName[ 64 ]; SW32 jmp; W32 ceiling; W32 floor; W32 palOffset; W32 temp; float ftime; char *stime; W8 *data; printf( "Decoding Map Data..." ); if( ! MapFile_Setup( fmaphead, fmap, &Rtag, &totalMaps ) ) { return false; } for( i = 0 ; i < totalMaps ; ++i ) { if( fseek( map_file_handle, headerOffsets[ i ], SEEK_SET ) != 0 ) { break; } wt_snprintf( filename, sizeof( filename ), format, path, i ); fout = fopen( filename, "wb"); if( NULL == fout ) { continue; } // Get ceiling colour palOffset = (ceilingColour[ i ] & 0xff) * 3; ceiling = (palette[ palOffset ] << 16) | (palette[ palOffset + 1 ] << 8) | palette[ palOffset + 2 ]; // Get floor colour palOffset = 0x19 * 3; floor = (palette[ palOffset ] << 16 ) | (palette[ palOffset + 1 ] << 8) | palette[ palOffset + 2 ]; wt_snprintf( musicName, sizeof( musicName ), "%s/%s.ogg", DIR_MUSIC, musicFileName[ i ] ); ftime = parTimes[ i ].time; stime = parTimes[ i ].timestr; // // Read in map data // fread( &offsetin, sizeof( W32 ), 3, map_file_handle ); offsetin[ 0 ] = LittleLong( offsetin[ 0 ] ); offsetin[ 1 ] = LittleLong( offsetin[ 1 ] ); offsetin[ 2 ] = LittleLong( offsetin[ 2 ] ); fread( &length, sizeof( W16 ), 3, map_file_handle ); length[ 0 ] = LittleShort( length[ 0 ] ); length[ 1 ] = LittleShort( length[ 1 ] ); length[ 2 ] = LittleShort( length[ 2 ] ); fread( &w, sizeof( W16 ), 1, map_file_handle ); w = LittleShort( w ); fread( &h, sizeof( W16 ), 1, map_file_handle ); h = LittleShort( h ); fread( name, sizeof( W8 ), 16, map_file_handle ); fread( sig, sizeof( W8 ), 4, map_file_handle ); // // Output header // // Map file header signature fwrite( sig, sizeof( W8 ), 4, fout ); // RLE Word tag Rtag = LittleShort( Rtag ); fwrite( &Rtag, sizeof( W16 ), 1, fout ); // Max Width w = LittleShort( w ); fwrite( &w, sizeof( W16 ), 1, fout ); // Max Height h = LittleShort( h ); fwrite( &h, sizeof( W16 ), 1, fout ); // Ceiling Colour ceiling = LittleLong( ceiling ); fwrite( &ceiling, sizeof( W32 ), 1, fout ); // Floor Colour floor = LittleLong( floor ); fwrite( &floor, sizeof( W32 ), 1, fout ); // Length of layers temp = LittleShort( length[ 0 ] ); fwrite( &temp, sizeof( W16 ), 1, fout ); // Length One temp = LittleShort( length[ 1 ] ); fwrite( &temp, sizeof( W16 ), 1, fout ); // Length Two temp = LittleShort( length[ 2 ] ); fwrite( &temp, sizeof( W16 ), 1, fout ); // Length Three jmp = ftell( fout ); temp = 0; fwrite( &temp, sizeof( W32 ), 1, fout ); // Offset One fwrite( &temp, sizeof( W32 ), 1, fout ); // Offset Two fwrite( &temp, sizeof( W32 ), 1, fout ); // Offset Three // Map name length temp = strlen( name ); fwrite( &temp, sizeof( W16 ), 1, fout ); // Music name length temp = strlen( musicName ); fwrite( &temp, sizeof( W16 ), 1, fout ); // Par time Float ftime = LittleFloat( ftime ); fwrite( &ftime, sizeof( float ), 1, fout ); // Par time string fwrite( stime, sizeof( W8 ), 5 , fout ); // Map name fwrite( name, sizeof( W8 ), strlen( name ), fout ); // Music file name fwrite( musicName, sizeof( W8 ), strlen( musicName ), fout ); data = (PW8) MM_MALLOC( length[ 0 ] ); if( data == NULL ) { continue; } offset[ 0 ] = ftell( fout ); fseek( map_file_handle, offsetin[ 0 ], SEEK_SET ); fread( data, 1, length[ 0 ], map_file_handle ); fwrite( data, 1, length[ 0 ], fout ); MM_FREE( data ); data = (PW8) MM_MALLOC( length[ 1 ] ); if( data == NULL ) { MapFile_Shutdown(); return 0; } offset[ 1 ] = ftell( fout ); fseek( map_file_handle, offsetin[ 1 ], SEEK_SET ); fread( data, 1, length[ 1 ], map_file_handle ); fwrite( data, 1, length[ 1 ], fout ); MM_FREE( data ); data = (PW8) MM_MALLOC( length[ 2 ] ); if( data == NULL ) { MapFile_Shutdown(); return 0; } offset[ 2 ] = ftell( fout ); fseek( map_file_handle, offsetin[ 2 ], SEEK_SET ); fread( data, 1, length[ 2 ], map_file_handle ); fwrite( data, 1, length[ 2 ], fout ); MM_FREE( data ); fseek( fout, jmp, SEEK_SET ); temp = LittleLong( offset[ 0 ] ); fwrite( &temp, sizeof( W32 ), 1, fout ); // Offset One temp = LittleLong( offset[ 1 ] ); fwrite( &temp, sizeof( W32 ), 1, fout ); // Offset Two temp = LittleLong( offset[ 2 ] ); fwrite( &temp, sizeof( W32 ), 1, fout ); // Offset Three fclose( fout ); } MapFile_Shutdown(); printf( "Done\n" ); return true; }
/** * \brief Decode music chunks * \param[in] start Start of music chunks. * \param[in] end End of music chunks. * \param[in] songNames Song titles. * \return On success true, otherwise false. */ PUBLIC wtBoolean AudioFile_ReduxDecodeMusic( const W32 start, const W32 end, const char *path, char *songNames[] ) { SW8 *buffChunk; void *buffWav; W32 i; W32 length; char filename[ 1024 ]; W32 uncompr_length; printf( "Decoding Music (This could take a while)..." ); if( ! ADLIB_Init( 44100 ) ) { return false; } for( i = start ; i < end ; ++i ) { buffChunk = (PSW8) AudioFile_CacheAudioChunk( i ); if( buffChunk == NULL ) { continue; } uncompr_length = ADLIB_getLength( buffChunk ); if( uncompr_length <= 1 ) { MM_FREE( buffChunk ); continue; } ADLIB_LoadMusic( buffChunk ); buffWav = MM_MALLOC( uncompr_length * 64 * 2 ); if( buffWav == NULL ) { MM_FREE( buffChunk ); continue; } length = ADLIB_UpdateMusic( uncompr_length, buffWav ); #ifdef BIG_ENDIAN_SYSTEM AudioFile_dataByteSwap( buffWav, length ); #endif // Save audio buffer if( _saveMusicAsWav ) { if( songNames ) { wt_snprintf( filename, sizeof( filename ), "%s%c%s.wav", path, PATH_SEP, songNames[ i - start ] ); } else { wt_snprintf( filename, sizeof( filename ), "%s%c%d.wav", path, PATH_SEP, i - start ); } wav_write( filename, buffWav, length, 1, 44100, 2 ); } else { if( songNames ) { wt_snprintf( filename, sizeof( filename ), "%s%c%s.ogg", path, PATH_SEP, songNames[ i - start ] ); } else { wt_snprintf( filename, sizeof( filename ), "%s%c%d.ogg", path, PATH_SEP, i - start ); } vorbis_encode( filename, buffWav, length, 1, 16, 44100, 0, 0, 0 ); } MM_FREE( buffWav ); MM_FREE( buffChunk ); } ADLIB_Shutdown(); printf( "Done\n" ); return true; }
/** * \brief Decode sound fx. * \param[in] start Start of sound fx chunks. * \param[in] end End of sound fx chunks. * \param[in] path Directory path to save file to. * \return On success true, otherwise false. */ PUBLIC wtBoolean AudioFile_ReduxDecodeSound( const W32 start, const W32 end, const char *path ) { SW8 *buffChunk; void *buffWav; W32 i; W32 length; char filename[ 1024 ]; printf( "Decoding Sound FX..." ); if( ! ADLIB_Init( 22050 ) ) { return false; } for( i = start ; i < end ; ++i ) { buffChunk = (PSW8) AudioFile_CacheAudioChunk( i ); if( buffChunk == NULL ) { continue; } buffWav = ADLIB_DecodeSound( (AdLibSound *)buffChunk, &length ); if( buffWav == NULL ) { MM_FREE( buffChunk ); continue; } #ifdef BIG_ENDIAN_SYSTEM AudioFile_dataByteSwap( buffWav, length ); #endif if( _saveAudioAsWav ) { wt_snprintf( filename, sizeof( filename ), "%s%c%.3d.wav", path, PATH_SEP, GetSoundMappedIndex( i - start ) ); wav_write( filename, buffWav, length, 1, 22050, 2 ); } else { wt_snprintf( filename, sizeof( filename ), "%s%c%.3d.ogg", path, PATH_SEP, GetSoundMappedIndex( i - start ) ); vorbis_encode( filename, buffWav, length, 1, 16, 22050, 0, 0, 0 ); } MM_FREE( buffWav ); MM_FREE( buffChunk ); } ADLIB_Shutdown(); printf( "Done\n" ); return true; }
/** * \brief Decodes Blake Stone Aliens of Gold Full Version data. * \return Nothing. */ PUBLIC void blakestoneAGfull_decoder( void ) { W32 width, height; void *data; char fname[ 1024 ]; W8 *tempPalette; printf( "\n\nBlake Stone: Aliens of Gold Decoding\n" ); if( ! buildCacheDirectories() ) { printf( "Unable to create cache directories\n" ); return; } if( GFXFile_Setup( "VGADICT.BS6", "VGAHEAD.BS6", "VGAGRAPH.BS6" ) ) { GFXFile_decodeFont( 1, 256, 128, DIR_PICS ); GFXFile_decodeFont( 2, 256, 128, DIR_PICS ); GFXFile_decodeFont( 3, 256, 128, DIR_PICS ); GFXFile_decodeFont( 4, 256, 128, DIR_PICS ); GFXFile_decodeFont( 5, 256, 128, DIR_PICS ); GFXFile_decodeScript( 181, 223, DIR_GSCRIPTS ); GFXFile_decodeGFX( 6, 164, blakestone_gamepal, DIR_PICS ); GFXFile_cacheChunk( 168 ); tempPalette = (PW8)GFXFile_getChunk( 168 ); data = GFXFile_decodeChunk_RGB24( 29, &width, &height, tempPalette ); if( data ) { wt_snprintf( fname, sizeof( fname ), "%s%c%.3d.tga", DIR_PICS, PATH_SEP, 29 ); RGB24_adjustBrightness( data, width * height * 3 ); TGA_write( fname, 24, width, height, data, 0, 1 ); MM_FREE( data ); } GFXFile_cacheChunk( 167 ); tempPalette = (PW8)GFXFile_getChunk( 167 ); data = GFXFile_decodeChunk_RGB24( 30, &width, &height, tempPalette ); if( data ) { wt_snprintf( fname, sizeof( fname ), "%s%c%.3d.tga", DIR_PICS, PATH_SEP, 30 ); RGB24_adjustBrightness( data, width * height * 3 ); TGA_write( fname, 24, width, height, data, 0, 1 ); MM_FREE( data ); } } GFXFile_Shutdown(); PageFile_ReduxDecodePageData( "VSWAP.BS6", DIR_WALLS, DIR_SPRITES, DIR_DSOUND, blakestone_gamepal ); /* if( AudioFile_Setup( "AUDIOHED.BS6", "AUDIOT.BS6" ) ) { AudioFile_ReduxDecodeSound( 0, 200, DIR_SOUNDFX ); AudioFile_ReduxDecodeMusic( 200, 210, DIR_MUSIC, NULL ); } AudioFile_Shutdown(); */ }
/** * \brief Decodes Blake Stone Planet Strike data. * \return Nothing. */ PUBLIC void blakestonePS_decoder( void ) { W32 width, height; void *data; char fname[ 256 ]; W8 *tempPalette; printf( "Blake Stone: Planet Strike Decoding\n\n" ); if( ! buildCacheDirectories() ) { fprintf( stderr, "Unable to create cache directories\n" ); return; } if( GFXFile_Setup( "VGADICT.VSI", "VGAHEAD.VSI", "VGAGRAPH.VSI" ) ) { GFXFile_decodeFont( 1, 256, 128, DIR_PICS ); GFXFile_decodeFont( 2, 256, 128, DIR_PICS ); GFXFile_decodeFont( 3, 256, 128, DIR_PICS ); GFXFile_decodeFont( 4, 256, 128, DIR_PICS ); GFXFile_decodeFont( 5, 256, 128, DIR_PICS ); GFXFile_decodeScript( 216, 248, DIR_GSCRIPTS ); GFXFile_decodeGFX( 6, 197, blakestone_gamepal, DIR_PICS ); GFXFile_cacheChunk( 201 ); tempPalette = (PW8)GFXFile_getChunk( 201 ); data = GFXFile_decodeChunk_RGB24( 53, &width, &height, tempPalette ); if( data ) { wt_snprintf( fname, sizeof( fname ), "%s%c%.3d.tga", DIR_PICS, PATH_SEP, 53 ); RGB24_adjustBrightness( data, width * height * 3 ); TGA_write( fname, 24, width, height, data, 0, 1 ); MM_FREE( data ); } GFXFile_cacheChunk( 203 ); tempPalette = (PW8)GFXFile_getChunk( 203 ); data = GFXFile_decodeChunk_RGB24( 143, &width, &height, tempPalette ); if( data ) { wt_snprintf( fname, sizeof( fname ), "%s%c%.3d.tga", DIR_PICS, PATH_SEP, 143 ); RGB24_adjustBrightness( data, width * height * 3 ); TGA_write( fname, 24, width, height, data, 0, 1 ); MM_FREE( data ); } data = GFXFile_decodeChunk_RGB24( 144, &width, &height, tempPalette ); if( data ) { wt_snprintf( fname, sizeof( fname ), "%s%c%.3d.tga", DIR_PICS, PATH_SEP, 144 ); RGB24_adjustBrightness( data, width * height * 3 ); TGA_write( fname, 24, width, height, data, 0, 1 ); MM_FREE( data ); } } GFXFile_Shutdown(); PageFile_ReduxDecodePageData( "VSWAP.VSI", DIR_WALLS, DIR_SPRITES, DIR_DSOUND, blakestone_gamepal ); /* if( AudioFile_Setup( "AUDIOHED.VSI", "AUDIOT.VSI" ) ) { AudioFile_ReduxDecodeSound( 0, 0, DIR_SOUNDFX ); AudioFile_ReduxDecodeMusic( 0, 0, DIR_MUSIC, NULL ); } AudioFile_Shutdown(); */ }
/** * \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; }
/** * \brief Decodes Wolfenstein 3-D Shareware versions 1.0 to 1.4 * \return Nothing. */ void wolfshare_decoder( void ) { picNum_t picNum; W32 retCheck = 0; W32 pic_end = 147; char pakName[64]; // Following values are for share V14 W32 soundChunkStart = 87; W32 soundChunkEnd = 174; W32 musicChunkStart = 261; W32 musicChunkEnd = 261+27; W32 __WL1_L_COLONPIC = WL1_L_COLONPIC; W32 __WL1_L_NUM0PIC = WL1_L_NUM0PIC; W32 __WL1_L_NUM9PIC = WL1_L_NUM9PIC; W32 __WL1_L_PERCENTPIC = WL1_L_PERCENTPIC; W32 __WL1_L_APIC = WL1_L_APIC; W32 __WL1_L_ZPIC = WL1_L_ZPIC; W32 __WL1_L_EXPOINTPIC = WL1_L_EXPOINTPIC; W32 __WL1_L_APOSTROPHEPIC = WL1_L_APOSTROPHEPIC; W32 __WL1_STATUSBARPIC = WL1_STATUSBARPIC; W32 __WL1_NOKEYPIC = WL1_NOKEYPIC; W32 __WL1_N_BLANKPIC = WL1_N_BLANKPIC; W32 __WL1_N_0PIC = WL1_N_0PIC; W32 __WL1_N_1PIC = WL1_N_1PIC; W32 __WL1_N_9PIC = WL1_N_9PIC; W32 __WL1_H_BOTTOMINFOPIC = WL1_H_BOTTOMINFOPIC; printf( "Wolfenstein 3-D Shareware" ); if( wolf_version == WL1_V10 ) { printf( " V1.0" ); wt_snprintf( pakName, sizeof(pakName), "%s", "wolf_shareV10.pak" ); pic_end = 139; soundChunkStart = 87; soundChunkEnd = 146; musicChunkStart = 219; musicChunkEnd = 219+27; __WL1_L_COLONPIC = 49; __WL1_L_NUM0PIC = 50; __WL1_L_NUM9PIC = 59; __WL1_L_PERCENTPIC = 60; __WL1_L_APIC = 61; __WL1_L_ZPIC = 86; __WL1_L_EXPOINTPIC = 87; __WL1_L_APOSTROPHEPIC = 87; // none __WL1_STATUSBARPIC = 90; __WL1_NOKEYPIC = 99; __WL1_N_BLANKPIC = 102; __WL1_N_0PIC = 103; __WL1_N_1PIC = 104; __WL1_N_9PIC = 112; __WL1_H_BOTTOMINFOPIC = 20; } if( wolf_version == WL1_V11 ) { printf( " V1.1" ); wt_snprintf( pakName, sizeof(pakName), "%s", "wolf_shareV11.pak" ); pic_end = 141; __WL1_L_COLONPIC = 53; __WL1_L_NUM0PIC = 54; __WL1_L_NUM9PIC = 63; __WL1_L_PERCENTPIC = 64; __WL1_L_APIC = 65; __WL1_L_ZPIC = 90; __WL1_L_EXPOINTPIC = 91; __WL1_L_APOSTROPHEPIC = 92; __WL1_STATUSBARPIC = 95; __WL1_NOKEYPIC = 104; __WL1_N_BLANKPIC = 107; __WL1_N_0PIC = 108; __WL1_N_1PIC = 109; __WL1_N_9PIC = 117; __WL1_H_BOTTOMINFOPIC = 20; } if( wolf_version == WL1_V14 ) { printf( " V1.4" ); wt_snprintf( pakName, sizeof(pakName), "%s", "wolf_shareV14.pak" ); } printf( " Decoding\n\n" ); if( ! buildCacheDirectories() ) { fprintf( stderr, "Unable to create cache directories\n" ); return; } picNum.PN_StatusBar = __WL1_STATUSBARPIC; picNum.PN_NoKey = __WL1_NOKEYPIC; picNum.PN_Blank = __WL1_N_BLANKPIC; picNum.PN_Title1 = 999; picNum.PN_Title2 = 999; picNum.PN_TitlePalette = 999; picNum.PN_0 = __WL1_N_0PIC; picNum.PN_1 = __WL1_N_1PIC; picNum.PN_9 = __WL1_N_9PIC; picNum.PN_Colon = __WL1_L_COLONPIC; picNum.PN_Num0 = __WL1_L_NUM0PIC; picNum.PN_Num9 = __WL1_L_NUM9PIC; picNum.PN_Percent = __WL1_L_PERCENTPIC; picNum.PN_A = __WL1_L_APIC; picNum.PN_Z = __WL1_L_ZPIC; picNum.PN_Expoint = __WL1_L_EXPOINTPIC; picNum.PN_Apostrophe = __WL1_L_APOSTROPHEPIC; picNum.PN_IDGuys1 = 999; picNum.PN_IDGuys2 = 999; picNum.PN_EndScreen1 = 999; picNum.PN_EndScreen9 = 999; picNum.PN_HelpScript = 0; picNum.PN_ScriptStart = 0; picNum.PN_ScriptEnd = 0; picNum.PN_bottomInfoPic = __WL1_H_BOTTOMINFOPIC; retCheck += wolf3d_gfx( "VGADICT.WL1", "VGAHEAD.WL1", "VGAGRAPH.WL1", 3, pic_end, &picNum, WL1_GetReduxGFXFileName ); retCheck += PageFile_ReduxDecodePageData( "VSWAP.WL1", DIR_WALLS, DIR_SPRITES, DIR_DSOUND, wolf_gamepal ); if( _doRedux ) { retCheck += MapFile_ReduxDecodeMapData( "MAPHEAD.WL1", wolf_version == WL1_V10 ? "MAPTEMP.WL1" : "GAMEMAPS.WL1", DIR_MAPS, wolf_gamepal, CeilingColourWL6, WL6_songs, parTimesWL6, "%s/w%.2d.map" ); } if( AudioFile_Setup( "AUDIOHED.WL1", "AUDIOT.WL1" ) ) { retCheck += AudioFile_ReduxDecodeSound( soundChunkStart, soundChunkEnd, DIR_SOUNDFX ); retCheck += AudioFile_ReduxDecodeMusic( musicChunkStart, musicChunkEnd, DIR_MUSIC, songTitles ); } AudioFile_Shutdown(); if( retCheck == 5 && ! _outputInDirectory ) { PAK_builder( pakName, 0, true ); } }