#ifndef _included__d3_image_hpp_ #define _included__d3_image_hpp_ #error "This file is obsolete" #include #include #include #include "list_tem.hpp" #include "ddraw.h" #include "d3d.h" #include "vramtime.h" #include "system.h" #include "mem3dc.h" #include "dxlog.h" // define = 1 if you want an output log file of all texture files loaded and for which DD surface format #if debug #define OUTPUT_LOG 1 #else #define OUTPUT_LOG 0 #endif // define = 1 to use fast files for loading (will still try normal files if fastfile doesn't contain correct data) #define USE_FASTFILE 1 #if USE_FASTFILE #include "ffstdio.h" #define D3I_FILE FFILE #define d3i_fpos_t ffpos_t #define d3i_fclearerr ffclearerr #define d3i_fclose ffclose #define d3i_fcloseall ffcloseall #define d3i_feof ffeof #define d3i_ferror fferror #define d3i_fgetc ffgetc #define d3i_fgetpos ffgetpos #define d3i_fgets ffgets #define d3i_flook fflook #define d3i_flookb fflookb #define d3i_fopen ffopen #define d3i_fread ffread #define d3i_freadb ffreadb #define d3i_fseek ffseek #define d3i_fsetpos ffsetpos #define d3i_ftell fftell #else #define D3I_FILE FILE #define d3i_fpos_t fpos_t #define d3i_fclearerr fclearerr #define d3i_fclose fclose #define d3i_fcloseall fcloseall #define d3i_feof feof #define d3i_ferror ferror #define d3i_fgetc fgetc #define d3i_fgetpos fgetpos #define d3i_fgets fgets #define d3i_fopen fopen #define d3i_fread fread #define d3i_fseek fseek #define d3i_fsetpos fsetpos #define d3i_ftell ftell #endif // define = 1 if you do not want to handle the error return codes, and require a load failure to cause an exit #define EXIT_ON_LOAD_FAIL 0 // define = 1 if you are locating images through rif files and expect this to always succeed // works like EXIT_ON_LOAD_FAIL, and only if EXIT_ON_LOAD_FAIL is set, but most failures are handled // by assuming the given name to be a complete path and filename #define EXIT_ON_LOCATE_FAIL 0 // define = 1 to time file opens, file closes and file reads #define TIME_LOADS 0 // I tested the times with a typically complex set of images from AVP, // loaded over a nework. // Opening took 16secs, Reading 38secs and Closing 2secs for approx // for about 500 images (including mip maps) #if TIME_LOADS #include #define START_TIMER {clock_t __stime = clock(); #define END_TIMER(__var) __var += (unsigned int) ((clock() - __stime) * 1000 / CLOCKS_PER_SEC);} #else #define START_TIMER #define END_TIMER(__var) #endif #if TIME_LOADS extern unsigned int OpenTime; extern unsigned int CloseTime; extern unsigned int ReadTime; #endif #if OUTPUT_LOG #include "debuglog.hpp" extern LogFile CL_LogFile; #endif // externs for 3dc things extern "C" { extern LPDIRECTDRAW lpDD; extern DDPIXELFORMAT DisplayPixelFormat; }; enum CL_RGBFormat // for loading from files { CLF_RGB, CLF_BGR, CLF_BGRX }; struct CL_Pixel_24 { union { struct { unsigned char r,g,b; unsigned char xx; }; unsigned long l; }; CL_Pixel_24() : l(0) {} CL_Pixel_24(unsigned char const r,unsigned char const g,unsigned char const b) : r(r),g(g),b(b),xx(0) {} CL_Pixel_24(CL_Pixel_24 const & p24) : l(p24.l) {} CL_Pixel_24(unsigned long const i) : l(i) {} operator unsigned long (void) const { return l; } inline void Read (D3I_FILE * const f, CL_RGBFormat const t) { switch(t) { case CLF_RGB: d3i_fread(&r,1,1,f); d3i_fread(&g,1,1,f); d3i_fread(&b,1,1,f); break; case CLF_BGR: d3i_fread(&b,1,1,f); d3i_fread(&g,1,1,f); d3i_fread(&r,1,1,f); break; case CLF_BGRX: d3i_fread(&b,1,1,f); d3i_fread(&g,1,1,f); d3i_fread(&r,1,1,f); d3i_fseek(f,1,SEEK_CUR); default: break; } } inline void Read (D3I_FILE * const f, CL_RGBFormat const t, unsigned int const maxval) { Read(f,t); if (maxval != 255) { r = (unsigned char) ( ((unsigned int)r << 8) / (maxval+1) ); g = (unsigned char) ( ((unsigned int)g << 8) / (maxval+1) ); b = (unsigned char) ( ((unsigned int)b << 8) / (maxval+1) ); } } unsigned int FVD_Distance(CL_Pixel_24 const & p2) const; }; struct CL_DX_Format { unsigned int red_mask, red_shift, red_bits, red_bits_gt8, red_bits_lt8, blue_mask, blue_shift, blue_bits, blue_bits_gt8, blue_bits_lt8, green_mask, green_shift, green_bits, green_bits_gt8, green_bits_lt8; CL_Pixel_24 dx_black; inline void Init(unsigned int rmask,unsigned int gmask,unsigned int bmask) { red_mask = rmask; blue_mask = bmask; green_mask = gmask; for (red_shift = 0; !(rmask & 1); red_shift++, rmask>>=1); for (green_shift = 0; !(gmask & 1); green_shift++, gmask>>=1); for (blue_shift = 0; !(bmask & 1); blue_shift++, bmask>>=1); for (red_bits = 0; rmask; red_bits++, rmask>>=1); for (green_bits = 0; gmask; green_bits++, gmask>>=1); for (blue_bits = 0; bmask; blue_bits++, bmask>>=1); if (blue_bits >= green_bits && blue_bits >= red_bits) { dx_black = CL_Pixel_24(0,0,1); } else if (red_bits >= green_bits) { dx_black = CL_Pixel_24(1,0,0); } else { dx_black = CL_Pixel_24(0,1,0); } if (red_bits >= 8) { red_bits_gt8 = red_bits-8; red_bits_lt8 = 0; } else { red_bits_lt8 = 8-red_bits; red_bits_gt8 = 0; } if (green_bits >= 8) { green_bits_gt8 = green_bits-8; green_bits_lt8 = 0; } else { green_bits_lt8 = 8-green_bits; green_bits_gt8 = 0; } if (blue_bits >= 8) { blue_bits_gt8 = blue_bits-8; blue_bits_lt8 = 0; } else { blue_bits_lt8 = 8-blue_bits; blue_bits_gt8 = 0; } } }; // for 32 bit and 24 bit DirectX formats template struct CL_Pixel_T { static CL_DX_Format f; static CL_DX_Format f_d3d; static CL_DX_Format f_ddraw; S p; inline S r(void) const { return (S)((p & f.red_mask)>>f.red_shift); } inline S g(void) const { return (S)((p & f.green_mask)>>f.green_shift); } inline S b(void) const { return (S)((p & f.blue_mask)>>f.blue_shift); } CL_Pixel_T() {} CL_Pixel_T(CL_Pixel_T const & p32) : p(p32.p) {} CL_Pixel_T(CL_Pixel_24 const & p24) : p((S)( (S)p24.r>>f.red_bits_lt8<>f.green_bits_lt8<>f.blue_bits_lt8<>f.red_bits_gt8<>f.green_bits_gt8<>f.blue_bits_gt8<=r()<=g()<=g()<)p24; } inline void Read (D3I_FILE * const f, CL_RGBFormat const t, unsigned int const maxval) { CL_Pixel_24 p24; p24.Read(f,t,maxval); *this = (CL_Pixel_T)p24; } }; typedef CL_Pixel_T CL_Pixel_32; typedef CL_Pixel_T CL_Pixel_16; enum CL_Error { CLE_OK, CLE_LOADERROR, // file cannot be loaded - format is wrong CLE_OPENERROR, // file cannot be opened - does not exist? CLE_FINDERROR, // file cannot be found - not listed in .RIF file CLE_RIFFERROR, // rif file not loaded, or invalid CLE_INVALIDGAMEMODE, // specified game mode does not exist CLE_INVALIDDXMODE, // video mode is invalid CLE_DXERROR, // other direct X related error CLE_ALLOCFAIL // failed memory allocation }; enum CL_ImageMode { CLM_GLOBALPALETTE, // image shares a global palette in a palettized mode CLM_TLTPALETTE, // images may also share an abstract palette which remaps via a tlt to a global display palette CLM_ATTACHEDPALETTE, // 256 colour image with attached palette CLM_16BIT, // 16 bit in specified RGB format CLM_32BIT, // 32 bit in specified RGB format CLM_24BIT // 24 bit truecolour image in 888 format }; // Note: // currently 24-bit and 16-bit image formats are not output. // If the desired format is 24-bit or 16-bit then 256 colour BMPs are loaded // and 'unquantized' to generate the required format. enum CL_LoadMode { CLL_D3DTEXTURE, CLL_DDSURFACE }; void CL_Select_Mode(CL_LoadMode const lmode); void CL_Init_D3DMode(LPDDSURFACEDESC const format); enum CL_VideoMode { CLV_8, CLV_15, CLV_24, CLV_8T, CLV_8TLT }; void CL_Init_DirectDrawMode(CL_VideoMode const vmode); // test!!! #if HwTextureHack static int craptest = 0; #endif #if EXIT_ON_LOAD_FAIL extern "C" { #include "3dc.h" } #if EXIT_ON_LOCATE_FAIL #define EXITONLOCATEFAIL(__errcode,__iname,__enum_id) \ if (CLE_RIFFERROR != __errcode) { \ if (__iname) textprint("Cannot figure path for:\n%s\n",__iname); \ else textprint("Cannot figure path for:\nImage ID %d\n",__enum_id); \ WaitForReturn(); \ ExitSystem(); \ exit(0x10cafa11); \ } #else #define EXITONLOCATEFAIL(__errcode,__iname,__enum_id) #endif #define EXITONLOADFAIL(__iname) \ { \ textprint("Cannot open:\n%s\n",__iname); \ WaitForReturn(); \ ExitSystem(); \ exit(0x10adfa11); \ } #define EXITONREADFAIL(__iname) \ { \ textprint("Cannot read:\n%s\n",__iname); \ WaitForReturn(); \ ExitSystem(); \ exit(0x10adfa11); \ } #else #define EXITONLOCATEFAIL(__errcode,__iname,__enum_id) #define EXITONLOADFAIL(__iname) #define EXITONREADFAIL(__iname) #endif struct CL_Flags { unsigned int loaded : 1; unsigned int located : 1; unsigned int raw16bit : 1; unsigned int tltpalette : 1; CL_Flags() : loaded(0) , located(0) , tltpalette(0) , raw16bit(0) {} }; #define CL_EID_INVALID (-1) #if 0 template class CL_MIP_Image { public: unsigned int num_mipmaps; I * * mipmaps; // array of CL_Image pointers of decreasing image size unsigned int width; // == mipmaps[0]->width unsigned int height; // == mipmaps[0]->height unsigned int size; // == mipmaps[0]->size char * fname; // full filename (including directory/path) of mipmap with index 0 char * name; // name of image without directory/path or extension CL_MIP_Image() : mipmaps(0), num_mipmaps(0), fname(0), name(0) {} ~CL_MIP_Image() { Delete(); } CL_MIP_Image(CL_MIP_Image const & i2) : width (i2.width) , height (i2.height) , size (i2.size) , num_mipmaps (i2.num_mipmaps) { Copy(i2); } CL_MIP_Image & operator = (CL_MIP_Image const & i2) { if (&i2 != this) { Delete(); width = i2.width; height = i2.height; size = i2.size; num_mipmaps = i2.num_mipmaps; Copy(i2); } return *this; } private: void Copy(CL_MIP_Image const & i2) { if (i2.mipmaps) { mipmaps = new I * [num_mipmaps]; for (int i=0; iwidth*mipmaps[i-1]->height*(I::bitsperpixel>>3); CL_Error thismipmaperror = mipmaps[i]->CopyToScanDrawTexture(ImagePtrA[i]); if (CLE_OK != thismipmaperror) return thismipmaperror; } return CLE_OK; } CL_Error CopyToD3DTexture(LPDIRECTDRAWSURFACE * const DDPtrA [], LPVOID * const DDSurfaceA [], unsigned int maxnummips, int const MemoryType) { if (!flags.loaded) return CLE_LOADERROR; WaitForVRamReady(VWS_D3DTEXCREATE); if (CLL_D3DTEXTURE != I::lmode) CL_Select_Mode(CLL_D3DTEXTURE); LPDIRECTDRAWSURFACE lpDDS; DDSURFACEDESC ddsd; HRESULT ddrval; if (width & 3 || height & 3) { // return error code return CLE_DXERROR; } /* test !!! */ { #if HwTextureHack craptest++; if (craptest > 10) return CLE_DXERROR; #endif } if (num_mipmaps < maxnummips) maxnummips = num_mipmaps; // Set up the mip-mapped surface description. starting // with the passed texture format and then // incorporating the information read from the // ppm. memcpy(&ddsd, I::format, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT); ddsd.dwMipMapCount = maxnummips; // engine standard, primary plus six mip-maps ddsd.ddsCaps.dwCaps = (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | MemoryType); ddsd.dwHeight = height; ddsd.dwWidth = width; // 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 } // 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; while ((ddrval == DD_OK) && (MipMapNum < maxnummips)) // both tests in case... { // Call LoadPPMIntoDDSurface with lpThisMipMap, new file name, and // other values. *DDSurfaceA[MipMapNum] = mipmaps[MipMapNum]->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++; } return CLE_OK; } CL_Error CopyToDirectDrawSurface(LPDIRECTDRAWSURFACE * const DDPtrA [], LPVOID * const DDSurfaceA [], unsigned int maxnummips, int const MemoryType) { if (!flags.loaded) return CLE_LOADERROR; WaitForVRamReady(VWS_DDCREATE); if (CLL_DDSURFACE != I::lmode) CL_Select_Mode(CLL_DDSURFACE); LPDIRECTDRAWSURFACE lpDDS; DDSURFACEDESC ddsd; HRESULT ddrval; if (width & 3 || height & 3) { // return error code return CLE_DXERROR; } if (num_mipmaps < maxnummips) maxnummips = num_mipmaps; // Set up the mip-mapped 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 | DDSD_MIPMAPCOUNT); ddsd.dwMipMapCount = maxnummips; // engine standard, primary plus six mip-maps ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | MemoryType); ddsd.dwHeight = height; ddsd.dwWidth = width; // 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 } // 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; while ((ddrval == DD_OK) && (MipMapNum < maxnummips)) // both tests in case... { // Call LoadPPMIntoDDSurface with lpThisMipMap, new file name, and // other values. *DDSurfaceA[MipMapNum] = mipmaps[MipMapNum]->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++; } return CLE_OK; } private: // I was using Dan's list template for this, // but since it is not a standard part of 3DC, // I have had to write a specific simple list handler struct TempListMember { I * mip; TempListMember * next; TempListMember(I * data) : mip(data), next(0) {} //TempListMember() : next(0) {} ~TempListMember() { if (next) delete next; } }; struct TempList { unsigned int n_entries; TempListMember * first; TempListMember * last; TempList(I * data) : first(new TempListMember(data)), n_entries(1) { last = first; } TempList & operator += (I * data) { if (!first) { first = new TempListMember(data); last = first; } else { last->next = new TempListMember(data); last = last->next; } ++ n_entries; return *this; } ~TempList() { if (first) delete first; } }; CL_Error Load(char const * const iname, int const enum_id) { if (iname || CL_EID_INVALID != enum_id) flags.located = 0; I * mip0; if (flags.located && mipmaps) { mip0 = mipmaps[0]; // we have grabbed the previously allocated pointer // it will now be treated as if it were allocated here, // so we must remove it from the class, in case the // deconstructor tries to deallocate it delete[] mipmaps; mipmaps = 0; } else { mip0 = new I; CL_Error locate_err = mip0->Locate(iname,enum_id); if (locate_err != CLE_OK) { delete mip0; 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 (I::imode) { case CLM_GLOBALPALETTE: case CLM_TLTPALETTE: texformat = "Palettized Display"; 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",mip0->fname,texformat,I::bitsperpixel,redbits,greenbits,bluebits); #endif START_TIMER D3I_FILE * fp = d3i_fopen(mip0->fname,"rb"); END_TIMER(OpenTime) if (!fp) { #if OUTPUT_LOG CL_LogFile.lputs("** ERROR: unable to open\n"); #endif EXITONLOADFAIL(mip0->fname) delete mip0; return CLE_OPENERROR; } CL_Error load_err = mip0->Load_Image(fp); START_TIMER d3i_fclose(fp); END_TIMER(CloseTime) if (load_err != CLE_OK) { if (!flags.located) delete mip0; #if OUTPUT_LOG CL_LogFile.lputs("** ERROR: unable to read\n"); #endif EXITONREADFAIL(mip0->fname) return load_err; } TempList miplist(mip0); width = mip0->width; height = mip0->height; size = mip0->size; if (!flags.located) { if (fname) delete[] fname; if (name) delete[] name; fname = new char[strlen(mip0->fname)+1]; name = new char[strlen(mip0->name)+1]; strcpy(fname,mip0->fname); strcpy(name,mip0->name); } for (int mip_idx = 1; mip_idx < 7; ++mip_idx) { I * mip_n; mip_n = new I; 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); #if OUTPUT_LOG char const * texformat; unsigned int redbits = 8; unsigned int greenbits = 8; unsigned int bluebits = 8; switch (I::imode) { case CLM_GLOBALPALETTE: case CLM_TLTPALETTE: texformat = "Palettized Display"; 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",mip_n->fname,texformat,I::bitsperpixel,redbits,greenbits,bluebits); #endif START_TIMER fp = d3i_fopen(mip_n->fname,"rb"); END_TIMER(OpenTime) if (!fp) { delete mip_n; #if OUTPUT_LOG CL_LogFile.lputs("** Warning: unable to open\n"); #endif break; } load_err = mip_n->Load_Image(fp); START_TIMER d3i_fclose(fp); END_TIMER(CloseTime) if (load_err != CLE_OK) { delete mip_n; #if OUTPUT_LOG CL_LogFile.lputs("** Warning: unable to read\n"); #endif 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; } miplist += mip_n; } if (mipmaps) { for (int i = 0; imip; listP = listP->next; } flags.loaded = 1; flags.located = 1; return CLE_OK; } CL_Error PreLoad(char const * const iname, int const enum_id) { I * mip0 = new I; CL_Error locate_err = mip0->Locate(iname,enum_id); if (locate_err != CLE_OK) { delete mip0; return locate_err; } if (fname) delete[] fname; if (name) delete[] name; fname = new char[strlen(mip0->fname)+1]; name = new char[strlen(mip0->name)+1]; strcpy(fname,mip0->fname); strcpy(name,mip0->name); if (mipmaps) { for (int i=0; i mipmaps; CL_Image() : im8(0),im16(0),im24(0),palette(0),palette_size(0),fname(0),name(0) {} virtual ~CL_Image(); CL_Image(CL_Image const &); CL_Image & operator = (CL_Image const &); inline CL_Error Load(char const * const iname) // looks at rif file and video mode to determine which file to load { return Load(iname,CL_EID_INVALID); } inline CL_Error Load(int const enum_id) // looks at rif file and video mode to determine which file to load { return Load(0,enum_id); } inline CL_Error Load() // assumes preload has been called { return Load(0,CL_EID_INVALID); } inline CL_Error PreLoad(char const * const iname) // looks at rif file and video mode to determine which file to load { return PreLoad(iname,CL_EID_INVALID); } inline CL_Error PreLoad(int const enum_id) // looks at rif file and video mode to determine which file to load { return PreLoad(0,enum_id); } CL_Error LoadMipMaps(int const n_mips = 7); // assumes locating has been done (ie. PreLoad or Load has been called) CL_Error Load_BMP(D3I_FILE * f); // videomode != CLM_GLOBALPALETTE CL_Error Load_PPM(D3I_FILE * f); // videomode == CLM_16BIT || CLM_24BIT CL_Error Load_PGM(D3I_FILE * f); // videomode == CLM_GLOBALPALETTE CL_Error Load_PWM(D3I_FILE * f); // videomode == CLM_GLOBALPALETTE CL_Error Load_Image(D3I_FILE * f); // calls one of the above if correct format CL_Error GetBitsPerPixel(unsigned int* bpp); //returns bitsperpixel; // needs CL_Init_D3DMode((LPDDSURFACEDESC)format) to have been called inline CL_Error CopyToD3DTexture(LPDIRECTDRAWSURFACE * const DDPtrA, LPVOID * const DDSurfaceA, int const MemoryType) { return CopyToD3DTexture(&DDPtrA,&DDSurfaceA,MemoryType); } CL_Error CopyToD3DTexture(LPDIRECTDRAWSURFACE * const DDPtrA [], LPVOID * const DDSurfaceA [], int const MemoryType, unsigned int n_mips_max = 1); // needs CL_Init_ScanDrawMode((CL_VideoMode) videomode) to have been called inline CL_Error CopyToDirectDrawSurface(LPDIRECTDRAWSURFACE * const DDPtrA, LPVOID * const DDSurfaceA, int const MemoryType) { return CopyToDirectDrawSurface(&DDPtrA,&DDSurfaceA,MemoryType); } CL_Error CopyToDirectDrawSurface(LPDIRECTDRAWSURFACE * const DDPtrA [], LPVOID * const DDSurfaceA [], int const MemoryType, unsigned int n_mips_max = 1); // needs CL_Init_ScanDrawMode((CL_VideoMode) videomode) to have been called inline CL_Error CopyToScanDrawTexture(unsigned char * * const ImagePtrA) { return CopyToScanDrawTexture(&ImagePtrA); } CL_Error CopyToScanDrawTexture(unsigned char * * const ImagePtrA [], unsigned int n_mips_max = 1); // create an empty image for user manipulation CL_Error Make(int const _width,int const _height); // create an empty random image for user manipulation CL_Error MakeRandom(int const _width,int const _height,int const seed = -1); // ensure with and height are multiples of given units void PadTo(int const width_unit,int const height_unit); inline CL_Flags const & GetFlags() const { return flags; } protected: CL_Flags flags; virtual CL_Error Locate(char const * iname, int const enum_id); CL_Error Load(char const * const iname, int const enum_id); CL_Error PreLoad(char const * const iname, int const enum_id); CL_Error ReducePalette(unsigned int const num_colours); // returns DDSURFACEDESC.lpSurface // does what LoadPPMIntoDDSurface did LPVOID CopyToDDSurface(LPDIRECTDRAWSURFACE lpDDS); private: void Copy(CL_Image const &); void Delete(void); void DeleteNotMips(void); }; #endif // !_included__d3_image_hpp_