Added ability to edit the game name in opening.bnr; slightly reorganized world editor menu options

This commit is contained in:
Aruki 2017-07-10 16:43:53 -06:00
parent 581d5f7267
commit 0ffbaefcde
12 changed files with 299 additions and 120 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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())); }

View File

@ -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())); }

View File

@ -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

View File

@ -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<u8> 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);
}

View File

@ -0,0 +1,24 @@
#ifndef COPENINGBANNER_H
#define COPENINGBANNER_H
#include <Common/Common.h>
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<u8> mBannerData;
bool mWii;
public:
COpeningBanner(CGameProject *pProj);
TString EnglishGameName() const;
void SetEnglishGameName(const TString& rkName);
void Save();
u32 MaxGameNameLength() const;
};
#endif // COPENINGBANNER_H

View File

@ -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

View File

@ -7,6 +7,7 @@
#include "Editor/ResourceBrowser/CResourceBrowser.h"
#include <Common/AssertMacro.h>
#include <Core/GameProject/CGameExporter.h>
#include <Core/GameProject/COpeningBanner.h>
#include <QFileDialog>
#include <QFuture>
#include <QFutureWatcher>
@ -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();

View File

@ -26,6 +26,7 @@ public:
public slots:
void ActiveProjectChanged(CGameProject *pProj);
void GameNameChanged();
void SetupPackagesList();
void CookPackage();
void CookAllDirtyPackages();

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>558</height>
<width>269</width>
<height>552</height>
</rect>
</property>
<property name="windowTitle">
@ -15,97 +15,157 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="ProjectSettingsLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<widget class="QGroupBox" name="ProjectSettingsGroupBox">
<property name="title">
<string>Project Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="ProjectNameLabel">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="ProjectNameLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="GameLabel">
<property name="text">
<string>Game:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="GameLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="GameIdLabel">
<property name="text">
<string>Game ID:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="GameIdLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="BuildLabel">
<property name="text">
<string>Build:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="BuildLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="RegionLabel">
<property name="text">
<string>Region:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="RegionLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="ProjectNameLabel">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="ProjectNameLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="GameLabel">
<property name="text">
<string>Game:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="GameLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="GameIdLabel">
<property name="text">
<string>Game ID:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="GameIdLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="BuildLabel">
<property name="text">
<string>Build:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="BuildLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="RegionLabel">
<property name="text">
<string>Region:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="RegionLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
<widget class="QGroupBox" name="OpeningBannerGroupBox">
<property name="title">
<string>Opening Banner</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="GameNameLabel">
<property name="text">
<string>Game Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="GameNameLineEdit">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="PackagesGroupBox">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Packages</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QListWidget" name="PackagesList">
<property name="font">
@ -149,12 +209,18 @@
</font>
</property>
<property name="text">
<string>Build ISO</string>
<string> Build ISO</string>
</property>
<property name="icon">
<iconset resource="Icons.qrc">
<normaloff>:/icons/Disc_16px.png</normaloff>:/icons/Disc_16px.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="Icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -276,16 +276,16 @@
<property name="title">
<string>File</string>
</property>
<addaction name="ActionExportGame"/>
<addaction name="ActionOpenProject"/>
<addaction name="ActionOpenRecent"/>
<addaction name="separator"/>
<addaction name="ActionSave"/>
<addaction name="ActionSaveAndRepack"/>
<addaction name="separator"/>
<addaction name="ActionExportGame"/>
<addaction name="ActionProjectSettings"/>
<addaction name="ActionCloseProject"/>
<addaction name="separator"/>
<addaction name="ActionCloseProject"/>
<addaction name="ActionExit"/>
</widget>
<widget class="QMenu" name="menuEdit">
@ -714,8 +714,12 @@
</property>
</action>
<action name="ActionExportGame">
<property name="icon">
<iconset resource="../Icons.qrc">
<normaloff>:/icons/New_16px.png</normaloff>:/icons/New_16px.png</iconset>
</property>
<property name="text">
<string>Export Game</string>
<string>Create Project</string>
</property>
</action>
<action name="ActionExit">