bool Texture2D::LoadPOT(const std::string& imageFile, const Color& colorKey) {
	SDL_Surface* image = NULL;
	GLint colors;
	GLenum format = 0;

	if((image = IMG_Load(imageFile.c_str())) == NULL) {
		image = NULL;
		return false;
	}

	Width = (float)GetNearestPowerOfTwo(image->w);
	Height = (float)GetNearestPowerOfTwo(image->h);
	u = 1.f;
	v = 1.f;

	SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, colorKey.R, colorKey.G, colorKey.B));
	SDL_Surface* newImage = SDL_DisplayFormatAlpha(image);

	colors = newImage->format->BytesPerPixel;

	if(colors == 4) {
		format = GL_RGBA;

		if(newImage->format->Rmask == 0x000000ff)
			format = GL_RGBA;
        else
            format = GL_BGRA;
	} else if(colors == 3) {
		format = GL_RGB;

        if(newImage->format->Rmask == 0x000000ff)
            format = GL_RGB;
        else
            format = GL_BGR;
    } else {
		std::cerr << "Warning: Image is not truecolor. This might break" << std::endl
				  << "Image file: " << imageFile << std::endl;
    }

	if (textureID != 0)
		glDeleteTextures(1, &textureID);

	glGenTextures(1, &textureID);
	glBindTexture(GL_TEXTURE_2D, textureID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, colors, Width, Height, 0, format, GL_UNSIGNED_BYTE, newImage->pixels);

	if(image)
		SDL_FreeSurface(image);
	if(newImage)
		SDL_FreeSurface(newImage);

	image = NULL;
	newImage = NULL;

	return true;
}
Ejemplo n.º 2
0
bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount)
{
    TMPQArchive * ha = (TMPQArchive *)hMpq;
    DWORD dwNewHashTableSize = 0;
    int nError = ERROR_SUCCESS;

    // Test the valid parameters
    if(!IsValidMpqHandle(hMpq))
        nError = ERROR_INVALID_HANDLE;
    if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
        nError = ERROR_ACCESS_DENIED;
    if(dwMaxFileCount < ha->dwFileTableSize)
        nError = ERROR_DISK_FULL;

    // ALL file names must be known in order to be able to rebuild hash table
    if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
    {
        nError = CheckIfAllFilesKnown(ha);
        if(nError == ERROR_SUCCESS)
        {
            // Calculate the hash table size for the new file limit
            dwNewHashTableSize = GetNearestPowerOfTwo(dwMaxFileCount);

            // Rebuild both file tables
            nError = RebuildFileTable(ha, dwNewHashTableSize);
        }
    }

    // We always have to rebuild the (attributes) file due to file table change
    if(nError == ERROR_SUCCESS)
    {
        // Invalidate (listfile) and (attributes)
        InvalidateInternalFiles(ha);

        // Rebuild the HET table, if we have any
        if(ha->pHetTable != NULL)
            nError = RebuildHetTable(ha);
    }

    // Return the error
    if(nError != ERROR_SUCCESS)
        SetLastError(nError);
    return (nError == ERROR_SUCCESS);
}
Ejemplo n.º 3
0
bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq)
{
    TFileStream * pStream = NULL;           // File stream
    TMPQArchive * ha = NULL;                // MPQ archive handle
    TMPQHeader * pHeader;
    ULONGLONG MpqPos = 0;                   // Position of MPQ header in the file
    HANDLE hMpq = NULL;
    DWORD dwBlockTableSize = 0;             // Initial block table size
    DWORD dwHashTableSize = 0;
    DWORD dwReservedFiles = 0;              // Number of reserved file entries
    DWORD dwMpqFlags = 0;
    int nError = ERROR_SUCCESS;

    // Check the parameters, if they are valid
    if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // Verify if all variables in SFILE_CREATE_MPQ are correct
    if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ))    ||
       (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4)                              ||
       (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0)               ||
       (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL)                                 ||
       (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1))                   ||
       (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // One time initialization of MPQ cryptography
    InitializeMpqCryptography();

    // We verify if the file already exists and if it's a MPQ archive.
    // If yes, we won't allow to overwrite it.
    if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq))
    {
        SFileCloseArchive(hMpq);
        SetLastError(ERROR_ALREADY_EXISTS);
        return false;
    }

    //
    // At this point, we have to create the archive.
    // - If the file exists, convert it to MPQ archive.
    // - If the file doesn't exist, create new empty file
    //

    pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags);
    if(pStream == NULL)
    {
        pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags);
        if(pStream == NULL)
            return false;
    }

    // Increment the maximum amount of files to have space for (listfile)
    if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags1)
    {
        dwMpqFlags |= MPQ_FLAG_LISTFILE_NEW;
        dwReservedFiles++;
    }

    // Increment the maximum amount of files to have space for (attributes)
    if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags2 && pCreateInfo->dwAttrFlags)
    {
        dwMpqFlags |= MPQ_FLAG_ATTRIBUTES_NEW;
        dwReservedFiles++;
    }

    // Increment the maximum amount of files to have space for (signature)
    if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags3)
    {
        dwMpqFlags |= MPQ_FLAG_SIGNATURE_NEW;
        dwReservedFiles++;
    }

    // If file count is not zero, initialize the hash table size
    dwHashTableSize = GetNearestPowerOfTwo(pCreateInfo->dwMaxFileCount + dwReservedFiles);

    // Retrieve the file size and round it up to 0x200 bytes
    FileStream_GetSize(pStream, &MpqPos);
    MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL;
    if(!FileStream_SetSize(pStream, MpqPos))
        nError = GetLastError();

#ifdef _DEBUG    
    // Debug code, used for testing StormLib
//  dwBlockTableSize = dwHashTableSize * 2;
#endif

    // Create the archive handle
    if(nError == ERROR_SUCCESS)
    {
        if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Fill the MPQ archive handle structure
    if(nError == ERROR_SUCCESS)
    {
        memset(ha, 0, sizeof(TMPQArchive));
        ha->pfnHashString   = HashStringSlash;
        ha->pStream         = pStream;
        ha->dwSectorSize    = pCreateInfo->dwSectorSize;
        ha->UserDataPos     = MpqPos;
        ha->MpqPos          = MpqPos;
        ha->pHeader         = pHeader = (TMPQHeader *)ha->HeaderData;
        ha->dwMaxFileCount  = dwHashTableSize;
        ha->dwFileTableSize = 0;
        ha->dwReservedFiles = dwReservedFiles;
        ha->dwFileFlags1    = pCreateInfo->dwFileFlags1;
        ha->dwFileFlags2    = pCreateInfo->dwFileFlags2;
        ha->dwFileFlags3    = pCreateInfo->dwFileFlags3 ? MPQ_FILE_EXISTS : 0;
        ha->dwAttrFlags     = pCreateInfo->dwAttrFlags;
        ha->dwFlags         = dwMpqFlags | MPQ_FLAG_CHANGED;
        pStream = NULL;

        // Fill the MPQ header
        memset(pHeader, 0, sizeof(ha->HeaderData));
        pHeader->dwID             = ID_MPQ;
        pHeader->dwHeaderSize     = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
        pHeader->dwArchiveSize    = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
        pHeader->wFormatVersion   = (USHORT)pCreateInfo->dwMpqVersion;
        pHeader->wSectorSize      = GetSectorSizeShift(ha->dwSectorSize);
        pHeader->dwHashTablePos   = pHeader->dwHeaderSize;
        pHeader->dwHashTableSize  = dwHashTableSize;
        pHeader->dwBlockTablePos  = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
        pHeader->dwBlockTableSize = dwBlockTableSize;

        // For MPQs version 4 and higher, we set the size of raw data block
        // for calculating MD5
        if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
            pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize;

        // Write the naked MPQ header
        nError = WriteNakedMPQHeader(ha);
    }

    // Create initial HET table, if the caller required an MPQ format 3.0 or newer
    if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3 && pCreateInfo->dwMaxFileCount != 0)
    {
        ha->pHetTable = CreateHetTable(ha->dwFileTableSize, 0, 0x40, NULL);
        if(ha->pHetTable == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Create initial hash table
    if(nError == ERROR_SUCCESS && dwHashTableSize != 0)
    {
        nError = CreateHashTable(ha, dwHashTableSize);
    }

    // Create initial file table
    if(nError == ERROR_SUCCESS && ha->dwMaxFileCount != 0)
    {
        nError = CreateFileTable(ha, ha->dwMaxFileCount);
    }

    // Cleanup : If an error, delete all buffers and return
    if(nError != ERROR_SUCCESS)
    {
        FileStream_Close(pStream);
        FreeArchiveHandle(ha);
        SetLastError(nError);
        ha = NULL;
    }
    
    // Return the values
    *phMpq = (HANDLE)ha;
    return (nError == ERROR_SUCCESS);
}