GameUniverse.cpp 4 KB
Newer Older
1 2 3 4 5 6
#include <StdInc.h>

#include <Game.h>
#include <GameUniverse.h>

#include <vfs/Manager.h>
NTAuthority's avatar
NTAuthority committed
7
#include <vfs/RelativeDevice.h>
8 9 10 11

#include <CdImageDevice.h>

#include <Console.CommandHelpers.h>
NTAuthority's avatar
NTAuthority committed
12
#include <Console.h>
13 14 15 16

namespace krt
{
GameUniverse::GameUniverse(const GameConfiguration& configuration)
17 18
    : m_configuration(configuration), m_game(theGame),

19 20 21 22 23
      // Initialize all game universe commands.
      cmdAddImage("add_cdimage",
          [](const GameUniversePtr& universe, const std::string& path) {
	          universe->AddImage(path);
	      })
24 25 26 27 28 29 30
{
}

GameUniverse::~GameUniverse()
{
	for (streaming::ident_t index : m_streamingIndices)
	{
NTAuthority's avatar
NTAuthority committed
31
		m_game->GetStreaming().UnlinkResource(index);
32 33 34 35 36 37 38 39
	}
}

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());
NTAuthority's avatar
NTAuthority committed
40

41 42 43 44 45 46
	// load generic.txd if the game has one
	if (m_configuration.gameName == "gta3" || m_configuration.gameName == "gtavc")
	{
		m_game->GetTextureManager().RegisterResource("generic", device, GetMountPoint() + "models/generic.txd");
	}

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
	// 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)
{
NTAuthority's avatar
NTAuthority committed
69
	vfs::StreamPtr stream       = vfs::OpenRead(GetMountPoint() + relativePath);
70 71 72 73 74 75
	std::vector<uint8_t> string = stream->ReadToEnd();

	console::Context localConsole;

	// add commands to the context
	ConsoleCommand ideLoadCmd(&localConsole, "IDE",
76 77 78
	    [&](const std::string& fileName) {
		    localConsole.ExecuteSingleCommand(ProgramArguments{"load_ide", m_configuration.gameName, GetMountPoint() + fileName});
		});
79 80

	ConsoleCommand iplLoadCmd(&localConsole, "IPL",
81 82 83
	    [&](const std::string& fileName) {
		    localConsole.ExecuteSingleCommand(ProgramArguments{"load_ipl", m_configuration.gameName, GetMountPoint() + fileName});
		});
84 85

	ConsoleCommand imgMountCmd(&localConsole, "IMG",
86 87 88
	    [&](const std::string& path) {
		    localConsole.ExecuteSingleCommand(ProgramArguments{"add_cdimage", m_configuration.gameName, path});
		});
89

90 91 92 93 94 95
	ConsoleCommand colFileCmg(&localConsole, "COLFILE",
							  [&] (int levelNum, const std::string& fileName)
	{
		localConsole.ExecuteSingleCommand(ProgramArguments{"load_coll", GetMountPoint() + fileName});
	});

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	// 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;
NTAuthority's avatar
NTAuthority committed
118
		entry.cdimage       = cdImage;
119
		entry.relativeMount = relative;
NTAuthority's avatar
NTAuthority committed
120
		entry.primaryMount  = mountPath;
121 122 123 124

		m_imageFiles.push_back(entry);

		// pass the image file to be loaded immediately
NTAuthority's avatar
NTAuthority committed
125
		console::ExecuteSingleCommand(ProgramArguments{"load_cdimage", m_configuration.gameName, entry.primaryMount});
126 127 128 129 130 131 132 133 134 135 136 137 138
	}
}

std::string GameUniverse::GetMountPoint() const
{
	return m_configuration.gameName + ":/";
}

std::string GameUniverse::GetImageMountPoint() const
{
	return m_configuration.gameName + "img:/";
}
}