Commit 869bcae5 authored by NTAuthority's avatar NTAuthority

VFS relative device, GameUniverse stuff including split FileLoader and some other stuff

parent d6dfaefe
Pipeline #43 skipped
#pragma once
#include <vfs/Device.h>
namespace krt
{
namespace vfs
{
class RelativeDevice : public Device
{
public:
// finds the other device in the manager
RelativeDevice(const std::string& otherPrefix);
RelativeDevice(const DevicePtr& otherDevice, const std::string& otherPrefix);
virtual THandle Open(const std::string& fileName, bool readOnly) override;
virtual THandle OpenBulk(const std::string& fileName, uint64_t* ptr) override;
virtual THandle Create(const std::string& filename) override;
virtual size_t Read(THandle handle, void* outBuffer, size_t size) override;
virtual size_t ReadBulk(THandle handle, uint64_t ptr, void* outBuffer, size_t size) override;
virtual size_t Write(THandle handle, const void* buffer, size_t size) override;
virtual size_t WriteBulk(THandle handle, uint64_t ptr, const void* buffer, size_t size) override;
virtual size_t Seek(THandle handle, intptr_t offset, int seekType) override;
virtual bool Close(THandle handle) override;
virtual bool CloseBulk(THandle handle) override;
virtual bool RemoveFile(const std::string& filename) override;
virtual bool RenameFile(const std::string& from, const std::string& to) override;
virtual bool CreateDirectory(const std::string& name) override;
virtual bool RemoveDirectory(const std::string& name) override;
virtual size_t GetLength(THandle handle) override;
virtual size_t GetLength(const std::string& fileName) override;
virtual THandle FindFirst(const std::string& folder, FindData* findData) override;
virtual bool FindNext(THandle handle, FindData* findData) override;
virtual void FindClose(THandle handle) override;
// Sets the path prefix for the device, which implementations should strip for generating a local path portion.
virtual void SetPathPrefix(const std::string& pathPrefix) override;
private:
DevicePtr m_otherDevice;
std::string m_otherPrefix;
std::string m_pathPrefix;
private:
inline std::string TranslatePath(const std::string& inPath)
{
return m_otherPrefix + inPath.substr(m_pathPrefix.length());
}
};
}
}
\ No newline at end of file
......@@ -8,7 +8,7 @@
namespace krt
{
ConsoleCommandManager::ConsoleCommandManager(console::Context* parentContext)
: m_parentContext(parentContext)
: m_parentContext(parentContext), m_curToken(0)
{
}
......
#include <StdInc.h>
#include <vfs/Manager.h>
#include <vfs/RelativeDevice.h>
namespace krt
{
namespace vfs
{
RelativeDevice::RelativeDevice(const std::string& otherPrefix)
: RelativeDevice(GetDevice(otherPrefix), otherPrefix)
{
}
RelativeDevice::RelativeDevice(const DevicePtr& otherDevice, const std::string& otherPrefix)
: m_otherDevice(otherDevice), m_otherPrefix(otherPrefix)
{
}
Device::THandle RelativeDevice::Open(const std::string& fileName, bool readOnly)
{
return m_otherDevice->Open(TranslatePath(fileName), readOnly);
}
Device::THandle RelativeDevice::OpenBulk(const std::string& fileName, uint64_t* ptr)
{
return m_otherDevice->OpenBulk(TranslatePath(fileName), ptr);
}
Device::THandle RelativeDevice::Create(const std::string& filename)
{
return m_otherDevice->Create(TranslatePath(filename));
}
size_t RelativeDevice::Read(THandle handle, void* outBuffer, size_t size)
{
return m_otherDevice->Read(handle, outBuffer, size);
}
size_t RelativeDevice::ReadBulk(THandle handle, uint64_t ptr, void* outBuffer, size_t size)
{
return m_otherDevice->ReadBulk(handle, ptr, outBuffer, size);
}
size_t RelativeDevice::Write(THandle handle, const void* buffer, size_t size)
{
return m_otherDevice->Write(handle, buffer, size);
}
size_t RelativeDevice::WriteBulk(THandle handle, uint64_t ptr, const void* buffer, size_t size)
{
return m_otherDevice->WriteBulk(handle, ptr, buffer, size);
}
size_t RelativeDevice::Seek(THandle handle, intptr_t offset, int seekType)
{
return m_otherDevice->Seek(handle, offset, seekType);
}
bool RelativeDevice::Close(THandle handle)
{
return m_otherDevice->Close(handle);
}
bool RelativeDevice::CloseBulk(THandle handle)
{
return m_otherDevice->CloseBulk(handle);
}
bool RelativeDevice::RemoveFile(const std::string& filename)
{
return m_otherDevice->RemoveFile(TranslatePath(filename));
}
bool RelativeDevice::RenameFile(const std::string& from, const std::string& to)
{
return m_otherDevice->RenameFile(TranslatePath(from), TranslatePath(to));
}
bool RelativeDevice::CreateDirectory(const std::string& name)
{
return m_otherDevice->CreateDirectory(TranslatePath(name));
}
bool RelativeDevice::RemoveDirectory(const std::string& name)
{
return m_otherDevice->RemoveDirectory(TranslatePath(name));
}
size_t RelativeDevice::GetLength(THandle handle)
{
return m_otherDevice->GetLength(handle);
}
size_t RelativeDevice::GetLength(const std::string& fileName)
{
return m_otherDevice->GetLength(TranslatePath(fileName));
}
Device::THandle RelativeDevice::FindFirst(const std::string& folder, FindData* findData)
{
return m_otherDevice->FindFirst(TranslatePath(folder), findData);
}
bool RelativeDevice::FindNext(THandle handle, FindData* findData)
{
return m_otherDevice->FindNext(handle, findData);
}
void RelativeDevice::FindClose(THandle handle)
{
return m_otherDevice->FindClose(handle);
}
void RelativeDevice::SetPathPrefix(const std::string& pathPrefix)
{
m_pathPrefix = pathPrefix;
}
}
}
\ No newline at end of file
......@@ -7,11 +7,14 @@
namespace krt
{
class Game;
struct Entity
{
friend class Game;
friend struct World;
friend class Game;
friend class FileLoader;
friend struct inst_section_manager; // leaky abstraction?
Entity( Game *ourGame );
~Entity();
......
#pragma once
#include <GameUniverse.h>
namespace krt
{
class FileLoader
{
public:
// loads an IDE/IPL file without assigning to any universe
inline static void LoadIDEFile(const std::string& absPath)
{
LoadIDEFile(absPath, GameUniversePtr());
}
inline static void LoadIPLFile(const std::string& absPath)
{
LoadIPLFile(absPath, GameUniversePtr());
}
// loads an IDE/IPL file, assigning it to an universe
static void LoadIDEFile(const std::string& absPath, const GameUniversePtr& universe);
static void LoadIPLFile(const std::string& absPath, const GameUniversePtr& universe);
static void ScanIMG(const vfs::DevicePtr& device, const std::string& pathPrefix, const GameUniversePtr& universe);
private:
// static class only
FileLoader();
};
}
\ No newline at end of file
......@@ -12,6 +12,7 @@
#include "World.h"
#include "Console.Commands.h"
#include "GameUniverse.h"
namespace krt
{
......@@ -25,20 +26,17 @@ public:
std::string GetGamePath( std::string relPath );
void RunCommandFile( std::string relDir );
inline streaming::StreamMan& GetStreaming( void ) { return this->streaming; }
inline TextureManager& GetTextureManager( void ) { return this->texManager; }
inline ModelManager& GetModelManager( void ) { return this->modelManager; }
inline World* GetWorld( void ) { return &theWorld; }
void LoadIMG( std::string relPath );
std::string GetDevicePathPrefix( void ) { return "gta3:/"; }
void LoadIDEFile( std::string relPath );
void LoadIPLFile( std::string relPath );
GameUniversePtr AddUniverse(const GameConfiguration& configuration);
std::string GetDevicePathPrefix( void ) { return "gta3:/"; }
GameUniversePtr GetUniverse(const std::string& name);
private:
std::string gameDir;
......@@ -51,8 +49,20 @@ private:
World theWorld;
NestedList <Entity> activeEntities;
std::vector<GameUniversePtr> universes;
};
extern Game *theGame;
template<>
struct ConsoleArgumentType<GameUniversePtr>
{
static bool Parse(const std::string& input, GameUniversePtr* out)
{
*out = theGame->GetUniverse(input);
return true;
}
};
};
\ No newline at end of file
#pragma once
#include <Streaming.h>
#include <vfs/Device.h>
namespace krt
{
struct GameConfiguration
{
// the internal name of the game ('gta3', for instance)
std::string gameName;
// the path (in the existing VFS tree) to the game root
std::string rootPath;
// a list of game configuration files (world DAT files) to load, relative to the game root
std::vector<std::string> configurationFiles;
// a list of CD images to preload (say, 'models/gta3.img')
std::vector<std::string> imageFiles;
};
// a game universe represents a single game's asset configuration
class GameUniverse
{
public:
GameUniverse(const GameConfiguration& configuration);
~GameUniverse();
inline const GameConfiguration& GetConfiguration() const
{
return m_configuration;
}
void Load();
std::string GetMountPoint() const;
std::string GetImageMountPoint() const;
inline void RegisterOwnedStreamingIndex(streaming::ident_t id)
{
m_streamingIndices.push_back(id);
}
inline void RegisterModelIndexMapping(streaming::ident_t from, streaming::ident_t to)
{
m_modelIndexMapping.insert({ from, to });
}
inline streaming::ident_t GetModelIndexMapping(streaming::ident_t localId)
{
auto it = m_modelIndexMapping.find(localId);
assert(it != m_modelIndexMapping.end());
return it->second;
}
private:
void AddImage(const std::string& relativePath);
void LoadConfiguration(const std::string& relativePath);
private:
struct ImageFile
{
vfs::DevicePtr cdimage;
vfs::DevicePtr relativeMount;
// the path the CD image is primarily mounted at
std::string primaryMount;
};
private:
GameConfiguration m_configuration;
std::vector<ImageFile> m_imageFiles;
std::vector<streaming::ident_t> m_streamingIndices;
std::map<streaming::ident_t, streaming::ident_t> m_modelIndexMapping;
};
using GameUniversePtr = std::shared_ptr<GameUniverse>;
}
\ No newline at end of file
......@@ -69,10 +69,9 @@ struct ModelManager : public streaming::StreamingTypeInterface
ModelManager( streaming::StreamMan& streaming, TextureManager& texManager );
~ModelManager( void );
void RegisterAtomicModel(
streaming::ident_t id,
streaming::ident_t RegisterAtomicModel(
std::string name, std::string texDictName, float lodDistance, int flags,
std::string relFilePath
std::string absFilePath
);
ModelResource* GetModelByID( streaming::ident_t id );
......@@ -90,6 +89,8 @@ private:
std::vector <ModelResource*> models;
std::atomic <streaming::ident_t> curModelId;
std::map <std::string, ModelResource*> modelByName;
std::map <std::string, ModelResource*> basifierLookup;
......
This diff is collapsed.
This diff is collapsed.
#include <StdInc.h>
#include <Game.h>
#include <GameUniverse.h>
#include <Console.CommandHelpers.h>
#include <FileLoader.h>
#include <vfs/Manager.h>
namespace krt
{
ConsoleCommand loadIdeCommand("load_ide", [] (const GameUniversePtr& universe, const std::string& idePath)
{
FileLoader::LoadIDEFile(idePath, universe);
});
ConsoleCommand loadIplCommand("load_ipl", [] (const GameUniversePtr& universe, const std::string& iplPath)
{
FileLoader::LoadIPLFile(iplPath, universe);
});
ConsoleCommand loadImgCommand("load_cdimage", [] (const GameUniversePtr& universe, const std::string& mainMount)
{
FileLoader::ScanIMG(vfs::GetDevice(mainMount), mainMount, universe);
});
}
\ No newline at end of file
#include <StdInc.h>
#include <Game.h>
#include <GameUniverse.h>
#include <vfs/RelativeDevice.h>
#include <vfs/Manager.h>
#include <CdImageDevice.h>
#include <Console.h>
#include <Console.CommandHelpers.h>
namespace krt
{
GameUniverse::GameUniverse(const GameConfiguration& configuration)
: m_configuration(configuration)
{
}
GameUniverse::~GameUniverse()
{
for (streaming::ident_t index : m_streamingIndices)
{
theGame->GetStreaming().UnlinkResource(index);
}
}
void GameUniverse::Load()
{
// mount a relative device pointing at the root
vfs::DevicePtr device = std::make_shared<vfs::RelativeDevice>(m_configuration.rootPath);
vfs::Mount(device, GetMountPoint());
// enqueue pre-cached IMG files
for (const auto& imageFile : m_configuration.imageFiles)
{
AddImage(imageFile);
}
// load configuration files
for (const auto& configurationFile : m_configuration.configurationFiles)
{
LoadConfiguration(configurationFile);
}
// load IMG files
// TODO: figure out how to defer this?
/*for (const auto& imageFile : m_imageFiles)
{
console::ExecuteSingleCommand(ProgramArguments{ "load_cdimage", m_configuration.gameName, imageFile.primaryMount });
}*/
}
void GameUniverse::LoadConfiguration(const std::string& relativePath)
{
vfs::StreamPtr stream = vfs::OpenRead(GetMountPoint() + relativePath);
std::vector<uint8_t> string = stream->ReadToEnd();
console::Context localConsole;
// add commands to the context
ConsoleCommand ideLoadCmd(&localConsole, "IDE",
[&] (const std::string& fileName)
{
localConsole.ExecuteSingleCommand(ProgramArguments{ "load_ide", m_configuration.gameName, GetMountPoint() + fileName });
});
ConsoleCommand iplLoadCmd(&localConsole, "IPL",
[&] (const std::string& fileName)
{
localConsole.ExecuteSingleCommand(ProgramArguments{ "load_ipl", m_configuration.gameName, GetMountPoint() + fileName });
});
ConsoleCommand imgMountCmd(&localConsole, "IMG",
[&] (const std::string& path)
{
localConsole.ExecuteSingleCommand(ProgramArguments{ "add_cdimage", m_configuration.gameName, path });
});
// run the configuration file
localConsole.AddToBuffer(std::string(reinterpret_cast<char*>(string.data()), string.size()));
localConsole.ExecuteBuffer();
}
void GameUniverse::AddImage(const std::string& relativePath)
{
std::shared_ptr<streaming::CdImageDevice> cdImage = std::make_shared<streaming::CdImageDevice>();
// if opening the image succeeded
std::string imagePath = GetMountPoint() + relativePath;
std::string mountPath = imagePath.substr(0, imagePath.find_last_of('.')) + "/";
if (cdImage->OpenImage(imagePath))
{
// create a relative mount referencing the CD image and mount it
vfs::DevicePtr relative = std::make_shared<vfs::RelativeDevice>(cdImage, mountPath);
vfs::Mount(cdImage, mountPath);
vfs::Mount(relative, GetImageMountPoint());
// and add an entry to the list
ImageFile entry;
entry.cdimage = cdImage;
entry.relativeMount = relative;
entry.primaryMount = mountPath;
m_imageFiles.push_back(entry);
// pass the image file to be loaded immediately
console::ExecuteSingleCommand(ProgramArguments{ "load_cdimage", m_configuration.gameName, entry.primaryMount });
}
}
std::string GameUniverse::GetMountPoint() const
{
return m_configuration.gameName + ":/";
}
std::string GameUniverse::GetImageMountPoint() const
{
return m_configuration.gameName + "img:/";
}
}
\ No newline at end of file
......@@ -9,7 +9,7 @@
namespace krt
{
ModelManager::ModelManager( streaming::StreamMan& streaming, TextureManager& texManager ) : streaming( streaming ), texManager( texManager )
ModelManager::ModelManager( streaming::StreamMan& streaming, TextureManager& texManager ) : streaming( streaming ), texManager( texManager ), curModelId (0)
{
bool didRegister = streaming.RegisterResourceType( MODEL_ID_BASE, MAX_MODELS, this );
......@@ -40,22 +40,13 @@ ModelManager::~ModelManager( void )
streaming.UnregisterResourceType( MODEL_ID_BASE );
}
void ModelManager::RegisterAtomicModel(
streaming::ident_t id,
streaming::ident_t ModelManager::RegisterAtomicModel(
std::string name, std::string texDictName, float lodDistance, int flags,
std::string relFilePath
std::string absFilePath
)
{
// Check whether that id is taken already.
{
ModelResource *alreadyTaken = this->GetModelByID( id );
if ( alreadyTaken )
{
// Cannot take this id because occupied, meow.
return;
}
}
// Get an identifier
streaming::ident_t id = (curModelId.fetch_add(1)) + MODEL_ID_BASE;
// Check whether we already have a model that goes by that name.
{
......@@ -64,28 +55,26 @@ void ModelManager::RegisterAtomicModel(
if ( findIter != this->modelByName.end() )
{
// The name is already taken, so bail.
return;
return findIter->second->GetID();
}
}
// Get the device this model is bound to.
std::string pathPrefix = theGame->GetDevicePathPrefix();
std::string devPath = ( pathPrefix + relFilePath );
std::string devPath = ( absFilePath );
vfs::DevicePtr resDevice = vfs::GetDevice( devPath );
if ( resDevice == nullptr )
{
// No device means we do not care.
return;
return -1;
}
// Check whether this resource even exists.
if ( resDevice->GetLength( devPath ) == -1 )
{
// Does not exist, I think.
return;
return -1;
}
ModelResource *modelEntry = new ModelResource( resDevice, std::move( devPath ) );
......@@ -109,7 +98,7 @@ void ModelManager::RegisterAtomicModel(
// The resource does not really exist I guess.
delete modelEntry;
return;
return -1;
}
// Find the texture dictionary that should link with this model.
......@@ -198,6 +187,7 @@ void ModelManager::RegisterAtomicModel(
this->models[ id - MODEL_ID_BASE ] = modelEntry;
// Success!
return id;
}
// TODO: maybe allow unregistering of models.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment