Added wad files detection to the GameListCtrl, some changes to ISOProperties, needs a bit more work ?

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3348 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
sl1nk3.s 2009-06-07 02:54:07 +00:00
parent 7eea69f5c2
commit 8cb67f4729
14 changed files with 347 additions and 29 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="DiscIO"
ProjectGUID="{B7F1A9FB-BEA8-416E-9460-AE35A6A5165C}"
RootNamespace="DiscIO"
@ -656,6 +656,14 @@
RelativePath=".\Src\VolumeGC.h"
>
</File>
<File
RelativePath=".\Src\VolumeWad.cpp"
>
</File>
<File
RelativePath=".\Src\VolumeWad.h"
>
</File>
<File
RelativePath=".\Src\VolumeWiiCrypted.cpp"
>

View File

@ -140,11 +140,11 @@ bool IBannerLoader::CopyBeUnicodeToString( std::string& _rDestination, const u16
}
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem)
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume)
{
if (IsVolumeWiiDisc(_rFileSystem.GetVolume()))
if (IsVolumeWiiDisc(pVolume) || IsVolumeWadFile(pVolume))
{
return(new CBannerLoaderWii(_rFileSystem));
return(new CBannerLoaderWii(pVolume));
}
return(new CBannerLoaderGC(_rFileSystem));

View File

@ -57,7 +57,7 @@ class IBannerLoader
}
};
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem);
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume);
} // namespace
#endif

View File

@ -22,20 +22,25 @@
#include "Common.h"
#include "ColorUtil.h"
#include "BannerLoaderWii.h"
#include "VolumeCreator.h"
#include "FileUtil.h"
#include "FileHandlerARC.h"
namespace DiscIO
{
CBannerLoaderWii::CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem)
CBannerLoaderWii::CBannerLoaderWii(DiscIO::IVolume *pVolume)
: m_pBannerFile(NULL)
, m_IsValid(false)
{
char Filename[260];
u64 TitleID;
_rFileSystem.GetVolume()->RAWRead((u64)0x0F8001DC, 8, (u8*)&TitleID);
if (DiscIO::IsVolumeWadFile(pVolume))
pVolume->GetTitleID((u8*)&TitleID);
else
pVolume->RAWRead((u64)0x0F8001DC, 8, (u8*)&TitleID);
TitleID = Common::swap64(TitleID);
sprintf(Filename, FULL_WII_USER_DIR "title/%08x/%08x/data/banner.bin",

View File

@ -27,7 +27,7 @@ class CBannerLoaderWii
{
public:
CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem);
CBannerLoaderWii(DiscIO::IVolume *pVolume);
virtual ~CBannerLoaderWii();

View File

@ -39,6 +39,7 @@ class IVolume
virtual bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const = 0;
virtual bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const = 0;
virtual bool GetTitleID(u8* _pBuffer) const { return false; }
virtual std::string GetUniqueID() const = 0;
virtual std::string GetMakerID() const = 0;
virtual std::string GetName() const = 0;

View File

@ -25,6 +25,7 @@
#include "VolumeDirectory.h"
#include "VolumeGC.h"
#include "VolumeWiiCrypted.h"
#include "VolumeWad.h"
#include "Hash.h"
@ -35,7 +36,8 @@ enum EDiscType
DISC_TYPE_UNK,
DISC_TYPE_WII,
DISC_TYPE_WII_CONTAINER,
DISC_TYPE_GC
DISC_TYPE_GC,
DISC_TYPE_WAD
};
#ifndef _WIN32
@ -80,6 +82,9 @@ IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionG
case DISC_TYPE_GC:
return new CVolumeGC(pReader);
case DISC_TYPE_WAD:
return new CVolumeWAD(pReader);
case DISC_TYPE_WII_CONTAINER:
{
u8 region;
@ -123,6 +128,15 @@ bool IsVolumeWiiDisc(const IVolume *_rVolume)
//Gamecube 0xc2339f3d
}
bool IsVolumeWadFile(const IVolume *_rVolume)
{
u32 MagicWord = 0;
_rVolume->Read(0x02, 4, (u8*)&MagicWord);
return (Common::swap32(MagicWord) == 0x00204973);
// That would be 0x00206962 for boot2 wads
}
IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _PartitionGroup, u32 _VolumeType, u32 _VolumeNum, bool Korean)
{
CBlobBigEndianReader Reader(_rReader);
@ -209,6 +223,16 @@ EDiscType GetDiscType(IBlobReader& _rReader)
}
}
// check for WAD
{
u32 MagicWord = Reader.Read32(0x02);
// That would be 0x206962 for boot2 wads
// Should we add them too ?
if (MagicWord == 0x00204973)
return(DISC_TYPE_WAD);
}
// check for GC
{
u32 MagicWord = Reader.Read32(0x1C);

View File

@ -25,6 +25,7 @@ namespace DiscIO
IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup = 0, u32 _VolumeNum = -1);
IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii);
bool IsVolumeWiiDisc(const IVolume *_rVolume);
bool IsVolumeWadFile(const IVolume *_rVolume);
} // namespace
#endif

View File

@ -0,0 +1,204 @@
// 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);
ECountry country = COUNTRY_UNKNOWN;
switch (CountryCode)
{
case 'S':
country = COUNTRY_EUROPE;
break; // PAL // <- that is shitty :) zelda demo disc
case 'P':
country = COUNTRY_EUROPE;
break; // PAL
case 'D':
country = COUNTRY_EUROPE;
break; // PAL
case 'F':
country = COUNTRY_FRANCE;
break; // PAL
case 'I':
country = COUNTRY_ITALY;
break; // PAL
case 'X':
country = COUNTRY_EUROPE;
break; // XIII <- uses X but is PAL
case 'E':
country = COUNTRY_USA;
break; // USA
case 'J':
country = COUNTRY_JAP;
break; // JAP
case 'O':
country = COUNTRY_UNKNOWN;
break; // SDK
default:
// PanicAlert("Unknown Country Code!");
country = COUNTRY_UNKNOWN;
break;
}
return(country);
}
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];
if (!Read(0x198 + Offset, 2, (u8*)temp))
return "0";
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
{
if (m_pReader == NULL)
return "Unknown";
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))
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

View File

@ -0,0 +1,52 @@
// 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/
#pragma once
#include "Volume.h"
#include "Blob.h"
#include "NANDContentLoader.h"
// --- this volume type is used for Wad files ---
// Some of this code might look redundant with the CNANDContentLoader class, however,
// We do not do any decryption here, we do raw read, so things are -Faster-
namespace DiscIO
{
class CVolumeWAD : public IVolume
{
public:
CVolumeWAD(IBlobReader* _pReader);
~CVolumeWAD();
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const { return false; }
bool GetTitleID(u8* _pBuffer) const;
std::string GetUniqueID() const;
std::string GetMakerID() const;
std::string GetName() const;
u32 GetFSTSize() const { return 0; }
std::string GetApploaderDate() const { return "0"; }
ECountry GetCountry() const;
u64 GetSize() const;
private:
IBlobReader* m_pReader;
u64 m_titleID;
u32 OpeningBnrOffset, hdr_size, cert_size, tick_size, tmd_size, data_size;
};
} // namespace

View File

@ -58,7 +58,10 @@ GameListItem::GameListItem(const std::string& _rFileName)
if (pVolume != NULL)
{
m_Platform = DiscIO::IsVolumeWiiDisc(pVolume) ? WII_DISC : GAMECUBE_DISC;
if (!DiscIO::IsVolumeWadFile(pVolume))
m_Platform = DiscIO::IsVolumeWiiDisc(pVolume) ? WII_DISC : GAMECUBE_DISC;
else
m_Platform = WII_WAD;
m_Company = "N/A";
for (int i = 0; i < 6; i++)
@ -77,9 +80,9 @@ GameListItem::GameListItem(const std::string& _rFileName)
// check if we can get some infos from the banner file too
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
if (pFileSystem != NULL)
if (pFileSystem != NULL || m_Platform == WII_WAD)
{
DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem);
DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem, pVolume);
if (pBannerLoader != NULL)
{
@ -210,12 +213,16 @@ const std::string GameListItem::GetWiiFSPath() const
if (Iso != NULL)
{
if (DiscIO::IsVolumeWiiDisc(Iso))
if (DiscIO::IsVolumeWiiDisc(Iso) || DiscIO::IsVolumeWadFile(Iso))
{
char Path[250];
u64 Title;
Iso->RAWRead((u64)0x0F8001DC, 8, (u8*)&Title);
if (DiscIO::IsVolumeWiiDisc(Iso))
Iso->RAWRead((u64)0x0F8001DC, 8, (u8*)&Title);
else
Iso->GetTitleID((u8*)&Title);
Title = Common::swap64(Title);
sprintf(Path, FULL_WII_USER_DIR "title/%08x/%08x/data/", (u32)(Title>>32), (u32)Title);

View File

@ -78,7 +78,6 @@ private:
bool LoadFromCache();
void SaveToCache();
std::string CreateCacheFilename();
};

View File

@ -83,15 +83,19 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
}
else
{
pFileSystem = DiscIO::CreateFileSystem(OpenISO);
pFileSystem->GetFileList(GCFiles);
// TODO : Should we add a way to browse the wad file ?
if (!DiscIO::IsVolumeWadFile(OpenISO))
{
pFileSystem = DiscIO::CreateFileSystem(OpenISO);
pFileSystem->GetFileList(GCFiles);
}
}
OpenGameListItem = new GameListItem(fileName);
bRefreshList = false;
CreateGUIControls();
CreateGUIControls(DiscIO::IsVolumeWadFile(OpenISO));
GameIniFile = FULL_GAMECONFIG_DIR + (OpenISO->GetUniqueID()) + ".ini";
if (GameIni.Load(GameIniFile.c_str()))
@ -157,8 +161,12 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
}
else
{
fileIter beginning = GCFiles.begin(), end = GCFiles.end(), pos = GCFiles.begin();
CreateDirectoryTree(RootId, beginning, end, pos, (char *)"/");
// TODO : Should we add a way to browse the wad file ?
if (!DiscIO::IsVolumeWadFile(OpenISO))
{
fileIter beginning = GCFiles.begin(), end = GCFiles.end(), pos = GCFiles.begin();
CreateDirectoryTree(RootId, beginning, end, pos, (char *)"/");
}
}
m_Treectrl->Expand(RootId);
@ -177,7 +185,8 @@ CISOProperties::~CISOProperties()
if (IsVolumeWiiDisc(OpenISO))
WiiDisc.clear();
else
delete pFileSystem;
if (!IsVolumeWadFile(OpenISO))
delete pFileSystem;
delete OpenISO;
}
@ -232,9 +241,11 @@ void CISOProperties::CreateDirectoryTree(wxTreeItemId& parent,
} while(bRoot || strstr(name, directory));
}
void CISOProperties::CreateGUIControls()
void CISOProperties::CreateGUIControls(bool IsWad)
{
m_Close = new wxButton(this, ID_CLOSE, _("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
EditConfig = new wxButton(this, ID_EDITCONFIG, _("Edit Config"), wxDefaultPosition, wxDefaultSize);
EditConfig->SetToolTip(_("This will let you Manually Edit the INI config file"));
// Notebook
m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
@ -251,6 +262,7 @@ void CISOProperties::CreateGUIControls()
wxBoxSizer* sButtons;
sButtons = new wxBoxSizer(wxHORIZONTAL);
sButtons->Add(EditConfig, 0, wxALL, 5);
sButtons->Add(0, 0, 1, wxEXPAND, 5);
sButtons->Add(m_Close, 0, wxALL, 5);
@ -269,7 +281,7 @@ void CISOProperties::CreateGUIControls()
sbWiiOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Wii Console"));
EnableProgressiveScan = new wxCheckBox(m_GameConfig, ID_ENABLEPROGRESSIVESCAN, _("Enable Progressive Scan"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
if (!DiscIO::IsVolumeWiiDisc(OpenISO))
if (!DiscIO::IsVolumeWiiDisc(OpenISO) && !DiscIO::IsVolumeWadFile(OpenISO))
{
sbWiiOverrides->ShowItems(false);
EnableProgressiveScan->Hide();
@ -299,10 +311,9 @@ void CISOProperties::CreateGUIControls()
//HLE Audio
sbHLEaudioOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("HLE Audio"));
UseRE0Fix = new wxCheckBox(m_GameConfig, ID_RE0FIX, _("Use RE0 Fix"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
// Manual edit config file
sEmuState = new wxBoxSizer(wxHORIZONTAL);
EditConfig = new wxButton(m_GameConfig, ID_EDITCONFIG, _("Edit Config"), wxDefaultPosition, wxDefaultSize);
// Emulation State
sEmuState = new wxBoxSizer(wxHORIZONTAL);
EmuStateText = new wxStaticText(m_GameConfig, ID_EMUSTATE_TEXT, _("Emulation State: "), wxDefaultPosition, wxDefaultSize);
arrayStringFor_EmuState.Add(_("Not Set"));
arrayStringFor_EmuState.Add(_("Broken"));
@ -336,7 +347,6 @@ void CISOProperties::CreateGUIControls()
sbGameConfig->Add(sbWiiOverrides, 0, wxEXPAND);
sbGameConfig->Add(sbVideoOverrides, 0, wxEXPAND);
sbGameConfig->Add(sbHLEaudioOverrides, 0, wxEXPAND);
sbGameConfig->Add(EditConfig);
sConfigPage->Add(sbGameConfig, 0, wxEXPAND|wxALL, 5);
sEmuState->Add(EmuStateText, 0, wxALIGN_CENTER_VERTICAL);
sEmuState->Add(EmuState, 0, wxEXPAND);
@ -474,13 +484,17 @@ void CISOProperties::CreateGUIControls()
m_Filesystem->SetSizer(sTreePage);
sTreePage->Layout();
// It's a wad file, so we remove the FileSystem page
if (IsWad)
m_Notebook->RemovePage(4);
//////////////////////////////////////////////////////////////////////////
// Add notebook and buttons to the dialog
wxBoxSizer* sMain;
sMain = new wxBoxSizer(wxVERTICAL);
sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5);
sMain->Add(sButtons, 0, wxEXPAND, 5);
sMain->SetMinSize(wxSize(400,550));
sMain->SetMinSize(wxSize(400,500));
SetSizerAndFit(sMain);
}
@ -790,6 +804,9 @@ void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event))
bRefreshList = true; // Just in case
}
// Once we're done with the ini edit, give the focus back to Dolphin
SetFocus();
}
void CISOProperties::ListSelectionChanged(wxCommandEvent& event)

View File

@ -217,7 +217,7 @@ class CISOProperties : public wxDialog
IDM_BNRSAVEAS
};
void CreateGUIControls();
void CreateGUIControls(bool);
void OnClose(wxCloseEvent& event);
void OnCloseClick(wxCommandEvent& event);
void OnEditConfig(wxCommandEvent& event);