Page 1 of 1

Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 16, 2014 11:55 am
by Metalhead33
I am creating a game - the graphical rendering engine is Irrlicht, the Physics engine is Bullet, I'm going to use SFML for audio, and Lua for scripting.
While I'm having problem with integrating Bullet Physics into Irrlicht (loading Quake 3 maps, that is.... rather than applying physics to simple cubes and circles), I have decided to integrate audio.

Previously, I wrote a crude code that is supposed to handle audio.

Code: Select all

 
std::map<string,sf::Music*> Game_Music;
std::map<string,sf::SoundBuffer> Game_SoundBuffer;
std::map<string,sf::Sound*> Game_Sound;
 
void PlaySong(string song_to_play, float volume, float pitch)
{
Game_Music[song_to_play]->setRelativeToListener(true);
Game_Music[song_to_play]->setVolume(volume);
Game_Music[song_to_play]->setPitch(pitch);
Game_Music["Current Music"] = Game_Music[song_to_play];
Game_Music["Current Music"]->play();
};
 
void PlaySFX_absolute(string sound_to_play, float volume, float pitch)
        {
            sf::Sound* to_play = Game_Sound[sound_to_play];
            to_play->setRelativeToListener(true);
            to_play->setVolume(volume);
            to_play->setPitch(pitch);
            to_play->play();
        };
 
void PlaySFX_3D(string sound_to_play, float volume, float pitch, float attenuation, float x, float y, float z)
        {
            sf::Sound* to_play = Game_Sound[sound_to_play];
            to_play->setRelativeToListener(false);
            to_play->setVolume(volume);
            to_play->setPitch(pitch);
            to_play->setAttenuation(attenuation);
            to_play->setPosition(x, y, z);
            to_play->play();
        };
 
I don't think it's going to work correctly.
Besides, I'm going to use archives to store game files - so I'll need to get them first.

So, I got my eyes on this little thing....

Code: Select all

irrDevice->getFileSystem()->addFileArchive("../maps/map-20kdm2.pk3");
Which made me wonder - can I load sound buffers (and music) from the Irrlicht file system? (and the loaded map-20kdm2.pk3?)

Re: Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 16, 2014 12:02 pm
by CuteAlien
It depends on the audio library you are using. But in general those allow you to pass buffers from memory - in which case you can use the Irrlicht filesystem to load the music into memory first and then pass that memory-block to your audio library.

Re: Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 16, 2014 12:06 pm
by Metalhead33
CuteAlien wrote:It depends on the audio library you are using. But in general those allow you to pass buffers from memory - in which case you can use the Irrlicht filesystem to load the music into memory first and then pass that memory-block to your audio library.
Ah thanks. I'll do that in earnest.

EDIT: On second though...

Maybe I was doing something wrong.

Code: Select all

song_1.openFromMemory(irrDevice->getFileSystem()->createMemoryReadFile(0,0,"TrinityCross.ogg",false),irrDevice->getFileSystem()->createMemoryReadFile(0,0,"TrinityCross.ogg",false)->getSize());
 
song_1.play();
http://www.sfml-dev.org/documentation/2 ... 039111386e

EDIT 2: Ach, I knew it wouldn't be that simple....
But I got this though, which I can learn from.

Re: Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 16, 2014 1:15 pm
by CuteAlien
You don't need a MemoryReadFile here - that is the interface you use when you want to pass stuff to Irrlicht in memory. You want the other way round, so use the usual Irrlicht function to open and read a file. And then pass that block you have read to your sound-library. So something like:

Code: Select all

 
    irr::io::IReadFile* file = irrFileSystem->createAndOpenFile("yourfile");
    if (!file )
    {
        return false;
    }
 
    // Get the file size, so we can pre-allocate the buffer
    long length = file->getSize();
    if ( length == 0 )
    {
        file->drop();
        return false;
    }
 
    char* buf = new char[ length]; // (When reading  ascii-files instead of binary files you would use length+1 and add a 0 at the end)
    file->read(buf, length);
 
    // At this point you have the whole file in memory in the buf variable - do something with it!       
 
    // cleanup
    delete[] buf;
    file->drop();
 

Re: Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 16, 2014 1:26 pm
by Metalhead33
Thank you so much!
It works perfectly!

Well, if I do the cleanup, it crashes*, but otherwise, it works well.

* Which is to be excepted, because SFML's music is not loaded completely, but streamed.
Anyway, thanks. Now I know how to load audio from Irrlicht's filesystem.

Re: Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 16, 2014 4:54 pm
by Metalhead33
I wonder if I could use Lua's dofile command in a similar way.... storing Lua scripts in the Irrlicht File System, and running them from there.

Re: Irrlicht, Bullet, SFML and Lua - File system

Posted: Sun Mar 30, 2014 5:13 pm
by Metalhead33
Everything is fine and dandy, except that this music system does not seem to like Lua...

Code: Select all

 
IrrMusic* global_music;
void LoadSong(std::string song_to_play)
{
    global_music = new IrrMusic(song_to_play);
}
 
static int IrrLuaSongLoad(lua_State *L)
{
    LoadSong((string)lua_tostring(L, 1));
    return 0;
}
If I include the the Lua wrapper, the whole software crashes at start.
If I comment it out, the program works fine, and well. Even the music itself plays perfectly without the Lua wrapper.

If anyone is curious, here is the IrrMusic class:

Code: Select all

bool music_played;
class IrrMusic
{
private:
    long length;
    char* buf;
    irr::io::IReadFile* file;
public:
    sf::Music* nMusic;
    bool LoadFromSystem(std::string filename)
    {
    file = audio_load_from->createAndOpenFile(filename.c_str());
    if (!file )
    {
        return false;
    }
    else
        {
    // Get the file size, so we can pre-allocate the buffer
    length = file->getSize();
    if ( length == 0 )
    {
        file->drop();
        return false;
    }
    else{
    buf = new char[length+1]; // (When reading  ascii-files instead of binary files you would use length+1 and add a 0 at the end)
    file->read(buf, length);
 
    // At this point you have the whole file in memory in the buf variable - do something with it!
    nMusic = new sf::Music();
    music_played = true;
    nMusic->openFromMemory(buf, length);
    file->drop();
    return true;};}
    }
    void StopMusic()
    {nMusic->stop();
    music_played = false;}
    void PlaySong(float volume, float pitch)
    {
    nMusic->setRelativeToListener(true);
    nMusic->setVolume(volume);
    nMusic->setPitch(pitch);
    nMusic->play();
};
    IrrMusic(std::string filename)
    {
        music_played = false;
        LoadFromSystem(filename);
    }
    IrrMusic()
    {
        music_played = false;
    }
    ~IrrMusic()
    {nMusic->stop();
    music_played = false;
    file->drop();
    delete[] buf;
        delete[] nMusic;}
};