diff options
Diffstat (limited to 'DevIL/src-IL/src/il_doom.cpp')
-rw-r--r-- | DevIL/src-IL/src/il_doom.cpp | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/DevIL/src-IL/src/il_doom.cpp b/DevIL/src-IL/src/il_doom.cpp new file mode 100644 index 00000000..d032f24d --- /dev/null +++ b/DevIL/src-IL/src/il_doom.cpp @@ -0,0 +1,271 @@ +//----------------------------------------------------------------------------- +// +// ImageLib Sources +// Copyright (C) 2000-2009 by Denton Woods +// Last modified: 03/07/2009 +// +// Filename: src-IL/src/il_doom.c +// +// Description: Reads Doom textures and flats +// +//----------------------------------------------------------------------------- + + +#include "il_internal.h" +#ifndef IL_NO_DOOM +#include "il_pal.h" +#include "il_doompal.h" + + +ILboolean iLoadDoomInternal(void); +ILboolean iLoadDoomFlatInternal(void); + + +// +// READ A DOOM IMAGE +// + +//! Reads a Doom file +ILboolean ilLoadDoom(ILconst_string FileName) +{ + ILHANDLE DoomFile; + ILboolean bDoom = IL_FALSE; + + // Not sure of any kind of specified extension...maybe .lmp? + /*if (!iCheckExtension(FileName, "")) { + ilSetError(IL_INVALID_EXTENSION); + return NULL; + }*/ + + DoomFile = iopenr(FileName); + if (DoomFile == NULL) { + ilSetError(IL_COULD_NOT_OPEN_FILE); + return bDoom; + } + + bDoom = ilLoadDoomF(DoomFile); + icloser(DoomFile); + + return bDoom; +} + + +//! Reads an already-opened Doom file +ILboolean ilLoadDoomF(ILHANDLE File) +{ + ILuint FirstPos; + ILboolean bRet; + + iSetInputFile(File); + FirstPos = itell(); + bRet = iLoadDoomInternal(); + iseek(FirstPos, IL_SEEK_SET); + + return bRet; +} + + +//! Reads from a memory "lump" that contains a Doom texture +ILboolean ilLoadDoomL(const void *Lump, ILuint Size) +{ + iSetInputLump(Lump, Size); + return iLoadDoomInternal(); +} + + +// From the DTE sources (mostly by Denton Woods with corrections by Randy Heit) +ILboolean iLoadDoomInternal() +{ + ILshort width, height, graphic_header[2], column_loop, row_loop; + ILint column_offset, pointer_position, first_pos; + ILubyte post, topdelta, length; + ILubyte *NewData; + ILuint i; + + if (iCurImage == NULL) { + ilSetError(IL_ILLEGAL_OPERATION); + return IL_FALSE; + } + + first_pos = itell(); // Needed to go back to the offset table + width = GetLittleShort(); + height = GetLittleShort(); + graphic_header[0] = GetLittleShort(); // Not even used + graphic_header[1] = GetLittleShort(); // Not even used + + if (!ilTexImage(width, height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { + return IL_FALSE; + } + iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; + + iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE); + if (iCurImage->Pal.Palette == NULL) { + return IL_FALSE; + } + iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE; + iCurImage->Pal.PalType = IL_PAL_RGB24; + memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE); + + // 247 is always the transparent colour (usually cyan) + memset(iCurImage->Data, 247, iCurImage->SizeOfData); + + for (column_loop = 0; column_loop < width; column_loop++) { + column_offset = GetLittleInt(); + pointer_position = itell(); + iseek(first_pos + column_offset, IL_SEEK_SET); + + while (1) { + if (iread(&topdelta, 1, 1) != 1) + return IL_FALSE; + if (topdelta == 255) + break; + if (iread(&length, 1, 1) != 1) + return IL_FALSE; + if (iread(&post, 1, 1) != 1) + return IL_FALSE; // Skip extra byte for scaling + + for (row_loop = 0; row_loop < length; row_loop++) { + if (iread(&post, 1, 1) != 1) + return IL_FALSE; + if (row_loop + topdelta < height) + iCurImage->Data[(row_loop+topdelta) * width + column_loop] = post; + } + iread(&post, 1, 1); // Skip extra scaling byte + } + + iseek(pointer_position, IL_SEEK_SET); + } + + // Converts palette entry 247 (cyan) to transparent. + if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { + NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4); + if (NewData == NULL) { + return IL_FALSE; + } + + for (i = 0; i < iCurImage->SizeOfData; i++) { + NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; + NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; + NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; + NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0; + } + + if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, + 4, IL_RGBA, iCurImage->Type, NewData)) { + ifree(NewData); + return IL_FALSE; + } + iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; + ifree(NewData); + } + + return ilFixImage(); +} + + +// +// READ A DOOM FLAT +// + +//! Reads a Doom flat file +ILboolean ilLoadDoomFlat(ILconst_string FileName) +{ + ILHANDLE FlatFile; + ILboolean bFlat = IL_FALSE; + + // Not sure of any kind of specified extension...maybe .lmp? + /*if (!iCheckExtension(FileName, "")) { + ilSetError(IL_INVALID_EXTENSION); + return NULL; + }*/ + + FlatFile = iopenr(FileName); + if (FlatFile == NULL) { + ilSetError(IL_COULD_NOT_OPEN_FILE); + return bFlat; + } + + bFlat = ilLoadDoomF(FlatFile); + icloser(FlatFile); + + return bFlat; +} + + +//! Reads an already-opened Doom flat file +ILboolean ilLoadDoomFlatF(ILHANDLE File) +{ + ILuint FirstPos; + ILboolean bRet; + + iSetInputFile(File); + FirstPos = itell(); + bRet = iLoadDoomFlatInternal(); + iseek(FirstPos, IL_SEEK_SET); + + return bRet; +} + + +//! Reads from a memory "lump" that contains a Doom flat +ILboolean ilLoadDoomFlatL(const void *Lump, ILuint Size) +{ + iSetInputLump(Lump, Size); + return iLoadDoomFlatInternal(); +} + + +// Basically just ireads 4096 bytes and copies the palette +ILboolean iLoadDoomFlatInternal() +{ + ILubyte *NewData; + ILuint i; + + if (iCurImage == NULL) { + ilSetError(IL_ILLEGAL_OPERATION); + return IL_FALSE; + } + + if (!ilTexImage(64, 64, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { + return IL_FALSE; + } + iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; + + iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE); + if (iCurImage->Pal.Palette == NULL) { + return IL_FALSE; + } + iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE; + iCurImage->Pal.PalType = IL_PAL_RGB24; + memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE); + + if (iread(iCurImage->Data, 1, 4096) != 4096) + return IL_FALSE; + + if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { + NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4); + if (NewData == NULL) { + return IL_FALSE; + } + + for (i = 0; i < iCurImage->SizeOfData; i++) { + NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; + NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; + NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; + NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0; + } + + if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, + 4, IL_RGBA, iCurImage->Type, NewData)) { + ifree(NewData); + return IL_FALSE; + } + iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; + ifree(NewData); + } + + return ilFixImage(); +} + + +#endif |