コード例 #1
0
ファイル: TCD2.cpp プロジェクト: lioncash/ExtractData
/// Mount
///
/// @param archive Archive
///
bool CTCD2::Mount(CArcFile* archive)
{
	if (archive->GetArcExten() != _T(".TCD"))
		return false;

	if (memcmp(archive->GetHeader(), "TCD2", 4) != 0)
		return false;

	archive->SeekHed(4);

	// Get file count
	u32 files;
	archive->ReadU32(&files);

	// Get index info
	std::array<STCD2IndexInfo, 5> tcd2_index_info;
	archive->Read(tcd2_index_info.data(), sizeof(STCD2IndexInfo) * tcd2_index_info.size());

	// Create key table
	static constexpr std::array<u8, 5> key{{
		0x1F, 0x61, 0x43, 0x76, 0x76
	}};

	// Create extension table
	static const std::array<YCString, 5> file_exts{{
		_T(".tct"), _T(".tsf"), _T(".spd"), _T(".ogg"), _T(".wav")
	}};

	// Read index
	for (size_t file_type = 0; file_type < tcd2_index_info.size(); file_type++)
	{
		if (tcd2_index_info[file_type].file_size == 0)
		{
			// Index doesn't exist
			continue;
		}

		// Go to index
		archive->SeekHed(tcd2_index_info[file_type].index_offset);

		// Folder name
		const u32 all_dir_name_length = tcd2_index_info[file_type].dir_name_length;
		std::vector<u8> all_dir_names(all_dir_name_length);
		archive->Read(all_dir_names.data(), all_dir_names.size());

		// Decode folder name
		for (size_t i = 0; i < all_dir_name_length; i++)
		{
			all_dir_names[i] -= key[file_type];
		}

		// Get folder info
		std::vector<STCD2DirInfo> tcd2_dir_info(tcd2_index_info[file_type].dir_count);
		archive->Read(tcd2_dir_info.data(), sizeof(STCD2DirInfo) * tcd2_dir_info.size());

		// File name
		const u32 all_file_name_length = tcd2_index_info[file_type].file_name_length;
		std::vector<u8> all_file_names(all_file_name_length);
		archive->Read(all_file_names.data(), all_file_names.size());

		// Decode file name
		for (size_t i = 0; i < all_file_name_length; i++)
		{
			all_file_names[i] -= key[file_type];
		}

		// File offset
		const u32 all_file_offset_length = tcd2_index_info[file_type].file_count + 1;
		std::vector<u32> all_file_offsets(all_file_offset_length);
		archive->Read(all_file_offsets.data(), sizeof(u32) * all_file_offsets.size());

		// Store info
		size_t dir_name_ptr = 0;
		for (size_t dir = 0; dir < tcd2_index_info[file_type].dir_count; dir++)
		{
			// Get folder name
			char dir_name[_MAX_DIR];
			strcpy(dir_name, reinterpret_cast<char*>(&all_dir_names[dir_name_ptr]));
			dir_name_ptr += strlen(dir_name) + 1;

			size_t file_name_ptr = 0;
			for (size_t file = 0; file < tcd2_dir_info[dir].file_count; file++)
			{
				// Get file name
				char file_name[_MAX_FNAME];
				strcpy(file_name, reinterpret_cast<char*>(&all_file_names[tcd2_dir_info[dir].file_name_offset + file_name_ptr]));
				file_name_ptr += strlen(file_name) + 1;

				// Folder name + File name + Extension
				TCHAR full_name[_MAX_PATH];
				_stprintf(full_name, _T("%s\\%s%s"), dir_name, file_name, file_exts[file_type].GetString());

				// Store info
				SFileInfo file_info;
				file_info.name = full_name;
				file_info.start = all_file_offsets[tcd2_dir_info[dir].file_offset + file + 0];
				file_info.end = all_file_offsets[tcd2_dir_info[dir].file_offset + file + 1];
				file_info.size_cmp = file_info.end - file_info.start;
				file_info.size_org = file_info.size_cmp;

				archive->AddFileInfo(file_info);
			}
		}
	}

	return true;
}
コード例 #2
0
/// Mount
///
/// @param archive Archive
///
bool CTCD3::Mount(CArcFile* archive)
{
	if (archive->GetArcExten() != _T(".TCD"))
		return false;

	if (memcmp(archive->GetHeader(), "TCD3", 4) != 0)
		return false;

	archive->SeekHed(4);

	// Get file count
	u32 files;
	archive->ReadU32(&files);

	// Get index info
	std::array<STCD3IndexInfo, 5> tcd3_index_info;
	archive->Read(tcd3_index_info.data(), sizeof(STCD3IndexInfo) * tcd3_index_info.size());

	// Create Key Table
	static constexpr u8 key[5] = {
		0xB7, 0x39, 0x24, 0x8D, 0x8D
	};

	// Create extension table
	static const YCString file_exts[5] =
	{
		_T(".tct"), _T(".tsf"), _T(".spd"), _T(".ogg"), _T(".wav")
	};

	// Read index
	for (size_t file_type = 0; file_type < tcd3_index_info.size(); file_type++)
	{
		if (tcd3_index_info[file_type].file_size == 0)
		{
			// Index does not exist
			continue;
		}

		// Go to index
		archive->SeekHed(tcd3_index_info[file_type].index_offset);

		// Folder name
		const u32 all_dir_name_length = tcd3_index_info[file_type].dir_name_length * tcd3_index_info[file_type].dir_count;
		std::vector<u8> all_dir_names(all_dir_name_length);
		archive->Read(all_dir_names.data(), all_dir_names.size());

		// Decode folder name
		for (size_t i = 0; i < all_dir_names.size(); i++)
		{
			all_dir_names[i] -= key[file_type];
		}

		// Get folder info
		std::vector<STCD3DirInfo> tcd3_dir_info(tcd3_index_info[file_type].dir_count);
		archive->Read(tcd3_dir_info.data(), sizeof(STCD3DirInfo) * tcd3_dir_info.size());

		// File name
		const u32 all_file_name_length = tcd3_index_info[file_type].file_name_length * tcd3_index_info[file_type].file_count;
		std::vector<u8> all_file_names(all_file_name_length);
		archive->Read(all_file_names.data(), all_file_names.size());

		// Decode file name
		for (size_t i = 0; i < all_file_names.size(); i++)
		{
			all_file_names[i] -= key[file_type];
		}

		// File offset
		const u32 all_file_offset_length = tcd3_index_info[file_type].file_count + 1;
		std::vector<u32> all_file_offsets(all_file_offset_length);
		archive->Read(all_file_offsets.data(), sizeof(u32)* all_file_offsets.size());

		// Store Info
		for (size_t dir = 0; dir < tcd3_index_info[file_type].dir_count; dir++)
		{
			// Get folder info
			TCHAR dir_name[_MAX_DIR];
			memcpy(dir_name, &all_dir_names[tcd3_index_info[file_type].dir_name_length * dir], tcd3_index_info[file_type].dir_name_length);

			for (size_t file = 0; file < tcd3_dir_info[dir].file_count; file++)
			{
				// Get file name
				TCHAR file_name[_MAX_FNAME];
				memcpy(file_name, &all_file_names[tcd3_dir_info[dir].file_name_offset + tcd3_index_info[file_type].file_name_length * file], tcd3_index_info[file_type].file_name_length);
				file_name[tcd3_index_info[file_type].file_name_length] = _T('\0');

				// Folder name + File name + Extension
				TCHAR full_name[_MAX_PATH];
				_stprintf(full_name, _T("%s\\%s%s"), dir_name, file_name, file_exts[file_type].GetString());

				// Store Info
				SFileInfo file_info;
				file_info.name = full_name;
				file_info.start = all_file_offsets[tcd3_dir_info[dir].file_offset + file + 0];
				file_info.end = all_file_offsets[tcd3_dir_info[dir].file_offset + file + 1];
				file_info.sizeCmp = file_info.end - file_info.start;
				file_info.sizeOrg = file_info.sizeCmp;

				archive->AddFileInfo(file_info);
			}
		}
	}

	return true;
}