2016-11-10 18:56:16 +00:00
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2016 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
2016-11-12 10:03:29 +00:00
# ifdef _MSC_VER
2016-11-10 18:56:16 +00:00
# include <direct.h>
2016-11-12 10:03:29 +00:00
# else // !_MSC_VER
# include <unistd.h>
# include <sys/stat.h>
# endif // _MSC_VER
# include <string.h>
2016-11-10 18:56:16 +00:00
# include <stdio.h>
2016-11-10 19:47:27 +00:00
# include <string>
2016-11-10 18:56:16 +00:00
# include "wadext.h"
2016-11-12 10:03:29 +00:00
# include "resourcefile.h"
2016-11-10 18:56:16 +00:00
# include "fileformat.h"
# pragma warning(disable:4996)
bool isLevel ( WadItemList * we ) ;
char profile [ 256 ] ;
char maindir [ 128 ] ;
bool pstartfound = false ;
WadItemList PNames ( - 1 ) ;
2016-11-12 10:03:29 +00:00
# ifndef _MSC_VER
static char * strlwr ( char * str )
{
for ( char * ch = str ; ' \0 ' ! = * ch ; + + ch )
{
* ch = tolower ( * ch ) ;
}
return str ;
}
static char * strupr ( char * str )
{
for ( char * ch = str ; ' \0 ' ! = * ch ; + + ch )
{
2017-01-11 15:48:21 +00:00
* ch = toupper ( * ch ) ;
2016-11-12 10:03:29 +00:00
}
return str ;
}
static int mkdir ( const char * path )
{
return mkdir ( path , 0755 ) ;
}
# endif // !_MSC_VER
2016-11-10 18:56:16 +00:00
char * getdir ( const char * lump )
{
static char d [ 2 ] = " " ;
if ( * lump > = ' A ' & & * lump < = ' Z ' ) d [ 0 ] = * lump ;
else if ( * lump > = ' a ' & & * lump < = ' z ' ) d [ 0 ] = * lump - 32 ;
else if ( * lump > = ' 0 ' & & * lump < = ' 9 ' ) d [ 0 ] = ' 0 ' ;
else d [ 0 ] = ' @ ' ;
return d ;
}
bool isPatch ( const char * n )
{
if ( ! pstartfound | | PNames . mLump < 0 ) return false ;
2017-01-11 13:43:55 +00:00
uint32_t * l = ( uint32_t * ) PNames . Address ( ) ;
2016-11-10 18:56:16 +00:00
char * c = ( char * ) ( l + 1 ) ;
char nn [ 9 ] ;
if ( ! l ) return false ;
strncpy ( nn , n , 8 ) ;
nn [ 8 ] = 0 ;
strupr ( nn ) ;
2021-08-08 06:42:58 +00:00
for ( unsigned i = 0 ; i < * l ; i + + )
2016-11-10 18:56:16 +00:00
{
if ( ! strncmp ( c , nn , 8 ) ) return true ;
c + = 8 ;
}
return false ;
}
const char * MakeFileName ( const char * base , const char * ext )
{
char basebuffer [ 20 ] ;
static char buffer [ 40 ] ;
strncpy ( basebuffer , base , 8 ) ;
basebuffer [ 8 ] = 0 ;
for ( int i = 0 ; i < 8 ; i + + )
{
// replace special path characters in the lump name
if ( basebuffer [ i ] = = ' \\ ' ) basebuffer [ i ] = ' ^ ' ;
2016-11-12 10:04:17 +00:00
if ( basebuffer [ i ] = = ' / ' ) basebuffer [ i ] = ' \xA7 ' ;
if ( basebuffer [ i ] = = ' : ' ) basebuffer [ i ] = ' \xA1 ' ;
if ( basebuffer [ i ] = = ' * ' ) basebuffer [ i ] = ' \xB2 ' ;
if ( basebuffer [ i ] = = ' ? ' ) basebuffer [ i ] = ' \xBF ' ;
2016-11-10 18:56:16 +00:00
}
for ( int i = 0 ; ; i + + )
{
2021-08-08 06:42:58 +00:00
if ( i > 0 ) sprintf ( buffer , " %s%s(%d) " , basebuffer , ext , i ) ;
2016-11-10 18:56:16 +00:00
else sprintf ( buffer , " %s%s " , basebuffer , ext ) ;
strlwr ( buffer ) ;
FILE * f = fopen ( buffer , " rb " ) ;
if ( f = = NULL ) return buffer ;
fclose ( f ) ;
}
}
2016-11-12 10:04:17 +00:00
void Extract ( WadItemList * w , const char * dir , const char * ext , int options , bool isflat ) //It is completely impossible to detect flats, so we have to flag it when extracting the F_ namespace
2016-11-10 18:56:16 +00:00
{
FileType ft = IdentifyFileType ( w - > Name ( ) , ( uint8_t * ) w - > Address ( ) , w - > Length ( ) ) ;
const char * filename ;
if ( dir = = NULL )
{
switch ( ft . type & FG_MASK )
{
case FG_GFX :
if ( isPatch ( w - > Name ( ) ) ) dir = " patches " ;
else dir = " graphics " ;
break ;
case FG_SND :
dir = " sounds " ;
break ;
case FG_MUS :
dir = " music " ;
break ;
case FG_VOX :
dir = " voxels " ;
break ;
}
}
// Flats are easy to misidentify so if we are in the flat namespace and the size is exactly 4096 bytes, let it pass as flat
if ( isflat & & ( ft . type & FG_MASK ) ! = FG_GFX & & ( ft . type = = FT_DOOMSND | | ft . type = = FT_MP3 | | w - > Length ( ) = = 4096 ) )
{
2016-11-12 10:03:29 +00:00
ft . type = FT_BINARY ;
ft . extension = " .LMP " ;
2016-11-10 18:56:16 +00:00
}
if ( dir ! = NULL )
{
mkdir ( dir ) ;
chdir ( dir ) ;
}
printf ( " processing %.8s \n " , w - > Name ( ) ) ;
if ( ft . type = = FT_DOOMGFX & & ! ( options & NO_CONVERT_GFX ) )
{
filename = MakeFileName ( w - > Name ( ) , " .png " ) ;
PatchToPng ( options , ( const uint8_t * ) w - > Address ( ) , w - > Length ( ) , filename ) ;
}
else if ( w - > Length ( ) > 0 & & ft . type = = FT_BINARY & & ! ( options & NO_CONVERT_GFX ) & & ( isflat | | ( w - > Length ( ) = = 64000 & & options & ( DO_HEXEN_PAL | DO_HERETIC_PAL ) ) ) )
{
filename = MakeFileName ( w - > Name ( ) , " .png " ) ;
FlatToPng ( options , ( const uint8_t * ) w - > Address ( ) , w - > Length ( ) , filename ) ;
}
else if ( ft . type = = FT_DOOMSND & & ! ( options & NO_CONVERT_SND ) )
{
filename = MakeFileName ( w - > Name ( ) , " .wav " ) ;
DoomSndToWav ( ( const uint8_t * ) w - > Address ( ) , w - > Length ( ) , filename ) ;
}
else
{
filename = MakeFileName ( w - > Name ( ) , ft . extension ) ;
FILE * f = fopen ( filename , " wb " ) ;
if ( f = = NULL )
{
printf ( " %s: Unable to create file \n " , filename ) ;
chdir ( maindir ) ;
return ;
}
fwrite ( w - > Address ( ) , 1 , w - > Length ( ) , f ) ;
fclose ( f ) ;
}
chdir ( maindir ) ;
}
2016-11-12 10:04:17 +00:00
int ListExtract ( int startmarker , const char * dir , const char * endm , const char * endm2 , bool isflat , int options , int pack = 0 )
2016-11-10 18:56:16 +00:00
{
char dirbuf [ 200 ] ;
mkdir ( dir ) ;
strcpy ( dirbuf , dir ) ;
WadItemList ww ( startmarker + 1 ) ;
WadItemList * w = & ww ;
while ( strncmp ( w - > Name ( ) , endm , 8 ) & & strncmp ( w - > Name ( ) , endm2 , 8 ) )
{
Extract ( w , dir , NULL , options , isflat ) ;
ww = ww . mLump + 1 ;
}
return ww . mLump ;
}
bool isLevel ( int lump )
{
if ( lump > = mainwad - > NumLumps ( ) - 3 ) return false ; // any level is at least 3 lumps
WadItemList w ( lump + 1 ) ;
if ( ! stricmp ( w . Name ( ) , " THINGS " ) ) return true ;
if ( ! stricmp ( w . Name ( ) , " TEXTMAP " ) ) return true ;
return false ;
}
2016-11-12 10:04:17 +00:00
int MapExtract ( int startmarker , const char * dir , int options )
2016-11-10 18:56:16 +00:00
{
int i ;
char buffer [ 40 ] ;
TArray < CWADLump > directory ;
mkdir ( dir ) ;
chdir ( dir ) ;
WadItemList ww ( startmarker ) ;
sprintf ( buffer , " %.8s.wad " , ww . Name ( ) ) ;
printf ( " processing %s \n " , buffer ) ;
FILE * f = fopen ( buffer , " wb " ) ;
fwrite ( " PWAD \ xb \0 \0 \0 \0 \0 \0 \0 " , 1 , 12 , f ) ;
CWADLump lmp ;
lmp . offset = ftell ( f ) ;
strncpy ( lmp . name , ww . Name ( ) , 8 ) ;
lmp . length = ww . Length ( ) ;
fwrite ( ww . Address ( ) , 1 , ww . Length ( ) , f ) ;
directory . Push ( lmp ) ;
ww = ww . mLump + 1 ;
if ( ! stricmp ( ww . Name ( ) , " TEXTMAP " ) )
{
// UDMF
while ( true )
{
if ( ! ( options & DO_STRIP ) | | ( stricmp ( ww . Name ( ) , " ZNODES " ) & & stricmp ( ww . Name ( ) , " BLOCKMAP " ) & & stricmp ( ww . Name ( ) , " REJECT " ) ) )
{
CWADLump lmp ;
lmp . offset = ftell ( f ) ;
strncpy ( lmp . name , ww . Name ( ) , 8 ) ;
lmp . length = ww . Length ( ) ;
fwrite ( ww . Address ( ) , 1 , ww . Length ( ) , f ) ;
directory . Push ( lmp ) ;
}
if ( ! stricmp ( ww . Name ( ) , " ENDMAP " ) )
{
goto finalize ;
}
int lump = ww . mLump + 1 ;
if ( lump = = mainwad - > NumLumps ( ) )
{
printf ( " Unexpected end of UDMF map found \n " ) ;
return lump ;
}
ww = lump ;
}
}
else
{
static const char * maplumps [ ] = { " THINGS " , " LINEDEFS " , " SIDEDEFS " , " VERTEXES " , " SEGS " , " SSECTORS " , " NODES " , " SECTORS " , " REJECT " , " BLOCKMAP " , " BEHAVIOR " , " SCRIPTS " } ;
for ( i = 0 ; i < 12 ; i + + )
{
if ( ww . Name ( ) ! = NULL & & ! stricmp ( ww . Name ( ) , maplumps [ i ] ) )
{
CWADLump lmp ;
lmp . offset = ftell ( f ) ;
strncpy ( lmp . name , ww . Name ( ) , 8 ) ;
if ( ( options & DO_STRIP ) & & ( i = = 4 | | i = = 5 | | i = = 6 | | i = = 8 | | i = = 9 ) )
{
lmp . length = 0 ;
}
else
{
lmp . length = ww . Length ( ) ;
fwrite ( ww . Address ( ) , 1 , ww . Length ( ) , f ) ;
}
directory . Push ( lmp ) ;
ww = ww . mLump + 1 ;
}
}
}
finalize :
uint32_t lumpc = directory . Size ( ) ;
uint32_t dpos = ftell ( f ) ;
for ( auto & p : directory )
{
fwrite ( & p , 1 , 16 , f ) ;
}
fseek ( f , 4 , 0 ) ;
fwrite ( & lumpc , 1 , 4 , f ) ;
fwrite ( & dpos , 1 , 4 , f ) ;
fclose ( f ) ;
chdir ( " .. " ) ;
return directory . Size ( ) ;
}
typedef char pname [ 8 ] ;
bool AddWallTexture ( FILE * fo , maptexture_t * wt , pname * pNames , bool first )
{
int k ;
char buffer [ 9 ] ;
sprintf ( buffer , " %.8s " , wt - > name ) ;
strupr ( buffer ) ;
bool cc = strspn ( buffer , " ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789 " ) < strlen ( buffer ) | | * buffer < = ' 9 ' ;
fprintf ( fo , " WallTexture %s%s%s, %d, %d \n { \n " , cc ? " \" " : " " , buffer , cc ? " \" " : " " , wt - > width , wt - > height ) ;
if ( wt - > ScaleX ) fprintf ( fo , " \t XScale %f \n " , wt - > ScaleX / 8.0f ) ;
if ( wt - > ScaleY ) fprintf ( fo , " \t YScale %f \n " , wt - > ScaleY / 8.0f ) ;
if ( wt - > Flags & 0x8000 ) fprintf ( fo , " \t WorldPanning \n " ) ;
if ( first ) fprintf ( fo , " \t NullTexture \n " ) ;
for ( k = 0 ; k < wt - > patchcount ; k + + )
{
sprintf ( buffer , " %.8s " , pNames [ wt - > patches [ k ] . patch ] ) ;
strupr ( buffer ) ;
cc = strspn ( buffer , " ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789 " ) < strlen ( buffer ) | | * buffer < = ' 9 ' ;
fprintf ( fo , " \t Patch %s%.8s%s, %d, %d \n " , cc ? " \" " : " " , buffer , cc ? " \" " : " " , wt - > patches [ k ] . originx , wt - > patches [ k ] . originy ) ;
}
fprintf ( fo , " } \n " ) ;
return true ;
}
bool AddWallTexture ( FILE * fo , strifemaptexture_t * wt , pname * pNames , bool first )
{
int k ;
char buffer [ 9 ] ;
sprintf ( buffer , " %.8s " , wt - > name ) ;
strupr ( buffer ) ;
bool cc = strspn ( buffer , " ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789 " ) < strlen ( buffer ) | | * buffer < = ' 9 ' ;
fprintf ( fo , " WallTexture %s%s%s, %d, %d \n { \n " , cc ? " \" " : " " , buffer , cc ? " \" " : " " , wt - > width , wt - > height ) ;
if ( wt - > ScaleX ) fprintf ( fo , " \t XScale %f \n " , wt - > ScaleX / 8.0f ) ;
if ( wt - > ScaleY ) fprintf ( fo , " \t YScale %f \n " , wt - > ScaleY / 8.0f ) ;
if ( wt - > Flags & 0x8000 ) fprintf ( fo , " \t WorldPanning \n " ) ;
for ( k = 0 ; k < wt - > patchcount ; k + + )
{
sprintf ( buffer , " %.8s " , pNames [ wt - > patches [ k ] . patch ] ) ;
strupr ( buffer ) ;
cc = strspn ( buffer , " ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789 " ) < strlen ( buffer ) | | * buffer < = ' 9 ' ;
fprintf ( fo , " \t Patch %s%.8s%s, %d, %d \n " , cc ? " \" " : " " , buffer , cc ? " \" " : " " , wt - > patches [ k ] . originx , wt - > patches [ k ] . originy ) ;
}
fprintf ( fo , " } \n " ) ;
return true ;
}
void AnimExtract ( WadItemList * w )
{
int i , numentries ;
char * c ;
char buffer [ 30 ] ;
mkdir ( " decompiled " ) ;
chdir ( " decompiled " ) ;
strcpy ( buffer , " animdefs.animated " ) ;
printf ( " processing %s \n " , buffer ) ;
numentries = w - > Length ( ) / 23 ;
c = ( char * ) w - > Address ( ) ;
FILE * fo = fopen ( buffer , " wt " ) ;
for ( i = 0 ; i < numentries ; i + + )
{
fprintf ( fo , " %s %s Range %s Tics %d \n " , * c ? " Texture " : " Flat " , c + 10 , c + 1 , * ( int * ) ( c + 19 ) ) ;
c + = 23 ;
}
fclose ( fo ) ;
chdir ( maindir ) ;
}
void SwitchExtract ( WadItemList * w )
{
int i , numentries ;
char * c ;
char buffer [ 30 ] ;
mkdir ( " decompiled " ) ;
chdir ( " decompiled " ) ;
strcpy ( buffer , " animdefs.switches " ) ;
printf ( " processing %s \n " , buffer ) ;
numentries = w - > Length ( ) / 20 ;
c = ( char * ) w - > Address ( ) ;
FILE * fo = fopen ( buffer , " wt " ) ;
for ( i = 0 ; i < numentries ; i + + )
{
if ( * ( short * ) ( c + 18 ) = = 0 ) break ;
//fprintf(fo,"%s,%s,%d\n",c,c+9,*(short*)(c+18));
fprintf ( fo , " Switch %s on pic %s tics 0 \n " , c , c + 9 ) ;
c + = 20 ;
}
fclose ( fo ) ;
chdir ( maindir ) ;
//Extract(w, dir);
}
void GenerateTextureFile ( const char * name , const char * pTex , const char * pPNam , int options , bool nullfirst )
{
const char * tr = pTex ;
int tc = * ( int * ) tr ;
int * to = ( int * ) ( tr + 4 ) ;
pname * pr = ( pname * ) ( ( char * ) pPNam + 4 ) ;
FILE * fo = fopen ( name , " wt " ) ;
// Todo: Be more thorough than this!
if ( ! ( options & DO_STRIFE ) )
{
for ( int i = 0 ; i < tc ; i + + )
AddWallTexture ( fo , ( maptexture_t * ) ( tr + to [ i ] ) , pr , i = = 0 & & nullfirst ) ;
}
else
{
for ( int i = 0 ; i < tc ; i + + )
AddWallTexture ( fo , ( strifemaptexture_t * ) ( ( char * ) tr + to [ i ] ) , pr , i = = 0 & & nullfirst ) ;
}
fclose ( fo ) ;
}
void GenerateTextureFile ( WadItemList * pTex , WadItemList * pPNam , int options )
{
char buffer [ 40 ] ;
mkdir ( " decompiled " ) ;
sprintf ( buffer , " decompiled \\ textures.%c " , pTex - > Name ( ) [ 7 ] ) ;
bool nulltex = ! strnicmp ( pTex - > Name ( ) , " TEXTURE1 " , 8 ) ;
GenerateTextureFile ( buffer , ( const char * ) pTex - > Address ( ) , ( const char * ) pPNam - > Address ( ) , options , nulltex ) ;
}
2016-11-10 19:47:27 +00:00
//==========================================================================
//
// IsSeparator (taken from ZDoom)
//
// Returns true if the character is a path separator.
//
//==========================================================================
static inline bool IsSeparator ( int c )
{
if ( c = = ' / ' )
return true ;
# ifdef WIN32
if ( c = = ' \\ ' | | c = = ' : ' )
return true ;
# endif
return false ;
}
//==========================================================================
//
// ExtractFileBase (taken from ZDoom)
//
// Returns the file part of a pathname, optionally including the extension.
//
//==========================================================================
std : : string ExtractFileBase ( const char * path , bool include_extension )
{
const char * src , * dot ;
src = path + strlen ( path ) - 1 ;
if ( src > = path )
{
// back up until a / or the start
while ( src ! = path & & ! IsSeparator ( * ( src - 1 ) ) )
src - - ;
// Check for files with drive specification but no path
# if defined(_WIN32)
if ( src = = path & & src [ 0 ] ! = 0 )
{
if ( src [ 1 ] = = ' : ' )
src + = 2 ;
}
# endif
if ( ! include_extension )
{
dot = src ;
while ( * dot & & * dot ! = ' . ' )
{
dot + + ;
}
return std : : string ( src , dot - src ) ;
}
else
{
return std : : string ( src ) ;
}
}
return std : : string ( ) ;
}
2016-11-10 18:56:16 +00:00
void ExtractWad ( char * wadfilename , int options )
{
WadItemList pTex1 ( - 1 ) , pTex2 ( - 1 ) , pPnam ( - 1 ) ;
OpenMainWad ( wadfilename ) ;
2016-11-10 19:47:27 +00:00
auto name = ExtractFileBase ( wadfilename , false ) ;
mkdir ( name . c_str ( ) ) ;
chdir ( name . c_str ( ) ) ;
2016-11-10 18:56:16 +00:00
PNames = mainwad - > FindLump ( " PNAMES " ) ;
getcwd ( maindir , 128 ) ;
for ( int i = 0 ; i < mainwad - > NumLumps ( ) ; i + + )
{
WadItemList ww ( i ) ;
WadItemList * w = & ww ;
{
if ( ! strcmp ( w - > Name ( ) , " . " ) )
{
w - > Release ( ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " S_START " , 8 ) | | ! strnicmp ( w - > Name ( ) , " SS_START " , 8 ) )
{
i = ListExtract ( i , " SPRITES " , " S_END " , " SS_END " , false , options , false ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " F_START " , 8 ) | | ! strnicmp ( w - > Name ( ) , " FF_START " , 8 ) )
{
i = ListExtract ( i , " FLATS " , " F_END " , " FF_END " , true , options , false ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " C_START " , 8 ) )
{
i = ListExtract ( i , " COLORMAPS " , " C_END " , " CC_END " , false , false , options ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " A_START " , 8 ) )
{
i = ListExtract ( i , " ACS " , " A_END " , " AA_END " , false , false , options ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " P_START " , 8 ) | | ! strnicmp ( w - > Name ( ) , " PP_START " , 8 ) )
{
pstartfound = true ;
}
else if ( ! strnicmp ( w - > Name ( ) , " P_END " , 8 ) | | ! strnicmp ( w - > Name ( ) , " PP_END " , 8 ) ) // ignore
{
}
else if ( ! strnicmp ( w - > Name ( ) , " TX_START " , 8 ) )
{
i = ListExtract ( i , " TEXTURES " , " TX_END " , " TX_END " , false , options ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " HI_START " , 8 ) )
{
i = ListExtract ( i , " HIRES " , " HI_END " , " HI_END " , false , options ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " VX_START " , 8 ) )
{
i = ListExtract ( i , " VOXELS " , " VX_END " , " VX_END " , false , false , options ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " GL_VERT " , 8 ) ) // ignore
{
// skip GL nodes
}
else if ( ! strnicmp ( w - > Name ( ) , " GL_SEGS " , 8 ) ) // ignore
{
// skip GL nodes
}
else if ( ! strnicmp ( w - > Name ( ) , " GL_SSECT " , 8 ) ) // ignore
{
// skip GL nodes
}
else if ( ! strnicmp ( w - > Name ( ) , " GL_NODES " , 8 ) ) // ignore
{
// skip GL nodes
}
else if ( ! strnicmp ( w - > Name ( ) , " GL_PVS " , 8 ) ) // ignore
{
// skip GL nodes
}
else if ( isLevel ( i ) )
{
i + = MapExtract ( i , " MAPS " , options ) - 1 ;
}
else
{
if ( ! strnicmp ( w - > Name ( ) , " TEXTURE1 " , 8 ) ) pTex1 = * w ;
else if ( ! strnicmp ( w - > Name ( ) , " TEXTURE2 " , 8 ) ) pTex2 = * w ;
else if ( ! strnicmp ( w - > Name ( ) , " PNAMES " , 8 ) ) pPnam = * w ;
else if ( ! strnicmp ( w - > Name ( ) , " ANIMATED " , 8 ) )
{
AnimExtract ( w ) ;
}
else if ( ! strnicmp ( w - > Name ( ) , " SWITCHES " , 8 ) )
{
SwitchExtract ( w ) ;
}
Extract ( w , NULL , NULL , options , false ) ;
}
if ( pTex1 . mLump > = 0 & & pPnam . mLump > = 0 )
{
GenerateTextureFile ( & pTex1 , & pPnam , options ) ;
pTex1 = - 1 ;
}
if ( pTex2 . mLump > = 0 & & pPnam . mLump > = 0 )
{
GenerateTextureFile ( & pTex2 , & pPnam , options ) ;
pTex2 = - 1 ;
}
}
}
2016-11-10 19:47:27 +00:00
chdir ( " .. " ) ;
2016-11-10 18:56:16 +00:00
}
void ConvertTextureX ( )
{
FILE * ft1 = fopen ( " texture1 " , " rb " ) ;
if ( ! ft1 ) ft1 = fopen ( " texture1.lmp " , " rb " ) ;
FILE * ft2 = fopen ( " texture2 " , " rb " ) ;
if ( ! ft2 ) ft2 = fopen ( " texture2.lmp " , " rb " ) ;
FILE * pnm = fopen ( " pnames " , " rb " ) ;
if ( ! pnm ) pnm = fopen ( " pnames.lmp " , " rb " ) ;
if ( ! pnm ) exit ( 1 ) ;
static char bt1 [ 100000 ] , bt2 [ 100000 ] , bpn [ 100000 ] ;
if ( ft1 ) fread ( bt1 , 1 , 100000 , ft1 ) , fclose ( ft1 ) ;
if ( ft2 ) fread ( bt2 , 1 , 100000 , ft2 ) , fclose ( ft2 ) ;
if ( pnm ) fread ( bpn , 1 , 100000 , pnm ) , fclose ( pnm ) ;
if ( ft1 ) GenerateTextureFile ( " textures.txt " , bt1 , bpn , 0 , true ) ;
if ( ft2 ) GenerateTextureFile ( " textures.txt2 " , bt2 , bpn , 0 , false ) ;
}
2021-08-08 07:13:29 +00:00
//==========================================================================
//
//
//
//==========================================================================
struct GrpInfo
{
uint32_t Magic [ 3 ] ;
uint32_t NumLumps ;
} ;
struct GrpLump
{
union
{
struct
{
char Name [ 12 ] ;
uint32_t Size ;
} ;
char NameWithZero [ 13 ] ;
} ;
} ;
void GrpExtract ( const char * filename , FILE * f )
{
TArray < GrpLump > fileinfo ;
GrpInfo header ;
if ( 1 ! = fread ( & header , sizeof ( header ) , 1 , f ) ) return ;
fileinfo . Resize ( header . NumLumps ) ;
if ( header . NumLumps ! = fread ( & fileinfo [ 0 ] , sizeof ( GrpLump ) , header . NumLumps , f ) ) return ;
if ( memcmp ( header . Magic , " KenSilverman " , 12 ) )
{
return ;
}
auto name = ExtractFileBase ( filename , false ) ;
mkdir ( name . c_str ( ) ) ;
chdir ( name . c_str ( ) ) ;
TArray < char > buffer ;
for ( uint32_t i = 0 ; i < header . NumLumps ; i + + )
{
buffer . Resize ( fileinfo [ i ] . Size ) ;
fileinfo [ i ] . NameWithZero [ 12 ] = ' \0 ' ; // Be sure filename is null-terminated
if ( fileinfo [ i ] . Size ! = fread ( & buffer [ 0 ] , 1 , fileinfo [ i ] . Size , f ) ) return ;
FILE * fout = fopen ( fileinfo [ i ] . NameWithZero , " wb " ) ;
if ( fout )
{
fwrite ( & buffer [ 0 ] , 1 , fileinfo [ i ] . Size , fout ) ;
fclose ( fout ) ;
}
}
exit ( 1 ) ;
}