int main(int argc, char **argv) { if (parseopts(argc, argv) != 0) { fprintf(stderr, "Try the -h option for usage help.\n"); return 1; } if (MergeImages() != 0) { return 1; } return 0; }
/* ----------------------------------------------------------------------------- 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; }