Support for loading MP2/MP3/DKCR tweaks
This commit is contained in:
parent
6e3a07a967
commit
992c76720d
|
@ -562,7 +562,7 @@ void CTextureDecoder::ReadPixelC8(IInputStream& rSrc, IOutputStream& rDst)
|
||||||
((Index >> 2) & 0x1) ? G = 0xFF : G = 0x0;
|
((Index >> 2) & 0x1) ? G = 0xFF : G = 0x0;
|
||||||
((Index >> 1) & 0x1) ? B = 0xFF : B = 0x0;
|
((Index >> 1) & 0x1) ? B = 0xFF : B = 0x0;
|
||||||
((Index >> 0) & 0x1) ? A = 0xFF : A = 0x0;
|
((Index >> 0) & 0x1) ? A = 0xFF : A = 0x0;
|
||||||
u32 RGBA = (R << 24) | (G << 16) | (B << 8) | (A);
|
uint32 RGBA = (R << 24) | (G << 16) | (B << 8) | (A);
|
||||||
dst.WriteLong(RGBA);*/
|
dst.WriteLong(RGBA);*/
|
||||||
|
|
||||||
mPaletteInput.Seek(Index * 2, SEEK_SET);
|
mPaletteInput.Seek(Index * 2, SEEK_SET);
|
||||||
|
|
|
@ -26,6 +26,19 @@ public:
|
||||||
pProperties->Construct(mTweakData.data());
|
pProperties->Construct(mTweakData.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TString TweakName()
|
||||||
|
{
|
||||||
|
if (Entry() != nullptr)
|
||||||
|
{
|
||||||
|
return Entry()->Name();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IProperty* pNameProperty = mpTemplate->Properties()->ChildByID(0x7FDA1466);
|
||||||
|
return CStringRef(mTweakData.data(), pNameProperty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline CScriptTemplate* TweakTemplate() const
|
inline CScriptTemplate* TweakTemplate() const
|
||||||
{
|
{
|
||||||
return mpTemplate;
|
return mpTemplate;
|
||||||
|
|
|
@ -50,7 +50,81 @@ CTweakData* CTweakLoader::LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry)
|
||||||
return pTweakData;
|
return pTweakData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTweakLoader::LoadNTWK(IInputStream& NTWK, std::vector<CTweakData*>& OutTweaks)
|
void CTweakLoader::LoadNTWK(IInputStream& NTWK, EGame Game, std::vector<CTweakData*>& OutTweaks)
|
||||||
{
|
{
|
||||||
// Unimplemented
|
// Validate file. NTWK basically embeds a bunch of tweak objects using the script layers
|
||||||
|
// format, so it has the same version byte that script layers have.
|
||||||
|
uint Magic = NTWK.ReadLong();
|
||||||
|
uint8 LayerVersion = NTWK.ReadByte();
|
||||||
|
|
||||||
|
if (Magic != FOURCC('NTWK'))
|
||||||
|
{
|
||||||
|
errorf("Unrecognized NTWK magic: 0x%08X", Magic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (LayerVersion != 1)
|
||||||
|
{
|
||||||
|
errorf("Unrecognized layer version in NTWK: %d", LayerVersion);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate( Game );
|
||||||
|
ASSERT( pGameTemplate != nullptr );
|
||||||
|
|
||||||
|
// Start reading tweaks
|
||||||
|
uint NumTweaks = NTWK.ReadLong();
|
||||||
|
|
||||||
|
for (uint TweakIdx = 0; TweakIdx < NumTweaks; TweakIdx++)
|
||||||
|
{
|
||||||
|
// Find the correct template based on the tweak ID.
|
||||||
|
static const std::unordered_map<uint, const char*> skIdToTemplateName =
|
||||||
|
{
|
||||||
|
{ FOURCC('TWAC'), "TweakAdvancedControls" },
|
||||||
|
{ FOURCC('TWAM'), "TweakAutoMapper" },
|
||||||
|
{ FOURCC('TWBL'), "TweakBall" },
|
||||||
|
{ FOURCC('TWC2'), "TweakPlayerControls" },
|
||||||
|
{ FOURCC('TWCB'), "TweakCameraBob" },
|
||||||
|
{ FOURCC('TWCC'), "TweakGamecubeControls" },
|
||||||
|
{ FOURCC('TWCT'), "TweakControls" },
|
||||||
|
{ FOURCC('TWEC'), "TweakExpertControls" },
|
||||||
|
{ FOURCC('TWGM'), "TweakGame" },
|
||||||
|
{ FOURCC('TWGT'), "TweakGraphicalTransitions" },
|
||||||
|
{ FOURCC('TWGU'), "TweakGui" },
|
||||||
|
{ FOURCC('TWGC'), "TweakGuiColors" },
|
||||||
|
{ FOURCC('TWP2'), "TweakPlayer" },
|
||||||
|
{ FOURCC('TWPC'), "TweakPlayerControls" },
|
||||||
|
{ FOURCC('TWPG'), "TweakPlayerGun" },
|
||||||
|
{ FOURCC('TWPL'), "TweakPlayer" },
|
||||||
|
{ FOURCC('TWPM'), "TweakPlayerGun" },
|
||||||
|
{ FOURCC('TWPA'), "TweakParticle" },
|
||||||
|
{ FOURCC('TWPR'), "TweakPlayerRes" },
|
||||||
|
{ FOURCC('TWRC'), "TweakRevolutionControls" },
|
||||||
|
{ FOURCC('TWSS'), "TweakSlideShow" },
|
||||||
|
{ FOURCC('TWTG'), "TweakTargeting" },
|
||||||
|
};
|
||||||
|
|
||||||
|
uint TweakID = NTWK.ReadLong();
|
||||||
|
uint16 TweakSize = NTWK.ReadShort();
|
||||||
|
uint NextTweak = NTWK.Tell() + TweakSize;
|
||||||
|
|
||||||
|
auto Find = skIdToTemplateName.find(TweakID);
|
||||||
|
|
||||||
|
if (Find == skIdToTemplateName.end())
|
||||||
|
{
|
||||||
|
errorf("Unrecognized tweak ID: %s (0x%08X)", *CFourCC(TweakID).ToString(), TweakID);
|
||||||
|
NTWK.GoTo(NextTweak);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CScriptTemplate* pTweakTemplate = pGameTemplate->FindMiscTemplate( Find->second );
|
||||||
|
ASSERT( pTweakTemplate != nullptr );
|
||||||
|
|
||||||
|
// Load tweak data
|
||||||
|
NTWK.Skip(0xC);
|
||||||
|
CTweakData* pTweakData = new CTweakData(pTweakTemplate);
|
||||||
|
CScriptLoader::LoadStructData( NTWK, pTweakData->TweakData() );
|
||||||
|
OutTweaks.push_back(pTweakData);
|
||||||
|
|
||||||
|
NTWK.GoTo(NextTweak);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ class CTweakLoader
|
||||||
public:
|
public:
|
||||||
/** Loader entry point */
|
/** Loader entry point */
|
||||||
static CTweakData* LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry);
|
static CTweakData* LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry);
|
||||||
static void LoadNTWK(IInputStream& NTWK, std::vector<CTweakData*>& OutTweaks);
|
static void LoadNTWK(IInputStream& NTWK, EGame Game, std::vector<CTweakData*>& OutTweaks);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CTWEAKLOADER_H
|
#endif // CTWEAKLOADER_H
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CTweakManager.h"
|
#include "CTweakManager.h"
|
||||||
#include "Core/GameProject/CGameProject.h"
|
#include "Core/GameProject/CGameProject.h"
|
||||||
#include "Core/GameProject/CResourceIterator.h"
|
#include "Core/GameProject/CResourceIterator.h"
|
||||||
|
#include "Core/Tweaks/CTweakLoader.h"
|
||||||
|
|
||||||
CTweakManager::CTweakManager(CGameProject* pInProject)
|
CTweakManager::CTweakManager(CGameProject* pInProject)
|
||||||
: mpProject(pInProject)
|
: mpProject(pInProject)
|
||||||
|
@ -9,19 +10,40 @@ CTweakManager::CTweakManager(CGameProject* pInProject)
|
||||||
|
|
||||||
void CTweakManager::LoadTweaks()
|
void CTweakManager::LoadTweaks()
|
||||||
{
|
{
|
||||||
|
ASSERT( mTweakObjects.empty() );
|
||||||
|
|
||||||
// MP1 - Load all tweak assets into memory
|
// MP1 - Load all tweak assets into memory
|
||||||
if (mpProject->Game() <= EGame::Prime)
|
if (mpProject->Game() <= EGame::Prime)
|
||||||
{
|
{
|
||||||
for (TResourceIterator<EResourceType::Tweaks> It(mpProject->ResourceStore()); It; ++It)
|
for (TResourceIterator<EResourceType::Tweaks> It(mpProject->ResourceStore()); It; ++It)
|
||||||
{
|
{
|
||||||
CTweakData* pTweaks = (CTweakData*) It->Load();
|
CTweakData* pTweaks = (CTweakData*) It->Load();
|
||||||
|
pTweaks->Lock();
|
||||||
mTweakObjects.push_back(pTweaks);
|
mTweakObjects.push_back(pTweaks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MP2+ - Not supported, but tweaks are stored in Standard.ntwk
|
// MP2+ - Load tweaks from Standard.ntwk
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
TString FilePath = mpProject->DiscFilesystemRoot(false) + "Standard.ntwk";
|
||||||
|
CFileInStream StandardNTWK(FilePath, EEndian::BigEndian);
|
||||||
|
CTweakLoader::LoadNTWK(StandardNTWK, mpProject->Game(), mTweakObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CTweakManager::~CTweakManager()
|
||||||
|
{
|
||||||
|
for (CTweakData* pTweakData : mTweakObjects)
|
||||||
|
{
|
||||||
|
if (pTweakData->Entry() != nullptr)
|
||||||
|
{
|
||||||
|
pTweakData->Release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete pTweakData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,16 @@ class CTweakManager
|
||||||
CGameProject* mpProject;
|
CGameProject* mpProject;
|
||||||
|
|
||||||
/** All tweak resources in the current game */
|
/** All tweak resources in the current game */
|
||||||
std::vector< TResPtr<CTweakData> > mTweakObjects;
|
std::vector< CTweakData* > mTweakObjects;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTweakManager(CGameProject* pInProject);
|
CTweakManager(CGameProject* pInProject);
|
||||||
|
~CTweakManager();
|
||||||
void LoadTweaks();
|
void LoadTweaks();
|
||||||
void SaveTweaks();
|
void SaveTweaks();
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
inline const std::vector< TResPtr<CTweakData> >& TweakObjects() const
|
inline const std::vector<CTweakData*>& TweakObjects() const
|
||||||
{
|
{
|
||||||
return mTweakObjects;
|
return mTweakObjects;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,9 +144,9 @@ void CTweakEditor::OnProjectChanged(CGameProject* pNewProject)
|
||||||
// Create tweak list
|
// Create tweak list
|
||||||
if (pNewProject != nullptr)
|
if (pNewProject != nullptr)
|
||||||
{
|
{
|
||||||
for (TResPtr<CTweakData> pTweakData : pNewProject->TweakManager()->TweakObjects())
|
for (CTweakData* pTweakData : pNewProject->TweakManager()->TweakObjects())
|
||||||
{
|
{
|
||||||
mTweakAssets << pTweakData.RawPointer();
|
mTweakAssets << pTweakData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,12 +154,12 @@ void CTweakEditor::OnProjectChanged(CGameProject* pNewProject)
|
||||||
if (!mTweakAssets.isEmpty())
|
if (!mTweakAssets.isEmpty())
|
||||||
{
|
{
|
||||||
qSort(mTweakAssets.begin(), mTweakAssets.end(), [](CTweakData* pLeft, CTweakData* pRight) -> bool {
|
qSort(mTweakAssets.begin(), mTweakAssets.end(), [](CTweakData* pLeft, CTweakData* pRight) -> bool {
|
||||||
return pLeft->Entry()->Name().ToUpper() < pRight->Entry()->Name().ToUpper();
|
return pLeft->TweakName().ToUpper() < pRight->TweakName().ToUpper();
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (CTweakData* pTweakData, mTweakAssets)
|
foreach (CTweakData* pTweakData, mTweakAssets)
|
||||||
{
|
{
|
||||||
QString TweakName = TO_QSTRING( pTweakData->Entry()->Name() );
|
QString TweakName = TO_QSTRING( pTweakData->TweakName() );
|
||||||
mpUI->TweakTabs->addTab(TweakName);
|
mpUI->TweakTabs->addTab(TweakName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>MainWindow</string>
|
<string>Tweaks Editor</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
@ -93,10 +93,10 @@
|
||||||
<normaloff>:/icons/SaveAndRepack_32px.png</normaloff>:/icons/SaveAndRepack_32px.png</iconset>
|
<normaloff>:/icons/SaveAndRepack_32px.png</normaloff>:/icons/SaveAndRepack_32px.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Save and Repack</string>
|
<string>Save and Cook</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Save and Repack</string>
|
<string>Save and Cook</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -183,8 +183,7 @@ void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
|
||||||
|
|
||||||
if (pProp->Type() == EPropertyType::AnimationSet)
|
if (pProp->Type() == EPropertyType::AnimationSet)
|
||||||
{
|
{
|
||||||
EGame Game = mpObject->Area()->Game();
|
Type = mpDelegate->DetermineCharacterPropType(pProp->Game(), ChildIndex);
|
||||||
Type = mpDelegate->DetermineCharacterPropType(Game, ChildIndex);
|
|
||||||
IsAnimSet = true;
|
IsAnimSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue