diff options
| author | Steven Fuller <relnev@icculus.org> | 2008-05-04 02:51:54 -0700 |
|---|---|---|
| committer | Patryk Obara <dreamer.tan@gmail.com> | 2019-08-20 02:22:37 +0200 |
| commit | 76403986b15eb10e3045397ccb4262b87419c86c (patch) | |
| tree | f4effc045a39bf1bef37e5dddad0c20111ab1b3c /src/win95/d3_image.cpp | |
| parent | a64e1008385dd2eef5f44f9adb135f7644da92fd (diff) | |
Removed unused image and font code.
Diffstat (limited to 'src/win95/d3_image.cpp')
| -rw-r--r-- | src/win95/d3_image.cpp | 2491 |
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; -} - - |
