//----------------------------------------------------------------------------- // // ImageLib Sources // Copyright (C) 2000-2009 by Denton Woods // Last modified: 03/07/2009 // // Filename: src-IL/src/il_wal.c // // Description: Loads a Quake .wal texture. // //----------------------------------------------------------------------------- #include "il_internal.h" #ifndef IL_NO_WAL #include "il_manip.h" #include "il_q2pal.h" typedef struct WALHEAD { ILbyte FileName[32]; // Image name ILuint Width; // Width of first image ILuint Height; // Height of first image ILuint Offsets[4]; // Offsets to image data ILbyte AnimName[32]; // Name of next frame ILuint Flags; // ?? ILuint Contents; // ?? ILuint Value; // ?? } WALHEAD; ILboolean iLoadWalInternal(void); //! Reads a .wal file ILboolean ilLoadWal(ILconst_string FileName) { ILHANDLE WalFile; ILboolean bWal = IL_FALSE; WalFile = iopenr(FileName); if (WalFile == NULL) { ilSetError(IL_COULD_NOT_OPEN_FILE); return bWal; } bWal = ilLoadWalF(WalFile); icloser(WalFile); return bWal; } //! Reads an already-opened .wal file ILboolean ilLoadWalF(ILHANDLE File) { ILuint FirstPos; ILboolean bRet; iSetInputFile(File); FirstPos = itell(); bRet = iLoadWalInternal(); iseek(FirstPos, IL_SEEK_SET); return bRet; } //! Reads from a memory "lump" that contains a .wal file ILboolean ilLoadWalL(const void *Lump, ILuint Size) { iSetInputLump(Lump, Size); return iLoadWalInternal(); } ILboolean iLoadWalInternal() { WALHEAD Header; ILimage *Mipmaps[3], *CurImage; ILuint i, NewW, NewH; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } CurImage = iCurImage; // Read header iread(&Header.FileName, 1, 32); Header.Width = GetLittleUInt(); Header.Height = GetLittleUInt(); for (i = 0; i < 4; i++) Header.Offsets[i] = GetLittleUInt(); iread(Header.AnimName, 1, 32); Header.Flags = GetLittleUInt(); Header.Contents = GetLittleUInt(); Header.Value = GetLittleUInt(); if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; for (i = 0; i < 3; i++) { Mipmaps[i] = (ILimage*)icalloc(sizeof(ILimage), 1); if (Mipmaps[i] == NULL) goto cleanup_error; Mipmaps[i]->Pal.Palette = (ILubyte*)ialloc(768); if (Mipmaps[i]->Pal.Palette == NULL) goto cleanup_error; memcpy(Mipmaps[i]->Pal.Palette, ilDefaultQ2Pal, 768); Mipmaps[i]->Pal.PalType = IL_PAL_RGB24; } NewW = Header.Width; NewH = Header.Height; for (i = 0; i < 3; i++) { NewW /= 2; NewH /= 2; iCurImage = Mipmaps[i]; if (!ilTexImage(NewW, NewH, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) goto cleanup_error; // Don't set until now so ilTexImage won't get rid of the palette. Mipmaps[i]->Pal.PalSize = 768; Mipmaps[i]->Origin = IL_ORIGIN_UPPER_LEFT; } iCurImage = CurImage; ilCloseImage(iCurImage->Mipmaps); iCurImage->Mipmaps = Mipmaps[0]; Mipmaps[0]->Mipmaps = Mipmaps[1]; Mipmaps[1]->Mipmaps = Mipmaps[2]; iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) ifree(iCurImage->Pal.Palette); iCurImage->Pal.Palette = (ILubyte*)ialloc(768); if (iCurImage->Pal.Palette == NULL) goto cleanup_error; iCurImage->Pal.PalSize = 768; iCurImage->Pal.PalType = IL_PAL_RGB24; memcpy(iCurImage->Pal.Palette, ilDefaultQ2Pal, 768); iseek(Header.Offsets[0], IL_SEEK_SET); if (iread(iCurImage->Data, Header.Width * Header.Height, 1) != 1) goto cleanup_error; for (i = 0; i < 3; i++) { iseek(Header.Offsets[i+1], IL_SEEK_SET); if (iread(Mipmaps[i]->Data, Mipmaps[i]->Width * Mipmaps[i]->Height, 1) != 1) goto cleanup_error; } // Fixes all images, even mipmaps. return ilFixImage(); cleanup_error: for (i = 0; i < 3; i++) { ilCloseImage(Mipmaps[i]); } return IL_FALSE; } #endif//IL_NO_WAL