diff --git a/src/Common/FileIO/IOutputStream.cpp b/src/Common/FileIO/IOutputStream.cpp index 4ffaab7c..bb9d33ca 100644 --- a/src/Common/FileIO/IOutputStream.cpp +++ b/src/Common/FileIO/IOutputStream.cpp @@ -51,19 +51,14 @@ void IOutputStream::WriteFourCC(long Val) WriteBytes(&Val, 4); } -void IOutputStream::WriteString(const TString& rkVal) +void IOutputStream::WriteString(const TString& rkVal, int Count /*= -1*/, bool Terminate /*= true*/) { - WriteBytes(rkVal.Data(), rkVal.Size()); + if (Count < 0) + Count = rkVal.Size(); - if (rkVal.IsEmpty() || rkVal.Back() != '\0') - WriteByte(0); -} - -void IOutputStream::WriteString(const TString& rkVal, u32 Count, bool Terminate) -{ WriteBytes(rkVal.Data(), Count); - if (Terminate && (Count == 0 || rkVal.Back() != '\0')) + if (Terminate && (rkVal.IsEmpty() || rkVal[Count-1] != 0)) WriteByte(0); } @@ -73,26 +68,24 @@ void IOutputStream::WriteSizedString(const TString& rkVal) WriteBytes(rkVal.Data(), rkVal.Size()); } -void IOutputStream::WriteWideString(const TWideString& rkVal) +void IOutputStream::WriteWString(const TWideString& rkVal, int Count /*= -1*/, bool Terminate /*= true*/) { - WriteBytes(rkVal.Data(), rkVal.Size() * 2); + if (Count < 0) + Count = rkVal.Size(); - if (rkVal.IsEmpty() || rkVal.Back() != '\0') + for (int ChrIdx = 0; ChrIdx < Count; ChrIdx++) + WriteShort(rkVal[ChrIdx]); + + if (Terminate && (rkVal.IsEmpty() || rkVal[Count-1] != 0)) WriteShort(0); } -void IOutputStream::WriteWideString(const TWideString& rkVal, u32 Count, bool Terminate) -{ - WriteBytes(rkVal.Data(), Count * 2); - - if (Terminate && (Count == 0 || rkVal.Back() != 0)) - WriteShort(0); -} - -void IOutputStream::WriteSizedWideString(const TWideString& rkVal) +void IOutputStream::WriteSizedWString(const TWideString& rkVal) { WriteLong(rkVal.Size()); - WriteBytes(rkVal.Data(), rkVal.Size() * 2); + + for (u32 ChrIdx = 0; ChrIdx < rkVal.Size(); ChrIdx++) + WriteShort(rkVal[ChrIdx]); } bool IOutputStream::GoTo(u32 Address) diff --git a/src/Common/FileIO/IOutputStream.h b/src/Common/FileIO/IOutputStream.h index a5747261..15887d3c 100644 --- a/src/Common/FileIO/IOutputStream.h +++ b/src/Common/FileIO/IOutputStream.h @@ -19,12 +19,10 @@ public: void WriteFloat(float Val); void WriteDouble(double Val); void WriteFourCC(long Val); - void WriteString(const TString& rkVal); - void WriteString(const TString& rkVal, u32 Count, bool Terminate = false); + void WriteString(const TString& rkVal, int Count = -1, bool Terminate = true); void WriteSizedString(const TString& rkVal); - void WriteWideString(const TWideString& rkVal); - void WriteWideString(const TWideString& rkVal, u32 Count, bool Terminate = false); - void WriteSizedWideString(const TWideString& rkVal); + void WriteWString(const TWideString& rkVal, int Count = -1, bool Terminate = true); + void WriteSizedWString(const TWideString& rkVal); bool GoTo(u32 Address); bool Skip(s32 SkipAmount); diff --git a/src/Common/Serialization/CBasicBinaryWriter.h b/src/Common/Serialization/CBasicBinaryWriter.h index fe518906..ebc86af3 100644 --- a/src/Common/Serialization/CBasicBinaryWriter.h +++ b/src/Common/Serialization/CBasicBinaryWriter.h @@ -80,7 +80,7 @@ public: virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); } virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); } virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue); } - virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue); } + virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWString(rValue); } virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); } virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream, CAssetID::GameIDLength(Game())); } diff --git a/src/Common/Serialization/CBinaryWriter.h b/src/Common/Serialization/CBinaryWriter.h index 78ee6fec..675b6b63 100644 --- a/src/Common/Serialization/CBinaryWriter.h +++ b/src/Common/Serialization/CBinaryWriter.h @@ -156,7 +156,7 @@ public: virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); } virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); } virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue); } - virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue); } + virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWString(rValue); } virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); } virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream, CAssetID::GameIDLength(Game())); } diff --git a/src/Core/Core.pro b/src/Core/Core.pro index cda46bbc..db752fa6 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -230,7 +230,8 @@ HEADERS += \ Resource/CSavedStateID.h \ IProgressNotifier.h \ IUIRelay.h \ - Resource/CResTypeFilter.h + Resource/CResTypeFilter.h \ + GameProject/COpeningBanner.h # Source Files SOURCES += \ @@ -337,4 +338,5 @@ SOURCES += \ GameProject/CGameInfo.cpp \ Resource/CResTypeInfo.cpp \ CompressionUtil.cpp \ - IUIRelay.cpp + IUIRelay.cpp \ + GameProject\COpeningBanner.cpp diff --git a/src/Core/GameProject/COpeningBanner.cpp b/src/Core/GameProject/COpeningBanner.cpp new file mode 100644 index 00000000..fca194a4 --- /dev/null +++ b/src/Core/GameProject/COpeningBanner.cpp @@ -0,0 +1,71 @@ +#include "COpeningBanner.h" +#include "CGameProject.h" + +COpeningBanner::COpeningBanner(CGameProject *pProj) + : mpProj(pProj) +{ + mWii = mpProj->IsWiiBuild(); + + TString BannerPath = mpProj->DiscFilesystemRoot(false) + "opening.bnr"; + CFileInStream Banner(BannerPath, IOUtil::eBigEndian); + + if (Banner.IsValid()) + { + mBannerData.resize(Banner.Size()); + Banner.ReadBytes(mBannerData.data(), mBannerData.size()); + } +} + +TString COpeningBanner::EnglishGameName() const +{ + // opening.bnr stores the game name in a fixed-length buffer. Need to account for + // this and prevent the string-reading function from overrunning the buffer + CMemoryInStream Banner(mBannerData.data(), mBannerData.size(), IOUtil::eBigEndian); + + u32 CharSize = mWii ? 2 : 1; + u32 MaxLen = MaxGameNameLength(); + + std::vector NameBuffer((MaxLen + 1) * CharSize, 0); + Banner.GoTo( mWii ? 0xB0 : 0x1860 ); + Banner.ReadBytes(NameBuffer.data(), MaxLen * CharSize); + + Banner.SetData(NameBuffer.data(), NameBuffer.size(), IOUtil::eBigEndian); + return mWii ? Banner.ReadWString().ToUTF8() : Banner.ReadString(); +} + +void COpeningBanner::SetEnglishGameName(const TString& rkName) +{ + CMemoryOutStream Banner(mBannerData.data(), mBannerData.size(), IOUtil::eBigEndian); + u32 PadCount = 0; + + u32 MaxLen = MaxGameNameLength(); + ASSERT(rkName.Size() <= MaxLen); + + if (mWii) + { + Banner.GoTo(0xB0); + Banner.WriteWString(rkName.ToUTF16(), -1, false); + PadCount = (MaxLen - rkName.Size()) * 2; + } + else + { + Banner.GoTo(0x1860); + Banner.WriteString(rkName, -1, false); + PadCount = MaxLen - rkName.Size(); + } + + for (u32 Pad = 0; Pad < PadCount; Pad++) + Banner.WriteByte(0); +} + +void COpeningBanner::Save() +{ + TString BannerPath = mpProj->DiscFilesystemRoot(false) + "opening.bnr"; + CFileOutStream Banner(BannerPath, IOUtil::eBigEndian); + Banner.WriteBytes(mBannerData.data(), mBannerData.size()); +} + +u32 COpeningBanner::MaxGameNameLength() const +{ + return (mWii ? 21 : 64); +} diff --git a/src/Core/GameProject/COpeningBanner.h b/src/Core/GameProject/COpeningBanner.h new file mode 100644 index 00000000..6f5fe0e2 --- /dev/null +++ b/src/Core/GameProject/COpeningBanner.h @@ -0,0 +1,24 @@ +#ifndef COPENINGBANNER_H +#define COPENINGBANNER_H + +#include +class CGameProject; + +// This class can be expanded later for better editing functionality. +// For the moment, we're only worried about editing the long game name. +class COpeningBanner +{ + CGameProject *mpProj; + std::vector mBannerData; + bool mWii; + +public: + COpeningBanner(CGameProject *pProj); + TString EnglishGameName() const; + void SetEnglishGameName(const TString& rkName); + void Save(); + + u32 MaxGameNameLength() const; +}; + +#endif // COPENINGBANNER_H diff --git a/src/Core/Resource/CTexture.cpp b/src/Core/Resource/CTexture.cpp index aed27a16..9c33a5e1 100644 --- a/src/Core/Resource/CTexture.cpp +++ b/src/Core/Resource/CTexture.cpp @@ -187,7 +187,7 @@ bool CTexture::WriteDDS(IOutputStream& rOut) CopyGLBuffer(); - rOut.WriteString("DDS ", 4); // "DDS " fourCC + rOut.WriteFourCC(FOURCC('DDS')); // "DDS " fourCC rOut.WriteLong(0x7C); // dwSize rOut.WriteLong(0x21007); // dwFlags rOut.WriteLong(mHeight); // dwHeight @@ -245,7 +245,7 @@ bool CTexture::WriteDDS(IOutputStream& rOut) } rOut.WriteLong(PFFlags); // DDS_PIXELFORMAT.dwFlags - (mTexelFormat == eDXT1) ? rOut.WriteString("DXT1", 4) : rOut.WriteLong(0); // DDS_PIXELFORMAT.dwFourCC + (mTexelFormat == eDXT1) ? rOut.WriteFourCC(FOURCC('DXT1')) : rOut.WriteLong(0); // DDS_PIXELFORMAT.dwFourCC rOut.WriteLong(PFBpp); // DDS_PIXELFORMAT.dwRGBBitCount rOut.WriteLong(PFRBitMask); // DDS_PIXELFORMAT.dwRBitMask rOut.WriteLong(PFGBitMask); // DDS_PIXELFORMAT.dwGBitMask diff --git a/src/Editor/CProjectSettingsDialog.cpp b/src/Editor/CProjectSettingsDialog.cpp index 3d225519..fbac8c96 100644 --- a/src/Editor/CProjectSettingsDialog.cpp +++ b/src/Editor/CProjectSettingsDialog.cpp @@ -7,6 +7,7 @@ #include "Editor/ResourceBrowser/CResourceBrowser.h" #include #include +#include #include #include #include @@ -20,6 +21,7 @@ CProjectSettingsDialog::CProjectSettingsDialog(QWidget *pParent) { mpUI->setupUi(this); + connect(mpUI->GameNameLineEdit, SIGNAL(editingFinished()), this, SLOT(GameNameChanged())); connect(mpUI->CookPackageButton, SIGNAL(clicked()), this, SLOT(CookPackage())); connect(mpUI->CookAllDirtyPackagesButton, SIGNAL(clicked(bool)), this, SLOT(CookAllDirtyPackages())); connect(mpUI->BuildIsoButton, SIGNAL(clicked(bool)), this, SLOT(BuildISO())); @@ -57,6 +59,11 @@ void CProjectSettingsDialog::ActiveProjectChanged(CGameProject *pProj) TString BuildName = pProj->GameInfo()->GetBuildName(BuildVer, Region); mpUI->BuildLineEdit->setText( QString("%1 (%2)").arg(BuildVer).arg( TO_QSTRING(BuildName) ) ); mpUI->RegionLineEdit->setText( TO_QSTRING(GetRegionName(Region)) ); + + // Banner info + COpeningBanner Banner(pProj); + mpUI->GameNameLineEdit->setText( TO_QSTRING(Banner.EnglishGameName()) ); + mpUI->GameNameLineEdit->setMaxLength( Banner.MaxGameNameLength() ); } else { @@ -66,12 +73,25 @@ void CProjectSettingsDialog::ActiveProjectChanged(CGameProject *pProj) mpUI->GameIdLineEdit->clear(); mpUI->BuildLineEdit->clear(); mpUI->RegionLineEdit->clear(); + mpUI->GameNameLineEdit->clear(); close(); } SetupPackagesList(); } +void CProjectSettingsDialog::GameNameChanged() +{ + if (mpProject) + { + QString NewName = mpUI->GameNameLineEdit->text(); + + COpeningBanner Banner(mpProject); + Banner.SetEnglishGameName( TO_TSTRING(NewName) ); + Banner.Save(); + } +} + void CProjectSettingsDialog::SetupPackagesList() { mpUI->PackagesList->clear(); diff --git a/src/Editor/CProjectSettingsDialog.h b/src/Editor/CProjectSettingsDialog.h index c7be5c21..44b8eb31 100644 --- a/src/Editor/CProjectSettingsDialog.h +++ b/src/Editor/CProjectSettingsDialog.h @@ -26,6 +26,7 @@ public: public slots: void ActiveProjectChanged(CGameProject *pProj); + void GameNameChanged(); void SetupPackagesList(); void CookPackage(); void CookAllDirtyPackages(); diff --git a/src/Editor/CProjectSettingsDialog.ui b/src/Editor/CProjectSettingsDialog.ui index c2f48231..33167d8c 100644 --- a/src/Editor/CProjectSettingsDialog.ui +++ b/src/Editor/CProjectSettingsDialog.ui @@ -6,8 +6,8 @@ 0 0 - 290 - 558 + 269 + 552 @@ -15,97 +15,157 @@ - - - - 12 - - - + + Project Settings + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + Name: + + + + + + + false + + + + + + + Game: + + + + + + + false + + + + + + + Game ID: + + + + + + + false + + + + + + + Build: + + + + + + + false + + + + + + + Region: + + + + + + + false + + + + + + - - - - - Name: - - - - - - - false - - - - - - - Game: - - - - - - - false - - - - - - - Game ID: - - - - - - - false - - - - - - - Build: - - - - - - - false - - - - - - - Region: - - - - - - - false - - - - + + + Opening Banner + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + Game Name: + + + + + + + Qt::ClickFocus + + + + + + + - + Packages + + 3 + + + 3 + + + 3 + + + 3 + @@ -149,12 +209,18 @@ - Build ISO + Build ISO + + + + :/icons/Disc_16px.png:/icons/Disc_16px.png - + + + diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index 6fa89938..d87a995e 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -276,16 +276,16 @@ File + - - + @@ -714,8 +714,12 @@ + + + :/icons/New_16px.png:/icons/New_16px.png + - Export Game + Create Project