/**
 * Caution: This is Galaxy only and will be replaced some time
 * This function loads the PC Speaker sounds to CG (Galaxy Version, similar to Vorticon Version but not equal.)
 */
bool CAudioGalaxy::readPCSpeakerSoundintoWaveForm(CSoundSlot &soundslot, const byte *pcsdata, const unsigned int bytesize, const Uint8 formatsize)
{
	byte *pcsdata_ptr = (byte*)pcsdata;
	const longword size = READLONGWORD(pcsdata_ptr);
	soundslot.priority = READWORD(pcsdata_ptr);
	soundslot.setupAudioSpec(&m_AudioSpec);

	std::vector<Sint16> waveform;
	// TODO:  There should be a better way of determining if sound is signed or not...
	int AMP;
	if ((m_AudioSpec.format == AUDIO_S8) || (m_AudioSpec.format == AUDIO_S16))
		AMP = ((((1<<(formatsize*8))>>2)-1)*PC_Speaker_Volume)/100;
	else
bool CMapLoaderGalaxy::loadMap(CMap &Map, Uint8 level)
{
    // Get the MAPHEAD Location from within the Exe File or an external file
    std::vector<char> mapHeadContainer;
    const std::string &path = gKeenFiles.gameDir;

    // Set Map position and some flags for the freshly loaded level
    Map.gotoPos(0,0);
    Map.setLevel(level);
    Map.isSecret = false;
    Map.mNumFuses = 0;

    // In case no external file was read, let's use data from the embedded data
    byte *Maphead = gKeenFiles.exeFile.getRawData() + getMapheadOffset();

    // In case there is an external file read it into the container and replace the pointer
    const std::string mapHeadFilename = gKeenFiles.mapheadFilename;
    std::ifstream MapHeadFile;

    if(OpenGameFileR(MapHeadFile, getResourceFilename(mapHeadFilename,path,true,false), std::ios::binary))
    {
        // get length of file:
        MapHeadFile.seekg (0, std::ios::end);
        unsigned int length = MapHeadFile.tellg();
        MapHeadFile.seekg (0, std::ios::beg);
        mapHeadContainer.resize(length);
        MapHeadFile.read(&mapHeadContainer[0],length*sizeof(char));
        Maphead = reinterpret_cast<byte*>(&mapHeadContainer[0]);
    }

    word magic_word;
    longword level_offset;

    // Get the magic number of the level data from MAPHEAD Located in the EXE-File.
    // This is used for the decompression.
    magic_word = READWORD(Maphead);

    // Get location of the level data from MAPHEAD Located in the EXE-File.
    Maphead += level*sizeof(longword);
    level_offset = READLONGWORD(Maphead);

    // Open the Gamemaps file
    std::string gamemapfile = gKeenFiles.gamemapsFilename;

    std::ifstream MapFile;
    if(OpenGameFileR(MapFile, getResourceFilename(gamemapfile,path,true,false), std::ios::binary))
    {
        if(level_offset == 0 && mapHeadContainer.empty())
        {
            MapFile.close();
            gLogging.textOut("This Level doesn't exist in GameMaps");
            return false;
        }

        // Then jump to that location and read the level map data
        MapFile.seekg (level_offset, std::ios::beg);

        int headbegin;

        // Get the level plane header
        if(gotoNextSignature(MapFile))
        {
            /*
            *			  Plane Offsets:  Long[3]   Offset within GAMEMAPS to the start of the plane.  The first offset is for the background plane, the
            *                           second for the foreground plane, and the third for the info plane (see below).
            *			  Plane Lengths:  Word[3]   Length (in bytes) of the compressed plane data.  The first length is for the background plane, the
            *                           second for the foreground plane, and the third for the info plane (see below).
            *			  Width:          Word      Level width (in tiles).
            *			  Height:         Word      Level height (in tiles).  Together with Width, this can be used to calculate the uncompressed
            *										size of plane data, by multiplying Width by Height and multiplying the result by sizeof(Word).
            *			  Name:           Byte[16]  Null-terminated string specifying the name of the level.  This name is used only by TED5, not by Keen.
            *			  Signature:      Byte[4]   Marks the end of the Level Header.  Always "!ID!".
            */
            int jumpback = 3*sizeof(longword) + 3*sizeof(word) +
                           2*sizeof(word) + 16*sizeof(byte) + 4*sizeof(byte);

            headbegin = static_cast<int>(MapFile.tellg()) - jumpback;
        }
        else
        {
            MapFile.clear();
            headbegin =  level_offset;
        }

        MapFile.seekg( headbegin, std::ios_base::beg);

        // Get the header of level data
        longword Plane_Offset[3];
        longword Plane_Length[3];
        word Width, Height;
        char name[17];

        // Get the plane offsets
        Plane_Offset[0] = fgetl(MapFile);
        Plane_Offset[1] = fgetl(MapFile);
        Plane_Offset[2] = fgetl(MapFile);

        // Get the dimensions of the level
        Plane_Length[0] = fgetw(MapFile);
        Plane_Length[1] = fgetw(MapFile);
        Plane_Length[2] = fgetw(MapFile);

        Width = fgetw(MapFile);
        Height = fgetw(MapFile);


        if(Width>1024 || Height>1024)
        {
            gLogging.textOut("Sorry, but I cannot uncompress this map and must give up."
                             "Please report this to the developers and send that version to them in order to fix it.<br>" );
            return false;
        }


        for(int c=0 ; c<16 ; c++)
        {
            name[c] = MapFile.get();
        }
        name[16] = '\0';

        // Get and check the signature
        gLogging.textOut("Loading the Level \"" + static_cast<std::string>(name) + "\" (Level No. "+ itoa(level) + ")<br>" );
        Map.setLevelName(name);

        mLevelName = name;

        // Then decompress the level data using rlew and carmack
        gLogging.textOut("Decompressing the Map...<br>" );

        // Start with the Background
        Map.createEmptyDataPlane(0, Width, Height);
        Map.createEmptyDataPlane(1, Width, Height);
        Map.createEmptyDataPlane(2, Width, Height);

        unpackPlaneData(MapFile, Map, 0, Plane_Offset[0], Plane_Length[0], magic_word);
        unpackPlaneData(MapFile, Map, 1, Plane_Offset[1], Plane_Length[1], magic_word);
        unpackPlaneData(MapFile, Map, 2, Plane_Offset[2], Plane_Length[2], magic_word);


        Map.collectBlockersCoordiantes();
        MapFile.close();

        // Now that we have all the 3 planes (Background, Foreground, Foes) unpacked...
        // We only will show the first two of them in the screen, because the Foes one
        // is the one which will be used for spawning the foes (Keen, platforms, enemies, etc.)
        spawnFoes(Map);
    }
    else
    {
        return false;
    }


    // Set Scrollbuffer
    Map.drawAll();
    gVideoDriver.updateScrollBuffer(Map.m_scrollx, Map.m_scrolly);

    return true;
}