diff options
| author | Steven Fuller <relnev@icculus.org> | 2001-07-01 00:55:22 +0000 |
|---|---|---|
| committer | Patryk Obara <dreamer.tan@gmail.com> | 2019-08-20 02:09:04 +0200 |
| commit | 2186d5f3f95cd74a070a490d899291648d58667a (patch) | |
| tree | 55241a1afa3e1a22e0b6593a8dead0b703800f44 /3dc/win95/D3_IMAGE.HPP | |
| parent | 218ca90543758a20ac326e444ca0643174ca7384 (diff) | |
Initial revision
Diffstat (limited to '3dc/win95/D3_IMAGE.HPP')
| -rw-r--r-- | 3dc/win95/D3_IMAGE.HPP | 1223 |
1 files changed, 0 insertions, 1223 deletions
diff --git a/3dc/win95/D3_IMAGE.HPP b/3dc/win95/D3_IMAGE.HPP deleted file mode 100644 index a2bc639..0000000 --- a/3dc/win95/D3_IMAGE.HPP +++ /dev/null @@ -1,1223 +0,0 @@ -#ifndef _included__d3_image_hpp_ -#define _included__d3_image_hpp_ - -#error "This file is obsolete" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#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 <time.h> -#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 <class S> -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<S> const & p32) : p(p32.p) {} - CL_Pixel_T(CL_Pixel_24 const & p24) - : p((S)( - (S)p24.r>>f.red_bits_lt8<<f.red_shift+f.red_bits_gt8 | - (S)p24.g>>f.green_bits_lt8<<f.green_shift+f.green_bits_gt8 | - (S)p24.b>>f.blue_bits_lt8<<f.blue_shift+f.blue_bits_gt8 )) - { - // make the 32bit pixel non-black to avoid transparency problems - if (!p && p24.l) // if the 24bit pixel is not black and the 32 bit pixel is black - { - // choose which of r,g or b to make non-zero - try and get as close to black as poss - if ((1<<f.blue_bits_lt8)-p24.b <= (1<<f.red_bits_lt8)-p24.r && (1<<f.blue_bits_lt8)-p24.b <= (1<<f.green_bits_lt8)-p24.g) - p = (S)(1<<f.blue_shift); - else if ((1<<f.red_bits_lt8)-p24.r <= (1<<f.green_bits_lt8)-p24.g) - p = (S)(1<<f.red_shift); - else - p = (S)(1<<f.green_shift); - } - } - - inline operator CL_Pixel_24 (void) const - { - S rr = (S)(r()>>f.red_bits_gt8<<f.red_bits_lt8); - S gg = (S)(g()>>f.green_bits_gt8<<f.green_bits_lt8); - S bb = (S)(b()>>f.blue_bits_gt8<<f.blue_bits_lt8); - - if (!(rr|gg|bb) && p) - { - if (b()<<f.red_bits>=r()<<f.blue_bits && b()<<f.green_bits>=g()<<f.blue_bits) // make the 16bit pixel non-black to avoid transparency problems - bb = 1; - else if (r()<<f.green_bits>=g()<<f.red_bits) - rr = 1; - else - gg = 1; - } - - return CL_Pixel_24((unsigned char)rr,(unsigned char)gg,(unsigned char)bb); - }; - operator S (void) const { return p; } - - inline void Read (D3I_FILE * const f, CL_RGBFormat const t) - { - CL_Pixel_24 p24; - p24.Read(f,t); - *this = (CL_Pixel_T<S>)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<S>)p24; - } -}; - - -typedef CL_Pixel_T<unsigned long> CL_Pixel_32; -typedef CL_Pixel_T<unsigned short> 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 I> -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<I> const & i2) - : width (i2.width) - , height (i2.height) - , size (i2.size) - , num_mipmaps (i2.num_mipmaps) - { Copy(i2); } - - CL_MIP_Image<I> & operator = (CL_MIP_Image<I> 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<I> const & i2) - { - if (i2.mipmaps) - { - mipmaps = new I * [num_mipmaps]; - for (int i=0; i<num_mipmaps; ++i) - { - mipmaps[i] = new I(*i2.mipmaps[i]); - } - } - - if (i2.fname) - { - fname = new char[strlen(i2.fname)+1]; - strcpy(fname,i2.fname); - } - - if (i2.name) - { - name = new char[strlen(i2.name)+1]; - strcpy(name,i2.name); - } - } - void Delete(void) - { - if (mipmaps) - { - for (int i=0; i<num_mipmaps; ++i) delete mipmaps[i]; - delete[] mipmaps; - mipmaps = 0; - } - - if (name) - { - delete[] name; - name = 0; - } - - if (fname) - { - delete[] fname; - fname = 0; - } - } - - CL_Flags flags; - -public: - inline CL_Error Load(int const enum_id) - { - return Load(0,enum_id); - } - inline CL_Error Load(char const * const iname) - { - return Load(iname,CL_EID_INVALID); - } - inline CL_Error Load() - { - return Load(0,CL_EID_INVALID); - } - - inline CL_Error PreLoad(int const enum_id) - { - return PreLoad(0,enum_id); - } - inline CL_Error PreLoad(char const * const iname) - { - return PreLoad(iname,CL_EID_INVALID); - } - - CL_Error CopyToScanDrawTexture(unsigned char * * const ImagePtrA [], unsigned int maxnummips) - { - if (!flags.loaded) return CLE_LOADERROR; - - if (CLL_DDSURFACE != I::lmode) CL_Select_Mode(CLL_DDSURFACE); - - if (num_mipmaps < maxnummips) maxnummips = num_mipmaps; - if (!maxnummips) return CLE_ALLOCFAIL; - - if (!*ImagePtrA[0]) *ImagePtrA[0] = (unsigned char *) AllocateMem((2*width+1)*(2*height+1)*I::bitsperpixel/24+(maxnummips-3)*I::bitsperpixel/8); // slightly more than 4/3 w*h*bytedepth - - for (int i=0; i<maxnummips; ++i) - { - if (i) *ImagePtrA[i] = *ImagePtrA[i-1] + mipmaps[i-1]->width*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; i<num_mipmaps; ++i) delete mipmaps[i]; - delete[] mipmaps; - } - - num_mipmaps = miplist.n_entries; - mipmaps = new I * [num_mipmaps]; - - TempListMember * listP = miplist.first; - for (int i=0; i<num_mipmaps; ++i) - { - mipmaps[i] = listP->mip; - 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<num_mipmaps; ++i) delete mipmaps[i]; - delete[] mipmaps; - } - - num_mipmaps = 1; - mipmaps = new I * [1]; - *mipmaps = mip0; - - flags.loaded = 0; - flags.located = 1; - - return CLE_OK; - } -}; -#endif - -struct CL_Image -{ -public: - static CL_ImageMode imode; // video mode defines which format images should be loaded - static CL_ImageMode imode_d3d; // video mode defines which format images should be loaded - static CL_ImageMode imode_ddraw; // video mode defines which format images should be loaded - static LPDDSURFACEDESC format; - static unsigned int bitsperpixel; - static unsigned int bitsperpixel_d3d; - static unsigned int bitsperpixel_ddraw; - static CL_LoadMode lmode; - - // any one of these 3 may be valid - union - { // array of 24 bit or 32 bit pixels - CL_Pixel_24 * * im24; // array of 24 bit pixels - CL_Pixel_32 * * im32; // array of 32 bit pixels - // the data storage sizes of CL_Pixel_24 and CL_Pixel_32 must match - }; - union - { - CL_Pixel_16 * * im16; // array of 16 bit pixels - unsigned short * * im16raw; // raw double-byte pixel data - }; - unsigned char * * im8; // array of entrys into CLUT - - unsigned int palette_size; - CL_Pixel_24 * palette; // CLUT (applicable only if 'im8' is valid) - - unsigned int width; - unsigned int height; - unsigned int size; // width * height - - char * fname; // full name of image including directory/path and extension - char * name; // name of image without directory/path or extension - - List<CL_Image *> 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_ |
