00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma warning(disable : 4201 4214 4115)
00025 #include <windows.h>
00026 #pragma warning(default : 4201 4214 4115; disable : 4514 4244)
00027 #include <stdio.h>
00028 #include <Assert.h>
00029
00030 #include "SoftDrv.h"
00031 #include "CPUInfo.h"
00032 #include "DCommon.h"
00033 #include "SpanBuffer.h"
00034 #include "Span.h"
00035 #include "ram.h"
00036
00037 #include "SWTHandle.h"
00038 #include "Display.h"
00039 #include "TRaster.h"
00040 #include "DrawDecal.h"
00041
00042 #ifdef GENESIS_VERSION_2
00043 #include "errorlog.h"
00044 #else
00045 #define geErrorLog_AddString(Error,xx,yy)
00046 #endif
00047
00048
00049 #define SOFTDRV_MAX_AVG_SPANS_PER_LINE (22)
00050
00051 #define SOFTDRV_DESCRIPTION_LENGTH 256
00052 typedef struct
00053 {
00054 char Description[SOFTDRV_DESCRIPTION_LENGTH];
00055 Display_Type DisplayType;
00056 DisplayModeInfo *Info;
00057 } SoftDrv_DisplayInfo;
00058
00059 typedef struct SoftDrv
00060 {
00061 int RefCount;
00062 int DisplayCount;
00063 int CurrentDisplayIndex;
00064 geRDriver_THandle DrawBuffer;
00065 geRDriver_THandle ZBuffer;
00066 SoftDrv_DisplayInfo Display[DISPLAY_COUNT];
00067 } SoftDrv;
00068
00069 static SoftDrv SoftDrv_Internals={GE_FALSE};
00070
00071
00072 int32 RenderMode = RENDER_NONE;
00073 DRV_Window ClientWindow ={ 0 };
00074 Display *SD_Display = NULL;
00075 geBoolean SD_ProcessorHas3DNow;
00076 geBoolean SD_ProcessorHasMMX;
00077 geBoolean SD_DIBDisplayMode = GE_FALSE;
00078 geBoolean SD_Active = FALSE;
00079 DRV_EngineSettings SD_EngineSettings=
00080 {
00081 (DRV_SUPPORT_ALPHA|DRV_SUPPORT_COLORKEY),
00082 (DRV_PREFERENCE_NO_MIRRORS | DRV_PREFERENCE_DRAW_WALPHA_IN_BSP)
00083 };
00084
00085 DRV_CacheInfo SoftDrv_CacheInfo;
00086
00087 S32 LastError;
00088 char LastErrorStr[200];
00089
00090 void SoftDrv_LightMapSetupCallback(TRaster_Lightmap *LM);
00091
00092 void SoftDrv_ClearZBuffer(DRV_Window *Window)
00093 {
00094 int32 ZBSize;
00095
00096 ZBSize = (Window->Width*Window->Height)<<1;
00097
00098
00099 #pragma message ("clear z buffer to biggest z. was 0.")
00100 memset(SoftDrv_Internals.ZBuffer.BitPtr[0], 0xFF, ZBSize);
00101
00102 }
00103
00104
00105 static void SoftDrv_DisplayInfoTable_Destroy( SoftDrv *S )
00106 {
00107 int i;
00108
00109 S->RefCount--;
00110 if (S->RefCount>0)
00111 return;
00112
00113 for (i=0; i<S->DisplayCount; i++)
00114 {
00115 if (S->Display[i].Info != NULL)
00116 {
00117 DisplayModeInfo_Destroy( &(S->Display[i].Info) );
00118 S->Display[i].Info=NULL;
00119 }
00120 }
00121 S->DisplayCount = 0;
00122 }
00123
00124 static geBoolean SoftDrv_DisplayInfoTable_Create( SoftDrv *S, geBoolean FillOutModes)
00125 {
00126 char VersionString[SOFTDRV_DESCRIPTION_LENGTH]="v"DRV_VMAJS"."DRV_VMINS".";
00127 int i;
00128 FillOutModes;
00129
00130 assert( S != NULL );
00131 if (S->RefCount>0)
00132 {
00133 S->RefCount++;
00134 return GE_TRUE;
00135 }
00136 else
00137 S->RefCount=1;
00138
00139
00140 S->DisplayCount = 0;
00141 for (i=0; i<DISPLAY_COUNT; i++)
00142 {
00143 S->Display[i].Info = DisplayModeInfo_Create();
00144 if (S->Display[i].Info == NULL)
00145 {
00146 SoftDrv_DisplayInfoTable_Destroy( S );
00147 geErrorLog_AddString(GE_ERR_MEMORY_RESOURCE,"SoftDrv_DisplayInfoTableCreate: unable to create table",NULL);
00148 return GE_FALSE;
00149 }
00150 if (Display_GetDisplayInfo( i,
00151 S->Display[i].Description,
00152 SOFTDRV_DESCRIPTION_LENGTH-strlen(VersionString),
00153 S->Display[i].Info) == GE_FALSE)
00154 {
00155 DisplayModeInfo_Destroy( &(S->Display[i].Info) );
00156 geErrorLog_AddString(GE_ERR_MEMORY_RESOURCE,"SoftDrv_DisplayInfoTableCreate: problem filling table. (continuing)",NULL);
00157 S->Display[i].Info=NULL;
00158 }
00159 else
00160 {
00161 strcat(S->Display[i].Description,VersionString);
00162 S->Display[i].DisplayType = i;
00163 S->DisplayCount++;
00164 }
00165 }
00166 return GE_TRUE;
00167 }
00168
00169 geBoolean DRIVERCC SoftDrv_SetActive(geBoolean Active)
00170 {
00171 SD_Active = Active;
00172 Display_SetActive(SD_Display,Active);
00173 return TRUE;
00174 }
00175
00176
00177
00178 geBoolean DRIVERCC SoftDrv_Init(DRV_DriverHook *Hook)
00179 {
00180
00181 uint16 *ZBuffer=NULL;
00182
00183 #pragma message ("fix to:") //geBoolean DRIVERCC SoftDrv_Init(Hwnd, char *DriverString, int Height, int Width, int BitsPerPixel, uint32 Flags)
00184
00185 if (SoftDrv_DisplayInfoTable_Create(&(SoftDrv_Internals), GE_TRUE)==GE_FALSE)
00186 {
00187 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_Init: failed to get mode info",NULL);
00188 return FALSE;
00189 }
00190
00191 if ((Hook->Driver<0) || (Hook->Driver>=SoftDrv_Internals.DisplayCount))
00192 {
00193 geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDrv_Init: bad driver index",NULL);
00194 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00195 return FALSE;
00196 }
00197
00198
00199
00200
00201
00202 SD_ProcessorHas3DNow = CPUInfo_TestFor3DNow();
00203 SD_ProcessorHasMMX = CPUInfo_TestForMMX();
00204
00205 {
00206 int Height, Width, BitsPerPixel;
00207 uint32 Flags;
00208
00209 if (DisplayModeInfo_GetNth( SoftDrv_Internals.Display[Hook->Driver].Info,
00210 Hook->Mode,
00211 &Width,
00212 &Height,
00213 &BitsPerPixel,
00214 &Flags ) == GE_FALSE)
00215 {
00216 geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDrv_Init: unable to get mode info: bad mode index",NULL);
00217 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00218 return FALSE;
00219 }
00220
00221 SD_Display = Display_Create( Hook->hWnd,
00222 SoftDrv_Internals.Display[Hook->Driver].DisplayType,
00223 Width,
00224 Height,
00225 BitsPerPixel,
00226 Flags);
00227 if (SD_Display == NULL)
00228 {
00229 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDrv_Init: Could not initialize display",NULL);
00230 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00231 return FALSE;
00232 }
00233
00234 if( 1 )
00235 {
00236 int32 BitsPerPixel;
00237 Display_Type DisplayType;
00238 uint32 Flags;
00239
00240 Display_GetDisplayFormat( SD_Display,
00241 &DisplayType,
00242 &(ClientWindow.Width),
00243 &(ClientWindow.Height),
00244 &BitsPerPixel,
00245 &Flags);
00246
00247 }
00248
00249 }
00250
00251 if (SpanBuffer_Create(ClientWindow.Width,ClientWindow.Height, ClientWindow.Height * SOFTDRV_MAX_AVG_SPANS_PER_LINE)==GE_FALSE)
00252 {
00253 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDrv_Init: Could not create span buffer",NULL);
00254 Display_Destroy(&SD_Display);
00255 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00256 return FALSE;
00257 }
00258
00259 if (Display_GetPixelFormat( SD_Display,
00260
00261 &ClientWindow.BytesPerPixel,
00262 &ClientWindow.R_shift,
00263 &ClientWindow.R_mask,
00264 &ClientWindow.R_width,
00265 &ClientWindow.G_shift,
00266 &ClientWindow.G_mask,
00267 &ClientWindow.G_width,
00268 &ClientWindow.B_shift,
00269 &ClientWindow.B_mask,
00270 &ClientWindow.B_width)==GE_FALSE)
00271 {
00272 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDrv_Init: Could not get display pixel format",NULL);
00273 Display_Destroy(&SD_Display);
00274 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00275 return FALSE;
00276 }
00277
00278 {
00279 geSpan_DestinationFormat DestFormat;
00280 switch( ClientWindow.R_width + ClientWindow.G_width + ClientWindow.B_width )
00281 {
00282 case 15: DestFormat = GE_SPAN_DESTINATION_FORMAT_555;
00283 break;
00284 case 16: DestFormat = GE_SPAN_DESTINATION_FORMAT_565;
00285 break;
00286 default:
00287 geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDrv_Init: unsupported destination format",NULL);
00288 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00289 return FALSE;
00290 }
00291
00292 if (Span_SetOutputMode( DestFormat, GE_SPAN_HARDWARE_INTEL ) == GE_FALSE)
00293 {
00294 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_Init: unable to set span drawing mode",NULL);
00295 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00296 return FALSE;
00297 }
00298 }
00299
00300
00301 {
00302 U32 OldFlags =0;
00303
00304 ZBuffer =(U16 *)geRam_Allocate(ClientWindow.Width * ClientWindow.Height * 2);
00305
00306 if(!ZBuffer)
00307 {
00308 geErrorLog_AddString(GE_ERR_MEMORY_RESOURCE,"SoftDrv_Init: Not enought memory for ZBuffer",NULL);
00309 Display_Destroy(&SD_Display);
00310 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00311 return FALSE;
00312 }
00313
00314 if(!VirtualProtect((U8 *)ZBuffer,
00315 (ClientWindow.Width * ClientWindow.Height)*2,
00316 PAGE_READWRITE | PAGE_NOCACHE,
00317 &OldFlags))
00318 {
00319
00320 }
00321 }
00322
00323 #pragma message ("set up DRV_TLHandle for display and zbuffer")
00324
00325
00326
00327 SoftDrv_SetActive(GE_TRUE);
00328
00329 SoftDrv_Internals.DrawBuffer.Active=1;
00330 SoftDrv_Internals.DrawBuffer.Width = ClientWindow.Width;
00331 SoftDrv_Internals.DrawBuffer.Height = ClientWindow.Height;
00332 SoftDrv_Internals.DrawBuffer.MipLevels = 1;
00333 SoftDrv_Internals.DrawBuffer.BitPtr[0] = NULL;
00334 SoftDrv_Internals.DrawBuffer.PalHandle = NULL;
00335 SoftDrv_Internals.DrawBuffer.AlphaHandle = NULL;
00336 SoftDrv_Internals.DrawBuffer.Flags = 0;
00337
00338 SoftDrv_Internals.ZBuffer.Active=1;
00339 SoftDrv_Internals.ZBuffer.Width = ClientWindow.Width;
00340 SoftDrv_Internals.ZBuffer.Height = ClientWindow.Height;
00341 SoftDrv_Internals.ZBuffer.MipLevels = 1;
00342 SoftDrv_Internals.ZBuffer.BitPtr[0] = (U16 *)(ZBuffer);
00343 SoftDrv_Internals.ZBuffer.PalHandle = NULL;
00344 SoftDrv_Internals.ZBuffer.AlphaHandle = NULL;
00345 SoftDrv_Internals.ZBuffer.Flags = 0;
00346
00347 TRaster_Setup(32,&(SoftDrv_Internals.DrawBuffer),&(SoftDrv_Internals.ZBuffer),SoftDrv_LightMapSetupCallback);
00348
00349 return TRUE;
00350 }
00351
00352 geBoolean DRIVERCC SoftDrv_Shutdown(void)
00353 {
00354 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00355
00356 if (SD_Display)
00357 Display_Destroy(&SD_Display);
00358 SD_Display = NULL;
00359
00360 if(SoftDrv_Internals.ZBuffer.BitPtr[0]!=NULL)
00361 geRam_Free(SoftDrv_Internals.ZBuffer.BitPtr[0]);
00362 SoftDrv_Internals.ZBuffer.BitPtr[0]=NULL;
00363 SpanBuffer_Destroy();
00364 return TRUE;
00365 }
00366
00367 geBoolean DRIVERCC SoftDrv_SetGamma(geFloat Gamma)
00368 {
00369 Gamma;
00370 return TRUE;
00371 }
00372
00373 geBoolean DRIVERCC SoftDrv_GetGamma(geFloat *Gamma)
00374 {
00375 assert(Gamma);
00376
00377 *Gamma = 1.0f;
00378
00379 return TRUE;
00380 }
00381
00382
00383 geBoolean DRIVERCC SoftDrv_SetRenderWindowRect(void)
00384 {
00385 return GE_TRUE;
00386 }
00387
00388
00389 geBoolean DRIVERCC SoftDrv_BeginScene(geBoolean Clear, geBoolean ClearZ, RECT *pWorldRect)
00390 {
00391
00392 pWorldRect;
00393
00394 if (RenderMode != RENDER_NONE)
00395 {
00396 geErrorLog_AddString(GE_ERR_INTERNAL_RESOURCE,"SoftDrv_BeginScene: still in a render mode",geErrorLog_IntToString(RenderMode));
00397 return FALSE;
00398 }
00399
00400 memset(&SoftDrv_CacheInfo, 0, sizeof(DRV_CacheInfo));
00401
00402
00403 if (ClearZ)
00404 {
00405 SoftDrv_ClearZBuffer(&ClientWindow);
00406 }
00407
00408
00409 if(!Display_Lock(SD_Display,&(ClientWindow.Buffer), &(ClientWindow.PixelPitch)))
00410 {
00411 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE ,"SoftDrv_BeginScene: failed to lock display buffer",NULL );
00412 return FALSE;
00413 }
00414
00415 if (Clear)
00416 {
00417 if (!Display_Wipe(SD_Display,0))
00418 {
00419 geErrorLog_AddString( GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_BeginScene: failed to wipe display buffer",NULL );
00420 return FALSE;
00421 }
00422 }
00423 SoftDrv_Internals.DrawBuffer.BitPtr[0] = (U16 *)(ClientWindow.Buffer);
00424 return TRUE;
00425 }
00426
00427
00428 geBoolean DRIVERCC SoftDrv_EndScene(void)
00429 {
00430 assert( RenderMode == RENDER_NONE );
00431
00432
00433 #if 0
00434
00435 {
00436 int i;
00437 unsigned short *b,*z;
00438 b = (unsigned short *)ClientWindow.Buffer;
00439 z = (unsigned short *)ZBuffer;
00440 for (i=ClientWindow.Height * ClientWindow.Width; i>0; i--,b++,z++)
00441 {
00442 *b = *z;
00443 }
00444 }
00445 #endif
00446
00447 if (!Display_Unlock(SD_Display))
00448 {
00449 geErrorLog_AddString( GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_EndScene: failed to unlock display buffer",NULL );
00450 return FALSE;
00451 }
00452 if (!Display_Blit(SD_Display))
00453 {
00454 geErrorLog_AddString( GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_EndScene: failed to blit display buffer",NULL );
00455 return FALSE;
00456 }
00457
00458
00459
00460
00461 return TRUE;
00462 }
00463
00464
00465 geBoolean DRIVERCC SoftDrv_BeginWorld(void)
00466 {
00467 assert( RenderMode == RENDER_NONE );
00468 SpanBuffer_Clear();
00469 RenderMode = RENDER_WORLD;
00470 return TRUE;
00471 }
00472
00473 geBoolean DRIVERCC SoftDrv_EndRenderMode(void)
00474 {
00475 assert( RenderMode != RENDER_NONE );
00476 RenderMode = RENDER_NONE;
00477 return TRUE;
00478 }
00479
00480 geBoolean DRIVERCC SoftDrv_BeginMeshes(void)
00481 {
00482 assert( RenderMode == RENDER_NONE);
00483 RenderMode = RENDER_MESHES;
00484 return TRUE;
00485 }
00486
00487 geBoolean DRIVERCC SoftDrv_BeginModels(void)
00488 {
00489 assert( RenderMode == RENDER_NONE);
00490 RenderMode = RENDER_MODELS;
00491 return TRUE;
00492 }
00493
00494
00495 DllExport geBoolean DriverHook(DRV_Driver **Driver)
00496 {
00497
00498 *Driver = &SOFTDRV;
00499
00500
00501 SOFTDRV.LastErrorStr = LastErrorStr;
00502
00503
00504 return TRUE;
00505 }
00506
00507 GENESISAPI void * geEngine_SoftwareDriver(void)
00508 {
00509 return (void *)DriverHook;
00510 }
00511
00512
00513 geBoolean DRIVERCC SoftDrv_ScreenShot(const char *Name)
00514 {
00515 Name;
00516 return FALSE;
00517 }
00518
00519 geBoolean DRIVERCC SoftDrv_EnumSubDrivers(DRV_ENUM_DRV_CB *Cb, void *Context)
00520 {
00521 int i;
00522
00523 if (SoftDrv_DisplayInfoTable_Create(&(SoftDrv_Internals), GE_FALSE)==GE_FALSE)
00524 {
00525 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_EnumSubDrivers: failed to get mode info",NULL);
00526 return FALSE;
00527 }
00528
00529 for (i=0; i<SoftDrv_Internals.DisplayCount; i++)
00530 {
00531 if(!Cb(i, SoftDrv_Internals.Display[i].Description, Context))
00532 {
00533 break;
00534 }
00535 }
00536
00537 SoftDrv_DisplayInfoTable_Destroy(&SoftDrv_Internals);
00538 return TRUE;
00539 }
00540
00541
00542 geBoolean DRIVERCC SoftDrv_EnumModes(S32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, void *Context)
00543 {
00544 int i,Count;
00545 DriverName;
00546
00547 if (SoftDrv_DisplayInfoTable_Create(&(SoftDrv_Internals), GE_TRUE)==GE_FALSE)
00548 {
00549 geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDrv_EnumModes: failed to get mode info",NULL);
00550 return FALSE;
00551 }
00552
00553 if ((Driver < 0) || (Driver>=SoftDrv_Internals.DisplayCount))
00554 {
00555 geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDrv_EnumModes: bad driver index",NULL);
00556 SoftDrv_DisplayInfoTable_Destroy(&(SoftDrv_Internals));
00557 return FALSE;
00558 }
00559
00560
00561 Count = DisplayModeInfo_GetModeCount( SoftDrv_Internals.Display[Driver].Info );
00562
00563 for (i=0; i<Count; i++)
00564 {
00565 int Width,Height,BitsPerPixel;
00566 uint32 Flags;
00567
00568 if (DisplayModeInfo_GetNth(SoftDrv_Internals.Display[Driver].Info,i,
00569 &Width,&Height,&BitsPerPixel,&Flags) != GE_FALSE)
00570 {
00571 char Description[256];
00572 if (Width<0 && Height<0)
00573 {
00574 sprintf(Description,"Window Mode");
00575 }
00576 else
00577 {
00578 sprintf(Description,"%dx%dx%d",Width, Height, BitsPerPixel);
00579 }
00580 if(Flags & MODEXMODE)
00581 strcat(Description," ModeX");
00582 if (SD_ProcessorHas3DNow)
00583 strcat(Description," 3DNow!");
00584
00585 Cb(i,Description,Width,Height,Context);
00586 }
00587 }
00588 SoftDrv_DisplayInfoTable_Destroy(&SoftDrv_Internals);
00589 return TRUE;
00590 }
00591
00592 geROP SoftDrv_GouraudFlagsToRop[16] =
00593 {
00594 GE_ROP_LSHADE_ZTESTSET,
00595 GE_ROP_LSHADE_AFLAT_ZTESTSET,
00596 GE_ROP_LSHADE_ZTESTSET,
00597 GE_ROP_LSHADE_AFLAT_ZTESTSET,
00598 GE_ROP_LSHADE_ZSET,
00599 GE_ROP_LSHADE_AFLAT_ZSET,
00600 GE_ROP_LSHADE_ZSET,
00601 GE_ROP_LSHADE_AFLAT_ZSET,
00602 GE_ROP_LSHADE_ZTEST,
00603 GE_ROP_LSHADE_AFLAT_ZTEST,
00604 GE_ROP_LSHADE_ZTEST,
00605 GE_ROP_LSHADE_AFLAT_ZTEST,
00606 GE_ROP_LSHADE,
00607 GE_ROP_LSHADE_AFLAT,
00608 GE_ROP_LSHADE,
00609 GE_ROP_LSHADE_AFLAT,
00610 };
00611
00612 geROP SoftDrv_MiscFlagsToRop[16][2] =
00613 {
00614 {GE_ROP_TMAP_LSHADE_ZTESTSET, GE_ROP_TMAP_LSHADE_AMAP_ZTESTSET},
00615 {GE_ROP_TMAP_LSHADE_AFLAT_ZTESTSET, GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZTESTSET},
00616 {GE_ROP_TMAP_LSHADE_ZTESTSET, GE_ROP_TMAP_LSHADE_AMAP_ZTESTSET},
00617 {GE_ROP_TMAP_LSHADE_AFLAT_ZTESTSET, GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZTESTSET},
00618 {GE_ROP_TMAP_LSHADE_ZSET, GE_ROP_TMAP_LSHADE_AMAP_ZSET},
00619 {GE_ROP_TMAP_LSHADE_AFLAT_ZSET, GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZSET},
00620 {GE_ROP_TMAP_LSHADE_ZSET, GE_ROP_TMAP_LSHADE_AMAP_ZSET},
00621 {GE_ROP_TMAP_LSHADE_AFLAT_ZSET, GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZSET},
00622 {GE_ROP_TMAP_LSHADE_ZTEST, GE_ROP_TMAP_LSHADE_AMAP_ZTEST},
00623 {GE_ROP_TMAP_LSHADE_AFLAT_ZTEST, GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZTEST},
00624 {GE_ROP_TMAP_LSHADE_ZTEST, GE_ROP_TMAP_LSHADE_AMAP_ZTEST},
00625 {GE_ROP_TMAP_LSHADE_AFLAT_ZTEST, GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZTEST},
00626 {GE_ROP_TMAP_LSHADE, GE_ROP_TMAP_LSHADE_AMAP},
00627 {GE_ROP_TMAP_LSHADE_AFLAT, GE_ROP_TMAP_LSHADE_AMAP_AFLAT},
00628 {GE_ROP_TMAP_LSHADE, GE_ROP_TMAP_LSHADE_AMAP},
00629 {GE_ROP_TMAP_LSHADE_AFLAT, GE_ROP_TMAP_LSHADE_AMAP_AFLAT},
00630 };
00631
00632 static int SoftDrv_ComputeMipLevel(
00633 const DRV_TLVertex *Pnts,
00634 geFloat ScaleU,geFloat ScaleV,
00635 int MipCount,
00636 int NumPoints)
00637 {
00638 geFloat du, dv, dx, dy, MipScale;
00639 int MipLevel;
00640 int i;
00641
00642
00643 MipScale= 999999.999f;
00644 for (i=0; i<NumPoints; i++)
00645 {
00646 geFloat MipScaleT;
00647 int Nexti= (i+1)%NumPoints;
00648 du =Pnts[Nexti].u - Pnts[i].u;
00649 dv =Pnts[Nexti].v - Pnts[i].v;
00650 dx =Pnts[Nexti].x - Pnts[i].x;
00651 dy =Pnts[Nexti].y - Pnts[i].y;
00652
00653 du /= ScaleU;
00654 dv /= ScaleV;
00655
00656 MipScaleT =((du*du)+(dv*dv)) / ((dx*dx)+(dy*dy));
00657 if (MipScaleT < MipScale)
00658 MipScale = MipScaleT;
00659
00660 }
00661
00662 if(MipScale <= 3)
00663 {
00664 MipLevel =0;
00665 }
00666 else if(MipScale <= 15)
00667 {
00668 MipLevel =1;
00669 }
00670 else if(MipScale <= 35)
00671 {
00672 MipLevel =2;
00673 }
00674 else
00675 {
00676 MipLevel =3;
00677 }
00678 if(MipLevel >= MipCount)
00679 {
00680 MipLevel =MipCount-1;
00681 }
00682 return MipLevel;
00683 }
00684
00685
00686 geBoolean DRIVERCC SoftDrv_RenderGouraudPoly(DRV_TLVertex *Pnts, S32 NumPoints, U32 Flags)
00687 {
00688 int i;
00689 geROP ROP;
00690
00691 if(!SD_Active)
00692 {
00693 return GE_TRUE;
00694 }
00695
00696 assert(Pnts != NULL);
00697 assert(NumPoints > 2);
00698
00699 ROP = SoftDrv_GouraudFlagsToRop[Flags & 0xF];
00700 for(i=0;i < NumPoints-2;i++)
00701 {
00702 DRV_TLVertex Pnts2[3];
00703
00704 if ( (((Pnts[i+1].x-Pnts[0].x) * (Pnts[i+2].y-Pnts[0].y)) - ((Pnts[i+1].y-Pnts[0].y)*(Pnts[i+2].x-Pnts[0].x)))<0.0f)
00705 {
00706 Pnts2[0] = Pnts[i+2];
00707 Pnts2[1] = Pnts[i+1];
00708 Pnts2[2] = Pnts[0];
00709 }
00710 else
00711 {
00712 Pnts2[0] = Pnts[0];
00713 Pnts2[1] = Pnts[i+1];
00714 Pnts2[2] = Pnts[i+2];
00715 }
00716 Pnts2[0].a = Pnts[0].a;
00717 #ifdef GENESIS_VERSION_2
00718 #pragma message ("temporary:")
00719 if( Pnts2[0].x < 0 ) Pnts2[0].x = 0 ;
00720 if( Pnts2[1].x < 0 ) Pnts2[1].x = 0 ;
00721 if( Pnts2[2].x < 0 ) Pnts2[2].x = 0 ;
00722 if( Pnts2[0].y < 0 ) Pnts2[0].y = 0 ;
00723 if( Pnts2[1].y < 0 ) Pnts2[1].y = 0 ;
00724 if( Pnts2[2].y < 0 ) Pnts2[2].y = 0 ;
00725
00726 if( Pnts2[0].x >= ClientWindow.Width ) Pnts2[0].x = ClientWindow.Width-1 ;
00727 if( Pnts2[1].x >= ClientWindow.Width ) Pnts2[1].x = ClientWindow.Width-1 ;
00728 if( Pnts2[2].x >= ClientWindow.Width ) Pnts2[2].x = ClientWindow.Width-1 ;
00729 if( Pnts2[0].y >= ClientWindow.Height ) Pnts2[0].y = ClientWindow.Height-1 ;
00730 if( Pnts2[1].y >= ClientWindow.Height ) Pnts2[1].y = ClientWindow.Height-1 ;
00731 if( Pnts2[2].y >= ClientWindow.Height ) Pnts2[2].y = ClientWindow.Height-1 ;
00732 #else
00733 assert( Pnts2[0].x >= 0 ) ;
00734 assert( Pnts2[1].x >= 0 ) ;
00735 assert( Pnts2[2].x >= 0 ) ;
00736 assert( Pnts2[0].y >= 0 ) ;
00737 assert( Pnts2[1].y >= 0 ) ;
00738 assert( Pnts2[2].y >= 0 ) ;
00739
00740 assert( Pnts2[0].x < ClientWindow.Width ) ;
00741 assert( Pnts2[1].x < ClientWindow.Width ) ;
00742 assert( Pnts2[2].x < ClientWindow.Width ) ;
00743 assert( Pnts2[0].y < ClientWindow.Height ) ;
00744 assert( Pnts2[1].y < ClientWindow.Height ) ;
00745 assert( Pnts2[2].y < ClientWindow.Height ) ;
00746 #endif
00747
00748
00749 TRaster_Rasterize( ROP ,NULL, 0, Pnts2 );
00750 }
00751
00752
00753 return GE_TRUE;
00754 }
00755
00756
00757 DRV_LInfo *SoftDrv_TempLInfo;
00758 DRV_TexInfo *SoftDrv_TempTexInfo;
00759
00760 void SoftDrv_LightMapSetupCallback(TRaster_Lightmap *LM)
00761 {
00762 geBoolean Dynamic;
00763 SOFTDRV.SetupLightmap(SoftDrv_TempLInfo, &Dynamic);
00764 #pragma message ("SetupLightmap callback: can it fail?")
00765
00766 {
00767 geFloat MipScale;
00768 geFloat ShiftU,ShiftV;
00769 geFloat ScaleU,ScaleV;
00770 geFloat LightMapShiftU,LightMapShiftV;
00771
00772 ShiftU = SoftDrv_TempTexInfo->ShiftU;
00773 ShiftV = SoftDrv_TempTexInfo->ShiftV;
00774 MipScale = (geFloat)( 1<<LM->MipIndex);
00775 ScaleU = (1.0f/SoftDrv_TempTexInfo->DrawScaleU);
00776 ScaleV = (1.0f/SoftDrv_TempTexInfo->DrawScaleV);
00777
00778 LightMapShiftU = ((geFloat)(SoftDrv_TempLInfo->MinU));
00779 LightMapShiftV = ((geFloat)(SoftDrv_TempLInfo->MinV));
00780
00781 LM->LightMapShiftU = (ShiftU+LightMapShiftU*ScaleU)/MipScale;
00782 LM->LightMapScaleU = (1.0f/(16.0f * ScaleU )) * MipScale;
00783
00784 LM->LightMapShiftV = (ShiftV+LightMapShiftV*ScaleV)/MipScale;
00785 LM->LightMapScaleV = (1.0f/(16.0f * ScaleV )) *MipScale;
00786
00787
00788 LM->BitPtr = (unsigned short *)SoftDrv_TempLInfo->RGBLight[0];
00789 LM->Height = SoftDrv_TempLInfo->Height;
00790 LM->Width = SoftDrv_TempLInfo->Width;
00791 }
00792
00793
00794 }
00795
00796
00797
00798 geBoolean DRIVERCC SoftDrv_RenderWorldPoly( DRV_TLVertex *Pnts,
00799 S32 NumPoints,
00800 geRDriver_THandle *THandle,
00801 DRV_TexInfo *TexInfo,
00802 DRV_LInfo *LInfo,
00803 U32 Flags)
00804 {
00805 int32 i;
00806 geROP ROP;
00807 int MipLevel;
00808
00809 if(!SD_Active)
00810 {
00811 return GE_TRUE;
00812 }
00813
00814
00815 if (RenderMode==RENDER_WORLD )
00816 {
00817
00818 assert( !(Flags & DRV_RENDER_ALPHA) );
00819 assert( !(THandle->PixelFormat.PixelFormat ==GE_PIXELFORMAT_16BIT_4444_ARGB));
00820
00821 if (LInfo)
00822 {
00823 ROP = GE_ROP_TMAP_LMAP_ZSET_SBUF;
00824 }
00825 else
00826 {
00827 ROP = GE_ROP_TMAP_LSHADE_ZSET_SBUF;
00828 }
00829 }
00830 else
00831 {
00832 if (LInfo)
00833 {
00834 if (THandle->PixelFormat.PixelFormat ==GE_PIXELFORMAT_16BIT_4444_ARGB)
00835 {
00836 ROP = GE_ROP_TMAP_LMAP_AMAP_ZTESTSET;
00837 }
00838 else if (Flags & DRV_RENDER_ALPHA)
00839 {
00840 ROP = GE_ROP_TMAP_LMAP_AFLAT_ZTESTSET;
00841 }
00842 else
00843 {
00844
00845 ROP = GE_ROP_TMAP_LMAP_ZTESTSET;
00846 }
00847 }
00848 else
00849 {
00850 if (THandle->PixelFormat.PixelFormat ==GE_PIXELFORMAT_16BIT_4444_ARGB)
00851 {
00852 ROP = GE_ROP_TMAP_LSHADE_AMAP_ZTESTSET;
00853 }
00854 else if (Flags & DRV_RENDER_ALPHA)
00855 {
00856 ROP = GE_ROP_TMAP_LSHADE_AFLAT_ZTESTSET;
00857 }
00858 else
00859 {
00860
00861 ROP = GE_ROP_TMAP_LSHADE_ZTESTSET;
00862 }
00863 }
00864 }
00865
00866 assert(THandle != NULL);
00867 assert(Pnts != NULL);
00868 assert(NumPoints > 2);
00869 {
00870 DRV_TLVertex Pnts2[3];
00871 geFloat OOW,OOH;
00872 geFloat ShiftU,ShiftV,ScaleU,ScaleV;
00873
00874 ShiftU = TexInfo->ShiftU;
00875 ShiftV = TexInfo->ShiftV;
00876 ScaleU = 1.0f/TexInfo->DrawScaleU;
00877 ScaleV = 1.0f/TexInfo->DrawScaleV;
00878 OOW = 1.0f / (geFloat)THandle->Width;
00879 OOH = 1.0f / (geFloat)THandle->Height;
00880
00881 SoftDrv_TempTexInfo = TexInfo;
00882 SoftDrv_TempLInfo = LInfo;
00883
00884 Pnts2[0] = Pnts[0];
00885 Pnts2[0].u = (Pnts2[0].u*ScaleU+ShiftU)*OOW;
00886 Pnts2[0].v = (Pnts2[0].v*ScaleV+ShiftV)*OOH;
00887
00888 MipLevel = SoftDrv_ComputeMipLevel(Pnts,TexInfo->DrawScaleU,TexInfo->DrawScaleV,THandle->MipLevels,NumPoints);
00889
00890 for(i=0;i < NumPoints-2;i++)
00891 {
00892
00893 Pnts2[1] = Pnts[i+1];
00894 Pnts2[2] = Pnts[i+2];
00895 Pnts2[1].u = (Pnts2[1].u*ScaleU+ShiftU)*OOW;
00896 Pnts2[1].v = (Pnts2[1].v*ScaleV+ShiftV)*OOH;
00897 Pnts2[2].u = (Pnts2[2].u*ScaleU+ShiftU)*OOW;
00898 Pnts2[2].v = (Pnts2[2].v*ScaleV+ShiftV)*OOH;
00899 #ifdef GENESIS_VERSION_2
00900 #pragma message ("temporary:")
00901 if( Pnts2[0].x < 0 ) Pnts2[0].x = 0 ;
00902 if( Pnts2[1].x < 0 ) Pnts2[1].x = 0 ;
00903 if( Pnts2[2].x < 0 ) Pnts2[2].x = 0 ;
00904 if( Pnts2[0].y < 0 ) Pnts2[0].y = 0 ;
00905 if( Pnts2[1].y < 0 ) Pnts2[1].y = 0 ;
00906 if( Pnts2[2].y < 0 ) Pnts2[2].y = 0 ;
00907
00908 if( Pnts2[0].x >= ClientWindow.Width ) Pnts2[0].x = ClientWindow.Width-1 ;
00909 if( Pnts2[1].x >= ClientWindow.Width ) Pnts2[1].x = ClientWindow.Width-1 ;
00910 if( Pnts2[2].x >= ClientWindow.Width ) Pnts2[2].x = ClientWindow.Width-1 ;
00911 if( Pnts2[0].y >= ClientWindow.Height ) Pnts2[0].y = ClientWindow.Height-1 ;
00912 if( Pnts2[1].y >= ClientWindow.Height ) Pnts2[1].y = ClientWindow.Height-1 ;
00913 if( Pnts2[2].y >= ClientWindow.Height ) Pnts2[2].y = ClientWindow.Height-1 ;
00914 #else
00915 assert( Pnts2[0].x >= 0 ) ;
00916 assert( Pnts2[1].x >= 0 ) ;
00917 assert( Pnts2[2].x >= 0 ) ;
00918 assert( Pnts2[0].y >= 0 ) ;
00919 assert( Pnts2[1].y >= 0 ) ;
00920 assert( Pnts2[2].y >= 0 ) ;
00921
00922 assert( Pnts2[0].x < ClientWindow.Width ) ;
00923 assert( Pnts2[1].x < ClientWindow.Width ) ;
00924 assert( Pnts2[2].x < ClientWindow.Width ) ;
00925 assert( Pnts2[0].y < ClientWindow.Height ) ;
00926 assert( Pnts2[1].y < ClientWindow.Height ) ;
00927 assert( Pnts2[2].y < ClientWindow.Height ) ;
00928 #endif
00929
00930 TRaster_Rasterize( ROP,THandle, MipLevel, Pnts2 );
00931 }
00932 }
00933 return GE_TRUE;
00934 }
00935
00936 geBoolean DRIVERCC SoftDrv_RenderMiscTexturePoly(DRV_TLVertex *Pnts, S32 NumPoints, geRDriver_THandle *THandle, U32 Flags)
00937 {
00938 int i;
00939 geROP ROP;
00940 int MipLevel;
00941
00942 if(!SD_Active)
00943 {
00944 return GE_TRUE;
00945 }
00946
00947 assert(Pnts != NULL);
00948 assert(NumPoints > 2);
00949 ROP = SoftDrv_MiscFlagsToRop[Flags & 0xF][(THandle->PixelFormat.PixelFormat==GE_PIXELFORMAT_16BIT_4444_ARGB)?1:0];
00950
00951
00952 for(i=0;i < NumPoints-2;i++)
00953 {
00954 DRV_TLVertex Pnts2[3];
00955
00956 if ( (((Pnts[i+1].x-Pnts[0].x) * (Pnts[i+2].y-Pnts[0].y)) - ((Pnts[i+1].y-Pnts[0].y)*(Pnts[i+2].x-Pnts[0].x)))<0.0f)
00957 {
00958 Pnts2[0] = Pnts[i+2];
00959 Pnts2[1] = Pnts[i+1];
00960 Pnts2[2] = Pnts[0];
00961 }
00962 else
00963 {
00964 Pnts2[0] = Pnts[0];
00965 Pnts2[1] = Pnts[i+1];
00966 Pnts2[2] = Pnts[i+2];
00967 }
00968 Pnts2[0].a = Pnts[0].a;
00969 #ifdef GENESIS_VERSION_2
00970 #pragma message ("temporary:")
00971 if( Pnts2[0].x < 0 ) Pnts2[0].x = 0 ;
00972 if( Pnts2[1].x < 0 ) Pnts2[1].x = 0 ;
00973 if( Pnts2[2].x < 0 ) Pnts2[2].x = 0 ;
00974 if( Pnts2[0].y < 0 ) Pnts2[0].y = 0 ;
00975 if( Pnts2[1].y < 0 ) Pnts2[1].y = 0 ;
00976 if( Pnts2[2].y < 0 ) Pnts2[2].y = 0 ;
00977
00978 if( Pnts2[0].x >= ClientWindow.Width ) Pnts2[0].x = ClientWindow.Width-1 ;
00979 if( Pnts2[1].x >= ClientWindow.Width ) Pnts2[1].x = ClientWindow.Width-1 ;
00980 if( Pnts2[2].x >= ClientWindow.Width ) Pnts2[2].x = ClientWindow.Width-1 ;
00981 if( Pnts2[0].y >= ClientWindow.Height ) Pnts2[0].y = ClientWindow.Height-1 ;
00982 if( Pnts2[1].y >= ClientWindow.Height ) Pnts2[1].y = ClientWindow.Height-1 ;
00983 if( Pnts2[2].y >= ClientWindow.Height ) Pnts2[2].y = ClientWindow.Height-1 ;
00984 #else
00985 assert( Pnts2[0].x >= 0 ) ;
00986 assert( Pnts2[1].x >= 0 ) ;
00987 assert( Pnts2[2].x >= 0 ) ;
00988 assert( Pnts2[0].y >= 0 ) ;
00989 assert( Pnts2[1].y >= 0 ) ;
00990 assert( Pnts2[2].y >= 0 ) ;
00991
00992 assert( Pnts2[0].x < ClientWindow.Width ) ;
00993 assert( Pnts2[1].x < ClientWindow.Width ) ;
00994 assert( Pnts2[2].x < ClientWindow.Width ) ;
00995 assert( Pnts2[0].y < ClientWindow.Height ) ;
00996 assert( Pnts2[1].y < ClientWindow.Height ) ;
00997 assert( Pnts2[2].y < ClientWindow.Height ) ;
00998 #endif
00999
01000
01001 if (THandle->MipLevels>1)
01002 MipLevel = SoftDrv_ComputeMipLevel(Pnts,1.0f,1.0f,THandle->MipLevels,NumPoints);
01003 else
01004 MipLevel =0;
01005 TRaster_Rasterize( ROP,THandle,MipLevel, Pnts2 );
01006 }
01007
01008
01009 return GE_TRUE;
01010 }
01011
01012
01013 geBoolean DRIVERCC SoftDrv_ResetAll(void)
01014 {
01015 return SWTHandle_FreeAllTextureHandles();
01016 }
01017
01018 geBoolean DRIVERCC SoftDrv_SetFogEnable(geBoolean Enable, geFloat r, geFloat g, geFloat b, geFloat Start, geFloat End)
01019 {
01020 Enable,r,g,b,Start,End;
01021 return GE_FALSE;
01022 }
01023
01024
01025 DRV_Driver SOFTDRV =
01026 {
01027 "Software driver. v"DRV_VMAJS"."DRV_VMINS". Copyright 1999, WildTangent, Inc.; All Rights Reserved.",
01028 DRV_VERSION_MAJOR,
01029 DRV_VERSION_MINOR,
01030
01031 DRV_ERROR_NONE,
01032 NULL,
01033
01034 SoftDrv_EnumSubDrivers,
01035 SoftDrv_EnumModes,
01036 SWTHandle_EnumPixelFormats,
01037
01038 SoftDrv_Init,
01039 SoftDrv_Shutdown,
01040 SoftDrv_ResetAll,
01041 SoftDrv_SetRenderWindowRect,
01042 SoftDrv_SetActive,
01043
01044 SWTHandle_CreateTexture,
01045 SWTHandle_DestroyTexture,
01046
01047 SWTHandle_LockTextureHandle,
01048 SWTHandle_UnLockTextureHandle,
01049
01050 SWTHandle_SetPalette,
01051 SWTHandle_GetPalette,
01052 SWTHandle_SetAlpha,
01053 SWTHandle_GetAlpha,
01054
01055 SWTHandle_GetInfo,
01056
01057 SoftDrv_BeginScene,
01058 SoftDrv_EndScene,
01059
01060 SoftDrv_BeginWorld,
01061 SoftDrv_EndRenderMode,
01062 SoftDrv_BeginMeshes,
01063 SoftDrv_EndRenderMode,
01064 SoftDrv_BeginModels,
01065 SoftDrv_EndRenderMode,
01066
01067 SoftDrv_RenderGouraudPoly,
01068 SoftDrv_RenderWorldPoly,
01069 SoftDrv_RenderMiscTexturePoly,
01070
01071 DrawDecal,
01072
01073 0,0,0,
01074
01075 &SoftDrv_CacheInfo,
01076
01077 SoftDrv_ScreenShot,
01078
01079 SoftDrv_SetGamma,
01080 SoftDrv_GetGamma,
01081 SoftDrv_SetFogEnable,
01082
01083 &SD_EngineSettings,
01084 NULL,
01085 NULL
01086 };
01087
01088
01089