TC解析データ

NEXONが2005/8/31までサービスしていた「タクティカルコマンダー」
.dat file format
ゲーム内で使われるデータファイルを一括してまとめた形式

0x0000-0x0004 : int型で固めてあるファイルの個数

0x0005- : 固めてあるファイルの個数+1だけ FileAddr 構造体が連続する。
struct FileAddr { //各ファイルのアドレス格納構造体
 int istart ; //埋めてあるファイルの開始アドレス
 char szName[13] ; //埋めてあるファイル名
}
※一番最後のFileAddr構造体はファイル名が全て 0x00 で埋められており、
 アドレスはファイルの一番最後を指し示す。

例えば下記のような場合
 FileAddr[4].istart = 0x02BD
 FileAddr[5].istart = 0x7E99
FileAddr[4]のファイルは 0x02BD-0x7E98 に埋め込まれている。
その範囲のバイナリデータをFileAddr[4].szNameのファイル名で保存すれば元のファイルになる。
TCGETのプログラム
     1 :	#include <stdio.h>
     2 :	#include <string.h>
     3 :	#include <ctype.h>
     4 :	
     5 :	//ファイルアドレス構造体
     6 :	struct FName {
     7 :	    int istart ;
     8 :	    char szName[13] ;
     9 :	} ;
    10 :	
    11 :	//抽出を許可する拡張子
    12 :	const int EXEZ = 3 ;
    13 :	const char *SZEXE[EXEZ] = 
    14 :	{
    15 :	    ".jpg" , ".mp3" , ".wav"
    16 :	} ;
    17 :	
    18 :	int main(int argc , char *argv[ ]){
    19 :	    char szTcDat[256] ;
    20 :	    
    21 :	    if(argc != 2){
    22 :	        printf("tcget **.DAT") ;
    23 :	        return -1;
    24 :	    }
    25 :	    
    26 :	    strcpy(szTcDat , argv[1]) ;
    27 :	
    28 :	    FILE *fp = fopen(szTcDat , "rb" ) ;
    29 :	    if(!fp){
    30 :	        fclose(fp) ;
    31 :	        printf("File Not Found.\n") ;
    32 :	    }
    33 :	    
    34 :	    int n ;
    35 :	    fread(&n , 4 , 1 , fp) ;
    36 :	    
    37 :	    FName *pFN = new FName[n] ;
    38 :	    
    39 :	    bool bloop = true ;
    40 :	    int i = 0 ;
    41 :	
    42 :	    while(bloop){
    43 :	        fread(&pFN[i].istart , 4 , 1 , fp) ;
    44 :	        fread(pFN[i].szName , 13 , 1 , fp) ;
    45 :	        if(pFN[i].szName[0] == '\0'){
    46 :	            bloop = false ;
    47 :	        }else{
    48 :	            i++ ;
    49 :	        }
    50 :	    }
    51 :	    
    52 :	    n = i +1 ;
    53 :	    
    54 :	    for(i=0 ; i<n ; i++){
    55 :	        if(pFN[i].szName[0]== '\0'){
    56 :	            break ;
    57 :	        }else{
    58 :	            int len = strlen(pFN[i].szName) ;
    59 :	            char *cp = &pFN[i].szName[len-4] ;
    60 :	            bool bOK = false ;
    61 :	            int g ;
    62 :	            for(g=0 ; g<4 ; g++){
    63 :	                cp[g] = tolower(cp[g]) ;
    64 :	            }
    65 :	            for(g = 0 ; g<EXEZ ; g++){
    66 :	                if(strcmp(cp , SZEXE[g])==0){
    67 :	                    bOK = true ;
    68 :	                    break ;
    69 :	                }
    70 :	            }
    71 :	            if(!bOK){
    72 :	                continue ;
    73 :	            }
    74 :	        }
    75 :	        FILE *ofp = fopen(pFN[i].szName , "wb") ;
    76 :	        if(!ofp){
    77 :	            fclose(ofp) ;
    78 :	            printf("File cannot open. : %s\n" , pFN[i].szName) ;
    79 :	            continue ;
    80 :	        }
    81 :	        int size = pFN[i+1].istart - pFN[i].istart ;
    82 :	        char *buff = new char[size] ;
    83 :	        fseek(fp , pFN[i].istart , SEEK_SET) ;
    84 :	        fread(buff , size , 1 , fp) ;
    85 :	        fwrite(buff , size , 1 , ofp) ;
    86 :	        fclose(ofp) ;
    87 :	        delete [] buff ;
    88 :	        printf("%s done.\n" , pFN[i].szName) ;
    89 :	    }
    90 :	    
    91 :	    fclose(fp) ;
    92 :	    delete [] pFN ;
    93 :	
    94 :	    return 0 ;
    95 :	}
Return
Google

---------------

タクティカルコマンダー