texture.cpp
上传用户:garry_shen
上传日期:2015-04-15
资源大小:45647k
文件大小:16k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "XMudClient.h"
  3. #include "d3dappi.h"
  4. #define MAGICBYTES 2
  5. void D3DAppIAddPathList(const char *path);
  6. void D3DAppIInitialisePathList();
  7. FILE * D3DAppIFindFile(const char *name, const char *mode);
  8. BOOL loadPPMHeader(FILE *fp, DWORD *width, DWORD *height, int *maxgrey);
  9. BOOL D3DAppILoadTextureSurf(int n, BOOL* bInVideo)
  10. {
  11.   DDSURFACEDESC ddsd;
  12.   LPDIRECTDRAWSURFACE lpSrcTextureSurf = NULL;
  13.   LPDIRECT3DTEXTURE2 lpSrcTexture = NULL;
  14.   LPDIRECTDRAWPALETTE lpDstPalette = NULL;
  15.   PALETTEENTRY ppe[256];
  16.   DWORD pcaps;
  17.   RELEASE(d3dappi.lpTextureSurf[n]);
  18.   lpSrcTextureSurf = D3DAppILoadSurface(d3dappi.lpDD, d3dappi.ImageFile[n],
  19.     &d3dappi.ThisTextureFormat.ddsd,
  20.     DDSCAPS_SYSTEMMEMORY);
  21.   if (!lpSrcTextureSurf)
  22.     goto exit_with_error;
  23.   LastError = lpSrcTextureSurf->QueryInterface(IID_IDirect3DTexture2,
  24.     (LPVOID*)&lpSrcTexture);
  25.   if (LastError != DD_OK)
  26.   {
  27.     D3DAppISetErrorString("Failed to obtain D3D texture interface for a source texture.n%s", D3DAppErrorToString(LastError));
  28.     goto exit_with_error;
  29.   }
  30.   LastError = D3DAppIGetSurfDesc(&ddsd, lpSrcTextureSurf);
  31.   if (LastError != DD_OK) {
  32.     D3DAppISetErrorString("Could not get the surface description of the source texture.n%s",
  33.       D3DAppErrorToString(LastError));
  34.     goto exit_with_error;
  35.   }
  36.   ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
  37.   ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD;
  38.   if (!d3dappi.ThisDriver.bIsHardware)
  39.     ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
  40.   LastError = D3DAppICreateSurface(&ddsd, &d3dappi.lpTextureSurf[n]);
  41.   if (LastError != DD_OK) {
  42.     D3DAppISetErrorString("Could not create the destination texture surface.n%s",
  43.       D3DAppErrorToString(LastError));
  44.     goto exit_with_error;
  45.   }
  46.   if (ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
  47.     pcaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
  48.   } else if (ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) {
  49.     pcaps = DDPCAPS_4BIT;
  50.   } else {
  51.     pcaps = 0;
  52.   }
  53.   if (pcaps) {
  54.     memset(ppe, 0, sizeof(PALETTEENTRY) * 256);
  55.     LastError = d3dappi.lpDD->CreatePalette(pcaps,
  56.       ppe, &lpDstPalette, NULL);
  57.     if (LastError != DD_OK)
  58.     {
  59.       D3DAppISetErrorString("Failed to create a palette for the destination texture.n%s",
  60.         D3DAppErrorToString(LastError));
  61.       goto exit_with_error;
  62.     }
  63.     LastError = d3dappi.lpTextureSurf[n]->SetPalette(lpDstPalette);
  64.     if (LastError != DD_OK)
  65.     {
  66.       D3DAppISetErrorString("Failed to set the destination texture's palette.n%s",
  67.         D3DAppErrorToString(LastError));
  68.       goto exit_with_error;
  69.     }
  70.     lpDstPalette->Release( );
  71.   }
  72.   LastError = d3dappi.lpTextureSurf[n]->QueryInterface(IID_IDirect3DTexture2,
  73.     (LPVOID*)&d3dappi.lpTexture[n]);
  74.   if (LastError != DD_OK){
  75.     D3DAppISetErrorString("Failed to obtain D3D texture interface for a destination texture.n%s",
  76.       D3DAppErrorToString(LastError));
  77.     goto exit_with_error;
  78.   }
  79.   LastError = d3dappi.lpTexture[n]->Load(lpSrcTexture);
  80.   if (LastError != DD_OK)
  81.   {
  82.     D3DAppISetErrorString("Could not load a source texture into a destination texture.n%s",
  83.       D3DAppErrorToString(LastError));
  84.     goto exit_with_error;
  85.   }
  86.   RELEASE(lpSrcTexture);
  87.   RELEASE(lpSrcTextureSurf);
  88.   LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpTextureSurf[n]);
  89.   if (LastError != DD_OK){
  90.     D3DAppISetErrorString("Could not get the surface description of the loaded texture surface.n%s",
  91.       D3DAppErrorToString(LastError));
  92.     goto exit_with_error;
  93.   }
  94.   if (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
  95.     *bInVideo = TRUE;
  96.   else
  97.     *bInVideo = FALSE;
  98.   
  99.   
  100.   return TRUE;
  101.   
  102. exit_with_error:
  103.   RELEASE(lpSrcTexture);
  104.   RELEASE(lpSrcTextureSurf);
  105.   RELEASE(lpDstPalette);
  106.   RELEASE(d3dappi.lpTexture[n]);
  107.   RELEASE(d3dappi.lpTextureSurf[n]);
  108.   return FALSE;
  109. }
  110. BOOL D3DAppIReloadTextureSurf(int n)
  111. {
  112.   LPDIRECTDRAWSURFACE lpSrcTextureSurf = NULL;
  113.   LPDIRECT3DTEXTURE2 lpSrcTexture = NULL;
  114.   
  115.   lpSrcTextureSurf = D3DAppILoadSurface(d3dappi.lpDD, d3dappi.ImageFile[n],
  116.     &d3dappi.ThisTextureFormat.ddsd,
  117.     DDSCAPS_SYSTEMMEMORY);
  118.   if (!lpSrcTextureSurf)
  119.     goto exit_with_error;
  120.   LastError = lpSrcTextureSurf->QueryInterface(IID_IDirect3DTexture2,
  121.     (LPVOID*)&lpSrcTexture);
  122.   if (LastError != DD_OK) {
  123.     D3DAppISetErrorString("Failed to obtain D3D texture interface for a source texture.n%s", D3DAppErrorToString(LastError));
  124.     goto exit_with_error;
  125.   }
  126.   LastError = d3dappi.lpTexture[n]->Load(lpSrcTexture);
  127.   if (LastError != DD_OK)
  128.   {
  129.     D3DAppISetErrorString("Could not load a source texture into a destination texture.n%s",
  130.       D3DAppErrorToString(LastError));
  131.     goto exit_with_error;
  132.   }
  133.   RELEASE(lpSrcTexture);
  134.   RELEASE(lpSrcTextureSurf);
  135.   
  136.   return TRUE;
  137.   
  138. exit_with_error:
  139.   RELEASE(lpSrcTexture);
  140.   RELEASE(lpSrcTextureSurf);
  141.   return FALSE;
  142. }
  143. BOOL D3DAppIGetTextureHandle(int n)
  144. {
  145.   LastError = d3dappi.lpTexture[n]->GetHandle(d3dappi.lpD3DDevice, &MasterTextureHandle[n]);
  146.   if (LastError != DD_OK) {
  147.     D3DAppISetErrorString("Could not get a handle to loaded texture %i.n%s",
  148.       n, D3DAppErrorToString(LastError));
  149.     goto exit_with_error;
  150.   }
  151.   if (!d3dappi.bTexturesDisabled){
  152.     d3dappi.TextureHandle[n] = MasterTextureHandle[n];
  153.   }else{
  154.     d3dappi.TextureHandle[n] = 0;
  155.   }
  156.   return TRUE;
  157. exit_with_error:
  158.   MasterTextureHandle[n] = 0;
  159.   d3dappi.TextureHandle[n] = 0;
  160.   return FALSE;
  161. }
  162. void
  163. D3DAppIReleaseTexture(int n)
  164. {
  165.   RELEASE(d3dappi.lpTexture[n]);
  166.   RELEASE(d3dappi.lpTextureSurf[n]);
  167.   MasterTextureHandle[n] = 0;
  168.   d3dappi.TextureHandle[n] = 0;
  169. }
  170. void
  171. D3DAppIReleaseAllTextures(void)
  172. {
  173.   int i;
  174.   for (i = 0; i < d3dappi.NumTextures; i++) {
  175.     D3DAppIReleaseTexture(i);
  176.   }
  177. }
  178. BOOL D3DAppILoadAllTextures(void)
  179. {
  180.   int i;
  181.   if (d3dappi.ThisDriver.bDoesTextures)
  182.   {
  183.     d3dappi.NumUsableTextures = 0;
  184.     for (i = 0; i < d3dappi.NumTextures; i++)
  185.     {
  186.       BOOL bInVideo;
  187.       ATTEMPT(D3DAppILoadTextureSurf(i, &bInVideo));
  188.       if (!bInVideo && d3dappi.ThisDriver.bIsHardware)
  189.       {
  190.         D3DAppIReleaseTexture(i);
  191.         break;
  192.       }
  193.       else
  194.       {
  195.         ++d3dappi.NumUsableTextures;
  196.       }
  197.     }
  198.     for (i = 0; i < d3dappi.NumUsableTextures; i++)
  199.     {
  200.       ATTEMPT(D3DAppIGetTextureHandle(i));
  201.     }
  202.   }
  203.   else
  204.   {
  205.     d3dappi.NumUsableTextures = 0;
  206.   }
  207.   return TRUE;
  208.   
  209. exit_with_error:
  210.   for (i = 0; i < d3dappi.NumTextures; i++)
  211.   {
  212.     D3DAppIReleaseTexture(i);
  213.   }
  214.   return FALSE;
  215. }
  216. LPDIRECTDRAWSURFACE D3DAppILoadSurface(LPDIRECTDRAW lpDD, LPCSTR lpName,
  217.                                        LPDDSURFACEDESC lpFormat, DWORD memoryflag)
  218. {
  219.   LPDIRECTDRAWSURFACE lpDDS;
  220.   DDSURFACEDESC ddsd, format;
  221.   D3DCOLOR colors[256];
  222.   D3DCOLOR c;
  223.   DWORD dwWidth, dwHeight;
  224.   int i, j;
  225.   FILE *fp;
  226.   char *lpC;
  227.   LPDIRECTDRAWPALETTE lpDDPal;
  228.   PALETTEENTRY ppe[256];
  229.   int psize;
  230.   DWORD pcaps;
  231.   int color_count;
  232.   BOOL bQuant = FALSE;
  233.   HRESULT ddrval;
  234.   fp = D3DAppIFindFile(lpName, "rb");
  235.   if (fp == NULL)
  236.   {
  237.     D3DAppISetErrorString("Cannot find %s.n", lpName);
  238.     return NULL;
  239.   }
  240.   if (!loadPPMHeader(fp, &dwWidth, &dwHeight, &i))
  241.   {
  242.     fclose(fp);
  243.     D3DAppISetErrorString("Could not load or parse PPM header in %s.n", lpName);
  244.     return NULL;
  245.   }
  246.   memcpy(&format, lpFormat, sizeof(DDSURFACEDESC));
  247.   if (format.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
  248.   {
  249.     bQuant = TRUE;
  250.     psize = 256;
  251.     pcaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
  252.   } else if (format.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
  253.   {
  254.     bQuant = TRUE;
  255.     psize = 16;
  256.     pcaps = DDPCAPS_4BIT;
  257.   }
  258.   memcpy(&ddsd, &format, sizeof(ddsd));
  259.   ddsd.dwSize = sizeof(ddsd);
  260.   ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
  261.   ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | memoryflag;
  262.   ddsd.dwHeight = dwHeight;
  263.   ddsd.dwWidth = dwWidth;
  264.   
  265.   ddrval = lpDD->CreateSurface(&ddsd, &lpDDS, NULL);
  266.   if (ddrval != DD_OK) {
  267.     D3DAppISetErrorString("CreateSurface for texture failed (loadtex).n%s",
  268.       D3DAppErrorToString(ddrval));
  269.     return NULL;
  270.   }
  271.   memset(&ddsd, 0, sizeof(ddsd));
  272.   ddsd.dwSize = sizeof(ddsd);
  273.   ddrval = lpDDS->Lock(NULL, &ddsd, 0, NULL);
  274.   if (ddrval != DD_OK)
  275.   {
  276.     lpDDS->Release( );
  277.     D3DAppISetErrorString("Lock failed while loading surface (loadtex).n%s",
  278.       D3DAppErrorToString(ddrval));
  279.     return NULL;
  280.   }
  281.   if (!bQuant)
  282.   {
  283.     unsigned long* lpLP;
  284.     unsigned short* lpSP;
  285.     unsigned char* lpCP;
  286.     unsigned long m;
  287.     int s;
  288.     int red_shift, red_scale;
  289.     int green_shift, green_scale;
  290.     int blue_shift, blue_scale;
  291.     for (s = 0, m = format.ddpfPixelFormat.dwRBitMask; !(m & 1);
  292.     s++, m >>= 1);
  293.     red_shift = s;
  294.     red_scale = 255 / (format.ddpfPixelFormat.dwRBitMask >> s);
  295.     for (s = 0, m = format.ddpfPixelFormat.dwGBitMask; !(m & 1);
  296.     s++, m >>= 1);
  297.     green_shift = s;
  298.     green_scale = 255 / (format.ddpfPixelFormat.dwGBitMask >> s);
  299.     for (s = 0, m = format.ddpfPixelFormat.dwBBitMask; !(m & 1);
  300.     s++, m >>= 1);
  301.     blue_shift = s;
  302.     blue_scale = 255 / (format.ddpfPixelFormat.dwBBitMask >> s);
  303.     switch (format.ddpfPixelFormat.dwRGBBitCount)
  304.     {
  305.     case 32 :
  306.       for (j = 0; j < (int)dwHeight; j++) 
  307.       {
  308.         lpLP = (unsigned long*)(((char*)ddsd.lpSurface) +
  309.           ddsd.lPitch * j);
  310.         for (i = 0; i < (int)dwWidth; i++)
  311.         {
  312.           int r, g, b;
  313.           r = getc(fp) / red_scale;
  314.           g = getc(fp) / green_scale;
  315.           b = getc(fp) / blue_scale;
  316.           *lpLP = (r << red_shift) | (g << green_shift) |
  317.             (b << blue_shift);
  318.           lpLP++;
  319.         }
  320.       }
  321.       break;
  322.     case 16 :
  323.       for (j = 0; j < (int)dwHeight; j++) {
  324.         lpSP = (unsigned short*)(((char*)ddsd.lpSurface) +
  325.           ddsd.lPitch * j);
  326.         for (i = 0; i < (int)dwWidth; i++) {
  327.           int r, g, b;
  328.           r = getc(fp) / red_scale;
  329.           g = getc(fp) / green_scale;
  330.           b = getc(fp) / blue_scale;
  331.           *lpSP = (r << red_shift) | (g << green_shift) |
  332.             (b << blue_shift);
  333.           lpSP++;
  334.         }
  335.       }
  336.       break;
  337.     case 8:
  338.       for (j = 0; j < (int)dwHeight; j++) {
  339.         lpCP = (unsigned char*)(((char*)ddsd.lpSurface) +
  340.           ddsd.lPitch * j);
  341.         for (i = 0; i < (int)dwWidth; i++) {
  342.           int r, g, b;
  343.           r = getc(fp) / red_scale;
  344.           g = getc(fp) / green_scale;
  345.           b = getc(fp) / blue_scale;
  346.           *lpCP = (r << red_shift) | (g << green_shift) |
  347.             (b << blue_shift);
  348.           lpCP++;
  349.         }
  350.       }
  351.       break;
  352.     default:
  353.       lpDDS->Unlock(NULL);
  354.       fclose(fp);
  355.       lpDDS->Release( );
  356.       D3DAppISetErrorString("Unknown pixel format (loadtex).");
  357.       return NULL;
  358.     }
  359.     lpDDS->Unlock( NULL);
  360.     fclose(fp);
  361.     return (lpDDS);
  362.     }
  363.     color_count = 0;
  364.     for (j = 0; j < (int)dwHeight; j++)    {
  365.       lpC = ((char*)ddsd.lpSurface) + ddsd.lPitch * j;
  366.       for (i = 0; i < (int)dwWidth; i++)
  367.       {
  368.         int r, g, b, k;
  369.         r = getc(fp);
  370.         g = getc(fp);
  371.         b = getc(fp);
  372.         c = RGB_MAKE(r, g, b);
  373.         for (k = 0; k < color_count; k++)
  374.           if (c == colors[k]) break;
  375.           if (k == color_count) {
  376.             color_count++;
  377.             if (color_count > psize) {
  378.               color_count--;
  379.               k = color_count - 1;
  380.             }
  381.             colors[k] = c;
  382.           }
  383.           if (psize == 16) {
  384.             if ((i & 1) == 0)
  385.               *lpC = k & 0xf;
  386.             else {
  387.               *lpC |= (k & 0xf) << 4;
  388.               lpC++;
  389.             }
  390.           } else {
  391.             *lpC = (char)k;
  392.             lpC++;
  393.           }
  394.       }
  395.     }
  396.     fclose(fp);
  397.     lpDDS->Unlock(NULL);
  398.     
  399.     if (color_count > psize) {
  400.       lpDDS->Unlock(NULL);
  401.       lpDDS->Release( );
  402.       D3DAppISetErrorString("Palette burst. (loadtex).n");
  403.       return (NULL);
  404.     }
  405.     
  406.     memset(ppe, 0, sizeof(PALETTEENTRY) * 256);
  407.     for (i = 0; i < color_count; i++) {
  408.       ppe[i].peRed = (unsigned char)RGB_GETRED(colors[i]);
  409.       ppe[i].peGreen = (unsigned char)RGB_GETGREEN(colors[i]);
  410.       ppe[i].peBlue = (unsigned char)RGB_GETBLUE(colors[i]);
  411.     }
  412.     for (; i < 256; i++)
  413.       ppe[i].peFlags = D3DPAL_RESERVED;
  414.     ddrval = lpDD->CreatePalette(DDPCAPS_INITIALIZE | pcaps,
  415.       ppe, &lpDDPal, NULL);
  416.     if (ddrval != DD_OK){
  417.       lpDDS->Release( );
  418.       D3DAppISetErrorString("Create palette failed while loading surface (loadtex).n%s",
  419.         D3DAppErrorToString(ddrval));
  420.       return (NULL);
  421.     }
  422.     ddrval = lpDDS->SetPalette( lpDDPal);
  423.     if (ddrval != DD_OK){
  424.       lpDDS->Release( );
  425.       lpDDPal->Release( );
  426.       D3DAppISetErrorString("SetPalette failed while loading surface (loadtex).n%s",
  427.         D3DAppErrorToString(ddrval));
  428.       return (NULL);
  429.     }
  430.     
  431.     lpDDPal->Release( );
  432.     
  433.     return lpDDS;
  434. }
  435. BOOL ppm_getbyte(FILE *fp, char *newByte)
  436. {
  437.   char cchar;
  438.   int cc;
  439.   cchar = cc = getc(fp);
  440.   
  441.   if (cc == EOF) {
  442.     return FALSE;
  443.   }
  444.   
  445.   if (cchar == '#') {
  446.     do {
  447.       cchar = cc = getc(fp);
  448.       if (cc == EOF)
  449.         return FALSE;
  450.     } while (cchar != 'n' && cchar != 'r');
  451.   }
  452.   
  453.   *newByte = cchar;
  454.   
  455.   return TRUE;
  456. }
  457. BOOL ppm_getint(FILE *fp, DWORD *newInt)
  458. {
  459.   DWORD cint;
  460.   char cchar;
  461.   
  462.   do {
  463.     if (!ppm_getbyte(fp, &cchar)) return FALSE;
  464.   } while (isspace(cchar));
  465.   
  466.   if (!isdigit(cchar)) {
  467.     return FALSE;
  468.   }
  469.   
  470.   cint = 0;
  471.   
  472.   do {
  473.     cint = (cint * 10) + (cchar - '0');
  474.     if (!ppm_getbyte(fp, &cchar)) return FALSE;
  475.   } while(isdigit(cchar));
  476.   
  477.   *newInt = cint;
  478.   
  479.   return TRUE;
  480. }
  481. BOOL loadPPMHeader(FILE *fp, DWORD *width, DWORD *height, int *maxgrey)
  482. {
  483.   char magic[MAGICBYTES], cchar;
  484.   if (fread(magic, MAGICBYTES, 1, fp) != 1)
  485.     return FALSE;
  486.   if (magic[0] != 'P' || magic[1] != '6')
  487.     return FALSE;
  488.   if (!ppm_getint(fp, width))
  489.     return FALSE;
  490.   if (!ppm_getint(fp, height))
  491.     return FALSE;
  492.   if (!ppm_getint(fp, (DWORD * )maxgrey))
  493.     return FALSE;
  494.   do {
  495.     if (!ppm_getbyte(fp, &cchar))
  496.       return FALSE;
  497.   } while (cchar == ' ' || cchar == 't' || cchar == 'n' || cchar == 'r');
  498.   
  499.   fseek(fp, -1, SEEK_CUR);
  500.   
  501.   return TRUE;
  502. }
  503. #define MAXPATH    256
  504. #define PATHSEP    ';'
  505. #define FILESEP    '\'
  506. #define MAXCONTENTS 25
  507. #define RESPATH     "Software\Microsoft\Direct3D"
  508. int PathListInitialised = FALSE;
  509. static struct {
  510.   int count;
  511.   char *contents[MAXCONTENTS];
  512. } PathList;
  513. void D3DAppIAddPathList(const char *path)
  514. {
  515.   char *p;
  516.   char *elt;
  517.   int len;
  518.   
  519.   while (path) {
  520.     p = strchr(path, PATHSEP);
  521.     if (p)
  522.       len = p - path;
  523.     else
  524.       len = lstrlen(path);
  525.     elt = (char *) malloc(len + 1);
  526.     if (elt == NULL)
  527.       return;
  528.     lstrcpyn(elt, path, len + 1);
  529.     elt[len] = '';
  530.     PathList.contents[PathList.count] = elt;
  531.     PathList.count++;
  532.     if (p)
  533.       path = p + 1;
  534.     else
  535.       path = NULL;
  536.     if (PathList.count == MAXCONTENTS)
  537.       return;
  538.   }
  539.   return;
  540. }
  541. void D3DAppIInitialisePathList()
  542. {
  543.   long result;
  544.   HKEY key;
  545.   DWORD type, size;
  546.   static char buf[512];
  547.   char* path;
  548.   
  549.   if (PathListInitialised)
  550.     return;
  551.   PathListInitialised = TRUE;
  552.   
  553.   PathList.count = 0;
  554.   path = getenv("D3DPATH");
  555.   D3DAppIAddPathList(".");
  556.   if (path != NULL) {
  557.     D3DAppIAddPathList(path);
  558.     return;
  559.   }
  560.   result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RESPATH, 0, KEY_READ, &key);
  561.   if (result == ERROR_SUCCESS) {
  562.     size = sizeof(buf);
  563.     result = RegQueryValueEx(key, "D3D Path", NULL, &type, (LPBYTE) buf,
  564.       &size);
  565.     RegCloseKey(key);
  566.     if (result == ERROR_SUCCESS && type == REG_SZ)
  567.       D3DAppIAddPathList(buf);
  568.   }
  569. }
  570. FILE* D3DAppIFindFile(const char *name, const char *mode)
  571. {
  572.   FILE *fp;
  573.   char buf[MAXPATH];
  574.   static char filesep[] = {FILESEP, 0};
  575.   int i;
  576.   
  577.   D3DAppIInitialisePathList();
  578.   
  579.   fp = fopen(name, mode);
  580.   if (fp != NULL)
  581.     return fp;
  582.   
  583.   for (i = 0; i < PathList.count; i++) {
  584.     lstrcpy(buf, PathList.contents[i]);
  585.     lstrcat(buf, filesep);
  586.     lstrcat(buf, name);
  587.     fp = fopen(buf, mode);
  588.     if (fp)
  589.       return fp;
  590.   }
  591.   return NULL;
  592. }
  593. void
  594. D3DAppIReleasePathList(void)
  595. {
  596.   int i;
  597.   for (i = 0; i < PathList.count; i++) {
  598.     free(PathList.contents[i]);
  599.     PathList.contents[i] = NULL;
  600.   }
  601.   PathList.count = 0;
  602.   PathListInitialised = FALSE;
  603. }