Support loading game data from system path

Armin Burgmeier 2011-01-06 21:18:13 +01:00
parent 7c26fc4d8d
commit 9f74506e9b
24 changed files with 288 additions and 167 deletions

View File

@ -156,6 +156,8 @@ set(OC_CLONK_SOURCES
src/config/C4ConfigShareware.cpp
src/config/C4ConfigShareware.h
src/config/C4Constants.h
src/config/C4Reloc.cpp
src/config/C4Reloc.h
src/config/C4SecurityCertificates.cpp
src/config/C4SecurityCertificates.h
src/control/C4Control.cpp
@ -926,6 +928,12 @@ endif()
############################################################################
# Assemble compiler flags
############################################################################
if(UNIX)
# Don't put this into CMAKE_CXX_FLAGS because otherwise it is cached,
# and when the path is changed both the old and new definition appears
# in the list of flags.
add_definitions("-DOC_SYSTEM_DATA_DIR=\"${CMAKE_INSTALL_PREFIX}/share/openclonk\"")
endif()
if(OC_CXX_FLAGS)
list(REMOVE_DUPLICATES OC_CXX_FLAGS)
endif()
@ -1071,11 +1079,11 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY
############################################################################
# installation
############################################################################
# Install the icon into share/icons/hicolor/48x48/apps/clonk.png. Do this by
# extracting the correct size from oc.ico. Currently this is layer 2 - let's
# hope that it stays this way.
# TODO: Check for convert at configure step?
install(DIRECTORY DESTINATION share/icons/hicolor/48x48/apps)
install(CODE "
EXECUTE_PROCESS(COMMAND \"convert\" \"${CMAKE_CURRENT_SOURCE_DIR}/src/res/oc.ico[2]\" \"${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/clonk.png\" RESULT_VARIABLE CONVERT_RESULT)
IF(NOT \${CONVERT_RESULT} EQUAL 0)

View File

@ -36,7 +36,7 @@ GCC_FLAGS =
WARNING_FLAGS = -Wall
endif
AM_CXXFLAGS = $(PTHREAD_CFLAGS) $(WINDOWS_CFLAGS) $(WARNING_FLAGS) $(GCC_FLAGS)
AM_CXXFLAGS = $(PTHREAD_CFLAGS) $(WINDOWS_CFLAGS) $(WARNING_FLAGS) $(GCC_FLAGS) -DOC_SYSTEM_DATA_DIR=\"${datadir}/openclonk\"
AM_CFLAGS = -Wall $(GCC_FLAGS)
@ -196,6 +196,8 @@ src/config/C4Config.h \
src/config/C4ConfigShareware.cpp \
src/config/C4ConfigShareware.h \
src/config/C4Constants.h \
src/config/C4Reloc.cpp \
src/config/C4Reloc.h \
src/config/C4SecurityCertificates.cpp \
src/config/C4SecurityCertificates.h \
src/control/C4Control.cpp \

View File

@ -110,8 +110,11 @@ bool C4Application::DoInit(int argc, char * argv[])
Revision.Ref(C4REVISION);
// Initialize game data paths
Reloc.Init();
// init system group
if (!SystemGroup.Open(C4CFN_System))
if (!Reloc.Open(SystemGroup, C4CFN_System))
{
// Error opening system group - no LogFatal, because it needs language table.
// This will *not* use the FatalErrors stack, but this will cause the game
@ -204,7 +207,7 @@ void C4Application::ParseCommandLine(int argc, char * argv[])
ClearCommandLine();
Game.NetworkActive = false;
Config.General.ClearAdditionalDataPaths();
Reloc.Init(); // re-init from config
isEditor = 2;
int c;
while (1)
@ -303,7 +306,7 @@ void C4Application::ParseCommandLine(int argc, char * argv[])
// startup start screen
case 's': C4Startup::SetStartScreen(optarg); break;
// additional read-only data path
case 'd': Config.General.AddAdditionalDataPath(optarg); break;
case 'd': Reloc.AddPath(optarg); break;
// debug options
case 'D': Game.DebugPort = atoi(optarg); break;
case 'P': Game.DebugPassword = optarg; break;
@ -345,7 +348,11 @@ void C4Application::ParseCommandLine(int argc, char * argv[])
// Scenario file
if (SEqualNoCase(GetExtension(szParameter),"c4s"))
{
Game.SetScenarioFilename(Config.AtDataReadPath(szParameter, true));
if(IsGlobalPath(szParameter))
Game.SetScenarioFilename(szParameter);
else
Game.SetScenarioFilename((std::string(GetWorkingDirectory()) + DirSep + szParameter).c_str());
continue;
}
if (SEqualNoCase(GetFilename(szParameter),"scenario.txt"))
@ -356,8 +363,11 @@ void C4Application::ParseCommandLine(int argc, char * argv[])
// Player file
if (SEqualNoCase(GetExtension(szParameter),"c4p"))
{
const char *param = Config.AtDataReadPath(szParameter, true);
SAddModule(Game.PlayerFilenames,param);
if(IsGlobalPath(szParameter))
SAddModule(Game.PlayerFilenames, szParameter);
else
SAddModule(Game.PlayerFilenames, (std::string(GetWorkingDirectory()) + DirSep + szParameter).c_str());
continue;
}
// Definition file

View File

@ -181,9 +181,14 @@ bool C4Game::OpenScenario()
{ LogF("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), (const char *)ScenarioFilename); return false; }
}
else
{
// open directly
if (!ScenarioFile.Open(ScenarioFilename))
if (!Reloc.Open(ScenarioFile, ScenarioFilename))
{ LogF("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), (const char *)ScenarioFilename); return false; }
}
// Remember full (absolute) path
SCopy(ScenarioFile.GetFullName().getData(), ScenarioFilename, _MAX_PATH);
// add scenario to group
GroupSet.RegisterGroup(ScenarioFile, false, C4GSPrio_Scenario, C4GSCnt_Scenario);
@ -818,7 +823,7 @@ bool C4Game::InitMaterialTexture()
// Find next external material source
pMatRes = Game.Parameters.GameRes.iterRes(pMatRes, NRT_Material);
if (!pMatRes) break;
if (!Mats.Open(pMatRes->getFile()))
if (!Reloc.Open(Mats, pMatRes->getFile()))
return false;
}
@ -3210,9 +3215,6 @@ const char* C4Game::FoldersWithLocalsDefs(const char *szPath)
static char szDefs[10*_MAX_PATH+1];
szDefs[0]=0;
// Get relative path
szPath = Config.AtRelativePath(szPath);
// Scan path for folder names
int32_t cnt,iBackslash;
char szFoldername[_MAX_PATH+1];

View File

@ -43,6 +43,7 @@
#include "StdFile.h"
#include "StdResStr2.h"
#include "C4Log.h"
#include "C4Reloc.h"
#include "C4PlayerControl.h"

View File

@ -35,18 +35,20 @@ void C4Extra::Default()
void C4Extra::Clear()
{
// free class members
ExtraSysGrp.Close();
ExtraUserGrp.Close();
for(unsigned int i = 0; i < ExtraGroups.size(); ++i)
delete ExtraGroups[i];
ExtraGroups.clear();
}
bool C4Extra::InitGroup()
{
// register extra root into game group set
if (ItemExists(Config.AtSystemDataPath(C4CFN_Extra)) && ExtraSysGrp.Open(Config.AtSystemDataPath(C4CFN_Extra)))
Game.GroupSet.RegisterGroup(ExtraSysGrp, false, C4GSPrio_ExtraRoot, C4GSCnt_ExtraRoot);
// Add user Extra.c4g
if (ItemExists(Config.AtUserDataPath(C4CFN_Extra)) && ExtraUserGrp.Open(Config.AtUserDataPath(C4CFN_Extra)))
Game.GroupSet.RegisterGroup(ExtraUserGrp, false, C4GSPrio_ExtraRoot, C4GSCnt_ExtraRoot);
for(C4Reloc::iterator iter = Reloc.begin(); iter != Reloc.end(); ++iter)
{
std::auto_ptr<C4Group> pGroup(new C4Group);
if(pGroup->Open( (*iter + DirSep + C4CFN_Extra).getData()))
ExtraGroups.push_back(pGroup.release());
}
// done, success
return true;
@ -55,15 +57,23 @@ bool C4Extra::InitGroup()
bool C4Extra::Init()
{
// no group: OK
if (!ExtraSysGrp.IsOpen() && !ExtraUserGrp.IsOpen()) return true;
if (ExtraGroups.empty()) return true;
// load from all definitions that are activated
// add first definition first, so the priority will be lowest
// (according to definition load/overload order)
char szSegment[_MAX_PATH+1];
bool fAnythingLoaded=false;
for (int cseg=0; SCopySegment(Game.DefinitionFilenames,cseg,szSegment,';',_MAX_PATH); cseg++)
if (LoadDef(ExtraUserGrp,GetFilename(szSegment)) || LoadDef(ExtraSysGrp,GetFilename(szSegment)))
fAnythingLoaded=true;
{
for(unsigned int i = 0; i < ExtraGroups.size(); ++i)
{
if(LoadDef(*ExtraGroups[i], GetFilename(szSegment)))
{
fAnythingLoaded=true;
break;
}
}
}
// done, success
return true;
}
@ -73,7 +83,7 @@ bool C4Extra::LoadDef(C4Group &hGroup, const char *szName)
// check if file exists
if (!hGroup.FindEntry(szName)) return false;
// log that extra group is loaded
LogF(LoadResStr("IDS_PRC_LOADEXTRA"), ExtraSysGrp.GetName(), szName);
LogF(LoadResStr("IDS_PRC_LOADEXTRA"), hGroup.GetName(), szName);
// open and add group to set
C4Group *pGrp = new C4Group;
if (!pGrp->OpenAsChild(&hGroup, szName)) { Log(LoadResStr("IDS_ERR_FAILURE")); delete pGrp; return false; }

View File

@ -33,8 +33,7 @@ public:
bool Init(); // init extra group, using scneario presets
bool InitGroup(); // open extra group
C4Group ExtraSysGrp; // extra.c4g root folder
C4Group ExtraUserGrp; // extra.c4g root folder
std::vector<C4Group*> ExtraGroups; // extra.c4g root folders
protected:
bool LoadDef(C4Group &hGroup, const char *szName); // load preset for definition

View File

@ -357,7 +357,7 @@ C4Group *C4GroupSet::RegisterParentFolders(const char *szScenFilename)
delete pGroup; return false;
}
}
else if (!pGroup->Open(szParentfolder+iPos))
else if (!Reloc.Open(*pGroup, szParentfolder+iPos))
{
LogFatal(FormatString("%s: %s", LoadResStr("IDS_PRC_FILENOTFOUND"), szParentfolder+iPos).getData());
delete pGroup; return false;

View File

@ -83,39 +83,58 @@ bool C4Language::Init()
}
}*/
// Make sure Language.c4g is unpacked
if (ItemExists(C4CFN_Languages))
if (!DirectoryExists(C4CFN_Languages))
C4Group_UnpackDirectory(C4CFN_Languages);
// Look for available language packs in Language.c4g
C4Group *pPack;
char strPackFilename[_MAX_FNAME + 1], strEntry[_MAX_FNAME + 1];
//Log("Registering languages...");
if (PackDirectory.Open(C4CFN_Languages))
while (PackDirectory.FindNextEntry("*.c4g", strEntry))
// Make sure Language.c4g is unpacked (TODO: This won't work properly if Language.c4g is in system data path)
// Assume for now that Language.c4g is either at a writable location or unpacked already.
// TODO: Use all Language.c4gs that we find, and merge them.
// TODO: Use gettext instead?
StdStrBuf langPath;
C4Reloc::iterator iter;
for(iter = Reloc.begin(); iter != Reloc.end(); ++iter)
{
langPath.Copy(*iter + DirSep + C4CFN_Languages);
if(ItemExists(langPath.getData()))
{
sprintf(strPackFilename, "%s" DirSep "%s", C4CFN_Languages, strEntry);
pPack = new C4Group();
if (pPack->Open(strPackFilename))
if(DirectoryExists(langPath.getData()))
break;
if(C4Group_UnpackDirectory(langPath.getData()))
break;
}
}
// Break if no language.c4g found
if(iter != Reloc.end())
{
// Look for available language packs in Language.c4g
C4Group *pPack;
char strPackFilename[_MAX_FNAME + 1], strEntry[_MAX_FNAME + 1];
//Log("Registering languages...");
if (PackDirectory.Open(langPath.getData()))
{
while (PackDirectory.FindNextEntry("*.c4g", strEntry))
{
//sprintf(strLog, " %s...", strPackFilename); Log(strLog);
Packs.RegisterGroup(*pPack, true, C4GSCnt_Language, false);
}
else
{
//sprintf(strLog, "Could not open language pack %s...", strPackFilename); Log(strLog);
delete pPack;
sprintf(strPackFilename, "%s" DirSep "%s", C4CFN_Languages, strEntry);
pPack = new C4Group();
if (pPack->Open(strPackFilename))
{
//sprintf(strLog, " %s...", strPackFilename); Log(strLog);
Packs.RegisterGroup(*pPack, true, C4GSCnt_Language, false);
}
else
{
//sprintf(strLog, "Could not open language pack %s...", strPackFilename); Log(strLog);
delete pPack;
}
}
}
// Log
//sprintf(strLog, "%d external language packs registered.", GetPackCount()); Log(strLog);
// Log
//sprintf(strLog, "%d external language packs registered.", GetPackCount()); Log(strLog);
// Now create a pack group for each language pack (these pack groups are child groups
// that browse along each pack to access requested data)
for (int iPack = 0; (pPack = Packs.GetGroup(iPack)); iPack++)
PackGroups.RegisterGroup(*(new C4Group), true, C4GSPrio_Base, C4GSCnt_Language);
// Now create a pack group for each language pack (these pack groups are child groups
// that browse along each pack to access requested data)
for (int iPack = 0; (pPack = Packs.GetGroup(iPack)); iPack++)
PackGroups.RegisterGroup(*(new C4Group), true, C4GSPrio_Base, C4GSCnt_Language);
}
// Load language infos by scanning string tables (the engine doesn't really need this at the moment)
InitInfos();
@ -339,7 +358,7 @@ void C4Language::InitInfos()
{
C4Group hGroup;
// First, look in System.c4g
if (hGroup.Open(C4CFN_System))
if (Reloc.Open(hGroup, C4CFN_System))
{
LoadInfos(hGroup);
hGroup.Close();
@ -436,7 +455,7 @@ bool C4Language::InitStringTable(const char *strCode)
{
C4Group hGroup;
// First, look in System.c4g
if (hGroup.Open(C4CFN_System))
if (Reloc.Open(hGroup, C4CFN_System))
{
if (LoadStringTable(hGroup, strCode))
{ hGroup.Close(); return true; }

View File

@ -479,8 +479,14 @@ void C4ConfigGeneral::DeterminePaths(bool forceWorkingDirectory)
SCopy(GetWorkingDirectory(),SystemDataPath);
AppendBackslash(SystemDataPath);
#elif defined(__linux__)
// FIXME: Where to put this?
SCopy(ExePath,SystemDataPath);
#ifdef OC_SYSTEM_DATA_DIR
SCopy(OC_SYSTEM_DATA_DIR, SystemDataPath);
AppendBackslash(SystemDataPath);
#else
#error Please define OC_SYSTEM_DATA_DIR!
//SCopy(ExePath,SystemDataPath);
#endif
#endif
// Find user-specific data path
@ -540,21 +546,7 @@ void C4ConfigGeneral::AdoptOldSettings()
}
}
void C4ConfigGeneral::ClearAdditionalDataPaths()
{
for (PathList::iterator it = AdditionalDataPaths.begin(); it != AdditionalDataPaths.end(); ++it)
delete[] *it;
AdditionalDataPaths.clear();
}
void C4ConfigGeneral::AddAdditionalDataPath(const char *szPath)
{
char *clone = new char[SLen(szPath)+1];
SCopy(szPath,clone);
AdditionalDataPaths.push_back(clone);
}
char AtPathFilename[_MAX_PATH+1];
static char AtPathFilename[_MAX_PATH+1];
const char* C4Config::AtExePath(const char *szFilename)
{
@ -660,54 +652,6 @@ void C4ConfigControls::ResetKeys()
StdCompilerNull Comp; Comp.Compile(mkParAdapt(*this, true));
}
const char* C4Config::AtDataReadPath(const char *szFilename, bool fPreferWorkdir)
{
if (IsGlobalPath(szFilename)) return szFilename;
StdCopyStrBuf sfn(szFilename);
do
{
const char *path = AtDataReadPathCore(sfn.getData(), fPreferWorkdir);
if (path)
{
if (path != AtPathFilename) SCopy(path,AtPathFilename);
AtPathFilename[_MAX_PATH] = '\0';
AppendBackslash(AtPathFilename);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
return AtPathFilename;
}
}
while (TruncatePath(sfn.getMData()));
return szFilename;
}
const char* C4Config::AtDataReadPathCore(const char *szFilename, bool fPreferWorkdir)
{
if (fPreferWorkdir && FileExists(szFilename))
{
SCopy(GetWorkingDirectory(),AtPathFilename,_MAX_PATH-1);
return AtPathFilename;
}
// Check extra data paths
for (C4ConfigGeneral::PathList::iterator it = General.AdditionalDataPaths.begin();
it != General.AdditionalDataPaths.end();
++it)
{
SCopy(*it, AtPathFilename, _MAX_PATH-1);
AppendBackslash(AtPathFilename);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
if (FileExists(AtPathFilename))
return *it;
}
if (FileExists(AtUserDataPath(szFilename))) return General.UserDataPath;
if (FileExists(AtSystemDataPath(szFilename))) return General.SystemDataPath;
if (!fPreferWorkdir && FileExists(szFilename))
{
SCopy(GetWorkingDirectory(),AtPathFilename,_MAX_PATH-1);
return AtPathFilename;
}
return NULL;
}
const char* C4Config::AtUserDataRelativePath(const char *szFilename)
{
// Specified file is located in UserDataPath: return relative path

View File

@ -68,9 +68,6 @@ public:
bool FirstStart;
bool UserPortraitsWritten; // set when default portraits have been copied to the UserPath (this is only done once)
// Additional paths to read data from (prioritized lower than UserDataPath/SystemDataPath)
typedef std::list<const char *> PathList;
PathList AdditionalDataPaths;
public:
static int GetLanguageSequence(const char *strSource, char *strTarget);
void DefaultLanguage();
@ -78,9 +75,6 @@ public:
void AdoptOldSettings();
void DeterminePaths(bool forceWorkingDirectory);
void CompileFunc(StdCompiler *pComp);
void AddAdditionalDataPath(const char *szPath);
void ClearAdditionalDataPaths();
~C4ConfigGeneral() { ClearAdditionalDataPaths(); }
private:
struct
@ -292,7 +286,6 @@ public:
const char *AtSystemDataPath(const char *szFilename);
const char *AtSystemDataRelativePath(const char *szFilename);
const char *AtRelativePath(const char *szFilename); // Returns ASDRP or AUDRP depending on location
const char *AtDataReadPath(const char *szFilename, bool fPreferWorkdir = false);
const char *GetRegistrationData(const char* strField) { return ""; }
void ForceRelativePath(StdStrBuf *sFilename); // try AtRelativePath; force GetC4Filename if not possible
void CompileFunc(StdCompiler *pComp);
@ -303,8 +296,6 @@ public:
void GetConfigFileName(StdStrBuf &filename, bool forceWorkingDirectory, const char *szConfigFile);
static void ExpandEnvironmentVariables(char *strPath, size_t iMaxLen);
private:
const char *AtDataReadPathCore(const char *szFilename, bool fPreferWorkdir = false);
};
#include <C4ConfigShareware.h>

View File

@ -0,0 +1,86 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2011 Armin Burgmeier
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
#include <C4Include.h>
#include <C4Reloc.h>
C4Reloc Reloc; // singleton
void C4Reloc::Init()
{
Paths.clear();
// TODO: On Linux, we might not always want to have ExePath (= working directory)
// here. It's handy for development so that we can easily run the engine in planet/
// but for distribution it might make sense to disable it.
// TODO: We might also want to add ExePath/planet if it exists, so that we don't
// need to run the engine in planet/.
AddPath(Config.General.ExePath);
AddPath(Config.General.UserDataPath);
AddPath(Config.General.SystemDataPath);
}
bool C4Reloc::AddPath(const char* path)
{
if(!IsGlobalPath(path))
return false;
if(std::find(Paths.begin(), Paths.end(), path) != Paths.end())
return false;
Paths.push_back(StdCopyStrBuf(path));
return true;
}
C4Reloc::iterator C4Reloc::begin() const
{
return Paths.begin();
}
C4Reloc::iterator C4Reloc::end() const
{
return Paths.end();
}
bool C4Reloc::Open(C4Group& hGroup, const char* filename) const
{
if(IsGlobalPath(filename)) return hGroup.Open(filename);
for(iterator iter = begin(); iter != end(); ++iter)
if(hGroup.Open((*iter + DirSep + filename).getData()))
return true;
return false;
}
bool C4Reloc::LocateItem(const char* filename, StdStrBuf& str) const
{
if(IsGlobalPath(filename))
{
str.Copy(filename);
return true;
}
for(iterator iter = begin(); iter != end(); ++iter)
{
str.Copy(*iter + DirSep + filename);
if(ItemExists(str.getData()))
return true;
}
return false;
}

View File

@ -0,0 +1,46 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2011 Armin Burgmeier
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
#ifndef C4RELOC_H
#define C4RELOC_H
#include <vector>
class C4Reloc
{
public:
typedef std::vector<StdCopyStrBuf> PathList;
typedef PathList::const_iterator iterator;
// Can also be used for re-init, drops custom paths added with AddPath.
// Make sure to call after Config.Load.
void Init();
bool AddPath(const char* path);
iterator begin() const;
iterator end() const;
bool Open(C4Group& hGroup, const char* filename) const;
bool LocateItem(const char* filename, StdStrBuf& str) const;
private:
C4Reloc::PathList Paths;
};
extern C4Reloc Reloc;
#endif // C4RELOC_H

View File

@ -667,35 +667,40 @@ C4ControlJoinPlayer::C4ControlJoinPlayer(const char *szFilename, int32_t iAtClie
idInfo(iIDInfo), fByRes(false)
{
// load from file if filename is given - which may not be the case for script players
if (szFilename)
StdStrBuf filename;
if (szFilename && Reloc.LocateItem(szFilename, filename))
{
StdStrBuf filename_buf;
const char *filename = Config.AtDataReadPath(szFilename);
bool file_is_temp = false;
if (DirectoryExists(filename))
if (DirectoryExists(filename.getData()))
{
// the player file is unpacked - temp pack and read
filename_buf.Copy(Config.AtTempPath(GetFilenameOnly(filename)));
StdStrBuf filename_buf;
filename_buf.Copy(Config.AtTempPath(GetFilenameOnly(filename.getData())));
MakeTempFilename(&filename_buf);
if (C4Group_PackDirectoryTo(filename, filename_buf.getData()))
if (C4Group_PackDirectoryTo(filename.getData(), filename_buf.getData()))
{
filename = filename_buf.getData();
filename = filename_buf;
file_is_temp = true;
}
else
{
// pack failed
LogF("[!]Error packing player file %s to %s for join: Pack failed.", filename, filename_buf.getData());
LogF("[!]Error packing player file %s to %s for join: Pack failed.", filename.getData(), filename_buf.getData());
assert(false);
}
}
bool fSuccess = PlrData.LoadFromFile(filename);
bool fSuccess = PlrData.LoadFromFile(filename.getData());
if (!fSuccess)
{
LogF("[!]Error loading player file from %s.", filename.getData());
assert(false);
LogF("[!]Error loading player file from %s.", filename);
}
if (file_is_temp) EraseFile(filename);
if (file_is_temp) EraseFile(filename.getData());
}
else
{
LogF("[!]Error loading player file from %s.", szFilename ? szFilename : "(null)");
assert(false);
}
}

View File

@ -77,11 +77,9 @@ bool C4PlayerInfo::LoadFromLocalFile(const char *szFilename)
assert(!Game.C4S.Head.Replay);
// clear previous
Clear();
// find (possibly overridden) filename
szFilename = Config.AtDataReadPath(szFilename);
// open player file group
C4Group Grp;
if (!Grp.Open(szFilename)) return false;
if (!Reloc.Open(Grp, szFilename)) return false;
// read core
C4PlayerInfoCore C4P;

View File

@ -821,7 +821,7 @@ int32_t C4DefList::Load(const char *szSearch,
// Load from specified file
C4Group hGroup;
if (!hGroup.Open(Config.AtDataReadPath(szSearch)))
if (!Reloc.Open(hGroup, szSearch))
{
// Specified file not found (failure)
LogFatal(FormatString(LoadResStr("IDS_PRC_DEFNOTFOUND"),szSearch).getData());

View File

@ -238,10 +238,6 @@ bool C4Player::Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientNa
}
// Status init
Status=PS_Normal;
if (szFilename)
SCopy(Config.AtDataReadPath(szFilename),Filename);
else
*Filename='\0';
Number = iNumber;
ID = pInfo->GetID();
Team = pInfo->GetTeam();
@ -250,14 +246,14 @@ bool C4Player::Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientNa
// At client
AtClient=iAtClient; SCopy(szAtClientName,AtClientName,C4MaxTitle);
if (Filename)
if (szFilename)
{
// Load core & crew info list
// do not load portraits for remote players
// this will prevent portraits from being shown for "remotely controlled"-Clonks of other players
bool fLoadPortraits = (AtClient==C4ClientIDUnknown) || SEqualNoCase(AtClientName, Game.Clients.getLocalName());
// fLoadPortraits = true
if (!Load(Filename, !fScenarioInit, fLoadPortraits)) return false;
if (!Load(szFilename, !fScenarioInit, fLoadPortraits)) return false;
}
else
{
@ -984,7 +980,7 @@ bool C4Player::Load(const char *szFilename, bool fSavegame, bool fLoadPortraits)
{
C4Group hGroup;
// Open group
if (!hGroup.Open(szFilename)) return false;
if (!Reloc.Open(hGroup, szFilename)) return false;
// Load core
if (!C4PlayerInfoCore::Load(hGroup))
{ hGroup.Close(); return false; }

View File

@ -569,10 +569,10 @@ C4PortraitSelDlg::C4PortraitSelDlg(C4FileSel_BaseCB *pSelCallback, bool fSetPict
char path[_MAX_PATH+1];
// add common picture locations
StdStrBuf strLocation;
SCopy(Config.AtUserDataPath(""), path, _MAX_PATH); TruncateBackslash(path);
SCopy(Config.General.UserDataPath, path, _MAX_PATH); TruncateBackslash(path);
strLocation.Format("%s %s", C4ENGINECAPTION, LoadResStr("IDS_TEXT_USERPATH"));
AddLocation(strLocation.getData(), path);
SCopy(Config.AtSystemDataPath(""), path, _MAX_PATH); TruncateBackslash(path);
SCopy(Config.General.SystemDataPath, path, _MAX_PATH); TruncateBackslash(path);
strLocation.Format("%s %s", C4ENGINECAPTION, LoadResStr("IDS_TEXT_PROGRAMDIRECTORY"));
AddCheckedLocation(strLocation.getData(), Config.General.ExePath);
#ifdef _WIN32
@ -653,7 +653,7 @@ bool C4PortraitSelDlg::SelectPortrait(C4GUI::Screen *pOnScreen, StdStrBuf *pSele
{
Log("Copying default portraits to user path...");
C4Group hGroup;
if (hGroup.Open(Config.AtSystemDataPath(C4CFN_Graphics)))
if (Reloc.Open(hGroup, C4CFN_Graphics))
{
hGroup.Extract("Portrait1.png", Config.AtUserDataPath("Clonk.png"));
hGroup.Close();

View File

@ -73,7 +73,7 @@ bool C4LoaderScreen::Init(const char *szLoaderSpec)
{
// open it
GfxGrp.Close();
if (!GfxGrp.Open(Config.AtSystemDataPath(C4CFN_Graphics)))
if (!Reloc.Open(GfxGrp, C4CFN_Graphics))
{
LogFatal(FormatString(LoadResStr("IDS_PRC_NOGFXFILE"),C4CFN_Graphics,GfxGrp.GetError()).getData());
return false;

View File

@ -73,7 +73,7 @@ static bool GetPortrait(char **ppBytes, size_t *ipSize)
C4Group GfxGroup;
int iCount;
StdStrBuf EntryName;
if (!GfxGroup.Open(Config.AtSystemDataPath(C4CFN_Graphics))) return false;
if (!Reloc.Open(GfxGroup, C4CFN_Graphics)) return false;
if ((iCount = GfxGroup.EntryCount("Portrait*.png")) < 1) return false;
EntryName.Format("Portrait%d.png", SafeRandom(iCount) + 1);
if (!GfxGroup.LoadEntry(EntryName.getData(), ppBytes, ipSize)) return false;
@ -1245,7 +1245,7 @@ C4StartupPlrPropertiesDlg::C4StartupPlrPropertiesDlg(C4StartupPlrSelDlg::PlayerL
// Set initial portrait and bigicon
C4Group hGroup;
StdStrBuf strPortrait; strPortrait.Format("Portrait%d.png", 1 + Random(5));
if (hGroup.Open(Config.AtSystemDataPath(C4CFN_Graphics)))
if (Reloc.Open(hGroup, C4CFN_Graphics))
{
hGroup.Extract(strPortrait.getData(), Config.AtTempPath("Portrait.png"));
hGroup.Close();

View File

@ -1044,7 +1044,7 @@ bool C4ScenarioListLoader::RegularFolder::DoLoadContents(C4ScenarioListLoader *p
ClearChildren();
// regular folders must exist and not be within group!
assert(!pFromGrp);
if (sFilename[0])
if (sFilename.getData() && sFilename[0])
Merge(sFilename.getData());
// get number of entries, to estimate progress
@ -1167,7 +1167,10 @@ bool C4ScenarioListLoader::Load(const StdStrBuf &sRootFolder)
if (!BeginActivity(true)) return false;
if (pRootFolder) { delete pRootFolder; pRootFolder = NULL; }
pCurrFolder = pRootFolder = new RegularFolder(NULL);
pRootFolder->Merge(Config.General.UserDataPath);
// Load regular game data if no explicit path specified
if(!sRootFolder.getData())
for(C4Reloc::iterator iter = Reloc.begin(); iter != Reloc.end(); ++iter)
pRootFolder->Merge(iter->getData());
bool fSuccess = pRootFolder->LoadContents(this, NULL, &sRootFolder, false, false);
EndActivity();
return fSuccess;
@ -1438,7 +1441,7 @@ void C4StartupScenSelDlg::OnShown()
// init file list
fIsInitialLoading = true;
if (!pScenLoader) pScenLoader = new C4ScenarioListLoader();
pScenLoader->Load(StdStrBuf(Config.General.ExePath));
pScenLoader->Load(StdStrBuf()); //Config.General.ExePath));
UpdateList();
UpdateSelection();
fIsInitialLoading = false;

View File

@ -318,7 +318,7 @@ bool C4GraphicsResource::RegisterGlobalGraphics()
// The cleanest alternative would be to reinit all the fonts whenever a scenario is reloaded
// FIXME: Test whether vector fonts from a scenario are correctly reloaded
C4Group *pMainGfxGrp = new C4Group();
if (!pMainGfxGrp->Open(C4CFN_Graphics) || !Files.RegisterGroup(*pMainGfxGrp, true, C4GSPrio_Base, C4GSCnt_Graphics, 1))
if (!Reloc.Open(*pMainGfxGrp, C4CFN_Graphics) || !Files.RegisterGroup(*pMainGfxGrp, true, C4GSPrio_Base, C4GSCnt_Graphics, 1))
{
// error
LogFatal(FormatString(LoadResStr("IDS_PRC_NOGFXFILE"),C4CFN_Graphics,pMainGfxGrp->GetError()).getData());

View File

@ -386,20 +386,21 @@ bool C4Network2Res::SetByFile(const char *strFilePath, bool fTemp, C4Network2Res
SCopy(strFilePath, szFile, sizeof(szFile)-1);
// group?
C4Group Grp;
if (Grp.Open(strFilePath))
if (Reloc.Open(Grp, strFilePath))
return SetByGroup(&Grp, fTemp, eType, iResID, szResName, fSilent);
// so it needs to be a file
if (!FileExists(szFile))
StdStrBuf szFullFile;
if (!Reloc.LocateItem(szFile, szFullFile))
{ if (!fSilent) LogF("SetByFile: file %s not found!", strFilePath); return false; }
// calc checksum
uint32_t iCRC32;
if (!C4Group_GetFileCRC(szFile, &iCRC32)) return false;
if (!C4Group_GetFileCRC(szFullFile.getData(), &iCRC32)) return false;
#ifdef C4NET2RES_DEBUG_LOG
// log
LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, szResName, szFile, fTemp ? "temp" : "static");
#endif
// set core
Core.Set(eType, iResID, szResName, iCRC32);
Core.Set(eType, iResID, Config.AtRelativePath(szFullFile.getData()), iCRC32);
// set own data
fDirty = true;
fTempFile = fTemp;

View File

@ -447,7 +447,7 @@ bool C4SoundSystem::Init()
ClearEffects();
// Open sound file
if (!SoundFile.IsOpen())
if (!SoundFile.Open(Config.AtSystemDataPath(C4CFN_Sound))) return false;
if (!Reloc.Open(SoundFile, C4CFN_Sound)) return false;
#ifdef HAVE_LIBSDL_MIXER
Mix_AllocateChannels(C4MaxSoundInstances);
#endif