00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Windows.h>
00023 #include <stdio.h>
00024 #include <Assert.h>
00025
00026 #include "SoftDrv.h"
00027 #include "DCommon.h"
00028 #include "Register.h"
00029 #include "Sal.h"
00030 #include "ddraw.h"
00031
00032 geRDriver_THandle TextureHandles[MAX_TEXTURE_HANDLES];
00033
00034 S32 SnapToPower2(S32 Width);
00035 S32 Log2(S32 P2);
00036
00037 extern CPUInfo ProcessorInfo;
00038
00039
00040
00041
00042 geRDriver_THandle *FindTextureHandle()
00043 {
00044 int32 i;
00045 geRDriver_THandle *THandle;
00046
00047 THandle = TextureHandles;
00048
00049 for (i=0; i< MAX_TEXTURE_HANDLES; i++, THandle++)
00050 {
00051 if (!THandle->Active)
00052 {
00053 memset(THandle, 0, sizeof(geRDriver_THandle));
00054
00055 THandle->Active = GE_TRUE;
00056
00057 return THandle;
00058 }
00059 }
00060
00061 return NULL;
00062 }
00063
00064
00065
00066
00067 geBoolean FreeTextureHandle(geRDriver_THandle *THandle)
00068 {
00069 int k;
00070
00071 assert(THandle);
00072
00073
00074 if( ! THandle->Active )
00075 {
00076 return GE_FALSE;
00077 }
00078
00079 if(THandle->PalHandle)
00080 {
00081 FreeTextureHandle(THandle->PalHandle);
00082 }
00083
00084 if(THandle->AlphaHandle)
00085 {
00086 FreeTextureHandle(THandle->AlphaHandle);
00087 }
00088
00089 for(k=0;k < THandle->MipLevels;k++)
00090 {
00091 if(!ProcessorInfo.Has3DNow)
00092 {
00093 if(THandle->BitPtr[k])
00094 {
00095 free(THandle->BitPtr[k]);
00096 }
00097 }
00098 THandle->BitPtr[k] =NULL;
00099 }
00100
00101 memset(THandle, 0, sizeof(geRDriver_THandle));
00102
00103 return GE_TRUE;
00104 }
00105
00106
00107
00108
00109 geBoolean FreeAllTextureHandles(void)
00110 {
00111 int32 i;
00112 geRDriver_THandle *pTHandle;
00113
00114 pTHandle = TextureHandles;
00115
00116 #ifdef _DEBUG
00117 OutputDebugString("FreeAllTextureHandles\n");
00118 #endif
00119
00120 for (i=0; i< MAX_TEXTURE_HANDLES; i++, pTHandle++)
00121 {
00122 if (!pTHandle->Active)
00123 {
00124 continue;
00125 }
00126
00127 FreeTextureHandle(pTHandle);
00128 }
00129
00130 return GE_TRUE;
00131 }
00132
00133 geRDriver_THandle *DRIVERCC CreateTexture(int32 Width, int32 Height, int32 NumMipLevels, const geRDriver_PixelFormat *PixelFormat)
00134 {
00135 int32 i, SWidth, SHeight;
00136 geRDriver_THandle *THandle;
00137
00138 assert(PixelFormat);
00139
00140 THandle = FindTextureHandle();
00141
00142 if (!THandle)
00143 {
00144 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_CreateTexture: No more handles left.");
00145 goto ExitWithError;
00146 }
00147
00148 if(PixelFormat->Flags & RDRIVER_PF_3D)
00149 {
00150 if (Width > 256)
00151 {
00152 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_CreateTexture: Width > 256.");
00153 goto ExitWithError;
00154 }
00155
00156 if (Height > 256)
00157 {
00158 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_CreateTexture: Height > 256.");
00159 goto ExitWithError;
00160 }
00161 SWidth = SnapToPower2(Width);
00162 SHeight = SnapToPower2(Height);
00163
00164 if (Width != SWidth)
00165 {
00166 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_CreateTexture: Not a power of 2.");
00167 goto ExitWithError;
00168 }
00169
00170 if (Height != SHeight)
00171 {
00172 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_CreateTexture: Not a power of 2.");
00173 goto ExitWithError;
00174 }
00175 }
00176
00177 THandle->MipLevels =NumMipLevels;
00178 THandle->Width =Width;
00179 THandle->Height =Height;
00180 THandle->PixelFormat =*PixelFormat;
00181 THandle->Flags =0;
00182
00183 for(i=0;i < NumMipLevels;i++)
00184 {
00185 if(PixelFormat->Flags & RDRIVER_PF_PALETTE)
00186 {
00187 if( PixelFormat->PixelFormat == GE_PIXELFORMAT_32BIT_ARGB ||
00188 PixelFormat->PixelFormat == GE_PIXELFORMAT_32BIT_XRGB )
00189 {
00190 THandle->BitPtr[i] =(U16 *)malloc(sizeof(U32) * Width * Height);
00191 }
00192 else
00193 {
00194 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_CreateTexture: Bad Pal format.");
00195 goto ExitWithError;
00196 }
00197 }
00198 else
00199 {
00200 switch (PixelFormat->PixelFormat)
00201 {
00202 case GE_PIXELFORMAT_16BIT_565_RGB:
00203 {
00204 THandle->BitPtr[i] =(U16 *)malloc(sizeof(U16) * Width * Height);
00205 break;
00206 }
00207
00208 case GE_PIXELFORMAT_16BIT_555_RGB:
00209 {
00210 THandle->BitPtr[i] =(U16 *)malloc(sizeof(U16) * Width * Height);
00211 break;
00212 }
00213
00214 case GE_PIXELFORMAT_8BIT:
00215 {
00216 THandle->BitPtr[i] =(U16 *)malloc(sizeof(U8) * Width * Height);
00217 break;
00218 }
00219
00220 case GE_PIXELFORMAT_24BIT_RGB:
00221 {
00222 THandle->BitPtr[i] =(U16 *)malloc((sizeof(U8)*3) * Width * Height);
00223 break;
00224 }
00225
00226 default:
00227 {
00228 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_Create3DTexture: Invalid pixel format.");
00229 goto ExitWithError;
00230
00231
00232 }
00233 }
00234
00235 if ( PixelFormat->Flags & RDRIVER_PF_CAN_DO_COLORKEY )
00236 {
00237 THandle->Flags |= THANDLE_TRANS;
00238 }
00239 }
00240 }
00241
00242 return THandle;
00243
00244 ExitWithError:
00245 {
00246 return NULL;
00247 }
00248 }
00249
00250 geBoolean DRIVERCC THandle_GetInfo(geRDriver_THandle *THandle, int32 MipLevel, geRDriver_THandleInfo *Info)
00251 {
00252 assert(THandle);
00253 assert(Info);
00254 #ifdef _DEBUG
00255 if ( ! THandle->Active )
00256 return GE_FALSE;
00257 #endif
00258
00259 Info->Width = THandle->Width >> MipLevel;
00260 Info->Height = THandle->Height >> MipLevel;
00261 Info->Stride = Info->Width;
00262 Info->Flags = 0;
00263 Info->PixelFormat =THandle->PixelFormat;
00264
00265 if ( ProcessorInfo.Has3DNow )
00266 Info->ColorKey = 255;
00267 else
00268 Info->ColorKey = 1;
00269
00270 if ( THandle->Flags & THANDLE_TRANS )
00271 {
00272 Info->Flags |= RDRIVER_THANDLE_HAS_COLORKEY;
00273 }
00274
00275 return GE_TRUE;
00276 }
00277
00278
00279 geBoolean DRIVERCC SetPalette(geRDriver_THandle *THandle, geRDriver_THandle *PalHandle)
00280 {
00281 assert(THandle);
00282
00283 THandle->PalHandle =PalHandle;
00284
00285 return GE_TRUE;
00286 }
00287
00288
00289 geRDriver_THandle *DRIVERCC GetPalette(geRDriver_THandle *THandle)
00290 {
00291 assert(THandle);
00292 #ifdef _DEBUG
00293 if ( ! THandle->Active )
00294 return GE_FALSE;
00295 #endif
00296
00297 return THandle->PalHandle;
00298 }
00299
00300 geBoolean DRIVERCC SetAlpha(geRDriver_THandle *THandle, geRDriver_THandle *AHandle)
00301 {
00302 assert(THandle);
00303 #ifdef _DEBUG
00304 if ( ! THandle->Active )
00305 return GE_FALSE;
00306 #endif
00307
00308 if(THandle->PixelFormat.Flags & RDRIVER_PF_HAS_ALPHA)
00309 {
00310 if(AHandle->PixelFormat.Flags & RDRIVER_PF_ALPHA)
00311 {
00312 THandle->AlphaHandle =AHandle;
00313 return GE_TRUE;
00314 }
00315 }
00316 return GE_FALSE;
00317 }
00318
00319 geRDriver_THandle *DRIVERCC GetAlpha(geRDriver_THandle *THandle)
00320 {
00321 assert(THandle);
00322 #ifdef _DEBUG
00323 if ( ! THandle->Active )
00324 return GE_FALSE;
00325 #endif
00326
00327 return THandle->AlphaHandle;
00328 }
00329
00330 geBoolean DRIVERCC DestroyTexture(geRDriver_THandle *THandle)
00331 {
00332 return FreeTextureHandle(THandle);
00333 }
00334
00335 geBoolean DRIVERCC LockTextureHandle(geRDriver_THandle *THandle, int32 MipLevel, void **Data)
00336 {
00337 assert(THandle);
00338 assert(MipLevel <= THandle->MipLevels && MipLevel >= 0);
00339 #ifdef _DEBUG
00340 if ( ! THandle->Active )
00341 return GE_FALSE;
00342 if ( ! THandle->BitPtr[MipLevel] )
00343 return GE_FALSE;
00344 #endif
00345
00346 THandle->Flags |=(THANDLE_LOCKED << MipLevel);
00347 *Data =(uint16*)THandle->BitPtr[MipLevel];
00348
00349 return GE_TRUE;
00350 }
00351
00352 geBoolean DRIVERCC UnLockTextureHandle(geRDriver_THandle *THandle, int32 MipLevel)
00353 {
00354 assert(THandle);
00355 if (!(THandle->Flags & (THANDLE_LOCKED << MipLevel)))
00356 return GE_FALSE;
00357
00358 THandle->Flags &=~(THANDLE_LOCKED << MipLevel);
00359 THandle->Flags |=THANDLE_UPDATE;
00360
00361 return GE_TRUE;
00362 }
00363
00364 BOOL DRIVERCC DrvResetAll(void)
00365 {
00366 return FreeAllTextureHandles();
00367 }
00368
00369
00370 static int Brighten(int Color)
00371 {
00372 Color =(int)((geFloat)Color * 1.5f);
00373
00374 return((Color > 255)? 255 : Color);
00375 }
00376
00377
00378 S32 SnapToPower2(S32 Width)
00379 {
00380 if (Width > 1 && Width <= 2) Width = 2;
00381 else if (Width > 2 && Width <= 4) Width = 4;
00382 else if (Width > 4 && Width <= 8) Width = 8;
00383 else if (Width > 8 && Width <= 16) Width =16;
00384 else if (Width > 16 && Width <= 32) Width = 32;
00385 else if (Width > 32 && Width <= 64) Width = 64;
00386 else if (Width > 64 && Width <= 128) Width = 128;
00387 else if (Width > 128 && Width <= 256) Width = 256;
00388
00389 return Width;
00390 }
00391
00392 S32 Log2(S32 P2)
00393 {
00394 S32 p = 0;
00395 S32 i = 0;
00396
00397 for (i = P2; (i&1) == 0; i>>=1)
00398 p++;
00399
00400 return p;
00401 }