#include "ma_oni_d.h" #include "utools.h" #define FourCharsToLong( a, b, c, d ) ((d << 24) | (c << 16) | (b << 8) | (a)) char *CMassOniDat::GetIdent( void ) { static char Ident[] = "DAT (Oni)"; return Ident; } char *CMassOniDat::GetExtension( void ) { static char Ext[] = "dat"; return Ext; } int CMassOniDat::CheckFileType( void ) { if ( massf == NULL ) return 0; char buf[ 100 ]; fseek( massf, 0, SEEK_SET ); fread( buf, 8, 1, massf ); if ( UnmassTools::_strcasecmp( MassFileExt, "dat" ) != 0 ) return 0; sprintf( RawFileName, "%s%s.raw", MassFilePath, MassFileName ); // if ( memcmp( buf, "\x1F\x27\xDC\x33\xDF\xBC\x03\x00", 8 ) == 0 ) // return 1; // if ( memcmp( buf, "\x61\x30\xC1\x23\xDF\xBC\x03\x00", 8 ) == 0 ) // return 1; if ( memcmp( &buf[4], "\xDF\xBC\x03\x00", 4 ) == 0 ) return 1; return 0; } void CMassOniDat::GetFileMainInfo( void ) { files_count = 0; if ( massf == NULL ) return; fseek( massf, 0, SEEK_END ); filesize = ftell( massf ); fseek( massf, 0, SEEK_SET ); fread( &OniDatHeader, 4, 4*4, massf ); files_count = OniDatHeader.file_list_elements; data_start = OniDatHeader.file_data_offset - 8; lib_start = 64; } int CMassOniDat::ReadRec( long num ) { if ( massf == NULL ) return 0; if (( (unsigned long)num >= files_count ) && ( num != -1 )) return 0; if (( num == -1 ) && (( ! next_set ) || ((unsigned long)next_rec_num >= files_count )) ) return 0; memset( &FileRec, 0, sizeof( FileRec ) ); if (( next_set ) && ( (signed)next_rec_num == num )) num = -1; //seek if ( num == -1 ) { if ( fseek( massf, next_rec_pos, SEEK_SET ) != 0 ) return 0; } else { pos = lib_start + SizeOfOniDatRec * num; if ( fseek( massf, pos, SEEK_SET ) != 0 ) return 0; } //read if ( fread( &OniDatRec, SizeOfOniDatRec, 1, massf ) != 1 ) return 0; //set position of the next next_rec_pos = ftell( massf ); if ( num == -1 ) next_rec_num ++; else next_rec_num = num + 1; if ( num + 1 >= (long)files_count ) next_set = false; else next_set = true; //get info num = next_rec_num - 1; if ( num == 817 ) { num++; num--; } FileRec.offset = OniDatHeader.file_data_offset + OniDatRec.offset -8; FileRec.size = OniDatRec.size; if (( OniDatRec.flags & 1 ) == 0 ) { if ( OniDatRec.name_offset > OniDatHeader.name_table_size ) { sprintf( error, "ReadRec: seek for filename\n" ); return 0; } fseek( massf, OniDatHeader.name_table_offset + OniDatRec.name_offset, SEEK_SET ); fread( FileRec.type, 1, 4, massf ); FileRec.type[ 4 ] = 0; fread( str, 1, FileNameWithPathMaxLen-1, massf ); i = strlen( str ); // while (( str[ i-1 ] != '/' ) && ( str[ i-1 ] != '\\' ) && ( i > 0 )) // i--; while ( i > 0 ) { if(( str[ i-1 ] == '/' ) || ( str[ i-1 ] == '\\' )) str[ i-1 ] = '!'; i--; } // strcpy( str2, &str[ i ] ); // str[ i ] = 0; // sprintf( FileRec.name, "%s%05lu-%s", str, num, str2 ); sprintf( FileRec.name, "%05lu-%s", num, str ); pos = strlen( FileRec.name ); FileRec.name[ pos ] = '.'; FileRec.name[ pos + 1 ] = OniDatRec.type[3]; FileRec.name[ pos + 2 ] = OniDatRec.type[2]; FileRec.name[ pos + 3 ] = OniDatRec.type[1]; FileRec.name[ pos + 4 ] = OniDatRec.type[0]; FileRec.name[ pos + 5 ] = 0; FileRec.name[ FileNameWithPathMaxLen-1 ] = 0; } else { sprintf( FileRec.type, "%c%c%c%c", OniDatRec.type[ 3 ], OniDatRec.type[ 2 ], OniDatRec.type[ 1 ], OniDatRec.type[ 0 ] ); sprintf( FileRec.name, "%05lu-.%s", num, FileRec.type ); } FileRec.flaga[0] = FileRec.size; if (( OniDatRec.flags & 2 ) == 0 ) { //uprava, podla typu musim priratat aj data s RAW suboru switch( OniDatRec.typel ) { case FourCharsToLong( 'P', 'M', 'X', 'T' ): //pridam k velkosti velkost bitmapy. fseek( massf, FileRec.offset, SEEK_SET ); fread( &TXMP_structure, 1, sizeof( TXMP_structure ), massf ); switch( TXMP_structure.format ) { case 0: case 1: case 2: FileRec.size += TXMP_structure.width * TXMP_structure.height * 2; break; case 8: FileRec.size += TXMP_structure.width * TXMP_structure.height * 4; break; case 9: FileRec.size += TXMP_structure.width * TXMP_structure.height / 2; break; }//switch FileRec.flaga[1] = TXMP_structure.dataOffset; break; } }//flag != 2, (no data) FileRec.set = 1; return 1; } int CMassOniDat::GetFlags( void ) { return ma_flag_fills_type; } unsigned long CMassOniDat::Extract( unsigned long offset, unsigned long size, unsigned char *output ) { if ( massf == NULL ) return 0; unsigned long s, c, p; // vo FileRec.flaga[0] je velkost headra, v [1] je offset raw dat //nacitam header if ( offset < FileRec.flaga[0] ) { s = offset; c = size; if ( s + c > FileRec.flaga[0] ) c = FileRec.flaga[0] - s; if ( fseek( massf, FileRec.offset + s, SEEK_SET ) != 0 ) return 0; if ( fread( output, c, 1, massf ) != 1 ) return 0; } //nacitam data z raw suboru // if (( FileRec.flaga[0] < FileRec.size ) && ( offset + size >= FileRec.flaga[0] )) { if ( FileRec.flaga[0] < FileRec.size ) { fraw = fopen( RawFileName, "rb" ); if ( fraw == NULL ) return 0; if ( offset < FileRec.flaga[0] ) { s = FileRec.flaga[1]; c = offset + size - FileRec.flaga[0]; p = FileRec.flaga[0] - offset; } else { s = FileRec.flaga[1] + offset - FileRec.flaga[0]; c = size; p = 0; } if ( fseek( fraw, s, SEEK_SET ) != 0 ) return 0; if ( fread( &output[ p ], c, 1, fraw ) != 1 ) return 0; fclose( fraw ); } return size; }