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

Modified CMediaHandler to handle more than one file.

This commit is contained in:
Frank Zago 2011-08-07 19:14:46 +00:00
parent f417cee2c0
commit 2cc80e1267
6 changed files with 63 additions and 47 deletions

View File

@ -62,7 +62,7 @@ void CAudioBase::setVolume(unsigned int percent)
volume = percent; volume = percent;
} }
CSoundHandler::CSoundHandler(): sndh(NULL) CSoundHandler::CSoundHandler()
{ {
// Map sound names // Map sound names
#define VCMI_SOUND_NAME(x) ( soundBase::x, #define VCMI_SOUND_NAME(x) ( soundBase::x,
@ -86,16 +86,17 @@ void CSoundHandler::init()
{ {
CAudioBase::init(); CAudioBase::init();
if (initialized) if (initialized) {
// Load sounds // Load sounds
sndh = new CSndHandler(std::string(DATA_DIR "/Data/Heroes3.snd")); sndh.add_file(std::string(DATA_DIR "/Data/Heroes3.snd"));
sndh.add_file(std::string(DATA_DIR "/Data/H3ab_ahd.snd"));
}
} }
void CSoundHandler::release() void CSoundHandler::release()
{ {
if (initialized) { if (initialized) {
Mix_HaltChannel(-1); Mix_HaltChannel(-1);
delete sndh;
std::map<soundBase::soundID, Mix_Chunk *>::iterator it; std::map<soundBase::soundID, Mix_Chunk *>::iterator it;
for (it=soundChunks.begin(); it != soundChunks.end(); it++) { for (it=soundChunks.begin(); it != soundChunks.end(); it++) {
@ -118,7 +119,7 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
// Load and insert // Load and insert
int size; int size;
const char *data = sndh->extract(it->second, size); const char *data = sndh.extract(it->second, size);
if (!data) if (!data)
return NULL; return NULL;

View File

@ -6,7 +6,7 @@
#include "CSoundBase.h" #include "CSoundBase.h"
#include "CMusicBase.h" #include "CMusicBase.h"
#include "../lib/CCreatureHandler.h" #include "../lib/CCreatureHandler.h"
#include "CSndHandler.h"
/* /*
* CMusicHandler.h, part of VCMI engine * CMusicHandler.h, part of VCMI engine
@ -18,7 +18,6 @@
* *
*/ */
class CSndHandler;
class CSpell; class CSpell;
struct _Mix_Music; struct _Mix_Music;
typedef struct _Mix_Music Mix_Music; typedef struct _Mix_Music Mix_Music;
@ -67,7 +66,7 @@ public:
class CSoundHandler: public CAudioBase class CSoundHandler: public CAudioBase
{ {
private: private:
CSndHandler *sndh; CSndHandler sndh;
soundBase::soundID getSoundID(std::string &fileName); soundBase::soundID getSoundID(std::string &fileName);
std::map<soundBase::soundID, Mix_Chunk *> soundChunks; std::map<soundBase::soundID, Mix_Chunk *> soundChunks;

View File

@ -14,16 +14,27 @@
* *
*/ */
/* Media file are kept in container files. We map these files in
* memory, parse them and create an index of them to easily retrieve
* the data+size of the objects. */
CMediaHandler::~CMediaHandler() CMediaHandler::~CMediaHandler()
{ {
std::vector<boost::iostreams::mapped_file_source *>::iterator it;
entries.clear(); entries.clear();
fimap.clear(); fimap.clear();
mfile->close();
delete mfile; for (it=mfiles.begin() ; it < mfiles.end(); it++ ) {
(*it)->close();
delete *it;
}
} }
CMediaHandler::CMediaHandler(std::string fname) boost::iostreams::mapped_file_source *CMediaHandler::add_file(std::string fname)
{ {
boost::iostreams::mapped_file_source *mfile;
try //c-tor of mapped_file_source throws exception on failure try //c-tor of mapped_file_source throws exception on failure
{ {
mfile = new boost::iostreams::mapped_file_source(fname); mfile = new boost::iostreams::mapped_file_source(fname);
@ -32,15 +43,19 @@ CMediaHandler::CMediaHandler(std::string fname)
{ {
tlog1 << "Cannot open " << fname << std::endl; tlog1 << "Cannot open " << fname << std::endl;
throw std::string("Cannot open ")+fname; throw std::string("Cannot open ")+fname;
return NULL;
} else {
mfiles.push_back(mfile);
return mfile;
} }
} }
void CMediaHandler::extract(int index, std::string dstfile) //saves selected file void CMediaHandler::extract(int index, std::string dstfile) //saves selected file
{ {
std::ofstream out(dstfile.c_str(),std::ios_base::binary); std::ofstream out(dstfile.c_str(),std::ios_base::binary);
const char *data = mfile->data(); Entry &entry = entries[index];
out.write(&data[entries[index].offset], entries[index].size); out.write(entry.data, entry.size);
out.close(); out.close();
} }
@ -98,10 +113,10 @@ MemberFile CMediaHandler::getFile(std::string name)
const char * CMediaHandler::extract (int index, int & size) const char * CMediaHandler::extract (int index, int & size)
{ {
size = entries[index].size; Entry &entry = entries[index];
const char *data = mfile->data();
return &data[entries[index].offset]; size = entry.size;
return entry.data;
} }
const char * CMediaHandler::extract (std::string srcName, int &size) const char * CMediaHandler::extract (std::string srcName, int &size)
@ -119,35 +134,38 @@ const char * CMediaHandler::extract (std::string srcName, int &size)
return NULL; return NULL;
} }
CSndHandler::CSndHandler(std::string fname) : CMediaHandler(fname) void CSndHandler::add_file(std::string fname)
{ {
const unsigned char *data = (const unsigned char *)mfile->data(); boost::iostreams::mapped_file_source *mfile = CMediaHandler::add_file(fname);
if (!mfile)
/* File doesn't exist. Silently skip it.*/
return;
const char *data = mfile->data();
unsigned int numFiles = SDL_SwapLE32(*(Uint32 *)&data[0]); unsigned int numFiles = SDL_SwapLE32(*(Uint32 *)&data[0]);
struct soundEntry *se = (struct soundEntry *)&data[4]; struct soundEntry *se = (struct soundEntry *)&data[4];
for (unsigned int i=0; i<numFiles; i++, se++) for (unsigned int i=0; i<numFiles; i++, se++)
{ {
Entry entry; Entry entry;
// char *p;
// Reassemble the filename, drop extension
entry.name = se->filename; entry.name = se->filename;
// entry.name += '.';
// p = se->filename;
// while(*p) p++;
// p++;
// entry.name += p;
entry.offset = SDL_SwapLE32(se->offset); entry.offset = SDL_SwapLE32(se->offset);
entry.size = SDL_SwapLE32(se->size); entry.size = SDL_SwapLE32(se->size);
entry.data = mfile->data() + entry.offset;
entries.push_back(entry); entries.push_back(entry);
fimap[entry.name] = i; fimap[entry.name] = i;
} }
} }
CVidHandler::CVidHandler(std::string fname) : CMediaHandler(fname) void CVidHandler::add_file(std::string fname)
{ {
boost::iostreams::mapped_file_source *mfile = CMediaHandler::add_file(fname);
if (!mfile)
/* File doesn't exist. Silently skip it.*/
return;
if(mfile->size() < 48) if(mfile->size() < 48)
{ {
tlog1 << fname << " doesn't contain needed data!\n"; tlog1 << fname << " doesn't contain needed data!\n";
@ -173,6 +191,7 @@ CVidHandler::CVidHandler(std::string fname) : CMediaHandler(fname)
entry.size = SDL_SwapLE32(ve_next->offset) - entry.offset; entry.size = SDL_SwapLE32(ve_next->offset) - entry.offset;
} }
entry.data = mfile->data() + entry.offset;
entries.push_back(entry); entries.push_back(entry);
fimap[entry.name] = i; fimap[entry.name] = i;

View File

@ -54,15 +54,16 @@ protected:
std::string name; std::string name;
unsigned int size; unsigned int size;
unsigned int offset; unsigned int offset;
const char *data;
}; };
boost::iostreams::mapped_file_source *mfile; std::vector<boost::iostreams::mapped_file_source *> mfiles;
boost::iostreams::mapped_file_source *add_file(std::string fname);
public: public:
std::vector<Entry> entries; std::vector<Entry> entries;
std::map<std::string, int> fimap; // map of file and index std::map<std::string, int> fimap; // map of file and index
~CMediaHandler(); //d-tor ~CMediaHandler(); //d-tor
CMediaHandler(std::string fname); //c-tor
void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file
const char * extract (std::string srcfile, int & size); //return selecte file data, NULL if file doesn't exist const char * extract (std::string srcfile, int & size); //return selecte file data, NULL if file doesn't exist
void extract(int index, std::string dstfile); //saves selected file void extract(int index, std::string dstfile); //saves selected file
@ -73,13 +74,13 @@ public:
class CSndHandler: public CMediaHandler class CSndHandler: public CMediaHandler
{ {
public: public:
CSndHandler(std::string fname); void add_file(std::string fname);
}; };
class CVidHandler: public CMediaHandler class CVidHandler: public CMediaHandler
{ {
public: public:
CVidHandler(std::string fname); void add_file(std::string fname);
}; };

View File

@ -401,15 +401,14 @@ void CSmackPlayer::redraw( int x, int y, SDL_Surface *dst, bool update )
CVideoPlayer::CVideoPlayer() CVideoPlayer::CVideoPlayer()
{ {
vidh = new CVidHandler(std::string(DATA_DIR "/Data/VIDEO.VID")); vidh.add_file(std::string(DATA_DIR "/Data/VIDEO.VID"));
vidh_ab = new CVidHandler(std::string(DATA_DIR "/Data/H3ab_ahd.vid")); vidh.add_file(std::string(DATA_DIR "/Data/H3ab_ahd.vid"));
current = NULL; current = NULL;
} }
CVideoPlayer::~CVideoPlayer() CVideoPlayer::~CVideoPlayer()
{ {
delete vidh;
delete vidh_ab;
} }
bool CVideoPlayer::open(std::string name) bool CVideoPlayer::open(std::string name)
@ -663,8 +662,8 @@ CVideoPlayer::CVideoPlayer()
av_register_protocol(&lod_protocol); av_register_protocol(&lod_protocol);
#endif #endif
vidh = new CVidHandler(std::string(DATA_DIR "/Data/VIDEO.VID")); vidh.add_file(std::string(DATA_DIR "/Data/VIDEO.VID"));
vidh_ab = new CVidHandler(std::string(DATA_DIR "/Data/H3ab_ahd.vid")); vidh.add_file(std::string(DATA_DIR "/Data/H3ab_ahd.vid"));
} }
// loop = to loop through the video // loop = to loop through the video
@ -679,10 +678,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
refreshCount = -1; refreshCount = -1;
doLoop = loop; doLoop = loop;
data = vidh->extract(fname, length); data = vidh.extract(fname, length);
if (!data) {
data = vidh_ab->extract(fname, length);
}
if (data) { if (data) {
// Create our URL name with the 'lod' protocol as a prefix and a // Create our URL name with the 'lod' protocol as a prefix and a

View File

@ -9,6 +9,8 @@ struct SDL_Surface;
#define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing #define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing
#include <windows.h> #include <windows.h>
#include "CSndHandler.h"
#pragma pack(push,1) #pragma pack(push,1)
struct BINK_STRUCT struct BINK_STRUCT
{ {
@ -161,8 +163,7 @@ class CVidHandler;
class CVideoPlayer : public IVideoPlayer class CVideoPlayer : public IVideoPlayer
{ {
private: private:
CVidHandler * vidh; //.vid file handling CVidHandler vidh; //.vid file handling
CVidHandler *vidh_ab; // armageddon's blade video file handling
CSmackPlayer smkPlayer; //for .SMK CSmackPlayer smkPlayer; //for .SMK
CBIKHandler bikPlayer; //for .BIK CBIKHandler bikPlayer; //for .BIK
@ -199,6 +200,7 @@ public:
#else #else
#include "CSndHandler.h"
#include <SDL_video.h> #include <SDL_video.h>
typedef struct AVFormatContext AVFormatContext; typedef struct AVFormatContext AVFormatContext;
@ -206,7 +208,6 @@ typedef struct AVCodecContext AVCodecContext;
typedef struct AVCodec AVCodec; typedef struct AVCodec AVCodec;
typedef struct AVFrame AVFrame; typedef struct AVFrame AVFrame;
struct SwsContext; struct SwsContext;
class CVidHandler;
class CVideoPlayer //: public IVideoPlayer class CVideoPlayer //: public IVideoPlayer
{ {
@ -224,8 +225,7 @@ private:
SDL_Rect destRect; // valid when dest is used SDL_Rect destRect; // valid when dest is used
SDL_Rect pos; // destination on screen SDL_Rect pos; // destination on screen
CVidHandler *vidh; CVidHandler vidh;
CVidHandler *vidh_ab;
int refreshWait; // Wait several refresh before updating the image int refreshWait; // Wait several refresh before updating the image
int refreshCount; int refreshCount;