summaryrefslogtreecommitdiff
path: root/src/win95/d3_image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win95/d3_image.cpp')
-rw-r--r--src/win95/d3_image.cpp2491
1 files changed, 0 insertions, 2491 deletions
diff --git a/src/win95/d3_image.cpp b/src/win95/d3_image.cpp
deleted file mode 100644
index c068b82..0000000
--- a/src/win95/d3_image.cpp
+++ /dev/null
@@ -1,2491 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include "d3_image.hpp"
-#include "platform.h"
-
-// define = 1 if you dont have pre-quantized images to load into palettized D3D texture surfaces
-#define QUANTISE_ON_LOAD 0
-
-#if debug
-#define DEBUG_TRANSPARENCY 1
-#else
-#define DEBUG_TRANSPARENCY 0
-#endif
-
-// image loader stuff
-
-#if OUTPUT_LOG
-#include "debuglog.hpp"
-LogFile CL_LogFile("DB_IMLD.LOG");
-#endif
-
-#if TIME_LOADS
-unsigned int OpenTime;
-unsigned int CloseTime;
-unsigned int ReadTime;
-#endif
-
-static inline unsigned long read_le_dword(D3I_FILE * f)
-{
- unsigned char d1,d2,d3,d4;
- d3i_fread(&d1,1,1,f);
- d3i_fread(&d2,1,1,f);
- d3i_fread(&d3,1,1,f);
- d3i_fread(&d4,1,1,f);
-
- return (unsigned long)d1 | (unsigned long)d2<<8 | (unsigned long)d3<<16 | (unsigned long)d4<<24;
-}
-
-static inline unsigned short read_le_word(D3I_FILE * f)
-{
- unsigned char d1,d2;
- d3i_fread(&d1,1,1,f);
- d3i_fread(&d2,1,1,f);
-
- return (unsigned short)d1 | (unsigned short)((unsigned short)d2<<8);
-}
-
-// some default globals
-CL_ImageMode CL_Image::imode = CLM_GLOBALPALETTE;
-CL_ImageMode CL_Image::imode_d3d = CLM_ATTACHEDPALETTE;
-CL_ImageMode CL_Image::imode_ddraw = CLM_GLOBALPALETTE;
-LPDDSURFACEDESC CL_Image::format = 0;
-unsigned int CL_Image::bitsperpixel;
-unsigned int CL_Image::bitsperpixel_d3d;
-unsigned int CL_Image::bitsperpixel_ddraw;
-CL_LoadMode CL_Image::lmode = CLL_DDSURFACE;
-
-CL_DX_Format CL_Pixel_32::f;
-CL_DX_Format CL_Pixel_32::f_d3d;
-CL_DX_Format CL_Pixel_32::f_ddraw;
-CL_DX_Format CL_Pixel_16::f;
-CL_DX_Format CL_Pixel_16::f_d3d;
-CL_DX_Format CL_Pixel_16::f_ddraw;
-
-
-void CL_Image::DeleteNotMips(void)
-{
- if (im24)
- {
- delete[] *im24;
- delete[] im24;
- im24 = 0;
- }
- if (im16)
- {
- delete[] *im16;
- delete[] im16;
- im16 = 0;
- }
- if (im8)
- {
- delete[] *im8;
- delete[] im8;
- im8 = 0;
- }
- if (palette)
- {
- delete[] palette;
- palette = 0;
- palette_size = 0;
- }
- flags.loaded = 0;
- flags.raw16bit = 0;
-}
-
-void CL_Image::Delete(void)
-{
- DeleteNotMips();
- while (mipmaps.size())
- {
- delete mipmaps.last_entry();
- mipmaps.delete_last_entry();
- }
-}
-
-
-void CL_Image::Copy(CL_Image const & i2)
-{
- if (i2.im24)
- {
- im24 = new CL_Pixel_24 * [height];
- *im24 = new CL_Pixel_24 [size];
-
- CL_Pixel_24 const * sptr = *i2.im24;
- CL_Pixel_24 * dptr = *im24;
-
- for (int i=size; i; --i)
- {
- *dptr++ = *sptr++;
- }
-
- CL_Pixel_24 const * * dptrptr = (CL_Pixel_24 const * *) im24;
- CL_Pixel_24 const * aptr = *im24;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
-
- if (i2.im16)
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- CL_Pixel_16 const * sptr = *i2.im16;
- CL_Pixel_16 * dptr = *im16;
-
- for (int i=size; i; --i)
- {
- *dptr++ = *sptr++;
- }
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 const * aptr = *im16;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
-
- if (i2.im8)
- {
- im8 = new unsigned char * [height];
- *im8 = new unsigned char [size];
-
- unsigned char const * sptr = *i2.im8;
- unsigned char * dptr = *im8;
-
- for (int i=size; i; --i)
- {
- *dptr++ = *sptr++;
- }
-
- unsigned char const * * dptrptr = (unsigned char const * *) im8;
- unsigned char const * aptr = *im8;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
-
- if (i2.palette)
- {
- palette = new CL_Pixel_24 [palette_size];
-
- CL_Pixel_24 const * sptr = i2.palette;
- CL_Pixel_24 * dptr = palette;
-
- for (int i=palette_size; i; --i)
- {
- *dptr++ = *sptr;
- }
- }
-
- if (i2.name)
- {
- name = new char [strlen(i2.name)+1];
- strcpy(name,i2.name);
- }
-
- if (i2.fname)
- {
- fname = new char [strlen(i2.fname)+1];
- strcpy(fname,i2.fname);
- }
-
- for (CLIF<CL_Image *> i_mip(&i2.mipmaps); !i_mip.done(); i_mip.next())
- {
- mipmaps.add_entry_end(new CL_Image(*i_mip()));
- }
-}
-
-
-CL_Image::~CL_Image()
-{
- Delete();
- if (fname) delete[] fname;
- if (name) delete[] name;
-}
-
-
-CL_Image::CL_Image(CL_Image const & i2)
-: width(i2.width)
-, height(i2.height)
-, size(i2.size)
-, im24(0)
-, im16(0)
-, im8(0)
-, palette(0)
-, palette_size(i2.palette_size)
-, fname(0)
-, name(0)
-, flags(i2.flags)
-{
- Copy(i2);
-}
-
-
-CL_Image & CL_Image::operator = (CL_Image const & i2)
-{
- if (&i2 != this)
- {
- Delete();
- if (fname) delete[] fname;
- if (name) delete[] name;
-
- width = i2.width;
- height = i2.height;
- size = i2.size;
- palette_size = i2.palette_size;
-
- fname = 0;
- name = 0;
-
- flags = i2.flags;
-
- Copy(i2);
- }
- return *this;
-}
-
-
-CL_Error CL_Image::Make(int const _width, int const _height)
-{
- Delete();
-
- width = _width;
- height = _height;
- palette_size = 0;
- size = width*height;
-
- switch (imode)
- {
- case CLM_ATTACHEDPALETTE:
- {
- palette_size = 256;
- palette = new CL_Pixel_24 [palette_size];
- }
- case CLM_GLOBALPALETTE:
- case CLM_TLTPALETTE:
- {
- im8 = new unsigned char * [height];
- *im8 = new unsigned char [size];
-
- unsigned char const * * dptrptr = (unsigned char const * *) im8;
- unsigned char * dptr = *im8;
- for (int i=height; i; --i, dptr+=width)
- {
- *dptrptr++ = dptr;
- }
-
- break;
- }
- case CLM_24BIT:
- {
- im24 = new CL_Pixel_24 * [height];
- *im24 = new CL_Pixel_24 [size];
-
- CL_Pixel_24 const * * dptrptr = (CL_Pixel_24 const * *) im24;
- CL_Pixel_24 const * aptr = *im24;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- break;
- }
- case CLM_16BIT:
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 const * aptr = *im16;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- break;
- }
- case CLM_32BIT:
- {
- im32 = new CL_Pixel_32 * [height];
- *im32 = new CL_Pixel_32 [size];
-
- CL_Pixel_32 const * * dptrptr = (CL_Pixel_32 const * *) im32;
- CL_Pixel_32 const * aptr = *im32;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- break;
- }
- default:
- return CLE_INVALIDDXMODE;
- }
-
- flags.loaded = 1;
- return CLE_OK;
-}
-
-
-CL_Error CL_Image::MakeRandom(int const _width, int const _height, int const seed)
-{
- Delete();
-
- if (-1!=seed) srand((unsigned int)seed);
-
- width = _width;
- height = _height;
- size = width*height;
- palette_size = 0;
-
- switch (imode)
- {
- case CLM_ATTACHEDPALETTE:
- {
- palette_size = 256;
- palette = new CL_Pixel_24 [palette_size];
- CL_Pixel_24 * palP = palette;
- for (int i=palette_size; i; --i, ++palP)
- {
- *palP = CL_Pixel_24(rand()&255,rand()&255,rand()&255);
- }
- }
- case CLM_GLOBALPALETTE:
- case CLM_TLTPALETTE:
- {
- im8 = new unsigned char * [height];
- *im8 = new unsigned char [size];
-
- unsigned char const * * dptrptr = (unsigned char const * *) im8;
- unsigned char * dptr = *im8;
- for (int i=height; i; --i)
- {
- *dptrptr++ = dptr;
- for (int j=width; j; --j, ++dptr)
- *dptr = (unsigned char)(rand()&(palette_size-1));
- }
-
- break;
- }
- case CLM_24BIT:
- {
- im24 = new CL_Pixel_24 * [height];
- *im24 = new CL_Pixel_24 [size];
-
- CL_Pixel_24 const * * dptrptr = (CL_Pixel_24 const * *) im24;
- CL_Pixel_24 * aptr = *im24;
- for (int i=height; i; --i)
- {
- *dptrptr++ = aptr;
- for (int j=width; j; --j, ++aptr)
- *aptr = CL_Pixel_24(rand()&255,rand()&255,rand()&255);
- }
-
- break;
- }
- case CLM_16BIT:
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 * aptr = *im16;
- for (int i=height; i; --i)
- {
- *dptrptr++ = aptr;
- for (int j=width; j; --j, ++aptr)
- *aptr = CL_Pixel_24(rand()&255,rand()&255,rand()&255);
- }
-
- break;
- }
- case CLM_32BIT:
- {
- im32 = new CL_Pixel_32 * [height];
- *im32 = new CL_Pixel_32 [size];
-
- CL_Pixel_32 const * * dptrptr = (CL_Pixel_32 const * *) im32;
- CL_Pixel_32 * aptr = *im32;
- for (int i=height; i; --i)
- {
- *dptrptr++ = aptr;
- for (int j=width; j; --j, ++aptr)
- *aptr = CL_Pixel_24(rand()&255,rand()&255,rand()&255);
- }
-
- break;
- }
- default:
- return CLE_INVALIDDXMODE;
- }
-
- flags.loaded = 1;
- return CLE_OK;
-}
-
-
-CL_Error CL_Image::Load_BMP(D3I_FILE * f)
-{
- if (!f) return CLE_OPENERROR;
-
- DeleteNotMips();
-
- switch (imode)
- {
- case CLM_ATTACHEDPALETTE:
- case CLM_24BIT:
- case CLM_16BIT:
- case CLM_32BIT:
- break;
- default:
- return CLE_INVALIDDXMODE;
- }
-
- d3i_fseek(f,0,SEEK_SET);
- unsigned short magic;
- d3i_fread(&magic,2,1,f);
- if (magic != *(unsigned short const *)"BM") return CLE_LOADERROR;
-
- size_t filesize = read_le_dword(f);
- d3i_fseek(f,4,SEEK_CUR);
- size_t offset = read_le_dword(f);
- size_t headsize = read_le_dword(f);
-
- unsigned short bitdepth;
-
- if (12 == headsize) // OS/2 1.x
- {
- width = read_le_word(f);
- height = read_le_word(f);
- size = width * height;
- if (!width || !height) return CLE_LOADERROR;
- unsigned short planes = read_le_word(f);
- if (1 != planes) return CLE_LOADERROR;
- bitdepth = read_le_word(f);
-
- if (bitdepth != 24)
- {
- palette_size = 1<<bitdepth;
- palette = new CL_Pixel_24 [palette_size];
- CL_Pixel_24 * rptr = palette;
- for (int i=palette_size; i; --i)
- {
- rptr++->Read(f,CLF_BGR);
- }
- }
- }
- else if (40 == headsize || 64 == headsize) // Windows 3.x || OS/2 2.x
- {
- width = read_le_dword(f);
- height = read_le_dword(f);
- unsigned short planes = read_le_word(f);
- if (1 != planes) return CLE_LOADERROR;
- bitdepth = read_le_word(f);
-
- if (read_le_dword(f)) return CLE_LOADERROR; // compressed bmps not supported
-
- size = read_le_dword(f);
-
- d3i_fseek(f,8,SEEK_CUR);
- palette_size = read_le_dword(f);
- if (!palette_size && bitdepth != 24) palette_size = 1<<bitdepth;
-
- if (palette_size)
- {
- d3i_fseek(f,headsize+14,SEEK_SET);
- palette = new CL_Pixel_24 [palette_size];
- CL_Pixel_24 * rptr = palette;
- for (int i=palette_size; i; --i)
- {
- rptr++->Read(f,CLF_BGRX);
- }
- }
- }
- else return CLE_LOADERROR;
-
- d3i_fseek(f,offset,SEEK_SET);
-
- if (palette_size)
- {
- if (bitdepth < 4)
- {
- delete[] palette;
- palette_size = 0;
- return CLE_LOADERROR;
- }
-
- im8 = new unsigned char * [height];
- *im8 = new unsigned char [size];
-
- unsigned char const * * dptrptr = (unsigned char const * *) im8;
- unsigned char * dptr = *im8;
- for (int i=height; i; --i, dptr+=width)
- {
- *dptrptr++ = dptr;
- }
-
- #if DEBUG_TRANSPARENCY
- int num_tps=0;
- #endif
- for (i=height-1; i>=0; --i)
- {
- dptr = im8[i];
-
- if (4==bitdepth)
- {
- for (int i=width>>1; i; --i)
- {
- unsigned char byte;
- d3i_fread(&byte,1,1,f);
- #if DEBUG_TRANSPARENCY
- *dptr = (unsigned char)(byte >> 4 & 0xf);
- if (!*dptr) num_tps++;
- *++dptr = (unsigned char)(byte & 0xf);
- if (!*dptr) num_tps++;
- ++dptr;
- #else
- *dptr++ = (unsigned char)(byte >> 4 & 0xf);
- *dptr++ = (unsigned char)(byte & 0xf);
- #endif
- }
- if (width & 1)
- {
- d3i_fread(dptr,1,1,f);
- *dptr &= 0xf;
- #if DEBUG_TRANSPARENCY
- if (!*dptr) num_tps++;
- #endif
- }
-
- d3i_fseek(f,(~(width-1) & 7)>>1,SEEK_CUR);
- }
- else
- {
- for (int i=width; i; --i)
- {
- #if DEBUG_TRANSPARENCY
- d3i_fread(dptr,1,1,f);
- if (!*dptr) num_tps++;
- dptr++;
- #else
- d3i_fread(dptr++,1,1,f);
- #endif
- }
- d3i_fseek(f,~(width-1) & 3,SEEK_CUR);
- }
- }
- #if DEBUG_TRANSPARENCY
- if (num_tps) CL_LogFile.lprintf("-- %d TRANSPARENT PIXELS FOUND\n",num_tps);
- #endif
- }
- else if (CLM_16BIT == imode)
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 const * aptr = *im16;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- for (i=height-1; i>=0; --i)
- {
- CL_Pixel_16 * dptr = im16[i];
-
- for (int i=width; i; --i)
- {
- dptr++->Read(f,CLF_BGR);
- }
- d3i_fseek(f,~(width*3-1) & 3,SEEK_CUR);
- }
-
- }
- else if (CLM_32BIT == imode)
- {
- im32 = new CL_Pixel_32 * [height];
- *im32 = new CL_Pixel_32 [size];
-
- CL_Pixel_32 const * * dptrptr = (CL_Pixel_32 const * *) im32;
- CL_Pixel_32 const * aptr = *im32;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- for (i=height-1; i>=0; --i)
- {
- CL_Pixel_32 * dptr = im32[i];
-
- for (int i=width; i; --i)
- {
- dptr++->Read(f,CLF_BGR);
- }
- d3i_fseek(f,~(width*3-1) & 3,SEEK_CUR);
- }
-
- }
- else if (CLM_24BIT == imode)
- {
- im24 = new CL_Pixel_24 * [height];
- *im24 = new CL_Pixel_24 [size];
-
- CL_Pixel_24 const * * dptrptr = (CL_Pixel_24 const * *) im24;
- CL_Pixel_24 const * aptr = *im24;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- for (i=height-1; i>=0; --i)
- {
- CL_Pixel_24 * dptr = im24[i];
-
- for (int i=width; i; --i)
- {
- dptr++->Read(f,CLF_BGR);
- }
- d3i_fseek(f,~(width*3-1) & 3,SEEK_CUR);
- }
-
- }
- else return CLE_INVALIDDXMODE;
-
- if (palette_size && CLM_ATTACHEDPALETTE != imode)
- {
- if (CLM_16BIT == imode)
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- unsigned char const * sptr = *im8;
- CL_Pixel_16 * dptr = *im16;
-
- for (int i=size; i; --i, ++dptr,++sptr)
- {
- if (*sptr && !palette[*sptr])
- *dptr = dptr->f.dx_black;
- else
- *dptr = palette[*sptr];
- }
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 const * aptr = *im16;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
- else if (CLM_32BIT == imode)
- {
- im32 = new CL_Pixel_32 * [height];
- *im32 = new CL_Pixel_32 [size];
-
- unsigned char const * sptr = *im8;
- CL_Pixel_32 * dptr = *im32;
-
- for (int i=size; i; --i, ++dptr,++sptr)
- {
- if (*sptr && !palette[*sptr])
- *dptr = dptr->f.dx_black;
- else
- *dptr = palette[*sptr];
- }
-
- CL_Pixel_32 const * * dptrptr = (CL_Pixel_32 const * *) im32;
- CL_Pixel_32 const * aptr = *im32;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
- else
- {
- im24 = new CL_Pixel_24 * [height];
- *im24 = new CL_Pixel_24 [size];
-
- unsigned char const * sptr = *im8;
- CL_Pixel_24 * dptr = *im24;
-
- for (int i=size; i; --i, ++dptr,++sptr)
- {
- if (*sptr && !palette[*sptr])
- *dptr = CL_Pixel_24(0,1,0);
- else
- *dptr = palette[*sptr];
- }
-
- CL_Pixel_24 const * * dptrptr = (CL_Pixel_24 const * *) im24;
- CL_Pixel_24 const * aptr = *im24;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
-
- delete[] palette;
- palette = 0;
- palette_size = 0;
- delete[] *im8;
- delete[] im8;
- im8 = 0;
- }
-
- if (d3i_ferror(f) || d3i_feof(f))
- {
- DeleteNotMips();
- return CLE_LOADERROR;
- }
-
- flags.loaded = 1;
- return CLE_OK;
-}
-
-
-CL_Error CL_Image::Load_PPM(D3I_FILE * f)
-{
- if (!f) return CLE_OPENERROR;
-
- DeleteNotMips();
-
- switch (imode)
- {
- case CLM_24BIT:
- case CLM_16BIT:
- case CLM_32BIT:
- break;
- default:
- return CLE_INVALIDDXMODE;
- }
-
- d3i_fseek(f,0,SEEK_SET);
- unsigned short magic;
- d3i_fread(&magic,2,1,f);
- if (magic != *(unsigned short const *)"P6") return CLE_LOADERROR;
-
- d3i_fseek(f,1,SEEK_CUR);
- char buf[256];
- char * bufptr = buf;
- unsigned int fields[5];
- unsigned int fields_read = 0;
- while (fields_read < 3 && bufptr)
- {
- do bufptr = d3i_fgets(buf, sizeof buf, f);
- while ('#'==buf[0] && bufptr);
-
- int num_fields_read = sscanf(buf,"%u %u %u",&fields[fields_read],&fields[fields_read+1],&fields[fields_read+2]);
- if (EOF != num_fields_read) fields_read += num_fields_read;
- }
- if (fields_read < 3) return CLE_LOADERROR;
- width = fields[0];
- height = fields[1];
- unsigned int maxval = fields[2];
- if (maxval > 255) return CLE_LOADERROR;
-
- size = width * height;
-
- if (CLM_16BIT == imode)
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- CL_Pixel_16 * rptr = *im16;
- for (int i=size; i; --i)
- {
- rptr++->Read(f,CLF_RGB,maxval);
- }
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 const * aptr = *im16;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
- else if (CLM_32BIT == imode)
- {
- im32 = new CL_Pixel_32 * [height];
- *im32 = new CL_Pixel_32 [size];
-
- CL_Pixel_32 * rptr = *im32;
- for (int i=size; i; --i)
- {
- rptr++->Read(f,CLF_RGB,maxval);
- }
-
- CL_Pixel_32 const * * dptrptr = (CL_Pixel_32 const * *) im32;
- CL_Pixel_32 const * aptr = *im32;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
- else
- {
- im24 = new CL_Pixel_24 * [height];
- *im24 = new CL_Pixel_24 [size];
-
- CL_Pixel_24 * rptr = *im24;
- for (int i=size; i; --i)
- {
- rptr++->Read(f,CLF_RGB,maxval);
- }
-
- CL_Pixel_24 const * * dptrptr = (CL_Pixel_24 const * *) im24;
- CL_Pixel_24 const * aptr = *im24;
- for (i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
- }
-
- if (d3i_ferror(f) || d3i_feof(f))
- {
- DeleteNotMips();
- return CLE_LOADERROR;
- }
-
- flags.loaded = 1;
- return CLE_OK;
-}
-
-
-CL_Error CL_Image::Load_PGM(D3I_FILE * f)
-{
- if (!f) return CLE_OPENERROR;
-
- DeleteNotMips();
-
- switch (imode)
- {
- case CLM_GLOBALPALETTE:
- case CLM_TLTPALETTE:
- break;
- default:
- return CLE_INVALIDDXMODE;
- }
-
- d3i_fseek(f,0,SEEK_SET);
- unsigned short magic;
- d3i_fread(&magic,2,1,f);
- if (magic != *(unsigned short const *)"P5") return CLE_LOADERROR;
-
- d3i_fseek(f,1,SEEK_CUR);
- char buf[256];
- char * bufptr = buf;
- unsigned int fields[5];
- unsigned int fields_read = 0;
- while (fields_read < 3 && bufptr)
- {
- do bufptr = d3i_fgets(buf, sizeof buf, f);
- while ('#'==buf[0] && bufptr);
-
- int num_fields_read = sscanf(buf,"%u %u %u",&fields[fields_read],&fields[fields_read+1],&fields[fields_read+2]);
- if (EOF != num_fields_read) fields_read += num_fields_read;
- }
- if (fields_read < 3) return CLE_LOADERROR;
- width = fields[0];
- height = fields[1];
- unsigned int maxval = fields[2];
- if (maxval > 255) return CLE_LOADERROR;
-
- size = width * height;
-
- im8 = new unsigned char * [height];
- *im8 = new unsigned char [size];
-
- d3i_fread(*im8,1,size,f);
-
- unsigned char const * * dptrptr = (unsigned char const * *) im8;
- unsigned char const * aptr = *im8;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- if (d3i_ferror(f) || d3i_feof(f))
- {
- DeleteNotMips();
- return CLE_LOADERROR;
- }
-
- flags.loaded = 1;
- return CLE_OK;
-}
-
-
-CL_Error CL_Image::Load_PWM(D3I_FILE * f)
-{
- if (!f) return CLE_OPENERROR;
-
- DeleteNotMips();
-
- switch (imode)
- {
- case CLM_TLTPALETTE:
- break;
- default:
- return CLE_INVALIDDXMODE;
- }
-
- d3i_fseek(f,0,SEEK_SET);
- unsigned short magic;
- d3i_fread(&magic,2,1,f);
- if (magic != *(unsigned short const *)"P8") return CLE_LOADERROR;
-
- d3i_fseek(f,1,SEEK_CUR);
- char buf[256];
- char * bufptr = buf;
- unsigned int fields[5];
- unsigned int fields_read = 0;
- while (fields_read < 3 && bufptr)
- {
- do bufptr = d3i_fgets(buf, sizeof buf, f);
- while ('#'==buf[0] && bufptr);
-
- int num_fields_read = sscanf(buf,"%u %u %u",&fields[fields_read],&fields[fields_read+1],&fields[fields_read+2]);
- if (EOF != num_fields_read) fields_read += num_fields_read;
- }
- if (fields_read < 3) return CLE_LOADERROR;
- width = fields[0];
- height = fields[1];
- unsigned int maxval = fields[2];
- if (maxval > 65535) return CLE_LOADERROR;
-
- size = width * height;
-
- im16raw = new unsigned short * [height];
- *im16raw = new unsigned short [size];
-
- d3i_fread(*im16raw,2,size,f);
-
- unsigned short const * * dptrptr = (unsigned short const * *) im16raw;
- unsigned short const * aptr = *im16raw;
- for (int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- if (d3i_ferror(f) || d3i_feof(f))
- {
- DeleteNotMips();
- return CLE_LOADERROR;
- }
-
- flags.loaded = 1;
- flags.raw16bit = 1;
- return CLE_OK;
-}
-
-
-
-CL_Error CL_Image::GetBitsPerPixel(unsigned int* bpp)
-{
- *bpp = bitsperpixel;
- return CLE_OK;
-}
-
-CL_Error CL_Image::Load_Image(D3I_FILE * f)
-{
- if (!f) return CLE_OPENERROR;
-
- CL_Error retval = CLE_LOADERROR;
-
- START_TIMER
-
- d3i_fseek(f,0,SEEK_SET);
- unsigned short magic;
- d3i_fread(&magic,2,1,f);
-
- if ( *(unsigned short const *)"BM" == magic)
- retval = Load_BMP(f);
- else if ( *(unsigned short const *)"P6" == magic)
- retval = Load_PPM(f);
- else if ( *(unsigned short const *)"P5" == magic)
- retval = Load_PGM(f);
- else if ( *(unsigned short const *)"P8" == magic)
- retval = Load_PWM(f);
- #if OUTPUT_LOG
- else CL_LogFile.lputs("** ERROR: Not a recognized file format\n");
- #endif
-
- END_TIMER(ReadTime)
-
- #if OUTPUT_LOG
- #if TIME_LOADS
- CL_LogFile.lprintf("-- Timer Stats (ms): Open %d Read %d Close %d\n",OpenTime,ReadTime,CloseTime);
- #endif
- #endif
-
- return retval;
-}
-
-
-void CL_Image::PadTo(int const width_unit,int const height_unit)
-{
- if (!flags.loaded) return;
-
- unsigned int const owidth = width;
- unsigned int const oheight = height;
-
- width += width_unit-1;
- width &= ~(width_unit-1);
- height += height_unit-1;
- height &= ~(height_unit-1);
-
- if (width == owidth && height == oheight) return; // already in spec
-
- size = width * height;
-
- CL_Pixel_32 * * const oim32 = im32;
- CL_Pixel_16 * * const oim16 = im16;
- unsigned char * * const oim8 = im8;
-
- if (oim32)
- {
- im32 = new CL_Pixel_32 * [height];
- *im32 = new CL_Pixel_32 [size];
-
- CL_Pixel_32 const * * dptrptr = (CL_Pixel_32 const * *) im32;
- CL_Pixel_32 const * aptr = *im32;
- for (unsigned int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- for (unsigned int y = 0; y < oheight; ++y)
- {
- CL_Pixel_32 const * sptr = oim32[y];
- CL_Pixel_32 * dptr = im32[y];
-
- for (unsigned int x = 0; x < owidth; ++x, ++dptr, ++sptr)
- *dptr = *sptr;
-
- for (; x < width; ++x, ++dptr)
- *dptr = CL_Pixel_24(0,0,0);
- }
-
- for (; y < height; ++y)
- {
- CL_Pixel_32 * dptr = im32[y];
- for (unsigned int x = 0; x < width; ++x, ++dptr)
- *dptr = CL_Pixel_24(0,0,0);
- }
-
- delete[] *oim32;
- delete[] oim32;
- }
-
- if (oim16)
- {
- im16 = new CL_Pixel_16 * [height];
- *im16 = new CL_Pixel_16 [size];
-
- CL_Pixel_16 const * * dptrptr = (CL_Pixel_16 const * *) im16;
- CL_Pixel_16 const * aptr = *im16;
- for (unsigned int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- for (unsigned int y = 0; y < oheight; ++y)
- {
- CL_Pixel_16 const * sptr = oim16[y];
- CL_Pixel_16 * dptr = im16[y];
-
- for (unsigned int x = 0; x < owidth; ++x, ++dptr, ++sptr)
- *dptr = *sptr;
-
- for (; x < width; ++x, ++dptr)
- *dptr = CL_Pixel_24(0,0,0);
- }
-
- for (; y < height; ++y)
- {
- CL_Pixel_16 * dptr = im16[y];
- for (unsigned int x = 0; x < width; ++x, ++dptr)
- *dptr = CL_Pixel_24(0,0,0);
- }
-
- delete[] *oim16;
- delete[] oim16;
- }
-
- if (oim8)
- {
- im8 = new unsigned char * [height];
- *im8 = new unsigned char [size];
-
- unsigned char const * * dptrptr = (unsigned char const * *) im8;
- unsigned char const * aptr = *im8;
- for (unsigned int i=height; i; --i, aptr+=width)
- {
- *dptrptr++ = aptr;
- }
-
- for (unsigned int y = 0; y < oheight; ++y)
- {
- unsigned char const * sptr = oim8[y];
- unsigned char * dptr = im8[y];
-
- for (unsigned int x = 0; x < owidth; ++x, ++dptr, ++sptr)
- *dptr = *sptr;
-
- for (; x < width; ++x, ++dptr)
- *dptr = 0;
- }
-
- for (; y < height; ++y)
- {
- unsigned char * dptr = im8[y];
- for (unsigned int x = 0; x < width; ++x, ++dptr)
- *dptr = 0;
- }
-
- delete[] *oim8;
- delete[] oim8;
- }
-}
-
-// implementation of the 'popularity algorithm' for reducing palette
-
-unsigned int CL_Pixel_24::FVD_Distance(CL_Pixel_24 const & p2) const
-{
- unsigned int dg = g > p2.g ? g - p2.g : p2.g - g;
- unsigned int db = b > p2.b ? b - p2.b : p2.b - b;
-
- unsigned int dgb = dg + db + ((dg > db ? dg : db)<<1);
-
- unsigned int dr = r > p2.r ? r - p2.r : p2.r - r;
- dr += dr<<1; // *= 3
-
- return dr + dgb + ((dr > dgb ? dr : dgb)<<1);
-}
-
-struct _CL_palpixcnt
-{
- unsigned int cnt;
- unsigned int palpos;
-};
-
-int _CL_cmp_palpixcnt(void const * e1, void const * e2)
-{
- return ((_CL_palpixcnt *)e2)->cnt - ((_CL_palpixcnt *)e1)->cnt;
-}
-
-CL_Error CL_Image::ReducePalette(unsigned int const num_colours)
-{
- if (!flags.loaded) return CLE_LOADERROR;
-
- if (!palette) return CLE_INVALIDDXMODE;
- if (!im8) return CLE_INVALIDDXMODE;
-
- if (palette_size <= num_colours) return CLE_OK;
-
- _CL_palpixcnt * const sortarray = new _CL_palpixcnt[palette_size];
-
- for (unsigned int i=0; i<palette_size; ++i)
- {
- sortarray[i].cnt = 0;
- sortarray[i].palpos = i;
- }
-
- for (unsigned int y=0; y<height; ++y)
- {
- unsigned char const * sptr = im8[y];
-
- for (unsigned int x=width; x; --x, ++sptr)
- ++ sortarray[*sptr].cnt;
- }
-
- unsigned int const palstart = CL_Pixel_24(0,0,0) == palette[0] ? 1 : 0;
- qsort(sortarray + palstart, palette_size - palstart, sizeof(_CL_palpixcnt), _CL_cmp_palpixcnt);
-
- CL_Pixel_24 * const opalette = palette;
- unsigned int const opalette_size = palette_size;
- palette = new CL_Pixel_24[num_colours];
- palette_size = num_colours;
-
- for (i=0; i<palette_size; ++i)
- palette[i] = opalette[sortarray[i].palpos];
-
- delete[] sortarray;
-
- // umm - if theres black thats not transparent, make sure it doesnt become colour 0 in palette
- for (unsigned int pswap=1; pswap<palette_size && 0==palstart && CL_Pixel_24(0,0,0)==palette[0]; ++pswap)
- {
- palette[0]=palette[pswap];
- palette[pswap]=CL_Pixel_24(0,0,0);
- }
-
- // emergency?
- if (0==palstart && CL_Pixel_24(0,0,0)==palette[0])
- palette[0] = CL_Pixel_24(1,1,1);
-
- unsigned int * const palmaps = new unsigned int [opalette_size];
- palmaps[0] = 0;
- for (i=palstart; i<opalette_size; ++i)
- {
- unsigned int closest = palstart;
- unsigned int distance = opalette[i].FVD_Distance(palette[palstart]);
-
- for (unsigned int j = palstart+1; j<palette_size; ++j)
- {
- unsigned int thisdist = opalette[i].FVD_Distance(palette[j]);
- if (thisdist < distance)
- {
- distance = thisdist;
- closest = j;
- }
- }
-
- palmaps[i] = closest;
- }
-
- delete[] opalette;
-
- for (y=0; y<height; ++y)
- {
- unsigned char * sptr = im8[y];
-
- for (unsigned int x=width; x; --x, ++sptr)
- *sptr = (unsigned char)palmaps[*sptr];
- }
-
- delete[] palmaps;
-
- return CLE_OK;
-}
-
-// useful filename handling functions
-
-// returns pointer into string pointing to filename without dirname
-static char const * strip_path(char const * n)
-{
- char const * rm = strrchr(n,':');
- if (rm) n = rm+1;
- rm = strrchr(n,'/');
- if (rm) n = rm+1;
- rm = strrchr(n,'\\');
- if (rm) n = rm+1;
-
- return n;
-}
-
-#if 0
-static char * strip_path(char * n)
-{
- char * rm = strrchr(n,':');
- if (rm) n = rm+1;
- rm = strrchr(n,'/');
- if (rm) n = rm+1;
- rm = strrchr(n,'\\');
- if (rm) n = rm+1;
-
- return n;
-}
-#endif
-
-// removes any .extension from filename by inserting null character
-static void strip_file_extension(char * n)
-{
- char * dotpos = strrchr(n,'.');
- if (dotpos) *dotpos = 0;
-}
-
-static char * strip_file_extension(char const * n)
-{
- char * nn = new char[strlen(n)+1];
- strcpy(nn,n);
- strip_file_extension(nn);
- return nn;
-}
-
-// CL_Image functions
-
-CL_Error CL_Image::Locate(char const * iname, int const /* enum_id */)
-{
- if (!iname) return CLE_RIFFERROR;
-
- if (name)
- delete[] name;
- name = strip_file_extension(strip_path(iname));
-
- if (fname)
- delete[] fname;
- fname = new char[strlen(iname)+1];
- strcpy(fname,iname);
-
- flags.located = 1;
- return CLE_OK;
-}
-
-CL_Error CL_Image::Load(char const * const iname, int const enum_id)
-{
- if (iname || CL_EID_INVALID != enum_id || !flags.located)
- {
- CL_Error locate_err = Locate(iname,enum_id);
-
- if (locate_err != CLE_OK)
- {
- EXITONLOCATEFAIL(locate_err,iname,enum_id)
- return locate_err;
- }
- }
-
- #if OUTPUT_LOG
- char const * texformat;
- unsigned int redbits = 8;
- unsigned int greenbits = 8;
- unsigned int bluebits = 8;
- switch (imode)
- {
- case CLM_GLOBALPALETTE:
- texformat = "Palettized Display";
- break;
- case CLM_TLTPALETTE:
- texformat = "Palettized Display with Abstract TLT Palette";
- break;
- case CLM_ATTACHEDPALETTE:
- texformat = "Palettized Textures";
- break;
- case CLM_32BIT:
- texformat = "32BIT DX";
- redbits += CL_Pixel_32::f.red_bits_gt8;
- redbits -= CL_Pixel_32::f.red_bits_lt8;
- greenbits += CL_Pixel_32::f.green_bits_gt8;
- greenbits -= CL_Pixel_32::f.green_bits_lt8;
- bluebits += CL_Pixel_32::f.blue_bits_gt8;
- bluebits -= CL_Pixel_32::f.blue_bits_lt8;
- break;
- case CLM_24BIT:
- texformat = "24-bit for runtime conversion";
- break;
- case CLM_16BIT:
- texformat = "16BIT DX";
- redbits += CL_Pixel_16::f.red_bits_gt8;
- redbits -= CL_Pixel_16::f.red_bits_lt8;
- greenbits += CL_Pixel_16::f.green_bits_gt8;
- greenbits -= CL_Pixel_16::f.green_bits_lt8;
- bluebits += CL_Pixel_16::f.blue_bits_gt8;
- bluebits -= CL_Pixel_16::f.blue_bits_lt8;
- break;
- }
- CL_LogFile.lprintf("--%s %s (%u-bit, %u-%u-%u)\n",fname,texformat,bitsperpixel,redbits,greenbits,bluebits);
- #endif
-
- START_TIMER
- D3I_FILE * fp = d3i_fopen(fname,"rb");
- END_TIMER(OpenTime)
-
- if (fp)
- {
- CL_Error retval = Load_Image(fp);
- START_TIMER
- d3i_fclose(fp);
- END_TIMER(CloseTime)
- if (CLE_OK != retval)
- {
- #if OUTPUT_LOG
- CL_LogFile.lputs("** ERROR: unable to read\n");
- #endif
- EXITONREADFAIL(fname)
- }
- return retval;
- }
-
- #if OUTPUT_LOG
- CL_LogFile.lputs("** ERROR: unable to open\n");
- #endif
- EXITONLOADFAIL(fname)
- return CLE_OPENERROR;
-}
-
-CL_Error CL_Image::PreLoad(char const * const iname, int const enum_id)
-{
- CL_Error locate_err = Locate(iname,enum_id);
-
- if (locate_err != CLE_OK)
- {
- return locate_err;
- }
-
- return CLE_OK;
-}
-
-CL_Error CL_Image::LoadMipMaps(int const n_mips) // assumes locating has been done (ie. PreLoad or Load has been called)
-{
- if (!flags.located) return CLE_FINDERROR;
-
- while (mipmaps.size())
- {
- delete mipmaps.last_entry();
- mipmaps.delete_last_entry();
- }
-
- for (int mip_idx = 1; mip_idx < n_mips; ++mip_idx)
- {
- CL_Image * mip_n = new CL_Image;
-
- mip_n->name = new char[strlen(name)+1];
- mip_n->fname = new char[strlen(fname)+1];
- strcpy(mip_n->name,name);
- strcpy(mip_n->fname,fname);
-
- char * dotpos = strrchr(mip_n->fname,'.');
- if (!dotpos)
- {
- delete mip_n;
- break;
- }
- sprintf(dotpos+3,"%1d",mip_idx);
-
- mip_n->flags.located = 1;
-
- if (CLE_OK!=mip_n->Load())
- {
- delete mip_n;
- break;
- }
-
- if (mip_n->width << mip_idx < width || mip_n->height << mip_idx < height)
- {
- delete mip_n;
- #if OUTPUT_LOG
- CL_LogFile.lputs("** Warning: less than half size\n");
- #endif
- break;
- }
-
- mipmaps.add_entry_end(mip_n);
- }
- return CLE_OK;
-}
-
-void CL_Select_Mode(CL_LoadMode const lmode)
-{
- switch (lmode)
- {
- case CLL_D3DTEXTURE:
- CL_Image::imode = CL_Image::imode_d3d;
- CL_Image::bitsperpixel = CL_Image::bitsperpixel_d3d;
- CL_Pixel_16::f = CL_Pixel_16::f_d3d;
- CL_Pixel_32::f = CL_Pixel_32::f_d3d;
- break;
- case CLL_DDSURFACE:
- CL_Image::imode = CL_Image::imode_ddraw;
- CL_Image::bitsperpixel = CL_Image::bitsperpixel_ddraw;
- CL_Pixel_16::f = CL_Pixel_16::f_ddraw;
- CL_Pixel_32::f = CL_Pixel_32::f_ddraw;
- break;
- }
- CL_Image::lmode = lmode;
-}
-
-// 3DC interface
-
-void CL_Init_DirectDrawMode(CL_VideoMode const vmode)
-{
- switch (vmode)
- {
- case CLV_8:
- CL_Image::bitsperpixel_ddraw = 8;
- CL_Image::imode_ddraw = CLM_GLOBALPALETTE;
- break;
- case CLV_8TLT:
- CL_Image::bitsperpixel_ddraw = 8;
- CL_Image::imode_ddraw = CLM_TLTPALETTE;
- break;
- case CLV_15:
- CL_Image::bitsperpixel_ddraw = 16;
- CL_Image::imode_ddraw = CLM_16BIT;
- CL_Pixel_16::f_ddraw.Init
- (
- DisplayPixelFormat.dwRBitMask,
- DisplayPixelFormat.dwGBitMask,
- DisplayPixelFormat.dwBBitMask
- );
- break;
- case CLV_24:
- CL_Image::bitsperpixel_ddraw = DisplayPixelFormat.dwRGBBitCount;
- if (24 == CL_Image::bitsperpixel_ddraw)
- CL_Image::imode_ddraw = CLM_24BIT;
- else
- {
- CL_Image::imode_ddraw = CLM_32BIT;
- CL_Pixel_32::f_ddraw.Init
- (
- DisplayPixelFormat.dwRBitMask,
- DisplayPixelFormat.dwGBitMask,
- DisplayPixelFormat.dwBBitMask
- );
- }
- break;
- case CLV_8T:
- CL_Image::bitsperpixel_ddraw = 8;
- CL_Image::imode_ddraw = CLM_16BIT;
- CL_Pixel_16::f_ddraw.Init(7<<5,7<<2,3);
- break;
- }
- CL_Select_Mode(CLL_DDSURFACE);
-}
-
-
-CL_Error CL_Image::CopyToScanDrawTexture(unsigned char * * const ImagePtrA [], unsigned int n_mips_max)
-{
- if (!flags.loaded) return CLE_LOADERROR;
-
- if (CLL_DDSURFACE != lmode) CL_Select_Mode(CLL_DDSURFACE);
-
- if (n_mips_max > mipmaps.size()+1) n_mips_max = mipmaps.size()+1;
-
- if (!*ImagePtrA[0])
- {
- if (flags.raw16bit)
- {
- if (n_mips_max>1)
- *ImagePtrA[0] = (unsigned char *) AllocateMem((2*width+1)*(2*height+1)*2/3+(n_mips_max-3)*2); // slightly more than 4/3 w*h*bytedepth
- else
- *ImagePtrA[0] = (unsigned char *) AllocateMem(width*height*2);
- }
- else
- {
- if (n_mips_max>1)
- *ImagePtrA[0] = (unsigned char *) AllocateMem((2*width+1)*(2*height+1)*bitsperpixel/24+(n_mips_max-3)*(bitsperpixel/8)); // slightly more than 4/3 w*h*bytedepth
- else
- *ImagePtrA[0] = (unsigned char *) AllocateMem(width*height*(bitsperpixel>>3));
- }
- }
- if (!*ImagePtrA[0])
- return CLE_ALLOCFAIL;
-
- unsigned int my_bitsperpixel = bitsperpixel;
-
- switch (imode)
- {
- unsigned char * tptr;
- unsigned short * tSptr;
- unsigned long * tLptr;
-
- case CLM_GLOBALPALETTE:
- case CLM_TLTPALETTE:
- if (flags.raw16bit)
- {
- my_bitsperpixel = 16;
- tSptr = (unsigned short *)*ImagePtrA[0];
- if (tSptr)
- {
- for (int i=0; i<height; ++i)
- {
- memcpy(tSptr,im16raw[i],width*sizeof(unsigned short));
- tSptr += width;
- }
- }
- }
- else
- {
- tptr = *ImagePtrA[0];
- if (tptr)
- {
- for (int i=0; i<height; ++i)
- {
- memcpy(tptr,im8[i],width);
- tptr += width;
- }
- }
- }
- break;
- case CLM_16BIT:
- switch (bitsperpixel)
- {
- case 8:
- tptr = *ImagePtrA[0];
- if (tptr)
- {
- for (int i=0; i<height; ++i)
- {
- unsigned char const * i8ptr = im8[i];
- for (int j=width; j; --j)
- {
- *tptr++ = *i8ptr++;
- }
- }
- }
- break;
- case 16:
- tSptr = (unsigned short *)*ImagePtrA[0];
- if (tSptr)
- {
- for (int i=0; i<height; ++i)
- {
- CL_Pixel_16 const * i16ptr = im16[i];
- for (int j=width; j; --j)
- {
- *tSptr++ = *i16ptr++;
- }
- }
- }
- break;
- }
- break;
- case CLM_24BIT:
- switch (bitsperpixel)
- {
- case 24:
- tptr = *ImagePtrA[0];
- if (tptr)
- {
- for (int i=0; i<height; ++i)
- {
- CL_Pixel_24 const * i24ptr = im24[i];
- for (int j=width; j; --j)
- {
- *tptr++ = i24ptr->b;
- *tptr++ = i24ptr->g;
- *tptr++ = i24ptr->r;
- i24ptr++;
- }
- }
- }
- break;
- case 32:
- tLptr = (unsigned long *)*ImagePtrA[0];
- if (tLptr)
- {
- for (int i=0; i<height; ++i)
- {
- CL_Pixel_32 const * i32ptr = im32[i];
- for (int j=width; j; --j)
- {
- *tLptr++ = *i32ptr++;
- }
- }
- }
- break;
- }
- break;
- default:
- return CLE_INVALIDDXMODE;
- }
-
- // now do mipmaps if avail
-
- CL_Image * last_mipP = this;
-
- LIF<CL_Image *> i_mip(&mipmaps);
- for (int i=1; i<n_mips_max && !i_mip.done(); ++i, i_mip.next())
- {
- *ImagePtrA[i] = *ImagePtrA[i-1] + last_mipP->width*last_mipP->height*(my_bitsperpixel>>3);
- CL_Error thismipmaperror = i_mip()->CopyToScanDrawTexture(&ImagePtrA[i],1);
- if (CLE_OK != thismipmaperror) return thismipmaperror;
- last_mipP = i_mip();
- }
- return CLE_OK;
-}
-
-
-
-// Direct X interface
-
-void CL_Init_D3DMode(LPDDSURFACEDESC const format)
-{
- CL_Image::format = format;
-
- if (format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
- {
- #if QUANTISE_ON_LOAD
- CL_Image::imode_d3d = CLM_24BIT;
- #else
- CL_Image::imode_d3d = CLM_ATTACHEDPALETTE;
- #endif
- CL_Image::bitsperpixel_d3d = 8;
- }
- else if (format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
- {
- #if QUANTISE_ON_LOAD
- CL_Image::imode_d3d = CLM_24BIT;
- #else
- CL_Image::imode_d3d = CLM_ATTACHEDPALETTE;
- #endif
- CL_Image::bitsperpixel_d3d = 4;
- }
- else if (format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2)
- {
- #if QUANTISE_ON_LOAD
- CL_Image::imode_d3d = CLM_24BIT;
- #else
- CL_Image::imode_d3d = CLM_ATTACHEDPALETTE;
- #endif
- CL_Image::bitsperpixel_d3d = 2;
- }
- else if (format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1)
- {
- #if QUANTISE_ON_LOAD
- CL_Image::imode_d3d = CLM_24BIT;
- #else
- CL_Image::imode_d3d = CLM_ATTACHEDPALETTE;
- #endif
- CL_Image::bitsperpixel_d3d = 1;
- }
- else
- {
- CL_Image::bitsperpixel_d3d = format->ddpfPixelFormat.dwRGBBitCount;
- if (format->ddpfPixelFormat.dwRGBBitCount > 16)
- {
- CL_Image::imode_d3d = CLM_32BIT;
- CL_Pixel_32::f_d3d.Init
- (
- format->ddpfPixelFormat.dwRBitMask,
- format->ddpfPixelFormat.dwGBitMask,
- format->ddpfPixelFormat.dwBBitMask
- );
- }
- else
- {
- CL_Image::imode_d3d = CLM_16BIT;
- CL_Pixel_16::f_d3d.Init
- (
- format->ddpfPixelFormat.dwRBitMask,
- format->ddpfPixelFormat.dwGBitMask,
- format->ddpfPixelFormat.dwBBitMask
- );
- }
- }
- CL_Select_Mode(CLL_D3DTEXTURE);
-}
-
-
-CL_Error CL_Image::CopyToD3DTexture(LPDIRECTDRAWSURFACE * const DDPtrA [], LPVOID * const DDSurfaceA [], int const MemoryType, unsigned int n_mips_max)
-{
- if (!flags.loaded) return CLE_LOADERROR;
-
- WaitForVRamReady(VWS_D3DTEXCREATE);
-
- if (CLL_D3DTEXTURE != lmode) CL_Select_Mode(CLL_D3DTEXTURE);
-
- LPDIRECTDRAWSURFACE lpDDS;
- DDSURFACEDESC ddsd;
- HRESULT ddrval;
-
- // Check for image being 4 byte aligned
- // and fail if it is not
- if (width & 3 || height & 3)
- {
- // return error code
- return CLE_DXERROR;
- }
-
-
- // Set up the surface description. starting
- // with the passed texture format and then
- // incorporating the information read from the
- // ppm.
- memcpy(&ddsd, format, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddsd.dwFlags = (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT);
- ddsd.ddsCaps.dwCaps = (DDSCAPS_TEXTURE | MemoryType);
- ddsd.dwHeight = height;
- ddsd.dwWidth = width;
-
- if (n_mips_max > mipmaps.size()+1) n_mips_max = mipmaps.size()+1;
-
- if (n_mips_max>1)
- {
- ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
- ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
- ddsd.dwMipMapCount = n_mips_max;
- }
-
- // Create the surface
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDS, NULL);
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- return CLE_DXERROR;
- #endif
- }
-
-
- // now do mipmaps if avail
-
- if (n_mips_max>1)
- {
- // We must now traverse the mip-map chain from highest to lowest
- // resolutions, For each surface AFTER the first one, we must
- // load a new file, using a name obtained from the mip map number
-
- int MipMapNum = 0;
- LPDIRECTDRAWSURFACE lpThisMipMap, lpNextMipMap;
- DDSCAPS ddsCaps;
-
-
- lpThisMipMap = lpDDS;
- // Component Object Model, increase reference count on
- // mip-map surface by one.
- lpThisMipMap->AddRef();
- ddsCaps.dwCaps = (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP);
- ddrval = DD_OK;
-
- LIF<CL_Image *> i_mip(&mipmaps);
-
- CL_Image * last_mipP = this;
-
- while ((ddrval == DD_OK) && (MipMapNum < n_mips_max)) // both tests in case...
- {
- // Call LoadPPMIntoDDSurface with lpThisMipMap, new file name, and
- // other values.
-
- *DDSurfaceA[MipMapNum] = last_mipP->CopyToDDSurface(lpThisMipMap);
-
- // Death trap
- if (!*DDSurfaceA[MipMapNum])
- {
- return CLE_DXERROR;
- }
- *DDPtrA[MipMapNum] = lpThisMipMap;
-
- // Proceed to the next level.
- // Collect bonus rings.
- ddrval = lpThisMipMap->GetAttachedSurface(&ddsCaps, &lpNextMipMap);
- // Necessary to match the manual increment of the reference count on the
- // COM texture. I think.
- lpThisMipMap->Release();
- // ?? lpNextMipMap = lpThisMipMap;
- lpThisMipMap = lpNextMipMap;
-
- MipMapNum++;
- if (!i_mip.done())
- {
- last_mipP = i_mip();
- i_mip.next();
- }
- }
- }
- else
- {
- *DDSurfaceA[0] = CopyToDDSurface(lpDDS);
-
- if (!*DDSurfaceA[0]) return CLE_DXERROR;
-
- *DDPtrA[0] = lpDDS;
- }
-
- return CLE_OK;
-}
-
-
-CL_Error CL_Image::CopyToDirectDrawSurface(LPDIRECTDRAWSURFACE * const DDPtrA [], LPVOID * const DDSurfaceA [], int const MemoryType, unsigned int n_mips_max)
-{
- if (!flags.loaded) return CLE_LOADERROR;
-
- WaitForVRamReady(VWS_DDCREATE);
-
- if (CLL_DDSURFACE != lmode) CL_Select_Mode(CLL_DDSURFACE);
-
- LPDIRECTDRAWSURFACE lpDDS;
- DDSURFACEDESC ddsd;
- HRESULT ddrval;
-
- // Check for image being 4 byte aligned
- // and fail if it is not
- if (width & 3 || height & 3)
- {
- // return error code
- return CLE_DXERROR;
- }
-
- if (n_mips_max > mipmaps.size()+1) n_mips_max = mipmaps.size()+1;
-
- // Set up the surface description. starting
- // with the passed texture format and then
- // incorporating the information read from the
- // ppm.
- memset(&ddsd, 0, sizeof ddsd);
- ddsd.dwSize = sizeof ddsd;
- ddsd.dwFlags = (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT);
- // Ensure that created surface has same pixel desription
- // as primary
- memcpy(&ddsd.ddpfPixelFormat, &DisplayPixelFormat, sizeof(DDPIXELFORMAT));
- ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | MemoryType);
- ddsd.dwHeight = height;
- ddsd.dwWidth = width;
-
- if (n_mips_max>1)
- {
- ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
- ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
- ddsd.dwMipMapCount = n_mips_max;
- }
-
- // Create the surface
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDS, NULL);
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- return CLE_DXERROR;
- #endif
- }
-
- DDCOLORKEY set_zero = {0,0};
- ddrval = lpDDS->SetColorKey(DDCKEY_SRCBLT, &set_zero);
-
- LOGDXERR(ddrval);
- if(ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- return CLE_DXERROR;
- #endif
- }
-
-
- // now do mipmaps if avail
-
- if (n_mips_max>1)
- {
- // We must now traverse the mip-map chain from highest to lowest
- // resolutions, For each surface AFTER the first one, we must
- // load a new file, using a name obtained from the mip map number
-
- int MipMapNum = 0;
- LPDIRECTDRAWSURFACE lpThisMipMap, lpNextMipMap;
- DDSCAPS ddsCaps;
-
-
- lpThisMipMap = lpDDS;
- // Component Object Model, increase reference count on
- // mip-map surface by one.
- lpThisMipMap->AddRef();
- ddsCaps.dwCaps = (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP);
- ddrval = DD_OK;
-
- LIF<CL_Image *> i_mip(&mipmaps);
-
- CL_Image * last_mipP = this;
-
- while ((ddrval == DD_OK) && (MipMapNum < n_mips_max)) // both tests in case...
- {
- // Call LoadPPMIntoDDSurface with lpThisMipMap, new file name, and
- // other values.
-
- *DDSurfaceA[MipMapNum] = last_mipP->CopyToDDSurface(lpThisMipMap);
-
- // Death trap
- if (!*DDSurfaceA[MipMapNum])
- {
- return CLE_DXERROR;
- }
- *DDPtrA[MipMapNum] = lpThisMipMap;
-
- // Proceed to the next level.
- // Collect bonus rings.
- ddrval = lpThisMipMap->GetAttachedSurface(&ddsCaps, &lpNextMipMap);
- // Necessary to match the manual increment of the reference count on the
- // COM texture. I think.
- lpThisMipMap->Release();
- // ?? lpNextMipMap = lpThisMipMap;
- lpThisMipMap = lpNextMipMap;
-
- MipMapNum++;
- if (!i_mip.done())
- {
- last_mipP = i_mip();
- i_mip.next();
- }
- }
- }
- else
- {
- *DDSurfaceA[0] = CopyToDDSurface(lpDDS);
-
- if (!*DDSurfaceA[0]) return CLE_DXERROR;
-
- *DDPtrA[0] = lpDDS;
- }
-
- return CLE_OK;
-}
-
-
-LPVOID CL_Image::CopyToDDSurface(LPDIRECTDRAWSURFACE lpDDS)
-{
- if (!flags.loaded) return 0;
-
- LPDIRECTDRAWPALETTE lpDDPPMPal;
- PALETTEENTRY ppe[256];
- DDSURFACEDESC ddsd;
- #if QUANTISE_ON_LOAD
- D3DCOLOR colors[256];
- D3DCOLOR c;
- int color_count;
- #endif
- int psize;
- char *lpC;
- HRESULT ddrval;
- unsigned int i, j;
- unsigned int pcaps;
-
- // Lock the surface so it can be filled with the PPM file
-
- memset(&ddsd, 0, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddrval = lpDDS->Lock(NULL, &ddsd, 0, NULL);
-
- if (!ddsd.lpSurface)
- {
- lpDDS->Unlock(NULL);
- lpDDS->Release();
- LOGDXSTR("No surface");
- return 0;
- }
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- return 0;
- #endif
- }
-
- // The method of loading depends on the pixel format of the dest surface
-
- switch (imode)
- {
- case CLM_32BIT:
- switch (bitsperpixel)
- {
- case 32:
- for (j = 0; j < height; j++)
- {
- // Point to next row in texture surface
- unsigned long * lpLP = (unsigned long*)((char*)ddsd.lpSurface
- + ddsd.lPitch * j);
- CL_Pixel_32 * lpP32 = im32[j];
- for (i = width; i; --i)
- {
- *lpLP++ = *lpP32++;
- }
- }
- break;
- case 24:
- for (j = 0; j < height; j++)
- {
- // Point to next row in texture surface
- unsigned char * lpCP = (unsigned char*)ddsd.lpSurface
- + ddsd.lPitch * j;
- CL_Pixel_32 * lpP32 = im32[j];
- for (i = width; i; --i)
- {
- unsigned long lv = *lpP32++;
- unsigned char const * lpSrcCP = (unsigned char const *)&lv;
- // dodgy - makes assumtions about 24-bit values...
- *lpCP++ = *lpSrcCP++;
- *lpCP++ = *lpSrcCP++;
- *lpCP++ = *lpSrcCP++;
- }
- }
- break;
- default:
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Unlock(NULL);
- lpDDS->Release();
- return 0;
- #endif
- }
- lpDDS->Unlock(NULL);
- break;
- case CLM_16BIT:
- switch (bitsperpixel)
- {
- case 16:
- for (j = 0; j < height; j++)
- {
- // Point to next row in texture surface
- unsigned short * lpSP = (unsigned short*)((char*)ddsd.lpSurface
- + ddsd.lPitch * j);
- CL_Pixel_16 * lpP16 = im16[j];
- for (i = width; i; --i)
- {
- *lpSP++ = *lpP16++;
- }
- }
- break;
- case 8:
- for (j = 0; j < height; j++)
- {
- // Point to next row in texture surface
- unsigned char * lpCP = (unsigned char*)ddsd.lpSurface
- + ddsd.lPitch * j;
- CL_Pixel_16 * lpP16 = im16[j];
- for (i = width; i; --i)
- {
- *lpCP++ = *lpP16++;
- }
- }
- break;
- default:
- // Everything's gone pear-shaped...
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Unlock(NULL);
- lpDDS->Release();
- return 0;
- #endif
- }
- lpDDS->Unlock(NULL);
- break;
- case CLM_24BIT:
- if (24==bitsperpixel)
- {
- for (j = 0; j < height; j++)
- {
- // Point to next row in surface
- unsigned char * lpCP = ((unsigned char*)ddsd.lpSurface) + ddsd.lPitch * j;
- CL_Pixel_24 * lpP24 = im24[j];
- for (i = 0; i < width; i++)
- {
- // making an assumption about the ordering of r,g,b on the video card
- *lpCP++ = lpP24->b;
- *lpCP++ = lpP24->g;
- *lpCP++ = lpP24->r;
- lpP24++;
- }
- }
- lpDDS->Unlock(NULL);
- }
- else
- {
- #if QUANTISE_ON_LOAD // Neal's quantize on load stuff
-
- // Paletted target texture surface
- psize = 1<<bitsperpixel;
- color_count = 0; // number of colors in the texture
- for (j = 0; j < height; j++)
- {
- // Point to next row in surface
- lpC = ((char*)ddsd.lpSurface) + ddsd.lPitch * j;
- CL_Pixel_24 * lpP24 = im24[j];
- for (i = 0; i < width; i++, lpP24++)
- {
- int k;
- // Get the next red, green and blue values and turn them into a
- // D3DCOLOR.
- c = RGB_MAKE(lpP24->r, lpP24->g, lpP24->b);
- // Search for this color in a table of colors in this texture
- for (k = 0; k < color_count; k++)
- if (c == colors[k]) break;
- if (k == color_count)
- {
- // This is a new color, so add it to the list
- color_count++;
- // More than 256 and we fail (8-bit)
- if (color_count > psize)
- {
- color_count--;
- k = color_count - 1;
- }
- colors[k] = c;
- }
- // Set the "pixel" value on the surface to be the index into the
- // color table
- if (psize<256)
- {
- unsigned int bitmask;
- switch (psize)
- {
- default:
- bitmask = 1;
- break;
- case 4:
- bitmask = 3;
- break;
- case 2:
- bitmask = 7;
- break;
- }
- if ((i & bitmask) == 0)
- *lpC = (char)(k & (psize-1));
- else
- *lpC |= (char)((k & (psize-1)) << (i & (psize-1)));
- if ((~i & bitmask) == 0)
- lpC++;
- }
- else
- {
- *lpC = (char)k;
- lpC++;
- }
- }
- }
-
- // Close the file and unlock the surface
-
- lpDDS->Unlock(NULL);
-
- if (color_count > psize)
- {
- // If there are more than 256 colors, we overran our palette
- #if debug
- ReleaseDirect3D();
- exit(0x321123);
- #else
- lpDDS->Release();
- return 0;
- #endif
- }
-
- // Create a palette with the colors in our color table
-
- memset(ppe, 0, sizeof(PALETTEENTRY) * 256);
- for (i = 0; i < color_count; i++)
- {
- ppe[i].peRed = (unsigned char)RGB_GETRED(colors[i]);
- ppe[i].peGreen = (unsigned char)RGB_GETGREEN(colors[i]);
- ppe[i].peBlue = (unsigned char)RGB_GETBLUE(colors[i]);
- }
-
- // Set all remaining entry flags to D3DPAL_RESERVED, which are ignored by
- // the renderer.
-
- for (; i < 256; i++)
- ppe[i].peFlags = D3DPAL_RESERVED;
-
- // Create the palette with the DDPCAPS_ALLOW256 flag because we want to
- // have access to all entries.
-
- switch (bitsperpixel)
- {
- default:
- pcaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
- break;
- case 4:
- pcaps = DDPCAPS_4BIT;
- break;
- case 2:
- pcaps = DDPCAPS_2BIT;
- break;
- case 1:
- pcaps = DDPCAPS_1BIT;
- break;
- }
-
- ddrval = lpDD->CreatePalette
- (DDPCAPS_INITIALIZE | pcaps,
- ppe, &lpDDPPMPal, NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- return 0;
- #endif
- }
-
- // Finally, bind the palette to the surface
-
- ddrval = lpDDS->SetPalette(lpDDPPMPal);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- lpDDPPMPal->Release();
- return 0;
- #endif
- }
-
- lpDDPPMPal->Release();
- }
- break;
- #else
- // Everything's gone pear-shaped...
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Unlock(NULL);
- lpDDS->Release();
- return 0;
- #endif
- }
- break;
- case CLM_ATTACHEDPALETTE:
- #endif
- case CLM_GLOBALPALETTE:
- case CLM_TLTPALETTE:
- // Paletted target texture surface
-
- psize = 1<<bitsperpixel;
- ReducePalette(psize); // will do nothing if palette is already small enough
- // ignore returned error code, because I don't care if it failed
- for (j = 0; j < height; j++)
- {
- // Point to next row in surface
- lpC = ((char*)ddsd.lpSurface) + ddsd.lPitch * j;
- unsigned char * lpP8 = im8[j];
-
- if (psize<256)
- {
- unsigned int bitmask;
- unsigned int nextpixelshift;
- switch (psize)
- {
- default:
- nextpixelshift = 2;
- break;
- case 4:
- nextpixelshift = 1;
- break;
- case 2:
- nextpixelshift = 0;
- break;
- }
- bitmask = 7 >> nextpixelshift;
- for (i = 0; i < width; i++)
- {
- unsigned char k = *lpP8++;
- // Set the "pixel" value on the surface to be the index into the
- // color table
- if ((i & bitmask) == 0)
- *lpC = (char) (k & (psize-1));
- else
- *lpC |= (char) ((k & (psize-1)) << ((i & bitmask)<<nextpixelshift));
- if ((~i & bitmask) == 0)
- lpC++;
- }
- }
- else
- {
- memcpy(lpC,lpP8,width);
- }
- }
-
- // Close the file and unlock the surface
-
- lpDDS->Unlock(NULL);
-
- // Create a palette with the colors in our color table
-
- memset(ppe, 0, sizeof(PALETTEENTRY) * 256);
- for (i = 0; i < palette_size; i++)
- {
- ppe[i].peRed = palette[i].r;
- ppe[i].peGreen = palette[i].g;
- ppe[i].peBlue = palette[i].b;
- }
-
- // Set all remaining entry flags to D3DPAL_RESERVED, which are ignored by
- // the renderer.
-
- for (; i < 256; i++)
- ppe[i].peFlags = D3DPAL_RESERVED;
-
- // Create the palette with the DDPCAPS_ALLOW256 flag because we want to
- // have access to all entries.
-
- switch (bitsperpixel)
- {
- default:
- pcaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
- break;
- case 4:
- pcaps = DDPCAPS_4BIT;
- break;
- case 2:
- pcaps = DDPCAPS_2BIT;
- break;
- case 1:
- pcaps = DDPCAPS_1BIT;
- break;
- }
-
- ddrval = lpDD->CreatePalette
- (DDPCAPS_INITIALIZE | pcaps,
- ppe, &lpDDPPMPal, NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- return 0;
- #endif
- }
-
- // Finally, bind the palette to the surface
-
- ddrval = lpDDS->SetPalette(lpDDPPMPal);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Release();
- lpDDPPMPal->Release();
- return 0;
- #endif
- }
-
- lpDDPPMPal->Release();
- break;
- default:
- // Everything's gone pear-shaped...
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- lpDDS->Unlock(NULL);
- lpDDS->Release();
- return 0;
- #endif
-
-
- }
-
- return ddsd.lpSurface;
-}
-
-