00001
00002 #include "revolt.h"
00003 #include "texture.h"
00004 #include "dx.h"
00005 #include "main.h"
00006
00007
00008
00009 int TEX_NTPages = 0;
00010 TEXINFO *TexInfo;
00011 DDPIXELFORMAT TexFormat;
00012 char TexturesEnabled, TexturesSquareOnly, TexturesAGP;
00013 long TexturePixels, WorldTextureSet, CarTextureSet, FxTextureSet;
00014 DWORD TextureMinWidth, TextureMaxWidth, TextureMinHeight, TextureMaxHeight;
00015
00016 static long TexBppRequest;
00017
00019
00021 bool CreateTPages(int nPages)
00022 {
00023 if ((TexInfo = (TEXINFO *)malloc(sizeof(TEXINFO) * nPages)) == NULL) {
00024 return FALSE;
00025 }
00026
00027 TEX_NTPages = nPages;
00028
00029 return TRUE;
00030 }
00031
00033
00035
00036 void DestroyTPages()
00037 {
00038 free(TexInfo);
00039 TEX_NTPages = 0;
00040 }
00041
00043
00045
00046 void GetTextureFormat(long bpp)
00047 {
00048
00049
00050
00051 TexturesEnabled = FALSE;
00052 TexFormat.dwRGBBitCount = 0;
00053
00054
00055
00056 TexBppRequest = bpp;
00057 D3Ddevice->EnumTextureFormats(FindTextureCallback, NULL);
00058
00059 if (TexFormat.dwRGBBitCount)
00060 TexturesEnabled = TRUE;
00061 else
00062 TexturesEnabled = FALSE;
00063
00064
00065
00066 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
00067 TexturesSquareOnly = TRUE;
00068 else
00069 TexturesSquareOnly = FALSE;
00070
00071
00072
00073 if (D3Dcaps.dwDevCaps & D3DDEVCAPS_TEXTURENONLOCALVIDMEM)
00074 TexturesAGP = TRUE;
00075 else
00076 TexturesAGP = FALSE;
00077
00078
00079
00080 TextureMinWidth = D3Dcaps.dwMinTextureWidth;
00081 TextureMaxWidth = D3Dcaps.dwMaxTextureWidth;
00082 TextureMinHeight = D3Dcaps.dwMinTextureWidth;
00083 TextureMaxHeight = D3Dcaps.dwMaxTextureWidth;
00084
00085 }
00086
00088
00090
00091 void PickTextureSets(long playernum)
00092 {
00093 long max;
00094
00095
00096
00097 max = TPAGE_WORLD_NUM + playernum + TPAGE_SCALE_NUM + TPAGE_FIXED_NUM;
00098 max += max / 3;
00099
00100 TexturePixels = CountTexturePixels(max, 256, 256);
00101
00102
00103
00104 WorldTextureSet = 0;
00105 CarTextureSet = 0;
00106 FxTextureSet = 0;
00107
00108 if (MipSize(256, WorldTextureSet, TPAGE_WORLD_NUM, TRUE) + MipSize(256, CarTextureSet, playernum, TRUE) + MipSize(256, FxTextureSet, TPAGE_SCALE_NUM, TRUE) + MipSize(256, 0, TPAGE_FIXED_NUM, FALSE) > TexturePixels)
00109 FxTextureSet++;
00110
00111 if (MipSize(256, WorldTextureSet, TPAGE_WORLD_NUM, TRUE) + MipSize(256, CarTextureSet, playernum, TRUE) + MipSize(256, FxTextureSet, TPAGE_SCALE_NUM, TRUE) + MipSize(256, 0, TPAGE_FIXED_NUM, FALSE) > TexturePixels)
00112 CarTextureSet++;
00113
00114 if (MipSize(256, WorldTextureSet, TPAGE_WORLD_NUM, TRUE) + MipSize(256, CarTextureSet, playernum, TRUE) + MipSize(256, FxTextureSet, TPAGE_SCALE_NUM, TRUE) + MipSize(256, 0, TPAGE_FIXED_NUM, FALSE) > TexturePixels)
00115 WorldTextureSet++;
00116 }
00117
00119
00121
00122 long MipSize(long size, long set, long count, long mip)
00123 {
00124 long pixels = 0;
00125
00126 for ( ; set ; set--)
00127 size /= 2;
00128
00129 do {
00130 pixels += size * size;
00131 size /= 2;
00132 } while ((size >= 128) && mip);
00133
00134 return pixels * count;
00135 }
00136
00138
00140
00141 HRESULT CALLBACK FindTextureCallback(DDPIXELFORMAT *ddpf, void *lParam)
00142 {
00143
00144
00145
00146 if (ddpf->dwFlags & DDPF_ZBUFFER) return DDENUMRET_OK;
00147
00148
00149
00150 if (ddpf->dwFlags & DDPF_ALPHA) return DDENUMRET_OK;
00151
00152
00153
00154 if (ddpf->dwFlags & DDPF_ALPHAPIXELS) return DDENUMRET_OK;
00155
00156
00157
00158 if (ddpf->dwRGBBitCount < 16) return DDENUMRET_OK;
00159
00160
00161
00162 if (ddpf->dwRGBBitCount > 8 && !(ddpf->dwFlags & DDPF_RGB)) return DDENUMRET_OK;
00163
00164
00165
00166 if (TexFormat.dwRGBBitCount == 0) TexFormat = *ddpf;
00167
00168
00169
00170 if (ddpf->dwRGBBitCount == 16 && TexBppRequest == 16) TexFormat = *ddpf;
00171 if (ddpf->dwRGBBitCount >= 24 && TexBppRequest == 24) TexFormat = *ddpf;
00172
00173
00174
00175 return DDENUMRET_OK;
00176 }
00177
00179
00181
00182 long CountTexturePixels(long needed, long width, long height)
00183 {
00184 long i, max;
00185 DDSURFACEDESC2 ddsd2;
00186 HRESULT r;
00187 IDirectDrawSurface4 *sourcesurface;
00188 IDirect3DTexture2 *sourcetexture;
00189 IDirectDrawSurface4 *surface[MAX_TEXTURE_TEST];
00190 IDirect3DTexture2 *texture[MAX_TEXTURE_TEST];
00191
00192
00193
00194 max = 0;
00195
00196
00197
00198 ZeroMemory(&ddsd2, sizeof(ddsd2));
00199 ddsd2.dwSize = sizeof(ddsd2);
00200 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE;
00201 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
00202 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00203 ddsd2.dwWidth = width;
00204 ddsd2.dwHeight = height;
00205 ddsd2.ddpfPixelFormat = TexFormat;
00206 ddsd2.dwTextureStage = 0;
00207
00208 r = DD->CreateSurface(&ddsd2, &sourcesurface, NULL);
00209 if (r != DD_OK)
00210 {
00211 return 0;
00212 }
00213
00214 r = sourcesurface->QueryInterface(IID_IDirect3DTexture2, (void**)&sourcetexture);
00215 if (r != DD_OK)
00216 {
00217 RELEASE(sourcesurface);
00218 return 0;
00219 }
00220
00221
00222
00223 if (needed > MAX_TEXTURE_TEST) needed = MAX_TEXTURE_TEST;
00224
00225 for (i = 0 ; i < needed ; i++)
00226 {
00227 ZeroMemory(&ddsd2, sizeof(ddsd2));
00228 ddsd2.dwSize = sizeof(ddsd2);
00229 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE;
00230 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD;
00231 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00232 ddsd2.dwWidth = width;
00233 ddsd2.dwHeight = height;
00234 ddsd2.ddpfPixelFormat = TexFormat;
00235 ddsd2.dwTextureStage = 0;
00236
00237 r = DD->CreateSurface(&ddsd2, &surface[i], NULL);
00238 if (r != DD_OK)
00239 {
00240 break;
00241 }
00242
00243 r = surface[i]->QueryInterface(IID_IDirect3DTexture2, (void**)&texture[i]);
00244 if (r != DD_OK)
00245 {
00246 RELEASE(surface[i]);
00247 break;
00248 }
00249
00250 r = texture[i]->Load(sourcetexture);
00251 if (r != DD_OK)
00252 {
00253 RELEASE(texture[i]);
00254 RELEASE(surface[i]);
00255 break;
00256 }
00257
00258 max++;
00259 }
00260
00261
00262
00263 RELEASE(sourcesurface);
00264 RELEASE(sourcetexture);
00265
00266 for (i = 0 ; i < max ; i++)
00267 {
00268 RELEASE(texture[i]);
00269 RELEASE(surface[i]);
00270 }
00271
00272
00273
00274 return max * width * height;
00275 }
00276
00278
00280
00281 long CountMipTexturePixels(long needed, long width, long height)
00282 {
00283 long i, max;
00284 DDSURFACEDESC2 ddsd2;
00285 HRESULT r;
00286 IDirectDrawSurface4 *sourcesurface;
00287 IDirect3DTexture2 *sourcetexture;
00288 IDirectDrawSurface4 *surface[MAX_TEXTURE_TEST];
00289 IDirect3DTexture2 *texture[MAX_TEXTURE_TEST];
00290
00291
00292
00293 max = 0;
00294
00295
00296
00297 ZeroMemory(&ddsd2, sizeof(ddsd2));
00298 ddsd2.dwSize = sizeof(ddsd2);
00299 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE | DDSD_MIPMAPCOUNT;
00300 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
00301 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00302 ddsd2.dwWidth = width;
00303 ddsd2.dwHeight = height;
00304 ddsd2.ddpfPixelFormat = TexFormat;
00305 ddsd2.dwTextureStage = 0;
00306 ddsd2.dwMipMapCount = MAX_MIPMAPS;
00307
00308 r = DD->CreateSurface(&ddsd2, &sourcesurface, NULL);
00309 if (r != DD_OK)
00310 {
00311 return 0;
00312 }
00313
00314 r = sourcesurface->QueryInterface(IID_IDirect3DTexture2, (void**)&sourcetexture);
00315 if (r != DD_OK)
00316 {
00317 RELEASE(sourcesurface);
00318 return 0;
00319 }
00320
00321
00322
00323 if (needed > MAX_TEXTURE_TEST) needed = MAX_TEXTURE_TEST;
00324
00325 for (i = 0 ; i < needed ; i++)
00326 {
00327 ZeroMemory(&ddsd2, sizeof(ddsd2));
00328 ddsd2.dwSize = sizeof(ddsd2);
00329 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE | DDSD_MIPMAPCOUNT;
00330 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
00331 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00332 ddsd2.dwWidth = width;
00333 ddsd2.dwHeight = height;
00334 ddsd2.ddpfPixelFormat = TexFormat;
00335 ddsd2.dwTextureStage = 0;
00336 ddsd2.dwMipMapCount = MAX_MIPMAPS;
00337
00338 r = DD->CreateSurface(&ddsd2, &surface[i], NULL);
00339 if (r != DD_OK)
00340 {
00341 break;
00342 }
00343
00344 r = surface[i]->QueryInterface(IID_IDirect3DTexture2, (void**)&texture[i]);
00345 if (r != DD_OK)
00346 {
00347 RELEASE(surface[i]);
00348 break;
00349 }
00350
00351 r = texture[i]->Load(sourcetexture);
00352 if (r != DD_OK)
00353 {
00354 RELEASE(texture[i]);
00355 RELEASE(surface[i]);
00356 break;
00357 }
00358
00359 max++;
00360 }
00361
00362
00363
00364 RELEASE(sourcesurface);
00365 RELEASE(sourcetexture);
00366
00367 for (i = 0 ; i < max ; i++)
00368 {
00369 RELEASE(texture[i]);
00370 RELEASE(surface[i]);
00371 }
00372
00373
00374
00375 return max * width * height;
00376 }
00377
00379
00381
00382 bool LoadTextureClever(char *tex, char tpage, long width, long height, long stage, long set, long mip)
00383 {
00384 long i, len, mipcount;
00385 FILE *fp;
00386 char buf[256];
00387
00388
00389
00390 len = strlen(tex);
00391 if (!len) return FALSE;
00392
00393
00394
00395 mipcount = 0;
00396 strcpy(buf, tex);
00397
00398 for (i = 0 ; i < MAX_MIPMAPS ; i++)
00399 {
00400 buf[len - 1] = i + 'p';
00401 fp = fopen(buf, "rb");
00402 if (!fp) break;
00403 fclose(fp);
00404 mipcount++;
00405 }
00406
00407 if (!mipcount)
00408 return FALSE;
00409
00410
00411
00412 width >>= set;
00413 height >>= set;
00414
00415
00416
00417 if (set > mipcount - 1) set = mipcount - 1;
00418 buf[len - 1] = set + 'p';
00419
00420
00421
00422 if (!mip)
00423 mipcount = 1;
00424 else
00425 mipcount -= set;
00426
00427
00428
00429 return LoadMipTexture(buf, tpage, width, height, stage, mipcount);
00430 }
00431
00433
00435
00436 bool LoadTexture(char *tex, char tpage, long width, long height, long stage)
00437 {
00438 HBITMAP hbm;
00439 BITMAP bm;
00440 DDSURFACEDESC2 ddsd2;
00441 HRESULT r;
00442 HDC dcimage, dc;
00443 unsigned short cols, i;
00444 char buff[256];
00445 DWORD adw[256];
00446 DDCOLORKEY ck;
00447 short red, green, blue;
00448 IDirect3DTexture2 *texsource;
00449 IDirectDrawSurface4 *sourcesurface;
00450
00451
00452
00453 if (!tex || tex[0] == '\0')
00454 return FALSE;
00455
00456
00457
00458 if (tpage > TEX_NTPages)
00459 return FALSE;
00460
00461
00462
00463 if (!TexturesEnabled)
00464 {
00465 TexInfo[tpage].Active = FALSE;
00466 return FALSE;
00467 }
00468
00469
00470
00471 hbm = (HBITMAP)LoadImage(NULL, tex, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
00472 if (!hbm)
00473 {
00474 wsprintf(buff, "Can't load texture: '%s'", tex);
00475 Box("ERROR", buff, MB_OK);
00476 return FALSE;
00477 }
00478 GetObject(hbm, sizeof(bm), &bm);
00479
00480
00481
00482 ZeroMemory(&ddsd2, sizeof(ddsd2));
00483 ddsd2.dwSize = sizeof(ddsd2);
00484 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE;
00485 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
00486 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00487 ddsd2.dwWidth = width;
00488 ddsd2.dwHeight = height;
00489 ddsd2.ddpfPixelFormat = TexFormat;
00490 ddsd2.dwTextureStage = stage;
00491
00492 r = DD->CreateSurface(&ddsd2, &sourcesurface, NULL);
00493 if (r != DD_OK)
00494 {
00495 wsprintf(buff, "Can't create texture source surface for '%s'!", tex);
00496 ErrorDX(r, buff);
00497 return FALSE;
00498 }
00499
00500
00501
00502 ZeroMemory(&ddsd2, sizeof(ddsd2));
00503 ddsd2.dwSize = sizeof(ddsd2);
00504 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_TEXTURESTAGE;
00505 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD;
00506 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00507 ddsd2.dwWidth = width;
00508 ddsd2.dwHeight = height;
00509 ddsd2.ddpfPixelFormat = TexFormat;
00510 ddsd2.dwTextureStage = stage;
00511
00512 r = DD->CreateSurface(&ddsd2, &TexInfo[tpage].Surface, NULL);
00513 if (r != DD_OK)
00514 {
00515 wsprintf(buff, "Can't create texture dest surface for '%s'!", tex);
00516 ErrorDX(r, buff);
00517 return FALSE;
00518 }
00519
00520
00521
00522 if (TexFormat.dwRGBBitCount == 8)
00523 {
00524 dcimage = CreateCompatibleDC(NULL);
00525 SelectObject(dcimage, hbm);
00526 cols = GetDIBColorTable(dcimage, 0, 256, (RGBQUAD*)adw);
00527 DeleteDC(dcimage);
00528
00529 for (i = 0 ; i < cols ; i++)
00530 {
00531 red = GetRValue(adw[i]);
00532 green = GetGValue(adw[i]);
00533 blue = GetBValue(adw[i]);
00534
00535 adw[i] = RGB_MAKE(red, green, blue);
00536 }
00537
00538 r = DD->CreatePalette(DDPCAPS_8BIT, (PALETTEENTRY*)adw, &TexInfo[tpage].Palette, NULL);
00539 if (r != DD_OK)
00540 {
00541 ErrorDX(r, "Can't create texture palette");
00542 return FALSE;
00543 }
00544
00545 r = sourcesurface->SetPalette(TexInfo[tpage].Palette);
00546 if (r != DD_OK)
00547 {
00548 ErrorDX(r, "Can't attach palette to texture source surface");
00549 return FALSE;
00550 }
00551
00552 r = TexInfo[tpage].Surface->SetPalette(TexInfo[tpage].Palette);
00553 if (r != DD_OK)
00554 {
00555 ErrorDX(r, "Can't attach palette to texture dest surface");
00556 return FALSE;
00557 }
00558 }
00559
00560
00561
00562 dcimage = CreateCompatibleDC(NULL);
00563 SelectObject(dcimage, hbm);
00564
00565 r = sourcesurface->GetDC(&dc);
00566 if (r != DD_OK)
00567 {
00568 ErrorDX(r, "Can't get texture surface DC");
00569 return FALSE;
00570 }
00571
00572 r = StretchBlt(dc, 0, 0, width, height, dcimage, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
00573 if (!r)
00574 {
00575 ErrorDX(r, "Can't blit to texture surface");
00576 return FALSE;
00577 }
00578
00579 sourcesurface->ReleaseDC(dc);
00580 DeleteDC(dcimage);
00581
00582
00583
00584 r = TexInfo[tpage].Surface->QueryInterface(IID_IDirect3DTexture2, (void**)&TexInfo[tpage].Texture);
00585 if (r != DD_OK)
00586 {
00587 ErrorDX(r, "Can't query interface for texture dest surface");
00588 return FALSE;
00589 }
00590
00591 r = sourcesurface->QueryInterface(IID_IDirect3DTexture2, (void**)&texsource);
00592 if (r != DD_OK)
00593 {
00594 ErrorDX(r, "Can't query interface for texture source surface");
00595 return FALSE;
00596 }
00597
00598
00599
00600 r = TexInfo[tpage].Texture->Load(texsource);
00601 if (r != DD_OK)
00602 {
00603 ErrorDX(r, "Can't load dest texture");
00604 return FALSE;
00605 }
00606
00607
00608
00609 if (DxState.ColorKey)
00610 {
00611 ck.dwColorSpaceLowValue = 0;
00612 ck.dwColorSpaceHighValue = 0;
00613 TexInfo[tpage].Surface->SetColorKey(DDCKEY_SRCBLT, &ck);
00614 }
00615
00616
00617
00618 RELEASE(texsource);
00619 RELEASE(sourcesurface);
00620
00621
00622
00623 DeleteObject(hbm);
00624
00625
00626
00627 TexInfo[tpage].Active = TRUE;
00628 TexInfo[tpage].Width = width;
00629 TexInfo[tpage].Height = height;
00630 TexInfo[tpage].Stage = stage;
00631 TexInfo[tpage].MipCount = 0;
00632 wsprintf(TexInfo[tpage].File, "%s", tex);
00633
00634
00635
00636 return TRUE;
00637 }
00638
00640
00642
00643 bool LoadMipTexture(char *tex, char tpage, long width, long height, long stage, long mipcount)
00644 {
00645 HBITMAP hbm;
00646 BITMAP bm;
00647 DDSURFACEDESC2 ddsd2;
00648 DDSCAPS2 ddscaps2;
00649 HRESULT r;
00650 HDC dcimage, dc;
00651 unsigned short cols, i, miploop;
00652 char buff[256];
00653 DWORD adw[256];
00654 DDCOLORKEY ck;
00655 short red, green, blue;
00656 IDirect3DTexture2 *texsource;
00657 IDirectDrawSurface4 *sourcesurface;
00658 IDirectDrawSurface4 *mipsource, *mipdest, *mipsourcenext, *mipdestnext;
00659
00660
00661
00662 if (!tex || tex[0] == '\0')
00663 return FALSE;
00664
00665
00666
00667 if (tpage > TEX_NTPages)
00668 return FALSE;
00669
00670
00671
00672 if (!TexturesEnabled)
00673 {
00674 TexInfo[tpage].Active = FALSE;
00675 return FALSE;
00676 }
00677
00678
00679
00680 if (mipcount < 0 || mipcount > MAX_MIPMAPS)
00681 return FALSE;
00682
00683
00684
00685 ZeroMemory(&ddsd2, sizeof(ddsd2));
00686 ddsd2.dwSize = sizeof(ddsd2);
00687 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT | DDSD_TEXTURESTAGE;
00688 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
00689 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00690 ddsd2.dwWidth = width;
00691 ddsd2.dwHeight = height;
00692 ddsd2.ddpfPixelFormat = TexFormat;
00693 ddsd2.dwMipMapCount = mipcount;
00694 ddsd2.dwTextureStage = stage;
00695
00696 r = DD->CreateSurface(&ddsd2, &sourcesurface, NULL);
00697 if (r != DD_OK)
00698 {
00699 wsprintf(buff, "Can't create mipmap source surfaces for '%s'!", tex);
00700 ErrorDX(r, buff);
00701 return FALSE;
00702 }
00703
00704
00705
00706 ZeroMemory(&ddsd2, sizeof(ddsd2));
00707 ddsd2.dwSize = sizeof(ddsd2);
00708 ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT | DDSD_TEXTURESTAGE;
00709 ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
00710 ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_OPAQUE;
00711 ddsd2.dwWidth = width;
00712 ddsd2.dwHeight = height;
00713 ddsd2.ddpfPixelFormat = TexFormat;
00714 ddsd2.dwMipMapCount = mipcount;
00715 ddsd2.dwTextureStage = stage;
00716
00717 r = DD->CreateSurface(&ddsd2, &TexInfo[tpage].Surface, NULL);
00718 if (r != DD_OK)
00719 {
00720 wsprintf(buff, "Can't create mipmap dest surfaces for '%s'!", tex);
00721 ErrorDX(r, buff);
00722 return FALSE;
00723 }
00724
00725
00726
00727 mipsource = sourcesurface;
00728 mipsource->AddRef();
00729
00730 mipdest = TexInfo[tpage].Surface;
00731 mipdest->AddRef();
00732
00733 for (miploop = 0 ; miploop < mipcount ; miploop++)
00734 {
00735
00736
00737
00738 memcpy(buff, tex, MAX_TPAGE_FILENAME);
00739 buff[strlen(buff) - 1] += miploop;
00740 hbm = (HBITMAP)LoadImage(NULL, buff, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
00741 if (!hbm)
00742 {
00743 wsprintf(buff, "Can't load mipmap texture: '%s'", buff);
00744 Box("ERROR", buff, MB_OK);
00745 return FALSE;
00746 }
00747 GetObject(hbm, sizeof(bm), &bm);
00748
00749
00750
00751 if (TexFormat.dwRGBBitCount == 8)
00752 {
00753 if (!miploop)
00754 {
00755 dcimage = CreateCompatibleDC(NULL);
00756 SelectObject(dcimage, hbm);
00757 cols = GetDIBColorTable(dcimage, 0, 256, (RGBQUAD*)adw);
00758 DeleteDC(dcimage);
00759
00760 for (i = 0 ; i < cols ; i++)
00761 {
00762 red = GetRValue(adw[i]);
00763 green = GetGValue(adw[i]);
00764 blue = GetBValue(adw[i]);
00765
00766 adw[i] = RGB_MAKE(red, green, blue);
00767 }
00768
00769 r = DD->CreatePalette(DDPCAPS_8BIT, (PALETTEENTRY*)adw, &TexInfo[tpage].Palette, NULL);
00770 if (r != DD_OK)
00771 {
00772 ErrorDX(r, "Can't create texture palette");
00773 return FALSE;
00774 }
00775 }
00776
00777 r = mipsource->SetPalette(TexInfo[tpage].Palette);
00778 if (r != DD_OK)
00779 {
00780 ErrorDX(r, "Can't attach palette to texture source surface");
00781 return FALSE;
00782 }
00783
00784 r = mipdest->SetPalette(TexInfo[tpage].Palette);
00785 if (r != DD_OK)
00786 {
00787 ErrorDX(r, "Can't attach palette to texture dest surface");
00788 return FALSE;
00789 }
00790 }
00791
00792
00793
00794 dcimage = CreateCompatibleDC(NULL);
00795 SelectObject(dcimage, hbm);
00796
00797 r = mipsource->GetDC(&dc);
00798 if (r != DD_OK)
00799 {
00800 ErrorDX(r, "Can't get texture surface DC");
00801 return FALSE;
00802 }
00803
00804 r = StretchBlt(dc, 0, 0, width >> miploop, height >> miploop, dcimage, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
00805 if (!r)
00806 {
00807 ErrorDX(r, "Can't blit to texture surface");
00808 return FALSE;
00809 }
00810
00811 mipsource->ReleaseDC(dc);
00812 DeleteDC(dcimage);
00813
00814
00815
00816 if (DxState.ColorKey)
00817 {
00818 ck.dwColorSpaceLowValue = 0;
00819 ck.dwColorSpaceHighValue = 0;
00820 mipdest->SetColorKey(DDCKEY_SRCBLT, &ck);
00821 }
00822
00823
00824
00825 DeleteObject(hbm);
00826
00827
00828
00829 if (miploop != mipcount - 1)
00830 {
00831 ddscaps2.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
00832 r = mipsource->GetAttachedSurface(&ddscaps2, &mipsourcenext);
00833 if (r != DD_OK)
00834 {
00835 ErrorDX(r, "Can't get attached surface for source mipmap");
00836 return FALSE;
00837 }
00838
00839 ddscaps2.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_ALLOCONLOAD;
00840 r = mipdest->GetAttachedSurface(&ddscaps2, &mipdestnext);
00841 if (r != DD_OK)
00842 {
00843 ErrorDX(r, "Can't get attached surface for dest mipmap");
00844 return FALSE;
00845 }
00846 }
00847
00848 RELEASE(mipsource);
00849 mipsource = mipsourcenext;
00850
00851 RELEASE(mipdest);
00852 mipdest = mipdestnext;
00853 }
00854
00855
00856
00857 r = TexInfo[tpage].Surface->QueryInterface(IID_IDirect3DTexture2, (void**)&TexInfo[tpage].Texture);
00858 if (r != DD_OK)
00859 {
00860 ErrorDX(r, "Can't query interface for texture dest surface");
00861 return FALSE;
00862 }
00863
00864 r = sourcesurface->QueryInterface(IID_IDirect3DTexture2, (void**)&texsource);
00865 if (r != DD_OK)
00866 {
00867 ErrorDX(r, "Can't query interface for texture source surface");
00868 return FALSE;
00869 }
00870
00871
00872
00873 r = TexInfo[tpage].Texture->Load(texsource);
00874 if (r != DD_OK)
00875 {
00876 ErrorDX(r, "Can't load dest texture");
00877 return FALSE;
00878 }
00879
00880
00881
00882 TexInfo[tpage].Active = TRUE;
00883 TexInfo[tpage].Width = width;
00884 TexInfo[tpage].Height = height;
00885 TexInfo[tpage].Stage = stage;
00886 TexInfo[tpage].MipCount = mipcount;
00887 wsprintf(TexInfo[tpage].File, "%s", tex);
00888
00889
00890
00891 RELEASE(texsource);
00892 RELEASE(sourcesurface);
00893
00894
00895
00896 return TRUE;
00897 }
00898
00900
00902
00903 void InitTextures(void)
00904 {
00905 char i;
00906
00907 RenderTP = -2;
00908 RenderTP2 = -2;
00909
00910 for (i = 0 ; i < TEX_NTPages ; i++)
00911 {
00912 TexInfo[i].Active = FALSE;
00913 TexInfo[i].Palette = NULL;
00914 TexInfo[i].Texture = NULL;
00915 TexInfo[i].Surface = NULL;
00916 }
00917 }
00918
00920
00922
00923 void FreeTextures(void)
00924 {
00925 char i;
00926
00927 for (i = 0 ; i < TEX_NTPages ; i++)
00928 {
00929 if (TexInfo[i].Active)
00930 FreeOneTexture(i);
00931 }
00932 }
00933
00935
00937
00938 void FreeOneTexture(char tp)
00939 {
00940
00941
00942
00943 if (!TexInfo[tp].Active)
00944 return;
00945
00946
00947
00948 TexInfo[tp].Active = NULL;
00949 RELEASE(TexInfo[tp].Palette);
00950 RELEASE(TexInfo[tp].Texture);
00951 RELEASE(TexInfo[tp].Surface);
00952 }