1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- removed multiple unused files

- config folder with all json files is used via new FS API
- fixed campaigns loading. Replaced "detect h3m starts" heuristics with CCompessedStream::getNextBlock()
This commit is contained in:
Ivan Savenko 2012-08-02 11:03:26 +00:00
parent b3c17d2788
commit e67f8afdd9
60 changed files with 211 additions and 1397 deletions

View File

@ -3,6 +3,7 @@
#include "../CCallback.h"
#include "../lib/JsonNode.h"
#include "../lib/Filesystem/CResourceLoader.h"
#include "../lib/map.h"
#include "../lib/CObjectHandler.h"
#include "../lib/CGameState.h"
@ -479,7 +480,7 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
{
std::map<int, std::pair<SDL_Color, SDL_Color> > ret;
const JsonNode config(GameConstants::DATA_DIR + from);
const JsonNode config(ResourceID(from, EResType::TEXT));
BOOST_FOREACH(const JsonNode &m, config["MinimapColors"].Vector())
{
@ -513,7 +514,7 @@ CMinimap::CMinimap(const Rect &position):
aiShield(nullptr),
minimap(nullptr),
level(0),
colors(loadColors("/config/minimap.json"))
colors(loadColors("config/minimap.json"))
{
pos.w = position.w;
pos.h = position.h;

View File

@ -2,7 +2,6 @@
#include "CBattleInterface.h"
#include "../CGameInfo.h"
#include "../../lib/CLodHandler.h"
#include "../UIFramework/SDL_Extensions.h"
#include "../CAdvmapInterface.h"
#include "../CAnimation.h"

View File

@ -2,7 +2,6 @@
#include "CCreatureAnimation.h"
#include "../../lib/Filesystem/CResourceLoader.h"
#include "../../lib/CLodHandler.h"
#include "../../lib/VCMI_Lib.h"
#include "../../lib/vcmi_endian.h"
#include "../UIFramework/SDL_Extensions.h"

View File

@ -2,7 +2,6 @@
#include <SDL_image.h>
#include "../lib/Filesystem/CResourceLoader.h"
#include "../lib/CLodHandler.h"
#include "../lib/JsonNode.h"
#include "../lib/vcmi_endian.h"
@ -935,13 +934,9 @@ void CAnimation::init(CDefFile * file)
source[mapIt->first].resize(mapIt->second);
}
ResourceID identifier(std::string("SPRITES/") + name, EResType::TEXT);
if (CResourceHandler::get()->existsResource(identifier))
if (CResourceHandler::get()->existsResource(ResourceID(std::string("SPRITES/") + name, EResType::TEXT)))
{
auto configFile = CResourceHandler::get()->loadData(identifier);
const JsonNode config((char*)configFile.first.get(), configFile.second);
const JsonNode config(ResourceID(std::string("SPRITES/") + name, EResType::TEXT));
std::string basepath;
basepath = config["basepath"].String();

View File

@ -7,7 +7,6 @@
#include "CBitmapHandler.h"
#include "CDefHandler.h"
#include "UIFramework/SDL_Extensions.h"
#include "../lib/CLodHandler.h"
#include "../lib/vcmi_endian.h"
/*

View File

@ -1,6 +1,7 @@
#include "StdInc.h"
#include "CConfigHandler.h"
#include "../lib/Filesystem/CResourceLoader.h"
#include "../lib/GameConstants.h"
#include "../lib/VCMIDirs.h"
@ -56,8 +57,8 @@ SettingsStorage::SettingsStorage():
void SettingsStorage::init()
{
JsonNode(GVCMIDirs.UserPath + "/config/settings.json").swap(config);
JsonNode schema(GameConstants::DATA_DIR + "/config/defaultSettings.json");
JsonNode(ResourceID("config/settings.json")).swap(config);
JsonNode schema(ResourceID("config/defaultSettings.json"));
config.validate(schema);
}
@ -67,7 +68,7 @@ void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath
listener->nodeInvalidated(changedPath);
JsonNode savedConf = config;
JsonNode schema(GameConstants::DATA_DIR + "/config/defaultSettings.json");
JsonNode schema(ResourceID("config/defaultSettings.json"));
savedConf.Struct().erase("session");
savedConf.minimize(schema);
@ -194,7 +195,7 @@ CConfigHandler::~CConfigHandler(void)
void config::CConfigHandler::init()
{
/* Read resolutions. */
const JsonNode config(GameConstants::DATA_DIR + "/config/resolutions.json");
const JsonNode config(ResourceID("config/resolutions.json"));
const JsonVector &guisettings_vec = config["GUISettings"].Vector();
BOOST_FOREACH(const JsonNode &g, guisettings_vec)

View File

@ -3,7 +3,6 @@
#include "CDefHandler.h"
#include "../lib/Filesystem/CResourceLoader.h"
#include "../lib/CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "../lib/vcmi_endian.h"
#include "CBitmapHandler.h"

View File

@ -20,7 +20,6 @@
#include "CDefHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CHeroHandler.h"
#include "../lib/CLodHandler.h"
#include "../lib/CObjectHandler.h"
#include "../lib/NetPacks.h"

View File

@ -23,7 +23,6 @@
#include "../lib/CSpellHandler.h"
#include "CMusicHandler.h"
#include "CVideoHandler.h"
#include "../lib/CLodHandler.h"
#include "CDefHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "Graphics.h"
@ -232,6 +231,8 @@ int main(int argc, char** argv)
atexit(dispose);
tlog0 <<"Creating console and logfile: "<<pomtime.getDiff() << std::endl;
LibClasses::loadFilesystem();
settings.init();
conf.init();
tlog0 <<"Loading settings: "<<pomtime.getDiff() << std::endl;
@ -484,7 +485,7 @@ void processCommand(const std::string &message)
return ident.getType() == EResType::TEXT && boost::algorithm::starts_with(ident.getName(), "DATA/");
});
std::string basePath = CResourceHandler::get()->getResourceName(std::string("DATA")) + "/Extracted_txts/";
std::string basePath = CResourceHandler::get()->getResourceName(ResourceID("DATA")) + "/Extracted_txts/";
while (iterator.hasNext())
{
std::ofstream file(basePath + iterator->getName() + ".TXT");

View File

@ -6,7 +6,6 @@
#include "CAnimation.h"
#include "CGameInfo.h"
#include "UIFramework/SDL_Extensions.h"
#include "../lib/CLodHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "Graphics.h"
#include "GUIClasses.h"

View File

@ -9,6 +9,7 @@
#include "../client/CGameInfo.h"
#include "../lib/JsonNode.h"
#include "../lib/GameConstants.h"
#include "../lib/Filesystem/CResourceLoader.h"
/*
* CMusicHandler.cpp, part of VCMI engine
@ -174,7 +175,7 @@ soundBase::soundID CSoundHandler::getSoundID(const std::string &fileName)
void CSoundHandler::initCreaturesSounds(const std::vector<ConstTransitivePtr< CCreature> > &creatures)
{
tlog5 << "\t\tReading config/cr_sounds.json" << std::endl;
const JsonNode config(GameConstants::DATA_DIR + "/config/cr_sounds.json");
const JsonNode config(ResourceID("config/cr_sounds.json"));
CBattleSounds.resize(creatures.size());
@ -232,7 +233,7 @@ void CSoundHandler::initCreaturesSounds(const std::vector<ConstTransitivePtr< CC
void CSoundHandler::initSpellsSounds(const std::vector< ConstTransitivePtr<CSpell> > &spells)
{
const JsonNode config(GameConstants::DATA_DIR + "/config/sp_sounds.json");
const JsonNode config(ResourceID("config/sp_sounds.json"));
if (!config["spell_sounds"].isNull()) {
BOOST_FOREACH(const JsonNode &node, config["spell_sounds"].Vector()) {

View File

@ -21,7 +21,6 @@
#include "../lib/CArtHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CHeroHandler.h"
#include "../lib/CLodHandler.h"
#include "../lib/CObjectHandler.h"
#include "../lib/Connection.h"
#include "../lib/CSpellHandler.h"

View File

@ -13,7 +13,6 @@
#include "CDefHandler.h"
#include "../lib/CDefObjInfoHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CLodHandler.h"
#include "../lib/CTownHandler.h"
#include "../lib/CHeroHandler.h"
#include "../lib/CObjectHandler.h"
@ -39,7 +38,6 @@
#include "../lib/RegisterTypes.h"
#include "../lib/CThreadHelper.h"
#include "CConfigHandler.h"
#include "../lib/CFileUtility.h"
#include "../lib/GameConstants.h"
#include "UIFramework/CGuiHandler.h"
#include "UIFramework/CIntObjectClasses.h"
@ -436,7 +434,7 @@ void CreditsScreen::clickRight(tribool down, bool previousState)
}
CGPreGame::CGPreGame():
pregameConfig(new JsonNode(GameConstants::DATA_DIR + "/config/mainmenu.json"))
pregameConfig(new JsonNode(ResourceID("config/mainmenu.json")))
{
pos.w = screen->w;
pos.h = screen->h;
@ -1052,8 +1050,7 @@ void SelectionTab::parseMaps(const std::vector<ResourceID> &files, int start, in
while(start < allItems.size())
{
auto compressed = CResourceHandler::get()->load(files[start]);
CCompressedStream stream(compressed, true);
CCompressedStream stream(std::move(CResourceHandler::get()->load(files[start])), true);
int read = stream.read(mapBuffer, 1500);
if(read < 50 || !mapBuffer[4])
@ -2891,7 +2888,7 @@ void CBonusSelection::showAll(SDL_Surface * to)
void CBonusSelection::loadPositionsOfGraphics()
{
const JsonNode config(GameConstants::DATA_DIR + "/config/campaign_regions.json");
const JsonNode config(ResourceID("config/campaign_regions.json"));
int idx = 0;
BOOST_FOREACH(const JsonNode &campaign, config["campaign_regions"].Vector())
@ -2929,7 +2926,7 @@ void CBonusSelection::selectMap( int whichOne )
int i = 0;
delete ourHeader;
ourHeader = new CMapHeader();
ourHeader->initFromMemory((const unsigned char*)ourCampaign->camp->mapPieces.find(whichOne)->second.c_str(), i);
ourHeader->initFromMemory((const unsigned char*)ourCampaign->camp->mapPieces.find(whichOne)->second.data(), i);
std::map<ui32, std::string> names;
names[1] = settings["general"]["playerName"].String();
@ -3563,9 +3560,6 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode &config )
void CCampaignScreen::CCampaignButton::clickLeft(tribool down, bool previousState)
{
// Campaign screen is broken. Disabled for now
return;
if (down)
{
// Close running video and open the selected campaign

View File

@ -29,7 +29,6 @@ class CConnection;
class JsonNode;
struct CPackForSelectionScreen;
struct PlayerInfo;
struct FileInfo;
namespace boost{ class thread; class recursive_mutex;}

View File

@ -31,7 +31,6 @@
#include "BattleInterface/CBattleInterface.h"
#include "../lib/CThreadHelper.h"
#include "../lib/CScriptingModule.h"
#include "../lib/CFileUtility.h"
#include "../lib/RegisterTypes.h"
#include "UIFramework/CGuiHandler.h"

View File

@ -22,7 +22,6 @@
#include "../lib/CBuildingHandler.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CHeroHandler.h"
#include "../lib/CLodHandler.h"
#include "../lib/CObjectHandler.h"
#include "../lib/CSpellHandler.h"
#include "../lib/CTownHandler.h"

View File

@ -7,7 +7,6 @@
#include <SDL_ttf.h>
#include "../lib/CThreadHelper.h"
#include "CGameInfo.h"
#include "../lib/CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "../CCallback.h"
#include "../lib/CTownHandler.h"
@ -88,7 +87,7 @@ void Graphics::loadPaletteAndColors()
playerColors[i].unused = 255;
}
neutralColor->r = 0x84; neutralColor->g = 0x84; neutralColor->b = 0x84; neutralColor->unused = 255;//gray
const JsonNode config(GameConstants::DATA_DIR + "/config/town_pictures.json");
const JsonNode config(ResourceID("config/town_pictures.json"));
BOOST_FOREACH(const JsonNode &p, config["town_pictures"].Vector()) {
townBgs.push_back(p["town_background"].String());
@ -99,7 +98,7 @@ void Graphics::loadPaletteAndColors()
void Graphics::initializeBattleGraphics()
{
const JsonNode config(GameConstants::DATA_DIR + "/config/battles_graphics.json");
const JsonNode config(ResourceID("config/battles_graphics.json"));
// Reserve enough space for the terrains
int idx = config["backgrounds"].Vector().size();
@ -159,7 +158,7 @@ Graphics::Graphics()
tasks += GET_DEF_ESS(spellscr,"SPELLSCR.DEF");
tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF");
const JsonNode config(GameConstants::DATA_DIR + "/config/creature_backgrounds.json");
const JsonNode config(ResourceID("config/creature_backgrounds.json"));
BOOST_FOREACH(const JsonNode &b, config["backgrounds"].Vector()) {
const int id = b["id"].Float();
tasks += GET_SURFACE(backgrounds[id], b["bg130"].String());
@ -193,7 +192,7 @@ Graphics::Graphics()
}
void Graphics::loadHeroPortraits()
{
const JsonNode config(GameConstants::DATA_DIR + "/config/portraits.json");
const JsonNode config(ResourceID("config/portraits.json"));
BOOST_FOREACH(const JsonNode &portrait_node, config["hero_portrait"].Vector()) {
std::string filename = portrait_node["filename"].String();
@ -219,7 +218,7 @@ void Graphics::loadHeroPortraits()
void Graphics::loadWallPositions()
{
const JsonNode config(GameConstants::DATA_DIR + "/config/wall_pos.json");
const JsonNode config(ResourceID("config/wall_pos.json"));
BOOST_FOREACH(const JsonNode &town, config["towns"].Vector()) {
int townID = town["id"].Float();
@ -487,36 +486,8 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
void Graphics::loadTrueType()
{
bool ttfPresent = false;//was TTF initialised or not
for(int i = 0; i < FONTS_NUMBER; i++)
fontsTrueType[i] = NULL;
std::string fontsFile = GameConstants::DATA_DIR + "/config/fonts.txt";
std::ifstream ff(fontsFile.c_str());
while(!ff.eof())
{
int enabl, fntID, fntSize;
std::string fntName;
ff >> enabl;//enabled font or not
if (enabl==-1)
break;//end of data
ff >> fntID;//what font will be replaced
ff >> fntName;//name of truetype font
ff >> fntSize;//size of font
if (enabl)
{
if (!ttfPresent)
{
ttfPresent = true;
TTF_Init();
atexit(TTF_Quit);
};
fntName = GameConstants::DATA_DIR + ( "/Fonts/" + fntName);
fontsTrueType[fntID] = TTF_OpenFont(fntName.c_str(),fntSize);
}
}
ff.close();
ff.clear();
}
Font * Graphics::loadFont( const char * name )
@ -560,7 +531,7 @@ CDefEssential * Graphics::getDef( const CGDefInfo * info )
void Graphics::loadErmuToPicture()
{
//loading ERMU to picture
const JsonNode config(GameConstants::DATA_DIR + "/config/ERMU_to_picture.json");
const JsonNode config(ResourceID("config/ERMU_to_picture.json"));
int etp_idx = 0;
BOOST_FOREACH(const JsonNode &etp, config["ERMU_to_picture"].Vector()) {
int idx = 0;

View File

@ -1,31 +0,0 @@
#include "StdInc.h"
#include "SDL_framerate.h"
#include <SDL.h>
FPSManager::FPSManager(int rate)
{
this->rate = rate;
this->rateticks = (1000.0 / (double) rate);
this->fps = 0;
}
void FPSManager::init()
{
this->lastticks = SDL_GetTicks();
}
void FPSManager::framerateDelay()
{
Uint32 currentTicks = SDL_GetTicks();
double diff = currentTicks - this->lastticks;
if (diff < this->rateticks) // FPS is higher than it should be, then wait some time
{
SDL_Delay(ceil(this->rateticks) - diff);
}
this->fps = ceil(1000. / (SDL_GetTicks() - this->lastticks));
this->lastticks = SDL_GetTicks();
}

View File

@ -1,28 +0,0 @@
#pragma once
/*
* SDL_framerate.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// A fps manager which holds game updates at a constant rate
class FPSManager
{
private:
double rateticks;
ui32 lastticks;
int rate;
public:
int fps; // the actual fps value
FPSManager(int rate); // initializes the manager with a given fps rate
void init(); // needs to be called directly before the main game loop to reset the internal timer
void framerateDelay(); // needs to be called every game update cycle
};

View File

@ -3,7 +3,6 @@
#include "UIFramework/SDL_Extensions.h"
#include "CGameInfo.h"
#include "../lib/CLodHandler.h"
#include "../lib/CDefObjInfoHandler.h"
#include "../lib/CGameState.h"
#include "../lib/CHeroHandler.h"

View File

@ -10,7 +10,8 @@
#include "CSpellHandler.h"
#include "CTownHandler.h"
#include "NetPacks.h"
#include "../lib/JsonNode.h"
#include "JsonNode.h"
#include "Filesystem/CResourceLoader.h"
/*
@ -1766,7 +1767,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
//TODO: parse once to some structure
std::vector< std::vector<int> > attackerLoose, defenderLoose, attackerTight, defenderTight, attackerCreBank, defenderCreBank;
std::vector <int> commanderField, commanderBank;
const JsonNode config(GameConstants::DATA_DIR + "/config/battleStartpos.json");
const JsonNode config(ResourceID("config/battleStartpos.json"));
const JsonVector &positions = config["battle_positions"].Vector();
CGH::readBattlePositions(positions[0]["levels"], attackerLoose);

View File

@ -2,7 +2,6 @@
#include "CArtHandler.h"
#include "Filesystem/CResourceLoader.h"
#include "CLodHandler.h"
#include "CGeneralTextHandler.h"
#include <boost/random/linear_congruential.hpp>
#include "VCMI_Lib.h"
@ -364,7 +363,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
}
if (GameConstants::COMMANDERS)
{ //TODO: move all artifacts config to separate json file
const JsonNode config(GameConstants::DATA_DIR + "/config/commanders.json");
const JsonNode config(ResourceID("config/commanders.json"));
BOOST_FOREACH(const JsonNode &artifact, config["artifacts"].Vector())
{
auto ga = dynamic_cast <CGrowingArtifact *>(artifacts[artifact["id"].Float()].get());

View File

@ -2,7 +2,6 @@
#include "CBuildingHandler.h"
#include "CGeneralTextHandler.h"
#include "CLodHandler.h"
#include "../lib/Filesystem/CResourceLoader.h"
#include "../lib/VCMI_Lib.h"
#include "../lib/JsonNode.h"
@ -99,7 +98,7 @@ void CBuildingHandler::loadBuildings()
}
}
/////done reading BUILDING.TXT*****************************
const JsonNode config(GameConstants::DATA_DIR + "/config/hall.json");
const JsonNode config(ResourceID("config/hall.json"));
BOOST_FOREACH(const JsonNode &town, config["town"].Vector())
{

View File

@ -3,7 +3,6 @@
#include "Filesystem/CResourceLoader.h"
#include "Filesystem/CCompressedStream.h"
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "../lib/vcmi_endian.h"
#include "CGeneralTextHandler.h"
@ -25,45 +24,14 @@ namespace fs = boost::filesystem;
*/
std::vector<CCampaignHeader> CCampaignHandler::getCampaignHeaders(GetMode mode)
{
std::vector<CCampaignHeader> ret;
std::string dirname = GameConstants::DATA_DIR + "/Maps";
std::string ext = ".H3C";
if(!boost::filesystem::exists(dirname))
{
tlog1 << "Cannot find " << dirname << " directory!\n";
}
if (mode == Custom) //add custom campaigns
{
fs::path tie(dirname);
fs::directory_iterator end_iter;
for ( fs::directory_iterator file (tie); file!=end_iter; ++file )
{
if(fs::is_regular_file(file->status())
&& boost::ends_with(file->path().filename().string(), ext))
{
ret.push_back( getHeader( file->path().string()) );
}
}
}
return ret;
}
CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
{
ui8 * cmpgn = getFile(name).first;
std::vector<ui8> cmpgn = getFile(name, true)[0];
int it = 0;//iterator for reading
CCampaignHeader ret = readHeaderFromMemory(cmpgn, it);
CCampaignHeader ret = readHeaderFromMemory(cmpgn.data(), it);
ret.filename = name;
delete [] cmpgn;
return ret;
}
@ -71,56 +39,33 @@ CCampaign * CCampaignHandler::getCampaign( const std::string & name)
{
CCampaign * ret = new CCampaign();
auto file = getFile(name);
int realSize = file.second;
ui8 * cmpgn = file.first;
std::vector<std::vector<ui8>> file = getFile(name, false);
int it = 0; //iterator for reading
ret->header = readHeaderFromMemory(cmpgn, it);
ret->header = readHeaderFromMemory(file[0].data(), it);
ret->header.filename = name;
int howManyScenarios = VLC->generaltexth->campaignRegionNames[ret->header.mapVersion].size();
for(int g=0; g<howManyScenarios; ++g)
{
CCampaignScenario sc = readScenarioFromMemory(cmpgn, it, ret->header.version, ret->header.mapVersion);
CCampaignScenario sc = readScenarioFromMemory(file[0].data(), it, ret->header.version, ret->header.mapVersion);
ret->scenarios.push_back(sc);
}
std::vector<ui32> h3mStarts = locateH3mStarts(cmpgn, it, realSize);
assert(h3mStarts.size() <= howManyScenarios);
//it looks like we can have more scenarios than we should..
if(h3mStarts.size() > howManyScenarios)
{
tlog1<<"Our heuristic for h3m start points gave wrong results for campaign " << name <<std::endl;
tlog1<<"Please send this campaign to VCMI Project team to help us fix this problem" << std::endl;
delete [] cmpgn;
assert(0);
return NULL;
}
int scenarioID = 0;
for (int g=0; g<h3mStarts.size(); ++g)
//first entry is campaign header. start loop from 1
for (int g=1; g<file.size(); ++g)
{
while(!ret->scenarios[scenarioID].isNotVoid()) //skip void scenarios
{
scenarioID++;
}
//set map piece appropriately
if(g == h3mStarts.size() - 1)
{
ret->mapPieces[scenarioID] = std::string( cmpgn + h3mStarts[g], cmpgn + realSize );
}
else
{
ret->mapPieces[scenarioID] = std::string( cmpgn + h3mStarts[g], cmpgn + h3mStarts[g+1] );
}
scenarioID++;
ret->mapPieces[scenarioID++] = file[g];
}
delete [] cmpgn;
return ret;
}
@ -322,102 +267,24 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
return ret;
}
std::vector<ui32> CCampaignHandler::locateH3mStarts( const ui8 * buffer, int start, int size )
std::vector< std::vector<ui8> > CCampaignHandler::getFile(const std::string & name, bool headerOnly)
{
std::vector<ui32> ret;
for(int g=start; g<size; ++g)
CCompressedStream stream(std::move(CResourceHandler::get()->load(ResourceID(name, EResType::CAMPAIGN))), true);
std::vector< std::vector<ui8> > ret;
do
{
if(startsAt(buffer, size, g))
{
ret.push_back(g);
}
std::vector<ui8> block(stream.getSize());
stream.read(block.data(), block.size());
ret.push_back(block);
std::ofstream outFile("/home/ivan/vcmi.out");
outFile.write((char*)block.data(), block.size());
}
while (!headerOnly && stream.getNextBlock());
return ret;
}
bool CCampaignHandler::startsAt( const ui8 * buffer, int size, int pos )
{
struct HLP
{
static ui8 at(const ui8 * buffer, int size, int place)
{
if(place < size)
return buffer[place];
throw std::runtime_error("Out of bounds!");
}
};
try
{
//check minimal length of given region
HLP::at(buffer, size, 100);
//check version
ui8 tmp = HLP::at(buffer, size, pos);
if(!(tmp == 0x0e || tmp == 0x15 || tmp == 0x1c || tmp == 0x33))
{
return false;
}
//3 bytes following version
if(HLP::at(buffer, size, pos+1) != 0 || HLP::at(buffer, size, pos+2) != 0 || HLP::at(buffer, size, pos+3) != 0)
{
return false;
}
//unknown strange byte
tmp = HLP::at(buffer, size, pos+4);
if(tmp != 0 && tmp != 1 )
{
return false;
}
//size of map
int mapsize = read_le_u32(buffer + pos+5);
if(mapsize < 10 || mapsize > 530)
{
return false;
}
//underground or not
tmp = HLP::at(buffer, size, pos+9);
if( tmp != 0 && tmp != 1 )
{
return false;
}
//map name
int len = read_le_u32(buffer + pos+10);
if(len < 0 || len > 100)
{
return false;
}
for(int t=0; t<len; ++t)
{
tmp = HLP::at(buffer, size, pos+14+t);
if(tmp == 0 || (tmp > 15 && tmp < 32)) //not a valid character
{
return false;
}
}
}
catch (...)
{
return false;
}
return true;
}
std::pair<ui8 *, size_t> CCampaignHandler::getFile(const std::string & name)
{
std::unique_ptr<CInputStream> stream = CResourceHandler::get()->load(ResourceID(name, EResType::CAMPAIGN));
stream.reset(new CCompressedStream(stream, true));
ui8 * ret = new ui8[stream->getSize()];
stream->read(ret, stream->getSize());
return std::make_pair(ret, stream->getSize());
}
bool CCampaign::conquerable( int whichScenario ) const
{
//check for void scenraio

View File

@ -1,7 +1,5 @@
#pragma once
/*
* CCampaignHandler.h, part of VCMI engine
*
@ -126,7 +124,7 @@ class DLL_LINKAGE CCampaign
public:
CCampaignHeader header;
std::vector<CCampaignScenario> scenarios;
std::map<int, std::string> mapPieces; //binary h3ms, scenario number -> map data
std::map<int, std::vector<ui8> > mapPieces; //binary h3ms, scenario number -> map data
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
@ -160,12 +158,11 @@ class DLL_LINKAGE CCampaignHandler
static CCampaignHeader readHeaderFromMemory( const ui8 *buffer, int & outIt );
static CCampaignScenario readScenarioFromMemory( const ui8 *buffer, int & outIt, int version, int mapVersion );
static CScenarioTravel readScenarioTravelFromMemory( const ui8 * buffer, int & outIt , int version);
static std::vector<ui32> locateH3mStarts(const ui8 * buffer, int start, int size);
static bool startsAt( const ui8 * buffer, int size, int pos ); //a simple heuristic that checks if a h3m starts at given pos
static std::pair<ui8 *, size_t> getFile(const std::string & name);
/// returns h3c splitted in parts. 0 = h3c header, 1-end - maps (binary h3m)
/// headerOnly - only header will be decompressed, returned vector wont have any maps
static std::vector< std::vector<ui8> > getFile(const std::string & name, bool headerOnly);
public:
enum GetMode {RoE, AB, SoD, WoG, Custom};
static std::vector<CCampaignHeader> getCampaignHeaders(GetMode mode);
static CCampaignHeader getHeader( const std::string & name); //name - name of appropriate file
static CCampaign * getCampaign(const std::string & name); //name - name of appropriate file

View File

@ -2,7 +2,6 @@
#include "CCreatureHandler.h"
#include "Filesystem/CResourceLoader.h"
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "../lib/CGameState.h"
#include "../lib/JsonNode.h"
@ -412,7 +411,7 @@ void CCreatureHandler::loadCreatures()
// loading creatures properties
tlog5 << "\t\tReading config/creatures.json" << std::endl;
const JsonNode config(GameConstants::DATA_DIR + "/config/creatures.json");
const JsonNode config(ResourceID("config/creatures.json"));
BOOST_FOREACH(const JsonNode &creature, config["creatures"].Vector())
{
@ -476,7 +475,7 @@ void CCreatureHandler::loadCreatures()
loadAnimationInfo();
//reading creature ability names
const JsonNode config2(GameConstants::DATA_DIR + "/config/bonusnames.json");
const JsonNode config2(ResourceID("config/bonusnames.json"));
BOOST_FOREACH(const JsonNode &bonus, config2["bonuses"].Vector())
{
@ -606,7 +605,7 @@ void CCreatureHandler::loadCreatures()
// addBonusForTier(1, b);
tlog5 << "\t\tReading config/commanders.json" << std::endl;
const JsonNode config3(GameConstants::DATA_DIR + "/config/commanders.json");
const JsonNode config3(ResourceID("config/commanders.json"));
BOOST_FOREACH (auto creature, config3["factionCreatures"].Vector())
{

View File

@ -3,7 +3,6 @@
#include "Filesystem/CResourceLoader.h"
#include "../client/CGameInfo.h"
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "GameConstants.h"

View File

@ -1,55 +0,0 @@
#include "StdInc.h"
#include "CFileUtility.h"
/*
* CFileUtility.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/*
namespace fs = boost::filesystem;
CFileUtility::CFileUtility(void)
{
}
CFileUtility::~CFileUtility(void)
{
}
void CFileUtility::getFilesWithExt(std::vector<FileInfo> &out, const std::string &dirname, const std::string &ext)
{
if(!fs::exists(dirname))
{
tlog1 << "Cannot find " << dirname << " directory!\n";
}
fs::path tie(dirname);
fs::directory_iterator end_iter;
for ( fs::directory_iterator file (tie); file!=end_iter; ++file )
{
if(fs::is_regular_file(file->status())
&& boost::ends_with(file->path().filename().string(), ext))
{
std::time_t date = 0;
try
{
date = fs::last_write_time(file->path());
out.resize(out.size()+1);
out.back().date = date;
out.back().name = file->path().string();
}
catch(...)
{
tlog2 << "\t\tWarning: very corrupted file: " << file->path().string() << std::endl;
}
}
}
}*/

View File

@ -1,30 +0,0 @@
#pragma once
/*
* CFileUtility.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Struct which stores name, date and a value which says if the file is located in LOD
struct FileInfo
{
std::string name; // file URI (upper case, no extension)
std::time_t date;
};
/*
class DLL_LINKAGE CFileUtility
{
public:
CFileUtility(void);
~CFileUtility(void);
static void getFilesWithExt(std::vector<FileInfo> &out, const std::string &dirname, const std::string &ext);
};
*/

View File

@ -843,9 +843,9 @@ void CGameState::init(StartInfo * si)
campaign->initNewCampaign(*scenarioOps);
assert(vstd::contains(campaign->camp->mapPieces, scenarioOps->whichMapInCampaign));
std::string &mapContent = campaign->camp->mapPieces[scenarioOps->whichMapInCampaign];
std::vector<ui8> &mapContent = campaign->camp->mapPieces[scenarioOps->whichMapInCampaign];
map = new Mapa();
map->initFromBytes((const ui8*)mapContent.c_str(), mapContent.size());
map->initFromBytes((const ui8*)mapContent.data(), mapContent.size());
}
break;
case StartInfo::DUEL:
@ -1053,7 +1053,7 @@ void CGameState::init(StartInfo * si)
/******************RESOURCES****************************************************/
TResources startresAI, startresHuman;
const JsonNode config(GameConstants::DATA_DIR + "/config/startres.json");
const JsonNode config(ResourceID("config/startres.json"));
const JsonVector &vector = config["difficulty"].Vector();
const JsonNode &level = vector[scenarioOps->difficulty];
const JsonNode &human = level["human"];
@ -1746,7 +1746,7 @@ int CGameState::getPlayerRelations( ui8 color1, ui8 color2 )
void CGameState::loadTownDInfos()
{
int i;
const JsonNode config(GameConstants::DATA_DIR + "/config/towns_defs.json");
const JsonNode config(ResourceID("config/towns_defs.json"));
assert(config["town_defnames"].Vector().size() == GameConstants::F_NUMBER);
@ -2782,7 +2782,7 @@ DuelParameters DuelParameters::fromJSON(const std::string &fname)
{
DuelParameters ret;
const JsonNode duelData(fname);
const JsonNode duelData(ResourceID(fname, EResType::TEXT));
ret.terType = duelData["terType"].Float();
ret.bfieldType = duelData["bfieldType"].Float();
BOOST_FOREACH(const JsonNode &n, duelData["sides"].Vector())

View File

@ -3,7 +3,6 @@
#include "Filesystem/CResourceLoader.h"
#include "VCMI_Lib.h"
#include "CLodHandler.h"
#include "GameConstants.h"
/*

View File

@ -2,7 +2,6 @@
#include "CHeroHandler.h"
#include "Filesystem/CResourceLoader.h"
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "../lib/JsonNode.h"
#include "GameConstants.h"
@ -116,7 +115,7 @@ void CHeroHandler::loadObstacles()
};
const JsonNode config(GameConstants::DATA_DIR + "/config/obstacles.json");
const JsonNode config(ResourceID("config/obstacles.json"));
loadObstacles(config["obstacles"], false, obstacles);
loadObstacles(config["absoluteObstacles"], true, absoluteObstacles);
//loadObstacles(config["moats"], true, moats);
@ -124,7 +123,7 @@ void CHeroHandler::loadObstacles()
void CHeroHandler::loadPuzzleInfo()
{
const JsonNode config(GameConstants::DATA_DIR + "/config/puzzle_map.json");
const JsonNode config(ResourceID("config/puzzle_map.json"));
int faction = 0;
@ -230,7 +229,7 @@ void CHeroHandler::loadHeroes()
}
// Load heroes information
const JsonNode config(GameConstants::DATA_DIR + "/config/heroes.json");
const JsonNode config(ResourceID("config/heroes.json"));
BOOST_FOREACH(const JsonNode &hero, config["heroes"].Vector()) {
int hid = hero["id"].Float();
const JsonNode *value;
@ -426,7 +425,7 @@ ui64 CHeroHandler::reqExp (ui32 level) const
void CHeroHandler::loadTerrains()
{
int faction = 0;
const JsonNode config(GameConstants::DATA_DIR + "/config/terrains.json");
const JsonNode config(ResourceID("config/terrains.json"));
nativeTerrains.resize(GameConstants::F_NUMBER);

View File

@ -1,398 +0,0 @@
#include "StdInc.h"
#include "CLodHandler.h"
#include "vcmi_endian.h"
#ifdef max
#undef max
#endif
/*
* CLodHandler.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
std::string readString(const ui8 * bufor, int &i)
{
int len = read_le_u32(bufor + i); i+=4;
assert(len >= 0 && len <= 500000); //not too long
std::string ret; ret.reserve(len);
for(int gg=0; gg<len; ++gg)
{
ret += bufor[i++];
}
return ret;
}
/*
void CLodHandler::convertName(std::string &filename, std::string *extension)
{
std::transform(filename.begin(), filename.end(), filename.begin(), toupper);
size_t dotPos = filename.find_last_of("/.");
if ( dotPos != std::string::npos && filename[dotPos] == '.')
{
if (extension)
*extension = filename.substr(dotPos);
filename.erase(dotPos);
}
}
ui8 * CLodHandler::giveFile(std::string fname, LodFileType type, int * length)
{
convertName(fname);
boost::unordered_set<Entry>::const_iterator en_it = entries.find(Entry(fname, type));
if(en_it == entries.end()) //nothing's been found
{
tlog1 << "Cannot find file: " << fname << std::endl;
return NULL;
}
Entry ourEntry = *en_it;
if(length) *length = ourEntry.realSize;
boost::unique_lock<boost::mutex> lock(*mutex);
ui8 * outp;
if (ourEntry.offset<0) //file is in the sprites/ folder; no compression
{
int result;
outp = new ui8[ourEntry.realSize];
FILE * f = fopen((myDir + "/" + ourEntry.realName).c_str(), "rb");
if (f)
{
result = fread(outp,1,ourEntry.realSize,f);
fclose(f);
}
else
result = -1;
if(result<0)
{
tlog1<<"Error in file reading: " << ourEntry.realName << std::endl;
perror("Last error was: ");//print system error message
delete[] outp;
return NULL;
}
else
return outp;
}
else if (ourEntry.size==0) //file is not compressed
{
outp = new ui8[ourEntry.realSize];
LOD.seekg(ourEntry.offset, std::ios::beg);
LOD.read((char*)outp, ourEntry.realSize);
return outp;
}
else //we will decompress file
{
outp = new ui8[ourEntry.size];
LOD.seekg(ourEntry.offset, std::ios::beg);
LOD.read((char*)outp, ourEntry.size);
ui8 * decomp = NULL;
infs2(outp, ourEntry.size, ourEntry.realSize, decomp);
delete[] outp;
return decomp;
}
return NULL;
}
std::string CLodHandler::getFileName(std::string lodFile, LodFileType type)
{
convertName(lodFile);
boost::unordered_set<Entry>::const_iterator it = entries.find(Entry(lodFile, type));
if (it != entries.end())
return it->realName;
return "";
}
bool CLodHandler::haveFile(std::string name, LodFileType type)
{
convertName(name);
return vstd::contains(entries, Entry(name, type));
}
DLL_LINKAGE int CLodHandler::infs2(ui8 * in, int size, int realSize, ui8 *& out, int wBits)
{
int ret;
unsigned have;
z_stream strm;
out = new ui8 [realSize];
int latPosOut = 0;
// allocate inflate state
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, wBits);
if (ret != Z_OK)
return ret;
int chunkNumber = 0;
do
{
if(size < chunkNumber * NLoadHandlerHelp::fCHUNK)
break;
strm.avail_in = std::min(NLoadHandlerHelp::fCHUNK, size - chunkNumber * NLoadHandlerHelp::fCHUNK);
if (strm.avail_in == 0)
break;
strm.next_in = in + chunkNumber * NLoadHandlerHelp::fCHUNK;
// run inflate() on input until output buffer not full
do
{
strm.avail_out = realSize - latPosOut;
strm.next_out = out + latPosOut;
ret = inflate(&strm, Z_NO_FLUSH);
//assert(ret != Z_STREAM_ERROR); // state not clobbered
bool breakLoop = false;
switch (ret)
{
case Z_STREAM_END:
breakLoop = true;
break;
case Z_NEED_DICT:
ret = Z_DATA_ERROR; // and fall through
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
if(breakLoop)
break;
have = realSize - latPosOut - strm.avail_out;
latPosOut += have;
} while (strm.avail_out == 0);
++chunkNumber;
// done when inflate() says it's done
} while (ret != Z_STREAM_END);
// clean up and return
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
void CLodHandler::extractFile(const std::string FName, const std::string name, LodFileType type)
{
int len; //length of file to write
ui8 * outp = giveFile(name, type, &len);
std::ofstream out;
out.open(FName.c_str(), std::ios::binary);
if(!out.is_open())
{
tlog1<<"Unable to create "<<FName<<std::endl;
}
else
{
out.write(reinterpret_cast<char*>(outp), len);
out.close();
}
}
void CLodHandler::initEntry(Entry &e, std::string name)
{
std::string ext;
convertName(name, &ext);
e.name = name;
std::map<std::string, LodFileType>::iterator it = extMap.find(ext);
if (it == extMap.end())
e.type = FILE_OTHER;
else
e.type = it->second;
}
void CLodHandler::init(const std::string lodFile, const std::string dirName)
{
#define EXT(NAME, TYPE) extMap.insert(std::pair<std::string, LodFileType>(NAME, TYPE));
EXT(".TXT", FILE_TEXT);
EXT(".JSON",FILE_TEXT);
EXT(".DEF", FILE_ANIMATION);
EXT(".MSK", FILE_MASK);
EXT(".MSG", FILE_MASK);
EXT(".H3C", FILE_CAMPAIGN);
EXT(".H3M", FILE_MAP);
EXT(".FNT", FILE_FONT);
EXT(".BMP", FILE_GRAPHICS);
EXT(".JPG", FILE_GRAPHICS);
EXT(".PCX", FILE_GRAPHICS);
EXT(".PNG", FILE_GRAPHICS);
EXT(".TGA", FILE_GRAPHICS);
#undef EXT
myDir = dirName;
LOD.open(lodFile.c_str(), std::ios::in | std::ios::binary);
if (!LOD.is_open())
{
tlog1 << "Cannot open " << lodFile << std::endl;
return;
}
Uint32 temp;
LOD.seekg(8);
LOD.read((char *)&temp, 4);
totalFiles = SDL_SwapLE32(temp);
LOD.seekg(0x5c, std::ios::beg);
if(!LOD)
{
tlog2 << lodFile << " doesn't store anything!\n";
return;
}
struct LodEntry *lodEntries = new struct LodEntry[totalFiles];
LOD.read((char *)lodEntries, sizeof(struct LodEntry) * totalFiles);
for (ui32 i=0; i<totalFiles; i++)
{
Entry entry;
initEntry(entry, lodEntries[i].filename);
entry.offset= SDL_SwapLE32(lodEntries[i].offset);
entry.realSize = SDL_SwapLE32(lodEntries[i].uncompressedSize);
entry.size = SDL_SwapLE32(lodEntries[i].size);
entries.insert(entry);
}
delete [] lodEntries;
boost::filesystem::recursive_directory_iterator enddir;
if(boost::filesystem::exists(dirName))
{
std::vector<std::string> path;
for (boost::filesystem::recursive_directory_iterator dir(dirName); dir!=enddir; dir++)
{
//If a directory was found - add name to vector to recreate full path later
if (boost::filesystem::is_directory(dir->status()))
{
path.resize(dir.level()+1);
path.back() = dir->path().leaf().string();
}
if(boost::filesystem::is_regular(dir->status()))
{
Entry e;
//we can't get relative path with boost at the moment - need to create path to file manually
for (size_t i=0; i<dir.level() && i<path.size(); i++)
e.realName += path[i] + '/';
e.realName += dir->path().leaf().string();
initEntry(e, e.realName);
if(vstd::contains(entries, e)) //file present in .lod - overwrite its entry
entries.erase(e);
e.offset = -1;
e.realSize = e.size = boost::filesystem::file_size(dir->path());
entries.insert(e);
}
}
}
else
{
if (!dirName.empty())
tlog1<<"Warning: No "+dirName+"/ folder!"<<std::endl;
}
}
std::string CLodHandler::getTextFile(std::string name, LodFileType type)
{
int length=-1;
ui8* data = giveFile(name, type, &length);
if (!data) {
tlog1<<"Fatal error. Missing game file: " << name << ". Aborting!"<<std::endl;
exit(1);
}
std::string ret(data, data+length);
delete [] data;
return ret;
}
CLodHandler::CLodHandler()
{
mutex = new boost::mutex;
totalFiles = 0;
}
CLodHandler::~CLodHandler()
{
delete mutex;
}
//It is possible to use uncompress function from zlib but we need to know decompressed size (not present in compressed data)
ui8 * CLodHandler::getUnpackedData(ui8 *data, size_t inputSize, int * outputSize)
{
std::string filename = GVCMIDirs.UserPath + "/tmp_gzip";
FILE * file = fopen(filename.c_str(), "wb");
fwrite(data, 1, inputSize, file);
fclose(file);
ui8 * ret = getUnpackedFile(filename, outputSize);
remove(filename.c_str());
delete [] data;
return ret;
}
ui8 * CLodHandler::getUnpackedFile( const std::string & path, int * sizeOut )
{
const int bufsize = 65536;
int mapsize = 0;
gzFile map = gzopen(path.c_str(), "rb");
assert(map);
std::vector<ui8 *> mapstr;
// Read a map by chunks
// We could try to read the map size directly (cf RFC 1952) and then read
// directly the whole map, but that would create more problems.
do {
ui8 *buf = new ui8[bufsize];
int ret = gzread(map, buf, bufsize);
if (ret == 0 || ret == -1) {
delete [] buf;
break;
}
mapstr.push_back(buf);
mapsize += ret;
} while(1);
gzclose(map);
// Now that we know the uncompressed size, reassemble the chunks
ui8 *initTable = new ui8[mapsize];
std::vector<ui8 *>::iterator it;
int offset;
int tocopy = mapsize;
for (it = mapstr.begin(), offset = 0;
it != mapstr.end();
it++, offset+=bufsize ) {
memcpy(&initTable[offset], *it, tocopy > bufsize ? bufsize : tocopy);
tocopy -= bufsize;
delete [] *it;
}
*sizeOut = mapsize;
return initTable;
}
*/

View File

@ -1,117 +0,0 @@
#pragma once
/*
* CLodhandler.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
//namespace boost
//{class mutex;}
//namespace NLoadHandlerHelp
//{
// const int dmHelp=0, dmNoExtractingMask=1;
// //std::string P1,P2,CurDir;
// const int fCHUNK = 50000;
//}
//struct LodEntry {
// char filename[16];
// ui32 offset; /* little endian */
// ui32 uncompressedSize; /* little endian */
// ui32 unused; /* little endian */
// ui32 size; /* little endian */
//};
static inline char readChar(const ui8 * bufor, int &i)
{
return bufor[i++];
}
DLL_LINKAGE std::string readString(const ui8 * bufor, int &i);
/*
enum LodFileType{
FILE_ANY,
FILE_TEXT,
FILE_ANIMATION,
FILE_MASK,
FILE_CAMPAIGN,
FILE_MAP,
FILE_FONT,
FILE_GRAPHICS,
FILE_OTHER
};
struct Entry
{
// Info extracted from LOD file
std::string name,
realName;//for external files - case\extension may not match
int offset, //from beginning
realSize, //size without compression
size; //and with
LodFileType type;// file type determined by extension
bool operator == (const Entry & comp) const
{
return (type==comp.type || comp.type== FILE_ANY) && name==comp.name;
}
Entry(std::string con, LodFileType TYPE): name(con), type(TYPE){};
Entry(std::string con): name(con){};
Entry(){};
};
namespace boost
{
template<>
struct hash<Entry> : public std::unary_function<Entry, std::size_t>
{
private:
hash<std::string> stringHasher;
public:
std::size_t operator()(Entry const& en) const
{
//do NOT improve this hash function as we need same-name hash collisions for find to work properly
return stringHasher(en.name);
}
};
}
class DLL_LINKAGE CLodHandler
{
std::map<std::string, LodFileType> extMap;// to convert extensions to file type
std::ifstream LOD;
ui32 totalFiles;
boost::mutex *mutex;
std::string myDir; //load files from this dir instead of .lod file
void initEntry(Entry &e, const std::string name);
int infs2(ui8 * in, int size, int realSize, ui8*& out, int wBits=15); //zlib fast handler
ui8 * giveFile(std::string defName, LodFileType type=FILE_ANY, int * length=NULL);
boost::unordered_set<Entry> entries;
void extractFile(const std::string FName, const std::string name, LodFileType type=FILE_ANY);
static ui8 * getUnpackedData(ui8 *data, size_t inputSize, int * outputSize);
void convertName(std::string &filename, std::string *extension=NULL);
std::string getFileName(std::string lodFile, LodFileType type=FILE_ANY);
bool haveFile(std::string name, LodFileType type=FILE_ANY);
static ui8 * getUnpackedFile(const std::string & path, int * sizeOut);
std::string getTextFile(std::string name, LodFileType type=FILE_TEXT); //extracts one file
CLodHandler();
~CLodHandler();
void init(const std::string lodFile, const std::string dirName);
};
*/

View File

@ -13,7 +13,6 @@ set(lib_SRCS
Filesystem/CResourceLoader.cpp
Filesystem/CFileInputStream.cpp
Filesystem/CCompressedStream.cpp
Filesystem/ISimpleResourceLoader.cpp
BattleAction.cpp
BattleHex.cpp
BattleState.cpp
@ -24,12 +23,10 @@ set(lib_SRCS
CCreatureHandler.cpp
CCreatureSet.cpp
CDefObjInfoHandler.cpp
CFileUtility.cpp
CGameInterface.cpp
CGameState.cpp
CGeneralTextHandler.cpp
CHeroHandler.cpp
CLodHandler.cpp
CLogger.cpp
CMapInfo.cpp
CObjectHandler.cpp

View File

@ -2,7 +2,6 @@
#include "CObjectHandler.h"
#include "CDefObjInfoHandler.h"
#include "CLodHandler.h"
#include "CGeneralTextHandler.h"
#include "CDefObjInfoHandler.h"
#include "CHeroHandler.h"
@ -19,7 +18,8 @@
#include "map.h"
#include <SDL_stdinc.h>
#include "CBuildingHandler.h"
#include "../lib/JsonNode.h"
#include "JsonNode.h"
#include "Filesystem/CResourceLoader.h"
#include "GameConstants.h"
using namespace boost::assign;
@ -155,7 +155,7 @@ void CObjectHandler::loadObjects()
{
tlog5 << "\t\tReading cregens \n";
const JsonNode config(GameConstants::DATA_DIR + "/config/dwellings.json");
const JsonNode config(ResourceID("config/dwellings.json"));
BOOST_FOREACH(const JsonNode &dwelling, config["dwellings"].Vector())
{
cregens[dwelling["dwelling"].Float()] = dwelling["creature"].Float();
@ -163,7 +163,7 @@ void CObjectHandler::loadObjects()
tlog5 << "\t\tDone loading cregens!\n";
tlog5 << "\t\tReading resources prices \n";
const JsonNode config2(GameConstants::DATA_DIR + "/config/resources.json");
const JsonNode config2(ResourceID("config/resources.json"));
BOOST_FOREACH(const JsonNode &price, config2["resources_prices"].Vector())
{
resVals.push_back(price.Float());
@ -171,7 +171,7 @@ void CObjectHandler::loadObjects()
tlog5 << "\t\tDone loading resource prices!\n";
tlog5 << "\t\tReading banks configs \n";
const JsonNode config3(GameConstants::DATA_DIR + "/config/bankconfig.json");
const JsonNode config3(ResourceID("config/bankconfig.json"));
int bank_num = 0;
BOOST_FOREACH(const JsonNode &bank, config3["banks"].Vector())
{

View File

@ -2,7 +2,6 @@
#include "CSpellHandler.h"
#include "Filesystem/CResourceLoader.h"
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "../lib/JsonNode.h"
#include <cctype>
@ -350,7 +349,7 @@ void CSpellHandler::loadSpells()
boost::replace_first (spells[47]->attributes, "2", ""); // disrupting ray will now affect single creature
//loading of additional spell traits
const JsonNode config(GameConstants::DATA_DIR + "/config/spell_info.json");
const JsonNode config(ResourceID("config/spell_info.json"));
BOOST_FOREACH(const JsonNode &spell, config["spells"].Vector())
{

View File

@ -1,11 +1,11 @@
#include "StdInc.h"
#include "CTownHandler.h"
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "VCMI_Lib.h"
#include "CGeneralTextHandler.h"
#include "../lib/JsonNode.h"
#include "JsonNode.h"
#include "GameConstants.h"
#include "Filesystem/CResourceLoader.h"
/*
* CTownHandler.cpp, part of VCMI engine
@ -50,7 +50,7 @@ void CTownHandler::loadStructures()
structures.resize(GameConstants::F_NUMBER);
// read city properties
const JsonNode config(GameConstants::DATA_DIR + "/config/buildings.json");
const JsonNode config(ResourceID("config/buildings.json"));
// Iterate for each city type
townID = 0;

View File

@ -5,7 +5,7 @@
static const int inflateBlockSize = 10000;
CCompressedStream::CCompressedStream(std::unique_ptr<CInputStream> & stream, bool gzip, size_t decompressedSize):
CCompressedStream::CCompressedStream(std::unique_ptr<CInputStream> stream, bool gzip, size_t decompressedSize):
gzipStream(std::move(stream)),
buffer(decompressedSize),
decompressedSize(0),
@ -33,7 +33,11 @@ CCompressedStream::CCompressedStream(std::unique_ptr<CInputStream> & stream, boo
CCompressedStream::~CCompressedStream()
{
delete inflateState;
if (inflateState)
{
inflateEnd(inflateState);
delete inflateState;
}
}
si64 CCompressedStream::read(ui8 * data, si64 size)
@ -77,20 +81,15 @@ si64 CCompressedStream::getSize()
void CCompressedStream::decompressTill(si64 newSize)
{
//TODO: check if inflate have any special mode for inflating (e.g Z_BLOCK) that can
// be used for campaigns Technically .h3c consists from multiple
// concatenated gz streams (campaign header + every map)
// inflatings them separately can be useful for campaigns loading
assert(newSize < 100 * 1024 * 1024); //just in case
if (inflateState == nullptr)
return; //file already decompressed
if (newSize >= 0 && newSize < inflateState->total_out)
if (newSize >= 0 && newSize <= inflateState->total_out)
return; //no need to decompress anything
bool toEnd = newSize < 0;
bool toEnd = newSize < 0; //if true - we've got request to read whole file
if (toEnd && buffer.empty())
buffer.resize(16 * 1024); //some space for initial decompression
@ -98,7 +97,8 @@ void CCompressedStream::decompressTill(si64 newSize)
if (!toEnd && buffer.size() < newSize)
buffer.resize(newSize);
int ret;
bool fileEnded = false; //end of file reached
int endLoop = false;
do
{
@ -108,7 +108,7 @@ void CCompressedStream::decompressTill(si64 newSize)
// get new input data and update state accordingly
si64 size = gzipStream->read(compressedBuffer.data(), compressedBuffer.size());
if (size != compressedBuffer.size())
toEnd = true; //end of file reached
fileEnded = true; //end of file reached
inflateState->avail_in = size;
inflateState->next_in = compressedBuffer.data();
@ -117,7 +117,7 @@ void CCompressedStream::decompressTill(si64 newSize)
inflateState->avail_out = buffer.size() - inflateState->total_out;
inflateState->next_out = buffer.data() + inflateState->total_out;
ret = inflate(inflateState, Z_NO_FLUSH);
int ret = inflate(inflateState, Z_NO_FLUSH);
switch (ret)
{
@ -137,6 +137,8 @@ void CCompressedStream::decompressTill(si64 newSize)
}
else
{
//specific amount of data was requested. inflate extracted all requested data
// but returned "error". Ensure that enough data was extracted and return
assert(inflateState->total_out == newSize);
endLoop = true;
}
@ -150,7 +152,7 @@ void CCompressedStream::decompressTill(si64 newSize)
while (!endLoop);
// Clean up and return
if (toEnd)
if (fileEnded)
{
inflateEnd(inflateState);
buffer.resize(inflateState->total_out);
@ -159,4 +161,20 @@ void CCompressedStream::decompressTill(si64 newSize)
}
else
decompressedSize = inflateState->total_out;
}
}
bool CCompressedStream::getNextBlock()
{
if (!inflateState)
return false;
//inflateState->total_out = 0;
if (inflateReset(inflateState) < 0)
return false;
decompressedSize = 0;
position = 0;
buffer.clear();
return true;
}

View File

@ -29,7 +29,7 @@ public:
* @param gzip - this is gzipp'ed file e.g. campaign or maps, false for files in lod
* @param decompressedSize - optional parameter to hint size of decompressed data
*/
CCompressedStream(std::unique_ptr<CInputStream> & stream, bool gzip, size_t decompressedSize=0);
CCompressedStream(std::unique_ptr<CInputStream> stream, bool gzip, size_t decompressedSize=0);
~CCompressedStream();
@ -76,6 +76,14 @@ public:
*/
si64 getSize();
/**
* Prepare stream for decompression of next block (e.g. nect part of h3c)
* Applicable only for streams that contain multiple concatenated compressed data
*
* @return false if next block was not found, true othervice
*/
bool getNextBlock();
private:
/**
* Decompresses data to ensure that buffer has newSize bytes or end of stream was reached
@ -99,4 +107,14 @@ private:
/** Current read position */
si64 position;
enum EState
{
ERROR,
INITIALIZED,
IN_PROGRESS,
STREAM_END,
FINISHED
};
};

View File

@ -2,10 +2,6 @@
#include "CFileInputStream.h"
#include "CFileInfo.h"
CFileInputStream::CFileInputStream()
{
}
CFileInputStream::CFileInputStream(const std::string & file, si64 start, si64 size)
{
@ -19,13 +15,11 @@ CFileInputStream::CFileInputStream(const CFileInfo & file, si64 start, si64 size
CFileInputStream::~CFileInputStream()
{
close();
fileStream.close();
}
void CFileInputStream::open(const std::string & file, si64 start, si64 size)
{
close();
fileStream.open(file.c_str(), std::ios::in | std::ios::binary);
if (fileStream.fail())
@ -79,11 +73,3 @@ si64 CFileInputStream::getSize()
{
return dataSize;
}
void CFileInputStream::close()
{
if (fileStream.is_open())
{
fileStream.close();
}
}

View File

@ -21,11 +21,6 @@ class CFileInfo;
class DLL_LINKAGE CFileInputStream : public CInputStream
{
public:
/**
* Standard c-tor.
*/
CFileInputStream();
/**
* C-tor. Opens the specified file.
*
@ -45,17 +40,6 @@ public:
*/
~CFileInputStream();
/**
* Opens a file. If a file is currently opened, it will be closed.
*
* @param file Path to the file.
* @param start - offset from file start where real data starts (e.g file on archive)
* @param size - size of real data in file (e.g file on archive) or 0 to use whole file
*
* @throws std::runtime_error if file wasn't found
*/
void open(const std::string & file, si64 start, si64 size);
/**
* Reads n bytes from the stream into the data buffer.
*
@ -95,12 +79,18 @@ public:
*/
si64 getSize();
/**
* Closes the stream and releases any system resources associated with the stream explicitely.
*/
void close();
private:
/**
* Opens a file. If a file is currently opened, it will be closed.
*
* @param file Path to the file.
* @param start - offset from file start where real data starts (e.g file on archive)
* @param size - size of real data in file (e.g file on archive) or 0 to use whole file
*
* @throws std::runtime_error if file wasn't found
*/
void open(const std::string & file, si64 start, si64 size);
si64 dataStart;
si64 dataSize;
/** Native c++ input file stream object. */

View File

@ -3,7 +3,6 @@
#include "CInputStream.h"
#include "CFileInputStream.h"
#include "CCompressedStream.h"
#include "CLodStream.h"
#include "CBinaryReader.h"
#include "CFileInfo.h"
#include <SDL_endian.h>
@ -197,7 +196,7 @@ std::unique_ptr<CInputStream> CLodArchiveLoader::load(const std::string & resour
{
std::unique_ptr<CInputStream> fileStream(new CFileInputStream(getOrigin(), entry.offset, entry.size));
return std::unique_ptr<CInputStream>(new CCompressedStream(fileStream, false, entry.realSize));
return std::unique_ptr<CInputStream>(new CCompressedStream(std::move(fileStream), false, entry.realSize));
}
else
{

View File

@ -1,76 +0,0 @@
#include "StdInc.h"
#include "CLodStream.h"
/*
#include "CLodArchiveLoader.h"
#include "CFileInputStream.h"
#include "CMemoryStream.h"
CLodStream::CLodStream()
{
}
CLodStream::CLodStream(const CLodArchiveLoader * loader, const std::string & resourceName)
{
open(loader, resourceName);
}
void CLodStream::open(const CLodArchiveLoader * loader, const std::string & resourceName)
{
assert(!fileStream);
const ArchiveEntry * archiveEntry = loader->getArchiveEntry(resourceName);
if(archiveEntry == nullptr)
{
throw std::runtime_error("Archive entry " + resourceName + " wasn't found in the archive " + loader->getOrigin());
}
size = archiveEntry->size;
offset = archiveEntry->offset;
// Open the archive and set the read pointer to the correct position
fileStream.reset(new CFileInputStream(loader->getOrigin()));
fileStream->seek(archiveEntry->offset);
// Decompress file
if(archiveEntry->size != 0)
{
// replace original buffer with decompressed one
fileStream.reset(CLodArchiveLoader::decompress(*this, archiveEntry->realSize));
assert(fileStream->getSize() == archiveEntry->realSize);
//in memory stream we no longer need offset
offset = 0;
}
size = archiveEntry->realSize;
}
si64 CLodStream::read(ui8 * data, si64 size)
{
return fileStream->read(data, size);
}
si64 CLodStream::seek(si64 position)
{
return fileStream->seek(offset + position);
}
si64 CLodStream::tell()
{
return fileStream->tell() - offset;
}
si64 CLodStream::skip(si64 delta)
{
return fileStream->skip(delta);
}
si64 CLodStream::getSize()
{
return size;
}
void CLodStream::close()
{
fileStream->close();
}
*/

View File

@ -1,108 +0,0 @@
/*
* CLodStream.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
//#include "CInputStream.h"
//#include "CFileInputStream.h"
//#include "CLodArchiveLoader.h"
///**
// * A class which provides method definitions for reading a file from a LOD archive.
// */
//class DLL_LINKAGE CLodStream : public CInputStream
//{
//public:
// /**
// * Default c-tor.
// */
// CLodStream();
// /**
// * C-tor.
// *
// * @param loader The archive loader object which knows about the structure of the archive format.
// * @param resourceName The resource name which says what resource should be loaded.
// *
// * @throws std::runtime_error if the archive entry wasn't found
// */
// CLodStream(const CLodArchiveLoader * loader, const std::string & resourceName);
// /**
// * Opens a lod stream. It will close any currently opened file stream.
// *
// * @param loader The archive loader object which knows about the structure of the archive format.
// * @param resourceName The resource name which says what resource should be loaded.
// *
// * @throws std::runtime_error if the archive entry wasn't found
// */
// void open(const CLodArchiveLoader * loader, const std::string & resourceName);
// /**
// * Reads n bytes from the stream into the data buffer.
// *
// * Warning: You can't read just a part of the archive entry if it's a decompressed one. So reading the total size always is
// * recommended unless you really know what you're doing e.g. reading from a video stream.
// *
// * @param data A pointer to the destination data array.
// * @param size The number of bytes to read.
// * @return the number of bytes read actually.
// *
// * @throws std::runtime_error if the file decompression was not successful
// */
// si64 read(ui8 * data, si64 size);
// /**
// * Seeks the internal read pointer to the specified position.
// *
// * @param position The read position from the beginning.
// * @return the position actually moved to, -1 on error.
// */
// si64 seek(si64 position);
// /**
// * Gets the current read position in the stream.
// *
// * @return the read position.
// */
// si64 tell();
// /**
// * Skips delta numbers of bytes.
// *
// * @param delta The count of bytes to skip.
// * @return the count of bytes skipped actually.
// */
// si64 skip(si64 delta);
// /**
// * Gets the length in bytes of the stream.
// *
// * @return the length in bytes of the stream.
// */
// si64 getSize();
// /**
// * Closes the stream and releases any system resources associated with the stream explicitely.
// */
// void close();
//private:
// /** The file stream for reading from the LOD archive. */
// std::unique_ptr<CInputStream> fileStream;
// /** Offset of data in input stream. Used if input stream represents whole file*/
// size_t offset;
// /** Size of our data in input stream. */
// size_t size;
//};

View File

@ -1,29 +1,20 @@
#include "StdInc.h"
#include "CMemoryStream.h"
CMemoryStream::CMemoryStream() : data(nullptr), size(0), position(0), freeData(false)
CMemoryStream::CMemoryStream(const ui8 * data, si64 size, bool freeData /*= false*/):
data(data),
size(size),
position(0),
freeData(freeData)
{
}
CMemoryStream::CMemoryStream(const ui8 * data, si64 size, bool freeData /*= false*/) : data(data), size(size), position(0), freeData(freeData)
{
}
CMemoryStream::~CMemoryStream()
{
close();
}
void CMemoryStream::open(const ui8 * data, si64 size, bool freeData /*= false*/)
{
close();
this->size = size;
this->data = data;
this->freeData = freeData;
this->position = 0;
if(freeData)
{
delete[] data;
}
}
si64 CMemoryStream::read(ui8 * data, si64 size)
@ -55,11 +46,3 @@ si64 CMemoryStream::getSize()
{
return size;
}
void CMemoryStream::close()
{
if(freeData)
{
delete[] data;
}
}

View File

@ -19,11 +19,6 @@
class DLL_LINKAGE CMemoryStream : public CInputStream
{
public:
/**
* Default c-tor.
*/
CMemoryStream();
/**
* C-tor. The data buffer will be freed by the stream's destructor.
*
@ -31,23 +26,13 @@ public:
* @param size The size in bytes of the array.
* @param freeData Flag which specifies if the data array should be freed in the memory stream's destructor.
*/
CMemoryStream(const ui8 * data, si64 size, bool freeData = false);
CMemoryStream(const ui8 * data, si64 size, bool freeData);
/**
* D-tor. Frees the data array if the freeData flag was set to true.
*/
~CMemoryStream();
/**
* Opens the stream with the given data array. If a stream is currently loaded, it will be freed
* if neccessary.
*
* @param data A pointer to the data array.
* @param size The size in bytes of the array.
* @param freeData Flag which specifies if the data array should be freed in the memory stream's destructor.
*/
void open(const ui8 * data, si64 size, bool freeData = false);
/**
* Reads n bytes from the stream into the data buffer.
*
@ -87,11 +72,6 @@ public:
*/
si64 getSize();
/**
* Closes the stream and releases any system resources associated with the stream explicitely.
*/
void close();
private:
/** A pointer to the data array. */
const ui8 * data;

View File

@ -279,18 +279,27 @@ void CResourceHandler::initialize()
//create "LOCAL" dir with current userDir (may be same as rootDir)
initialLoader->addLoader("LOCAL/", userDir);
//check for presence of "VCMI" mod. If found - add it to our initial FS
std::string filename = initialLoader->getResourceName(ResourceID("ALL/MODS/VCMI"));
if (!filename.empty())
initialLoader->addLoader("ALL/", new CFilesystemLoader(filename, 2));
}
void CResourceHandler::loadFileSystem(const std::string fsConfigURI)
{
const JsonNode fsConfig(initialLoader->getResourceName(ResourceID(fsConfigURI, EResType::TEXT)));
//TODO: better way to detect fs config.
// right now it can be: global_dir/config/, local_dir/config, global/mods/vcmi/config, local/mods/vcmi/config
auto fsConfigData = initialLoader->loadData(ResourceID(fsConfigURI, EResType::TEXT));
const JsonNode fsConfig((char*)fsConfigData.first.get(), fsConfigData.second);
BOOST_FOREACH(auto & mountPoint, fsConfig["filesystem"].Struct())
{
BOOST_FOREACH(auto & entry, mountPoint.second.Vector())
{
tlog5 << "loading resource at " << entry["path"].String() << ": ";
std::string filename = initialLoader->getResourceName(entry["path"].String());
std::string filename = initialLoader->getResourceName(ResourceID(entry["path"].String()));
if (!filename.empty())
{
@ -317,11 +326,14 @@ void CResourceHandler::loadModsFilesystems()
{
#ifdef ENABLE_ERA_FILESYSTEM
auto iterator = initialLoader->getIterator([](const ResourceID & ident)
auto iterator = initialLoader->getIterator([](const ResourceID & ident) -> bool
{
std::string name = ident.getName();
return ident.getType() == EResType::TEXT
&& boost::algorithm::starts_with(ident.getName(), "ALL/MODS/")
&& boost::algorithm::ends_with(ident.getName(), "FILESYSTEM");
&& std::count(name.begin(), name.end(), '/') == 3
&& boost::algorithm::starts_with(name, "ALL/MODS/")
&& boost::algorithm::ends_with(name, "FILESYSTEM");
});
while (iterator.hasNext())

View File

@ -69,11 +69,11 @@ public:
ResourceID();
/**
* Ctor. Can be used to implicitly create indentifier for resource loading
* Ctor. Can be used to create indentifier for resource loading using one parameter
*
* @param name The resource name including extension.
*/
ResourceID(const std::string & fullName);
explicit ResourceID(const std::string & fullName);
/**
* Ctor.

View File

@ -1,114 +0,0 @@
#include "StdInc.h"
#include "ISimpleResourceLoader.h"
#include "CMemoryStream.h"
#include <zlib.h>
std::pair<ui8*, size_t> ISimpleResourceLoader::decompress(ui8 * in, size_t size, size_t realSize)
{
std::pair<ui8*, size_t> retError(nullptr, 0);
//realSize was not set. Use compressed size as basisto gen something usable
if (realSize == 0)
realSize = size * 2;
std::unique_ptr<ui8[]> out(new ui8[realSize]);
const int WBITS = 15;
const int FCHUNK = 50000;
int ret;
z_stream strm;
int lastPosOut = 0;
// Allocate inflate state
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, WBITS);
if (ret != Z_OK)
return retError;
int chunkNumber = 0;
do
{
if(size < chunkNumber * FCHUNK)
break;
strm.avail_in = std::min<size_t>(FCHUNK, size - chunkNumber * FCHUNK);
if (strm.avail_in == 0)
break;
strm.next_in = in + chunkNumber * FCHUNK;
// Run inflate() on input until output buffer not full
do
{
//TODO: check if inflate have any special mode for inflating (e.g Z_BLOCK)
//campaigns which consist from several blocks (campaign header + every map)
//technically .h3c consists from multiple cancatenated gz streams
//inflatings them separately can be useful for campaigns loading
strm.avail_out = realSize - lastPosOut;
strm.next_out = out.get() + lastPosOut;
ret = inflate(&strm, Z_NO_FLUSH);
bool breakLoop = false;
switch (ret)
{
case Z_STREAM_END: //end decompression
breakLoop = true;
case Z_OK: //decompress next chunk
break;
case Z_MEM_ERROR:
case Z_BUF_ERROR:
{
//not enough memory. Allocate bigger buffer and try again
realSize *= 2;
std::unique_ptr<ui8[]> newOut(new ui8[realSize]);
std::copy(out.get(), out.get() + strm.total_out, newOut.get());
out.reset(newOut.release());
}
default:
ret = Z_DATA_ERROR;
inflateEnd(&strm);
return retError;
}
if(breakLoop)
break;
lastPosOut = realSize - strm.avail_out;
}
while (strm.avail_out == 0);
++chunkNumber;
}
while (ret != Z_STREAM_END);
// Clean up and return
while (1)
{
ret = inflateEnd(&strm);
//FIXMWE: duplicates previous switch block
switch (ret)
{
case Z_STREAM_END:
case Z_OK:
//TODO: trim buffer? may be too time consuming
return std::make_pair(out.release(), realSize - strm.avail_out);
case Z_MEM_ERROR:
case Z_BUF_ERROR:
{
//not enough memory. Allocate bigger buffer and try again
realSize *= 2;
std::unique_ptr<ui8[]> newOut(new ui8[realSize]);
std::copy(out.get(), out.get() + strm.total_out, newOut.get());
out.reset(newOut.release());
}
default:
return retError;
}
}
}

View File

@ -18,17 +18,6 @@
*/
class DLL_LINKAGE ISimpleResourceLoader
{
/**
* Decompresses an archive entry.
*
* @param in A pointer to the compressed data array
* @param size The size of the compressed data array
* @param realSize - hint decompressed size (if known)
* @returns pair(decompressed data, size)
*/
static std::pair<ui8*, size_t> decompress(ui8 * in, size_t size, size_t realSize = 0);
public:
/**
* Dtor.

View File

@ -2,6 +2,7 @@
#include "JsonNode.h"
#include "HeroBonus.h"
#include "Filesystem/CResourceLoader.h"
const JsonNode JsonNode::nullNode;
@ -18,9 +19,10 @@ JsonNode::JsonNode(const char *data, size_t datasize):
JsonValidator validator(*this);
}
JsonNode::JsonNode(std::string filename):
JsonNode::JsonNode(ResourceID && fileURI):
type(DATA_NULL)
{
std::string filename = CResourceHandler::get()->getResourceName(fileURI);
FILE * file = fopen(filename.c_str(), "rb");
if (!file)
{

View File

@ -5,6 +5,7 @@ typedef std::map <std::string, JsonNode> JsonMap;
typedef std::vector <JsonNode> JsonVector;
struct Bonus;
class ResourceID;
class DLL_LINKAGE JsonNode
{
@ -38,7 +39,7 @@ public:
//Create tree from Json-formatted input
explicit JsonNode(const char * data, size_t datasize);
//Create tree from JSON file
explicit JsonNode(std::string filename);
explicit JsonNode(ResourceID && fileURI);
//Copy c-tor
JsonNode(const JsonNode &copy);

View File

@ -13,9 +13,8 @@ libvcmi_la_SOURCES = \
Filesystem/CFileInputStream.cpp \
Filesystem/CFilesystemLoader.cpp \
Filesystem/CLodArchiveLoader.cpp \
Filesystem/CMemoryStream.cpp \
Filesystem/CMemoryStream.cpp \
Filesystem/CResourceLoader.cpp \
Filesystem/ISimpleResourceLoader.cpp \
BattleAction.cpp \
BattleAction.h \
BattleState.cpp \
@ -34,8 +33,6 @@ libvcmi_la_SOURCES = \
CCreatureSet.h \
CDefObjInfoHandler.cpp \
CDefObjInfoHandler.h \
CFileUtility.cpp \
CFileUtility.h \
CGameInterface.cpp \
CGameInterface.h \
CGameState.cpp \
@ -44,8 +41,6 @@ libvcmi_la_SOURCES = \
CGeneralTextHandler.h \
CHeroHandler.cpp \
CHeroHandler.h \
CLodHandler.cpp \
CLodHandler.h \
CLogger.cpp \
CLogger.h \
CMapInfo.cpp \

View File

@ -89,15 +89,13 @@ am_libvcmi_la_OBJECTS = libvcmi_la-CBinaryReader.lo \
libvcmi_la-CCompressedStream.lo libvcmi_la-CFileInfo.lo \
libvcmi_la-CFileInputStream.lo libvcmi_la-CFilesystemLoader.lo \
libvcmi_la-CLodArchiveLoader.lo libvcmi_la-CMemoryStream.lo \
libvcmi_la-CResourceLoader.lo \
libvcmi_la-ISimpleResourceLoader.lo libvcmi_la-BattleAction.lo \
libvcmi_la-CResourceLoader.lo libvcmi_la-BattleAction.lo \
libvcmi_la-BattleState.lo libvcmi_la-CArtHandler.lo \
libvcmi_la-CBuildingHandler.lo libvcmi_la-CCampaignHandler.lo \
libvcmi_la-CConsoleHandler.lo libvcmi_la-CCreatureHandler.lo \
libvcmi_la-CCreatureSet.lo libvcmi_la-CDefObjInfoHandler.lo \
libvcmi_la-CFileUtility.lo libvcmi_la-CGameInterface.lo \
libvcmi_la-CGameState.lo libvcmi_la-CGeneralTextHandler.lo \
libvcmi_la-CHeroHandler.lo libvcmi_la-CLodHandler.lo \
libvcmi_la-CGameInterface.lo libvcmi_la-CGameState.lo \
libvcmi_la-CGeneralTextHandler.lo libvcmi_la-CHeroHandler.lo \
libvcmi_la-CLogger.lo libvcmi_la-CMapInfo.lo \
libvcmi_la-CObjectHandler.lo libvcmi_la-CObstacleInstance.lo \
libvcmi_la-CSpellHandler.lo libvcmi_la-CTownHandler.lo \
@ -306,9 +304,8 @@ libvcmi_la_SOURCES = \
Filesystem/CFileInputStream.cpp \
Filesystem/CFilesystemLoader.cpp \
Filesystem/CLodArchiveLoader.cpp \
Filesystem/CMemoryStream.cpp \
Filesystem/CMemoryStream.cpp \
Filesystem/CResourceLoader.cpp \
Filesystem/ISimpleResourceLoader.cpp \
BattleAction.cpp \
BattleAction.h \
BattleState.cpp \
@ -327,8 +324,6 @@ libvcmi_la_SOURCES = \
CCreatureSet.h \
CDefObjInfoHandler.cpp \
CDefObjInfoHandler.h \
CFileUtility.cpp \
CFileUtility.h \
CGameInterface.cpp \
CGameInterface.h \
CGameState.cpp \
@ -337,8 +332,6 @@ libvcmi_la_SOURCES = \
CGeneralTextHandler.h \
CHeroHandler.cpp \
CHeroHandler.h \
CLodHandler.cpp \
CLodHandler.h \
CLogger.cpp \
CLogger.h \
CMapInfo.cpp \
@ -468,14 +461,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CDefObjInfoHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CFileInfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CFileInputStream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CFileUtility.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CFilesystemLoader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CGameInterface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CGameState.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CGeneralTextHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CHeroHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CLodArchiveLoader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CLodHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CLogger.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CMapInfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CMemoryStream.Plo@am__quote@
@ -488,7 +479,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-Connection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-HeroBonus.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-IGameCallback.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-ISimpleResourceLoader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-JsonNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-NetPacksLib.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-ResourceSet.Plo@am__quote@
@ -572,13 +562,6 @@ libvcmi_la-CResourceLoader.lo: Filesystem/CResourceLoader.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CResourceLoader.lo `test -f 'Filesystem/CResourceLoader.cpp' || echo '$(srcdir)/'`Filesystem/CResourceLoader.cpp
libvcmi_la-ISimpleResourceLoader.lo: Filesystem/ISimpleResourceLoader.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-ISimpleResourceLoader.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-ISimpleResourceLoader.Tpo -c -o libvcmi_la-ISimpleResourceLoader.lo `test -f 'Filesystem/ISimpleResourceLoader.cpp' || echo '$(srcdir)/'`Filesystem/ISimpleResourceLoader.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-ISimpleResourceLoader.Tpo $(DEPDIR)/libvcmi_la-ISimpleResourceLoader.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Filesystem/ISimpleResourceLoader.cpp' object='libvcmi_la-ISimpleResourceLoader.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-ISimpleResourceLoader.lo `test -f 'Filesystem/ISimpleResourceLoader.cpp' || echo '$(srcdir)/'`Filesystem/ISimpleResourceLoader.cpp
libvcmi_la-BattleAction.lo: BattleAction.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-BattleAction.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-BattleAction.Tpo -c -o libvcmi_la-BattleAction.lo `test -f 'BattleAction.cpp' || echo '$(srcdir)/'`BattleAction.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-BattleAction.Tpo $(DEPDIR)/libvcmi_la-BattleAction.Plo
@ -642,13 +625,6 @@ libvcmi_la-CDefObjInfoHandler.lo: CDefObjInfoHandler.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CDefObjInfoHandler.lo `test -f 'CDefObjInfoHandler.cpp' || echo '$(srcdir)/'`CDefObjInfoHandler.cpp
libvcmi_la-CFileUtility.lo: CFileUtility.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CFileUtility.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CFileUtility.Tpo -c -o libvcmi_la-CFileUtility.lo `test -f 'CFileUtility.cpp' || echo '$(srcdir)/'`CFileUtility.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CFileUtility.Tpo $(DEPDIR)/libvcmi_la-CFileUtility.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CFileUtility.cpp' object='libvcmi_la-CFileUtility.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CFileUtility.lo `test -f 'CFileUtility.cpp' || echo '$(srcdir)/'`CFileUtility.cpp
libvcmi_la-CGameInterface.lo: CGameInterface.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CGameInterface.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CGameInterface.Tpo -c -o libvcmi_la-CGameInterface.lo `test -f 'CGameInterface.cpp' || echo '$(srcdir)/'`CGameInterface.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CGameInterface.Tpo $(DEPDIR)/libvcmi_la-CGameInterface.Plo
@ -677,13 +653,6 @@ libvcmi_la-CHeroHandler.lo: CHeroHandler.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CHeroHandler.lo `test -f 'CHeroHandler.cpp' || echo '$(srcdir)/'`CHeroHandler.cpp
libvcmi_la-CLodHandler.lo: CLodHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CLodHandler.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CLodHandler.Tpo -c -o libvcmi_la-CLodHandler.lo `test -f 'CLodHandler.cpp' || echo '$(srcdir)/'`CLodHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CLodHandler.Tpo $(DEPDIR)/libvcmi_la-CLodHandler.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CLodHandler.cpp' object='libvcmi_la-CLodHandler.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CLodHandler.lo `test -f 'CLodHandler.cpp' || echo '$(srcdir)/'`CLodHandler.cpp
libvcmi_la-CLogger.lo: CLogger.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CLogger.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CLogger.Tpo -c -o libvcmi_la-CLogger.lo `test -f 'CLogger.cpp' || echo '$(srcdir)/'`CLogger.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CLogger.Tpo $(DEPDIR)/libvcmi_la-CLogger.Plo

View File

@ -6,7 +6,6 @@
#include "CCreatureHandler.h"
#include "CDefObjInfoHandler.h"
#include "CHeroHandler.h"
#include "CLodHandler.h"
#include "CObjectHandler.h"
#include "CTownHandler.h"
#include "CBuildingHandler.h"
@ -37,11 +36,11 @@ DLL_LINKAGE void initDLL(CConsoleHandler *Console, std::ostream *Logfile)
console = Console;
logfile = Logfile;
VLC = new LibClasses;
try
//try
{
VLC->init();
}
HANDLE_EXCEPTION;
//HANDLE_EXCEPTION;
}
DLL_LINKAGE void loadToIt(std::string &dest, const std::string &src, int &iter, int mode)
@ -159,15 +158,19 @@ DLL_LINKAGE void loadToIt(si32 &dest, const std::string &src, int &iter, int mod
dest = atol(pom.c_str());
}
void LibClasses::init()
void LibClasses::loadFilesystem()
{
CStopWatch pomtime;
CResourceHandler::initialize();
CResourceHandler::loadFileSystem("ALL/config/filesystem.json");
CResourceHandler::loadModsFilesystems();
tlog0<<"\tFile system handler: "<<pomtime.getDiff()<<std::endl;
}
void LibClasses::init()
{
CStopWatch pomtime;
generaltexth = new CGeneralTextHandler;
generaltexth->load();

View File

@ -40,7 +40,8 @@ public:
void init(); //uses standard config file
void clear(); //deletes all handlers and its data
void makeNull(); //sets all handler (except of lodhs) pointers to null
static void loadFilesystem();
void callWhenDeserializing(); //should be called only by serialize !!!
template <typename Handler> void serialize(Handler &h, const int version)

View File

@ -7,7 +7,6 @@
#include "CDefObjInfoHandler.h"
#include "VCMI_Lib.h"
#include <boost/crc.hpp>
#include "CLodHandler.h"
#include "CArtHandler.h"
#include "CCreatureHandler.h"
#include "CSpellHandler.h"
@ -32,7 +31,7 @@ static std::set<si32> convertBuildings(const std::set<si32> h3m, int castleID, b
std::set<si32> ret;
// Note: this file is parsed many times.
const JsonNode config(GameConstants::DATA_DIR + "/config/buildings5.json");
const JsonNode config(ResourceID("config/buildings5.json"));
BOOST_FOREACH(const JsonNode &entry, config["table"].Vector())
{
@ -505,8 +504,8 @@ Mapa::Mapa(std::string filename)
{
tlog0<<"Opening map file: "<<filename<<"\t "<<std::flush;
std::unique_ptr<CInputStream> compressed(CResourceHandler::get()->load(ResourceID(filename, EResType::MAP)));
std::unique_ptr<CInputStream> decompressed(new CCompressedStream(compressed, true));
std::unique_ptr<CInputStream> decompressed(new CCompressedStream(
std::move(CResourceHandler::get()->load(ResourceID(filename, EResType::MAP))), true));
//load file and decompress
size_t mapSize = decompressed->getSize();

View File

@ -43,3 +43,20 @@ static inline ui32 read_unaligned_u32(const void *p)
#define read_le_u16(p) (SDL_SwapLE16(* reinterpret_cast<const ui16 *>(p)))
#define read_le_u32(p) (SDL_SwapLE32(* reinterpret_cast<const ui32 *>(p)))
#endif
static inline char readChar(const ui8 * bufor, int &i)
{
return bufor[i++];
}
static inline std::string readString(const ui8 * bufor, int &i)
{
int len = read_le_u32(bufor + i); i+=4;
assert(len >= 0 && len <= 500000); //not too long
std::string ret; ret.reserve(len);
for(int gg=0; gg<len; ++gg)
{
ret += bufor[i++];
}
return ret;
}

View File

@ -507,6 +507,7 @@ int main(int argc, char** argv)
port = _ttoi(argv[1]);
#endif
}
LibClasses::loadFilesystem();
tlog0 << "Port " << port << " will be used." << std::endl;
initDLL(console,logfile);
srand ( (ui32)time(NULL) );