mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- music player uses URI's instead of enum from music base
- #1045 and #1046 should be fixed - moved pregame backgrounds to config/mainmenu - animation can be overriden with .json multiple times
This commit is contained in:
parent
385be09248
commit
708ad6ac7f
@ -2576,7 +2576,7 @@ int3 whereToExplore(HeroPtr h)
|
||||
}
|
||||
catch(cannotFulfillGoalException &e)
|
||||
{
|
||||
std::vector<std::vector<int3> > tiles; //tiles[distance_to_fow], metryka taksówkowa
|
||||
std::vector<std::vector<int3> > tiles; //tiles[distance_to_fow]
|
||||
try
|
||||
{
|
||||
return ai->explorationNewPoint(radius, h, tiles);
|
||||
|
8
Global.h
8
Global.h
@ -268,16 +268,16 @@ namespace vstd
|
||||
|
||||
//checks if a is between b and c
|
||||
template <typename t1, typename t2, typename t3>
|
||||
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
|
||||
bool isbetween(const t1 &value, const t2 &min, const t3 &max)
|
||||
{
|
||||
return a > b && a < c;
|
||||
return value > min && value < max;
|
||||
}
|
||||
|
||||
//checks if a is within b and c
|
||||
template <typename t1, typename t2, typename t3>
|
||||
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
|
||||
bool iswithin(const t1 &value, const t2 &min, const t3 &max)
|
||||
{
|
||||
return a >= b && a <= c;
|
||||
return value >= min && value <= max;
|
||||
}
|
||||
|
||||
template <typename t1, typename t2>
|
||||
|
@ -371,7 +371,13 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
||||
CCS->musich->stopMusic();
|
||||
|
||||
int channel = CCS->soundh->playSoundFromSet(CCS->soundh->battleIntroSounds);
|
||||
CCS->soundh->setCallback(channel, boost::bind(&CMusicHandler::playMusicFromSet, CCS->musich, CCS->musich->battleMusics, -1));
|
||||
auto onIntroPlayed = []()
|
||||
{
|
||||
if (LOCPLINT->battleInt)
|
||||
CCS->musich->playMusicFromSet("battle", true);
|
||||
};
|
||||
|
||||
CCS->soundh->setCallback(channel, onIntroPlayed);
|
||||
memset(stackCountOutsideHexes, 1, GameConstants::BFIELD_SIZE * sizeof(bool)); //initialize array with trues
|
||||
|
||||
currentAction = INVALID;
|
||||
@ -446,7 +452,7 @@ CBattleInterface::~CBattleInterface()
|
||||
if(adventureInt && adventureInt->selection)
|
||||
{
|
||||
int terrain = LOCPLINT->cb->getTile(adventureInt->selection->visitablePos())->tertype;
|
||||
CCS->musich->playMusic(CCS->musich->terrainMusics[terrain], -1);
|
||||
CCS->musich->playMusicFromSet("terrain", terrain, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
|
||||
case 2: text = 302; break;
|
||||
}
|
||||
|
||||
CCS->musich->playMusic(musicBase::winBattle);
|
||||
CCS->musich->playMusic("Music/Win Battle", false);
|
||||
CCS->videoh->open(VIDEO_WIN);
|
||||
std::string str = CGI->generaltexth->allTexts[text];
|
||||
|
||||
@ -437,21 +437,21 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
|
||||
{
|
||||
case 0: //normal victory
|
||||
{
|
||||
CCS->musich->playMusic(musicBase::loseCombat);
|
||||
CCS->musich->playMusic("Music/LoseCombat", false);
|
||||
CCS->videoh->open(VIDEO_LOSE_BATTLE_START);
|
||||
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[311]);
|
||||
break;
|
||||
}
|
||||
case 1: //flee
|
||||
{
|
||||
CCS->musich->playMusic(musicBase::retreatBattle);
|
||||
CCS->musich->playMusic("Music/Retreat Battle", false);
|
||||
CCS->videoh->open(VIDEO_RETREAT_START);
|
||||
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[310]);
|
||||
break;
|
||||
}
|
||||
case 2: //surrender
|
||||
{
|
||||
CCS->musich->playMusic(musicBase::surrenderBattle);
|
||||
CCS->musich->playMusic("Music/Surrender Battle", false);
|
||||
CCS->videoh->open(VIDEO_SURRENDER);
|
||||
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[309]);
|
||||
break;
|
||||
|
@ -987,7 +987,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
||||
auto pos = sel->visitablePos();
|
||||
auto tile = LOCPLINT->cb->getTile(pos);
|
||||
if(tile)
|
||||
CCS->musich->playMusic(CCS->musich->terrainMusics[tile->tertype], -1);
|
||||
CCS->musich->playMusicFromSet("terrain", tile->tertype, true);
|
||||
}
|
||||
if(centerView)
|
||||
centerOn(sel);
|
||||
@ -1487,7 +1487,7 @@ const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *ob
|
||||
void CAdvMapInt::aiTurnStarted()
|
||||
{
|
||||
adjustActiveness(true);
|
||||
CCS->musich->playMusicFromSet(CCS->musich->aiMusics);
|
||||
CCS->musich->playMusicFromSet("enemy-turn", true);
|
||||
adventureInt->minimap.setAIRadar(true);
|
||||
adventureInt->infoBar.startEnemyTurn(LOCPLINT->cb->getCurrentPlayer());
|
||||
adventureInt->infoBar.showAll(screen);//force refresh on inactive object
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <SDL_image.h>
|
||||
|
||||
#include "../lib/Filesystem/CResourceLoader.h"
|
||||
#include "../lib/Filesystem/ISimpleResourceLoader.h"
|
||||
#include "../lib/JsonNode.h"
|
||||
#include "../lib/vcmi_endian.h"
|
||||
|
||||
@ -934,9 +935,16 @@ void CAnimation::init(CDefFile * file)
|
||||
source[mapIt->first].resize(mapIt->second);
|
||||
}
|
||||
|
||||
if (CResourceHandler::get()->existsResource(ResourceID(std::string("SPRITES/") + name, EResType::TEXT)))
|
||||
auto & configList = CResourceHandler::get()->getResourcesWithName(
|
||||
ResourceID(std::string("SPRITES/") + name, EResType::TEXT));
|
||||
|
||||
BOOST_FOREACH(auto & entry, configList)
|
||||
{
|
||||
const JsonNode config(ResourceID(std::string("SPRITES/") + name, EResType::TEXT));
|
||||
auto stream = entry.getLoader()->load(entry.getResourceName());
|
||||
std::unique_ptr<ui8[]> textData(new ui8[stream->getSize()]);
|
||||
stream->read(textData.get(), stream->getSize());
|
||||
|
||||
const JsonNode config((char*)textData.get(), stream->getSize());
|
||||
|
||||
std::string basepath;
|
||||
basepath = config["basepath"].String();
|
||||
|
@ -76,7 +76,16 @@ SDL_Surface * BitmapHandler::loadH3PCX(ui8 * pcx, size_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = CSDL_Ext::createSurfaceWithBpp<3>(width, height);
|
||||
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
int bmask = 0xff0000;
|
||||
int gmask = 0x00ff00;
|
||||
int rmask = 0x0000ff;
|
||||
#else
|
||||
int bmask = 0x0000ff;
|
||||
int gmask = 0x00ff00;
|
||||
int rmask = 0xff0000;
|
||||
#endif
|
||||
ret = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24, rmask, gmask, bmask, 0);
|
||||
|
||||
//it == 0xC;
|
||||
for (int i=0; i<height; i++)
|
||||
@ -127,7 +136,7 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
|
||||
|
||||
ret = IMG_LoadTyped_RW(
|
||||
//create SDL_RW with our data (will be deleted by SDL)
|
||||
SDL_RWFromConstMem((void*)readFile.first.release(), readFile.second),
|
||||
SDL_RWFromConstMem((void*)readFile.first.get(), readFile.second),
|
||||
1, // mark it for auto-deleting
|
||||
&info.getExtension()[0] + 1); //pass extension without dot (+1 character)
|
||||
|
||||
|
@ -951,7 +951,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
|
||||
townlist->onSelect = boost::bind(&CCastleInterface::townChange, this);
|
||||
|
||||
recreateIcons();
|
||||
CCS->musich->playMusic(CCS->musich->townMusics[town->subID], -1);
|
||||
CCS->musich->playMusicFromSet("town-theme", town->subID, true);
|
||||
|
||||
bicons = CDefHandler::giveDefEss(graphics->buildingPics[town->subID]);
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* CMusicBase.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
|
||||
*
|
||||
*/
|
||||
|
||||
// Use some magic to keep the list of files and their code name in sync.
|
||||
// FIXME: first half of this list should be read from campmusic.txt
|
||||
|
||||
#define VCMI_MUSIC_LIST \
|
||||
VCMI_MUSIC_ID(campainMusic01) VCMI_MUSIC_FILE("CampainMusic01.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic02) VCMI_MUSIC_FILE("CampainMusic02.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic03) VCMI_MUSIC_FILE("CampainMusic03.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic04) VCMI_MUSIC_FILE("CampainMusic04.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic05) VCMI_MUSIC_FILE("CampainMusic05.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic06) VCMI_MUSIC_FILE("CampainMusic06.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic07) VCMI_MUSIC_FILE("CampainMusic07.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic08) VCMI_MUSIC_FILE("CampainMusic08.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic09) VCMI_MUSIC_FILE("CampainMusic09.mp3") \
|
||||
VCMI_MUSIC_ID(AITheme0) VCMI_MUSIC_FILE("AITheme0.mp3") \
|
||||
VCMI_MUSIC_ID(AITheme1) VCMI_MUSIC_FILE("AITHEME1.MP3") \
|
||||
VCMI_MUSIC_ID(AITheme2) VCMI_MUSIC_FILE("AITHEME2.MP3") \
|
||||
VCMI_MUSIC_ID(combat1) VCMI_MUSIC_FILE("COMBAT01.MP3") \
|
||||
VCMI_MUSIC_ID(combat2) VCMI_MUSIC_FILE("COMBAT02.MP3") \
|
||||
VCMI_MUSIC_ID(combat3) VCMI_MUSIC_FILE("COMBAT03.MP3") \
|
||||
VCMI_MUSIC_ID(combat4) VCMI_MUSIC_FILE("COMBAT04.MP3") \
|
||||
VCMI_MUSIC_ID(castleTown) VCMI_MUSIC_FILE("CstleTown.mp3") \
|
||||
VCMI_MUSIC_ID(towerTown) VCMI_MUSIC_FILE("TowerTown.mp3") \
|
||||
VCMI_MUSIC_ID(rampartTown) VCMI_MUSIC_FILE("RAMPART.MP3") \
|
||||
VCMI_MUSIC_ID(infernoTown) VCMI_MUSIC_FILE("InfernoTown.mp3") \
|
||||
VCMI_MUSIC_ID(necroTown) VCMI_MUSIC_FILE("necroTown.mp3") \
|
||||
VCMI_MUSIC_ID(dungeonTown) VCMI_MUSIC_FILE("DUNGEON.MP3") \
|
||||
VCMI_MUSIC_ID(strongHoldTown) VCMI_MUSIC_FILE("StrongHold.mp3") \
|
||||
VCMI_MUSIC_ID(fortressTown) VCMI_MUSIC_FILE("FortressTown.mp3") \
|
||||
VCMI_MUSIC_ID(elemTown) VCMI_MUSIC_FILE("ElemTown.mp3") \
|
||||
VCMI_MUSIC_ID(dirt) VCMI_MUSIC_FILE("DIRT.MP3") \
|
||||
VCMI_MUSIC_ID(sand) VCMI_MUSIC_FILE("SAND.MP3") \
|
||||
VCMI_MUSIC_ID(grass) VCMI_MUSIC_FILE("GRASS.MP3") \
|
||||
VCMI_MUSIC_ID(snow) VCMI_MUSIC_FILE("SNOW.MP3") \
|
||||
VCMI_MUSIC_ID(swamp) VCMI_MUSIC_FILE("SWAMP.MP3") \
|
||||
VCMI_MUSIC_ID(rough) VCMI_MUSIC_FILE("ROUGH.MP3") \
|
||||
VCMI_MUSIC_ID(underground) VCMI_MUSIC_FILE("Underground.mp3") \
|
||||
VCMI_MUSIC_ID(lava) VCMI_MUSIC_FILE("LAVA.MP3") \
|
||||
VCMI_MUSIC_ID(water) VCMI_MUSIC_FILE("WATER.MP3") \
|
||||
VCMI_MUSIC_ID(goodTheme) VCMI_MUSIC_FILE("GoodTheme.mp3") \
|
||||
VCMI_MUSIC_ID(neutralTheme) VCMI_MUSIC_FILE("NeutralTheme.mp3") \
|
||||
VCMI_MUSIC_ID(evilTheme) VCMI_MUSIC_FILE("EvilTheme.mp3") \
|
||||
VCMI_MUSIC_ID(secretTheme) VCMI_MUSIC_FILE("SecretTheme.mp3") \
|
||||
VCMI_MUSIC_ID(loopLepr) VCMI_MUSIC_FILE("LoopLepr.mp3") \
|
||||
VCMI_MUSIC_ID(mainMenu) VCMI_MUSIC_FILE("MAINMENU.MP3") \
|
||||
VCMI_MUSIC_ID(winScenario) VCMI_MUSIC_FILE("Win Scenario.mp3" ) \
|
||||
VCMI_MUSIC_ID(campainMusic10) VCMI_MUSIC_FILE("CampainMusic10.mp3") \
|
||||
VCMI_MUSIC_ID(bladeABcampaign) VCMI_MUSIC_FILE("BladeABCampaign.mp3") \
|
||||
VCMI_MUSIC_ID(bladeDBcampaign) VCMI_MUSIC_FILE("BladeDBCampaign.mp3") \
|
||||
VCMI_MUSIC_ID(bladeDScampaign) VCMI_MUSIC_FILE("BladeDSCampaign.mp3") \
|
||||
VCMI_MUSIC_ID(bladeFLcampaign) VCMI_MUSIC_FILE("BladeFLCampaign.mp3") \
|
||||
VCMI_MUSIC_ID(bladeFWcampaign) VCMI_MUSIC_FILE("BladeFWCampaign.mp3") \
|
||||
VCMI_MUSIC_ID(bladePWcampaign) VCMI_MUSIC_FILE("BladePFCampaign.mp3") \
|
||||
VCMI_MUSIC_ID(campainMusic11) VCMI_MUSIC_FILE("CampainMusic11.mp3") \
|
||||
VCMI_MUSIC_ID(loseCampain) VCMI_MUSIC_FILE("Lose Campain.mp3") \
|
||||
VCMI_MUSIC_ID(loseCastle) VCMI_MUSIC_FILE("LoseCastle.mp3") \
|
||||
VCMI_MUSIC_ID(loseCombat) VCMI_MUSIC_FILE("LoseCombat.mp3") \
|
||||
VCMI_MUSIC_ID(mainMenuWoG) VCMI_MUSIC_FILE("MainMenuWoG.mp3") \
|
||||
VCMI_MUSIC_ID(retreatBattle) VCMI_MUSIC_FILE("Retreat Battle.mp3") \
|
||||
VCMI_MUSIC_ID(surrenderBattle) VCMI_MUSIC_FILE("Surrender Battle.mp3") \
|
||||
VCMI_MUSIC_ID(ultimateLose) VCMI_MUSIC_FILE("UltimateLose.mp3") \
|
||||
VCMI_MUSIC_ID(winBattle) VCMI_MUSIC_FILE("Win Battle.mp3") \
|
||||
VCMI_MUSIC_ID(defendCastle) VCMI_MUSIC_FILE("Defend Castle.mp3") \
|
||||
|
||||
class musicBase
|
||||
{
|
||||
public:
|
||||
// Make a list of enums
|
||||
#define VCMI_MUSIC_ID(x) x,
|
||||
#define VCMI_MUSIC_FILE(y)
|
||||
enum musicID {
|
||||
music_todo=0, // temp entry until code is fixed
|
||||
VCMI_MUSIC_LIST
|
||||
};
|
||||
#undef VCMI_MUSIC_ID
|
||||
#undef VCMI_MUSIC_FILE
|
||||
};
|
||||
|
||||
|
@ -332,40 +332,27 @@ CMusicHandler::CMusicHandler():
|
||||
{
|
||||
listener(boost::bind(&CMusicHandler::onVolumeChange, this, _1));
|
||||
// Map music IDs
|
||||
|
||||
#ifdef CPP11_USE_INITIALIZERS_LIST
|
||||
|
||||
#define VCMI_MUSIC_ID(x) { musicBase::x ,
|
||||
#define VCMI_MUSIC_FILE(y) y },
|
||||
musics = { VCMI_MUSIC_LIST};
|
||||
#undef VCMI_MUSIC_NAME
|
||||
#undef VCMI_MUSIC_FILE
|
||||
|
||||
#else
|
||||
|
||||
#define VCMI_MUSIC_ID(x) ( musicBase::x ,
|
||||
#define VCMI_MUSIC_FILE(y) y )
|
||||
musics = map_list_of
|
||||
VCMI_MUSIC_LIST;
|
||||
#undef VCMI_MUSIC_NAME
|
||||
#undef VCMI_MUSIC_FILE
|
||||
|
||||
#endif
|
||||
// Vectors for helper
|
||||
aiMusics += musicBase::AITheme0, musicBase::AITheme1, musicBase::AITheme2;
|
||||
const std::string setEnemy[] = {"AITheme0", "AITheme1", "AITheme2"};
|
||||
const std::string setBattle[] = {"Combat01", "Combat02", "Combat03", "Combat04"};
|
||||
const std::string setTerrain[] = {"Dirt", "Sand", "Grass", "Snow", "Swamp", "Rough", "Underground", "Lava", "Water"};
|
||||
const std::string setTowns[] = {"CstleTown", "Rampart", "TowerTown", "InfernoTown",
|
||||
"NecroTown", "Dungeon", "Stronghold", "FortressTown", "ElemTown"};
|
||||
|
||||
battleMusics += musicBase::combat1, musicBase::combat2,
|
||||
musicBase::combat3, musicBase::combat4;
|
||||
auto fillSet = [=](std::string setName, const std::string list[], size_t amount)
|
||||
{
|
||||
for (size_t i=0; i < amount; i++)
|
||||
addEntryToSet(setName, i, std::string("music/") + list[i]);
|
||||
};
|
||||
fillSet("enemy-turn", setEnemy, ARRAY_COUNT(setEnemy));
|
||||
fillSet("battle", setBattle, ARRAY_COUNT(setBattle));
|
||||
fillSet("terrain", setTerrain, ARRAY_COUNT(setTerrain));
|
||||
fillSet("town-theme", setTowns, ARRAY_COUNT(setTowns));
|
||||
}
|
||||
|
||||
townMusics += musicBase::castleTown, musicBase::rampartTown,
|
||||
musicBase::towerTown, musicBase::infernoTown,
|
||||
musicBase::necroTown, musicBase::dungeonTown,
|
||||
musicBase::strongHoldTown, musicBase::fortressTown,
|
||||
musicBase::elemTown;
|
||||
|
||||
terrainMusics += musicBase::dirt, musicBase::sand, musicBase::grass,
|
||||
musicBase::snow, musicBase::swamp, musicBase::rough,
|
||||
musicBase::underground, musicBase::lava,musicBase::water;
|
||||
void CMusicHandler::addEntryToSet(std::string set, int musicID, std::string musicURI)
|
||||
{
|
||||
musicsSet[set][musicID] = musicURI;
|
||||
}
|
||||
|
||||
void CMusicHandler::init()
|
||||
@ -391,23 +378,46 @@ void CMusicHandler::release()
|
||||
CAudioBase::release();
|
||||
}
|
||||
|
||||
// Plays a music
|
||||
// loop: -1 always repeats, 0=do not play, 1+=number of loops
|
||||
void CMusicHandler::playMusic(musicBase::musicID musicID, int loop)
|
||||
void CMusicHandler::playMusic(std::string musicURI, bool loop)
|
||||
{
|
||||
if (current.get() != NULL && *current == musicID)
|
||||
if (current && current->isTrack( musicURI))
|
||||
return;
|
||||
|
||||
queueNext(new MusicEntry(this, musicID, loop));
|
||||
queueNext(new MusicEntry(this, "", musicURI, loop));
|
||||
}
|
||||
|
||||
// Helper. Randomly plays tracks from music_vec
|
||||
void CMusicHandler::playMusicFromSet(std::vector<musicBase::musicID> &music_vec, int loop)
|
||||
void CMusicHandler::playMusicFromSet(std::string whichSet, bool loop)
|
||||
{
|
||||
if (current.get() != NULL && *current == music_vec)
|
||||
auto selectedSet = musicsSet.find(whichSet);
|
||||
if (selectedSet == musicsSet.end())
|
||||
{
|
||||
tlog0 << "Error: playing music from non-existing set: " << whichSet << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (current && current->isSet(whichSet))
|
||||
return;
|
||||
|
||||
queueNext(new MusicEntry(this, music_vec, loop));
|
||||
queueNext(new MusicEntry(this, whichSet, "", loop));
|
||||
}
|
||||
|
||||
|
||||
void CMusicHandler::playMusicFromSet(std::string whichSet, int entryID, bool loop)
|
||||
{
|
||||
auto selectedSet = musicsSet.find(whichSet);
|
||||
if (selectedSet == musicsSet.end())
|
||||
{
|
||||
tlog0 << "Error: playing music from non-existing set: " << whichSet << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
auto selectedEntry = selectedSet->second.find(entryID);
|
||||
if (selectedEntry == selectedSet->second.end())
|
||||
{
|
||||
tlog0 << "Error: playing non-existing entry " << entryID << " from set: " << whichSet << "\n";
|
||||
return;
|
||||
}
|
||||
queueNext(new MusicEntry(this, "", selectedEntry->second, loop));
|
||||
}
|
||||
|
||||
void CMusicHandler::queueNext(MusicEntry *queued)
|
||||
@ -430,7 +440,6 @@ void CMusicHandler::queueNext(MusicEntry *queued)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop and free the current music
|
||||
void CMusicHandler::stopMusic(int fade_ms)
|
||||
{
|
||||
if (!initialized)
|
||||
@ -441,10 +450,8 @@ void CMusicHandler::stopMusic(int fade_ms)
|
||||
if (current.get() != NULL)
|
||||
current->stop(fade_ms);
|
||||
next.reset();
|
||||
|
||||
}
|
||||
|
||||
// Sets the music volume, from 0 (mute) to 100
|
||||
void CMusicHandler::setVolume(ui32 percent)
|
||||
{
|
||||
CAudioBase::setVolume(percent);
|
||||
@ -453,7 +460,6 @@ void CMusicHandler::setVolume(ui32 percent)
|
||||
Mix_VolumeMusic((MIX_MAX_VOLUME * volume)/100);
|
||||
}
|
||||
|
||||
// Called by SDL when a music finished.
|
||||
void CMusicHandler::musicFinishedCallback(void)
|
||||
{
|
||||
boost::mutex::scoped_lock guard(musicMutex);
|
||||
@ -474,50 +480,39 @@ void CMusicHandler::musicFinishedCallback(void)
|
||||
}
|
||||
}
|
||||
|
||||
MusicEntry::MusicEntry(CMusicHandler *_owner, musicBase::musicID _musicID, int _loopCount):
|
||||
owner(_owner),
|
||||
music(NULL),
|
||||
loopCount(_loopCount)
|
||||
MusicEntry::MusicEntry(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped):
|
||||
owner(owner),
|
||||
music(nullptr),
|
||||
looped(looped),
|
||||
setName(setName)
|
||||
{
|
||||
load(_musicID);
|
||||
if (!musicURI.empty())
|
||||
load(musicURI);
|
||||
}
|
||||
|
||||
MusicEntry::MusicEntry(CMusicHandler *_owner, std::vector<musicBase::musicID> &_musicVec, int _loopCount):
|
||||
currentID(musicBase::music_todo),
|
||||
owner(_owner),
|
||||
music(NULL),
|
||||
loopCount(_loopCount),
|
||||
musicVec(_musicVec)
|
||||
{
|
||||
//In this case music will be loaded only on playing - no need to call load() here
|
||||
}
|
||||
|
||||
MusicEntry::~MusicEntry()
|
||||
{
|
||||
tlog5<<"Del-ing music file "<<filename<<"\n";
|
||||
tlog5<<"Del-ing music file "<<currentName<<"\n";
|
||||
if (music)
|
||||
Mix_FreeMusic(music);
|
||||
}
|
||||
|
||||
void MusicEntry::load(musicBase::musicID ID)
|
||||
void MusicEntry::load(std::string musicURI)
|
||||
{
|
||||
if (music)
|
||||
{
|
||||
tlog5<<"Del-ing music file "<<filename<<"\n";
|
||||
tlog5<<"Del-ing music file "<<currentName<<"\n";
|
||||
Mix_FreeMusic(music);
|
||||
}
|
||||
|
||||
currentID = ID;
|
||||
filename = GameConstants::DATA_DIR + "/Mp3/";
|
||||
filename += owner->musics[ID];
|
||||
currentName = musicURI;
|
||||
|
||||
tlog5<<"Loading music file "<<filename<<"\n";
|
||||
tlog5<<"Loading music file "<<musicURI<<"\n";
|
||||
|
||||
music = Mix_LoadMUS(filename.c_str());
|
||||
music = Mix_LoadMUS(CResourceHandler::get()->getResourceName(ResourceID(musicURI, EResType::MUSIC)).c_str());
|
||||
|
||||
if(!music)
|
||||
{
|
||||
tlog3 << "Warning: Cannot open " << filename << ": " << Mix_GetError() << std::endl;
|
||||
tlog3 << "Warning: Cannot open " << currentName << ": " << Mix_GetError() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -529,16 +524,19 @@ void MusicEntry::load(musicBase::musicID ID)
|
||||
|
||||
bool MusicEntry::play()
|
||||
{
|
||||
if (loopCount == 0)
|
||||
if (!looped && music) //already played once - return
|
||||
return false;
|
||||
|
||||
if (loopCount > 0)
|
||||
loopCount--;
|
||||
if (!setName.empty())
|
||||
{
|
||||
auto set = owner->musicsSet[setName];
|
||||
size_t entryID = rand() % set.size();
|
||||
auto iterator = set.begin();
|
||||
std::advance(iterator, entryID);
|
||||
load(iterator->second);
|
||||
}
|
||||
|
||||
if (!musicVec.empty())
|
||||
load(musicVec.at(rand() % musicVec.size()));
|
||||
|
||||
tlog5<<"Playing music file "<<filename<<"\n";
|
||||
tlog5<<"Playing music file "<<currentName<<"\n";
|
||||
if(Mix_PlayMusic(music, 1) == -1)
|
||||
{
|
||||
tlog1 << "Unable to play music (" << Mix_GetError() << ")" << std::endl;
|
||||
@ -549,17 +547,17 @@ bool MusicEntry::play()
|
||||
|
||||
void MusicEntry::stop(int fade_ms)
|
||||
{
|
||||
tlog5<<"Stoping music file "<<filename<<"\n";
|
||||
loopCount = 0;
|
||||
tlog5<<"Stoping music file "<<currentName<<"\n";
|
||||
looped = false;
|
||||
Mix_FadeOutMusic(fade_ms);
|
||||
}
|
||||
|
||||
bool MusicEntry::operator == (musicBase::musicID _musicID) const
|
||||
bool MusicEntry::isSet(std::string set)
|
||||
{
|
||||
return musicVec.empty() && currentID == _musicID;
|
||||
return !setName.empty() && set == setName;
|
||||
}
|
||||
|
||||
bool MusicEntry::operator == (std::vector<musicBase::musicID> &_musicVec) const
|
||||
bool MusicEntry::isTrack(std::string track)
|
||||
{
|
||||
return musicVec == _musicVec;
|
||||
return setName.empty() && track == currentName;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include "CConfigHandler.h"
|
||||
#include "CSoundBase.h"
|
||||
#include "CMusicBase.h"
|
||||
#include "../lib/CCreatureHandler.h"
|
||||
#include "CSndHandler.h"
|
||||
|
||||
@ -113,22 +112,21 @@ class CMusicHandler;
|
||||
//Class for handling one music file
|
||||
class MusicEntry
|
||||
{
|
||||
std::string filename; //used only for debugging and console messages
|
||||
musicBase::musicID currentID;
|
||||
CMusicHandler *owner;
|
||||
Mix_Music *music;
|
||||
int loopCount;
|
||||
//if not empty - vector from which music will be randomly selected
|
||||
std::vector<musicBase::musicID> musicVec;
|
||||
bool looped;
|
||||
//if not null - set from which music will be randomly selected
|
||||
std::string setName;
|
||||
std::string currentName;
|
||||
|
||||
void load(musicBase::musicID);
|
||||
|
||||
void load(std::string musicURI);
|
||||
|
||||
public:
|
||||
bool operator == (musicBase::musicID musicID) const;
|
||||
bool operator == (std::vector<musicBase::musicID> &_musicVec) const;
|
||||
bool isSet(std::string setName);
|
||||
bool isTrack(std::string trackName);
|
||||
|
||||
MusicEntry(CMusicHandler *owner, musicBase::musicID musicID, int _loopCount);
|
||||
MusicEntry(CMusicHandler *owner, std::vector<musicBase::musicID> &_musicVec, int _loopCount);
|
||||
MusicEntry(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped);
|
||||
~MusicEntry();
|
||||
|
||||
bool play();
|
||||
@ -149,22 +147,26 @@ private:
|
||||
unique_ptr<MusicEntry> next;
|
||||
|
||||
void queueNext(MusicEntry *queued);
|
||||
|
||||
std::map<std::string, std::map<int, std::string> > musicsSet;
|
||||
public:
|
||||
CMusicHandler();
|
||||
|
||||
/// add entry with URI musicURI in set. Track will have ID musicID
|
||||
void addEntryToSet(std::string set, int musicID, std::string musicURI);
|
||||
|
||||
void init();
|
||||
void release();
|
||||
void setVolume(ui32 percent);
|
||||
|
||||
// Musics
|
||||
std::map<musicBase::musicID, std::string> musics;
|
||||
std::vector<musicBase::musicID> aiMusics;
|
||||
std::vector<musicBase::musicID> battleMusics;
|
||||
std::vector<musicBase::musicID> townMusics;
|
||||
std::vector<musicBase::musicID> terrainMusics;
|
||||
|
||||
void playMusic(musicBase::musicID musicID, int loop=1);
|
||||
void playMusicFromSet(std::vector<musicBase::musicID> &music_vec, int loop=1);
|
||||
/// play track by URI, if loop = true music will be looped
|
||||
void playMusic(std::string musicURI, bool loop);
|
||||
/// play random track from this set
|
||||
void playMusicFromSet(std::string musicSet, bool loop);
|
||||
/// play specific track from set
|
||||
void playMusicFromSet(std::string musicSet, int entryID, bool loop);
|
||||
void stopMusic(int fade_ms=1000);
|
||||
void musicFinishedCallback(void);
|
||||
|
||||
friend class MusicEntry;
|
||||
};
|
||||
|
@ -256,7 +256,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
if(makingTurn && ho->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
|
||||
{
|
||||
//We may need to change music - select new track, music handler will change it if needed
|
||||
CCS->musich->playMusic(CCS->musich->terrainMusics[LOCPLINT->cb->getTile(ho->visitablePos())->tertype], -1);
|
||||
CCS->musich->playMusicFromSet("terrain", LOCPLINT->cb->getTile(ho->visitablePos())->tertype, true);
|
||||
|
||||
if(details.result == TryMoveHero::TELEPORTATION)
|
||||
{
|
||||
|
@ -259,7 +259,7 @@ void CMenuScreen::show(SDL_Surface * to)
|
||||
|
||||
void CMenuScreen::activate()
|
||||
{
|
||||
CCS->musich->playMusic(musicBase::mainMenu, -1);
|
||||
CCS->musich->playMusic("Music/MainMenu", true);
|
||||
if (!config["video"].isNull())
|
||||
CCS->videoh->open(config["video"]["name"].String());
|
||||
CIntObject::activate();
|
||||
@ -567,13 +567,15 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
|
||||
else if(Type == CMenuScreen::campaignList)
|
||||
{
|
||||
bordered = false;
|
||||
bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true);
|
||||
bg = new CPicture("CamCust.bmp", 0, 0);
|
||||
pos = bg->center();
|
||||
}
|
||||
else
|
||||
{
|
||||
bordered = true;
|
||||
bg = new CPicture(BitmapHandler::loadBitmap(rand()%2 ? "ZPIC1000.bmp" : "ZPIC1001.bmp"), 0, 0, true);
|
||||
//load random background
|
||||
const JsonVector & bgNames = (*CGP->pregameConfig)["game-select"].Vector();
|
||||
bg = new CPicture(bgNames[rand() % bgNames.size()].String(), 0, 0);
|
||||
pos = bg->center();
|
||||
}
|
||||
|
||||
|
@ -489,14 +489,14 @@ public:
|
||||
/// Handles background screen, loads graphics for victory/loss condition and random town or hero selection
|
||||
class CGPreGame : public CIntObject, public IUpdateable
|
||||
{
|
||||
const JsonNode * const pregameConfig;
|
||||
|
||||
void loadGraphics();
|
||||
void disposeGraphics();
|
||||
|
||||
CGPreGame(); //Use createIfNotPresent
|
||||
|
||||
public:
|
||||
const JsonNode * const pregameConfig;
|
||||
|
||||
CMenuScreen* menu;
|
||||
|
||||
SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs
|
||||
|
@ -431,15 +431,27 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
||||
|
||||
CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg, const CStackInstance * Creature)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
pos.x += x;
|
||||
pos.y += y;
|
||||
owner = Owner;
|
||||
|
||||
//assert(Creature == CGI->creh->creatures[Creature->idNumber]);
|
||||
upg = Upg;
|
||||
ID = IID;
|
||||
myStack = Creature;
|
||||
creature = Creature ? Creature->type : NULL;
|
||||
if (creature)
|
||||
{
|
||||
std::string imgName = owner->smallIcons ? "cprsmall" : "TWCRPORT";
|
||||
creatureImage = new CAnimImage(imgName, creature->idNumber + 2);
|
||||
}
|
||||
else
|
||||
creatureImage = nullptr;
|
||||
|
||||
count = Creature ? Creature->count : 0;
|
||||
pos.x += x;
|
||||
pos.y += y;
|
||||
|
||||
if(Owner->smallIcons)
|
||||
{
|
||||
pos.w = 32;
|
||||
@ -450,7 +462,6 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg
|
||||
pos.w = 58;
|
||||
pos.h = 64;
|
||||
}
|
||||
owner = Owner;
|
||||
}
|
||||
|
||||
void CGarrisonSlot::showAll(SDL_Surface * to)
|
||||
@ -458,9 +469,9 @@ void CGarrisonSlot::showAll(SDL_Surface * to)
|
||||
std::map<int,SDL_Surface*> &imgs = (owner->smallIcons ? graphics->smallImgs : graphics->bigImgs);
|
||||
if(creature)
|
||||
{
|
||||
creatureImage->showAll(to);
|
||||
char buf[15];
|
||||
SDL_itoa(count,buf,10);
|
||||
blitAt(imgs[creature->idNumber],pos,to);
|
||||
printTo(buf, pos.x+pos.w, pos.y+pos.h+1, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, Colors::Cornsilk, to);
|
||||
|
||||
if((owner->highlighted==this)
|
||||
@ -476,12 +487,6 @@ void CGarrisonSlot::showAll(SDL_Surface * to)
|
||||
}
|
||||
}
|
||||
|
||||
CGarrisonInt::~CGarrisonInt()
|
||||
{/*
|
||||
for(size_t i = 0; i<splitButtons.size(); i++)
|
||||
delete splitButtons[i];*/
|
||||
}
|
||||
|
||||
void CGarrisonInt::addSplitBtn(CAdventureMapButton * button)
|
||||
{
|
||||
addChild(button);
|
||||
|
@ -306,7 +306,6 @@ class CGarrisonInt;
|
||||
/// A single garrison slot which holds one creature of a specific amount
|
||||
class CGarrisonSlot : public CIntObject
|
||||
{
|
||||
public:
|
||||
int ID; //for identification
|
||||
CGarrisonInt *owner;
|
||||
const CStackInstance *myStack; //NULL if slot is empty
|
||||
@ -315,6 +314,8 @@ public:
|
||||
int upg; //0 - up garrison, 1 - down garrison
|
||||
bool highlight;
|
||||
|
||||
CAnimImage * creatureImage;
|
||||
public:
|
||||
virtual void hover (bool on); //call-in
|
||||
const CArmedInstance * getObj();
|
||||
bool our();
|
||||
@ -322,6 +323,8 @@ public:
|
||||
void clickLeft(tribool down, bool previousState);
|
||||
void showAll(SDL_Surface * to);
|
||||
CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg=0, const CStackInstance * Creature=NULL);
|
||||
|
||||
friend class CGarrisonInt;
|
||||
};
|
||||
|
||||
/// Class which manages slots of upper and lower garrison, splitting of units
|
||||
@ -367,7 +370,6 @@ public:
|
||||
//smallImgs - units images size 64x58 or 32x32;
|
||||
//twoRows - display slots in 2 row (1st row = 4 slots, 2nd = 3 slots)
|
||||
CGarrisonInt(int x, int y, int inx, const Point &garsOffset, SDL_Surface *pomsur, const Point &SurOffset, const CArmedInstance *s1, const CArmedInstance *s2=NULL, bool _removableUnits = true, bool smallImgs = false, bool _twoRows=false); //c-tor
|
||||
~CGarrisonInt(); //d-tor
|
||||
};
|
||||
|
||||
/// draws picture with creature on background, use Animated=true to get animation
|
||||
|
@ -64,8 +64,7 @@ void Graphics::loadPaletteAndColors()
|
||||
|
||||
neutralColorPalette = new SDL_Color[32];
|
||||
std::ifstream ncp;
|
||||
std::string neutralFile = GameConstants::DATA_DIR + "/config/NEUTRAL.PAL";
|
||||
ncp.open(neutralFile.c_str(), std::ios::binary);
|
||||
ncp.open(CResourceHandler::get()->getResourceName(ResourceID("config/NEUTRAL.PAL")), std::ios::binary);
|
||||
for(int i=0; i<32; ++i)
|
||||
{
|
||||
ncp.read((char*)&neutralColorPalette[i].r,1);
|
||||
|
@ -1303,7 +1303,6 @@ void CBoundedLabel::recalculateLines(const std::string &Txt)
|
||||
|
||||
const Font &f = *graphics->fonts[font];
|
||||
int lineHeight = f.height;
|
||||
int lineCapacity = pos.h / lineHeight;
|
||||
|
||||
lines = CMessage::breakText(Txt, pos.w, font);
|
||||
|
||||
|
@ -45,7 +45,7 @@ SDL_Surface * CSDL_Ext::copySurface(SDL_Surface * mod) //returns copy of given s
|
||||
template<int bpp>
|
||||
SDL_Surface * CSDL_Ext::createSurfaceWithBpp(int width, int height)
|
||||
{
|
||||
int rMask = 0, gMask = 0, bMask = 0, aMask = 0;
|
||||
Uint32 rMask = 0, gMask = 0, bMask = 0, aMask = 0;
|
||||
|
||||
Channels::px<bpp>::r.set((Uint8*)&rMask, 255);
|
||||
Channels::px<bpp>::g.set((Uint8*)&gMask, 255);
|
||||
|
@ -26,6 +26,7 @@
|
||||
"SOUNDS/":
|
||||
[
|
||||
{"type" : "file", "path" : "ALL/Data/H3ab_ahd.snd"},
|
||||
{"type" : "file", "path" : "ALL/Data/Heroes3-cd2.snd"},
|
||||
{"type" : "file", "path" : "ALL/Data/Heroes3.snd"},
|
||||
//WoG have overriden sounds with .82m extension in Data
|
||||
{"type" : "dir", "path" : "GLOBAL/Data"},
|
||||
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
//images used in game selection screen
|
||||
"game-select" : ["ZPIC1000", "ZPIC1001"],
|
||||
//Main menu window, consists of several sub-menus aka items
|
||||
"window":
|
||||
{
|
||||
@ -68,7 +70,7 @@
|
||||
{ "x":90, "y":72, "file":"DATA/GOOD1.H3C", "image":"CAMPGD1S", "video":"CGOOD1", "open": true },
|
||||
{ "x":539, "y":72, "file":"DATA/EVIL1.H3C", "image":"CAMPEV1S", "video":"CEVIL1", "open": true },
|
||||
{ "x":43, "y":245, "file":"DATA/GOOD2.H3C", "image":"CAMPGD2S", "video":"CGOOD2", "open": true },
|
||||
{ "x":313, "y":244, "file":"DATA/NEUTRAL.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
|
||||
{ "x":313, "y":244, "file":"DATA/NEUTRAL1.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
|
||||
{ "x":586, "y":246, "file":"DATA/EVIL2.H3C", "image":"CAMPEV2S", "video":"CEVIL2", "open": true },
|
||||
{ "x":34, "y":417, "file":"DATA/GOOD3.H3C", "image":"CAMPGD3S", "video":"CGOOD3", "open": true },
|
||||
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
|
||||
|
@ -560,8 +560,7 @@ void CGeneralTextHandler::load()
|
||||
zcrexp.push_back(nameBuf);
|
||||
}
|
||||
|
||||
std::string threatLevelDir = GameConstants::DATA_DIR + "/config/threatlevel.txt";
|
||||
std::ifstream ifs(threatLevelDir.c_str(), std::ios::in | std::ios::binary);
|
||||
std::ifstream ifs(CResourceHandler::get()->getResourceName(ResourceID("config/threatlevel.txt")), std::ios::binary);
|
||||
getline(ifs, buf); //skip 1st line
|
||||
for (int i = 0; i < 13; ++i)
|
||||
{
|
||||
|
@ -118,6 +118,17 @@ ResourceLocator CResourceLoader::getResource(const ResourceID & resourceIdent) c
|
||||
return resource->second.back();
|
||||
}
|
||||
|
||||
const std::list<ResourceLocator> & CResourceLoader::getResourcesWithName(const ResourceID & resourceIdent) const
|
||||
{
|
||||
static const std::list<ResourceLocator> emptyList;
|
||||
auto resource = resources.find(resourceIdent);
|
||||
|
||||
if (resource == resources.end())
|
||||
return emptyList;
|
||||
return resource->second;
|
||||
}
|
||||
|
||||
|
||||
std::string CResourceLoader::getResourceName(const ResourceID & resourceIdent) const
|
||||
{
|
||||
auto locator = getResource(resourceIdent);
|
||||
@ -147,6 +158,11 @@ void CResourceLoader::addLoader(std::string mountPoint, ISimpleResourceLoader *
|
||||
|
||||
// Create identifier and locator and add them to the resources list
|
||||
ResourceID ident(mountPoint, file.getStem(), file.getType());
|
||||
|
||||
//check if entry can be directory. Will only work for filesystem loader but H3 archives don't have dirs anyway.
|
||||
if (boost::filesystem::is_directory(loader->getOrigin() + '/' + entry))
|
||||
ident.setType(EResType::DIRECTORY);
|
||||
|
||||
ResourceLocator locator(loader, entry);
|
||||
resources[ident].push_back(locator);
|
||||
}
|
||||
@ -247,6 +263,7 @@ std::string EResTypeHelper::getEResTypeAsString(EResType::Type type)
|
||||
MAP_ENUM(CLIENT_SAVEGAME)
|
||||
MAP_ENUM(LIB_SAVEGAME)
|
||||
MAP_ENUM(SERVER_SAVEGAME)
|
||||
MAP_ENUM(DIRECTORY)
|
||||
MAP_ENUM(OTHER);
|
||||
|
||||
#undef MAP_ENUM
|
||||
@ -279,17 +296,10 @@ 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)
|
||||
{
|
||||
//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);
|
||||
@ -298,26 +308,26 @@ void CResourceHandler::loadFileSystem(const std::string fsConfigURI)
|
||||
{
|
||||
BOOST_FOREACH(auto & entry, mountPoint.second.Vector())
|
||||
{
|
||||
tlog5 << "loading resource at " << entry["path"].String() << ": ";
|
||||
std::string filename = initialLoader->getResourceName(ResourceID(entry["path"].String()));
|
||||
tlog5 << "loading resource at " << entry["path"].String() << "\n";
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
if (entry["type"].String() == "dir")
|
||||
{
|
||||
std::string filename = initialLoader->getResourceName(ResourceID(entry["path"].String(), EResType::DIRECTORY));
|
||||
if (!filename.empty())
|
||||
{
|
||||
int depth = 16;
|
||||
if (!entry["depth"].isNull())
|
||||
depth = entry["depth"].Float();
|
||||
resourceLoader->addLoader(mountPoint.first, new CFilesystemLoader(filename, depth));
|
||||
}
|
||||
}
|
||||
|
||||
if (entry["type"].String() == "file")
|
||||
{
|
||||
std::string filename = initialLoader->getResourceName(ResourceID(entry["path"].String(), EResType::ARCHIVE));
|
||||
if (!filename.empty())
|
||||
resourceLoader->addLoader(mountPoint.first, new CLodArchiveLoader(filename));
|
||||
|
||||
tlog5 << "OK\n";
|
||||
}
|
||||
else
|
||||
tlog5 << "Not found\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ namespace EResType
|
||||
CLIENT_SAVEGAME,
|
||||
LIB_SAVEGAME,
|
||||
SERVER_SAVEGAME,
|
||||
DIRECTORY,
|
||||
OTHER
|
||||
};
|
||||
}
|
||||
@ -259,9 +260,12 @@ public:
|
||||
* @return resource locator for this resource or empty one if resource was not found
|
||||
*/
|
||||
ResourceLocator getResource(const ResourceID & resourceIdent) const;
|
||||
|
||||
/// returns ALL overriden resources with same name, including last one acessible via getResource
|
||||
const std::list<ResourceLocator> & getResourcesWithName(const ResourceID & resourceIdent) const;
|
||||
|
||||
/// returns real name of file in filesystem. Not usable for archives
|
||||
std::string getResourceName(const ResourceID & resourceIdent) const;
|
||||
/// return size of file or 0 if not found
|
||||
|
||||
/**
|
||||
* Get iterator for looping all files matching filter
|
||||
|
Loading…
Reference in New Issue
Block a user