forked from dolphin-emu/dolphin
		
	git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3666 8ced0084-cf51-0410-be5f-012b33b47a6e
		
			
				
	
	
		
			157 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (C) 2003-2009 Dolphin Project.
 | 
						|
 | 
						|
// 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, version 2.0.
 | 
						|
 | 
						|
// 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 2.0 for more details.
 | 
						|
 | 
						|
// A copy of the GPL 2.0 should have been included with the program.
 | 
						|
// If not, see http://www.gnu.org/licenses/
 | 
						|
 | 
						|
// Official SVN repository and contact information can be found at
 | 
						|
// http://code.google.com/p/dolphin-emu/
 | 
						|
 | 
						|
#include "stdafx.h"
 | 
						|
#include <math.h>
 | 
						|
 | 
						|
#include "VolumeWad.h"
 | 
						|
#include "StringUtil.h"
 | 
						|
#include "MathUtil.h"
 | 
						|
 | 
						|
#define ALIGN_40(x) ROUND_UP(Common::swap32(x), 0x40)
 | 
						|
 | 
						|
namespace DiscIO
 | 
						|
{
 | 
						|
CVolumeWAD::CVolumeWAD(IBlobReader* _pReader)
 | 
						|
	: m_pReader(_pReader), OpeningBnrOffset(0), hdr_size(0), cert_size(0), tick_size(0), tmd_size(0), data_size(0)
 | 
						|
{
 | 
						|
	Read(0x00, 4, (u8*)&hdr_size);
 | 
						|
	Read(0x08, 4, (u8*)&cert_size);
 | 
						|
	Read(0x10, 4, (u8*)&tick_size);
 | 
						|
	Read(0x14, 4, (u8*)&tmd_size);
 | 
						|
	Read(0x18, 4, (u8*)&data_size);
 | 
						|
 | 
						|
	OpeningBnrOffset = ALIGN_40(hdr_size) + ALIGN_40(cert_size) + ALIGN_40(tick_size) + ALIGN_40(tmd_size) + ALIGN_40(data_size);
 | 
						|
}
 | 
						|
 | 
						|
CVolumeWAD::~CVolumeWAD()
 | 
						|
{
 | 
						|
	delete m_pReader;
 | 
						|
}
 | 
						|
 | 
						|
bool CVolumeWAD::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
 | 
						|
{
 | 
						|
	if (m_pReader == NULL)
 | 
						|
		return false;
 | 
						|
 | 
						|
	return m_pReader->Read(_Offset, _Length, _pBuffer);
 | 
						|
}
 | 
						|
 | 
						|
IVolume::ECountry CVolumeWAD::GetCountry() const
 | 
						|
{
 | 
						|
	if (!m_pReader)
 | 
						|
		return COUNTRY_UNKNOWN;
 | 
						|
 | 
						|
	u8 CountryCode;
 | 
						|
	u32 Offset = ALIGN_40(hdr_size) + ALIGN_40(cert_size);
 | 
						|
 | 
						|
	// read the last digit of the titleID in the ticket
 | 
						|
	Read(Offset + 0x01E3, 1, &CountryCode);
 | 
						|
 | 
						|
	return CountrySwitch(CountryCode);
 | 
						|
}
 | 
						|
 | 
						|
std::string CVolumeWAD::GetUniqueID() const
 | 
						|
{
 | 
						|
	std::string temp = GetMakerID();
 | 
						|
	u32 Offset = ALIGN_40(hdr_size) + ALIGN_40(cert_size);
 | 
						|
 | 
						|
	char GameCode[8];
 | 
						|
	if(!Read(Offset + 0x01E0, 4, (u8*)GameCode))
 | 
						|
		return "0";
 | 
						|
 | 
						|
	GameCode[4] = temp.at(0);
 | 
						|
	GameCode[5] = temp.at(1);
 | 
						|
	GameCode[6] = 0;
 | 
						|
 | 
						|
	return GameCode;
 | 
						|
}
 | 
						|
 | 
						|
std::string CVolumeWAD::GetMakerID() const
 | 
						|
{
 | 
						|
	u32 Offset = ALIGN_40(hdr_size) + ALIGN_40(cert_size) + ALIGN_40(tick_size);
 | 
						|
 | 
						|
	char temp[3] = {1};
 | 
						|
	// Some weird channels use 0x0000 in place of the MakerID, so we need a check there
 | 
						|
	if (!Read(0x198 + Offset, 2, (u8*)temp) || temp[0] == 0 || temp[1] == 0)
 | 
						|
		return "00";
 | 
						|
 | 
						|
	temp[2] = 0;
 | 
						|
 | 
						|
	return temp;
 | 
						|
}
 | 
						|
 | 
						|
bool CVolumeWAD::GetTitleID(u8* _pBuffer) const
 | 
						|
{
 | 
						|
	u32 Offset = ALIGN_40(hdr_size) + ALIGN_40(cert_size);
 | 
						|
 | 
						|
	if(!Read(Offset + 0x01DC, 8, _pBuffer))
 | 
						|
		return false;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
std::string CVolumeWAD::GetName() const
 | 
						|
{
 | 
						|
	u32 footer_size;
 | 
						|
 | 
						|
	if (!Read(0x1C, 4, (u8*)&footer_size))
 | 
						|
		return "Unknown";
 | 
						|
 | 
						|
	// Offset to the english title
 | 
						|
	char temp[85];
 | 
						|
	if (!Read(0xF1 + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1)
 | 
						|
		return "Unknown";
 | 
						|
 | 
						|
	char out_temp[43];
 | 
						|
	int j = 0;
 | 
						|
 | 
						|
	for (int i=0; i < 84; i++)
 | 
						|
	{
 | 
						|
		if (!(i & 1))
 | 
						|
		{
 | 
						|
			if (temp[i] != 0)
 | 
						|
				out_temp[j] = temp[i];
 | 
						|
			else
 | 
						|
			{
 | 
						|
				// Some wads have a few consecutive Null chars followed by text
 | 
						|
				// as i don't know what to do there: replace the frst one with space
 | 
						|
				if (out_temp[j-1] != 32)
 | 
						|
					out_temp[j] = 32;
 | 
						|
				else
 | 
						|
					continue;
 | 
						|
			}
 | 
						|
 | 
						|
			j++;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	out_temp[j] = 0;
 | 
						|
 | 
						|
	return out_temp;
 | 
						|
}
 | 
						|
 | 
						|
u64 CVolumeWAD::GetSize() const
 | 
						|
{
 | 
						|
	if (m_pReader)
 | 
						|
		return (size_t)m_pReader->GetDataSize();
 | 
						|
	else
 | 
						|
		return 0;
 | 
						|
}
 | 
						|
 | 
						|
} // namespace
 |