00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define WIN32_LEAN_AND_MEAN
00027 #include <windows.h>
00028 #include <mmsystem.h>
00029 #include <stdlib.h>
00030 #include <direct.h>
00031
00032 #include "engine.h"
00033
00034 #include "Errorlog.h"
00035 #include "DCommon.h"
00036 #include "BitmapList.h"
00037 #include "Bitmap.h"
00038 #include "Bitmap._h"
00039 #include "World.h"
00040 #include "log.h"
00041
00042
00043 #ifndef _DEBUG
00044 #undef DO_ADDREMOVE_MESSAGES
00045 #endif
00046
00047 extern geBoolean DoSplashScreen(geEngine *Engine, geDriver_Mode *Mode);
00048
00049
00050
00051
00052
00053 static geBoolean Engine_InitDriver( geEngine *Engine,
00054 geDriver *Driver,
00055 geDriver_Mode *DriverMode);
00056
00057 static void Engine_DrawFontBuffer(geEngine *Engine);
00058 static void Engine_Tick(geEngine *Engine);
00059
00060 static void SubLarge(LARGE_INTEGER *start, LARGE_INTEGER *end, LARGE_INTEGER *delta);
00061
00062 #define ABS(xx) ( (xx) < 0 ? (-(xx)) : (xx) )
00063
00064
00065
00066
00067 GENESISAPI geBoolean geEngine_SetGamma(geEngine *Engine, geFloat Gamma)
00068 {
00069 assert(Engine);
00070
00071 if ( Gamma < 0.01f )
00072 Gamma = 0.01f;
00073
00074 if ( ABS( Engine->CurrentGamma - Gamma) < 0.01f )
00075 return GE_TRUE;
00076
00077 Engine->CurrentGamma = Gamma;
00078
00079 geEngine_UpdateGamma(Engine);
00080
00081 return GE_TRUE;
00082 }
00083
00084
00085
00086
00087 GENESISAPI geBoolean geEngine_GetGamma(geEngine *Engine, geFloat *Gamma)
00088 {
00089 assert(Engine);
00090 assert(Gamma);
00091
00092 *Gamma = Engine->CurrentGamma;
00093
00094 return GE_TRUE;
00095 }
00096
00097
00098
00099
00100 static geBoolean geEngine_UpdateFogEnable(geEngine *Engine)
00101 {
00102 if (Engine->DriverInfo.RDriver)
00103 {
00104 return Engine->DriverInfo.RDriver->SetFogEnable(Engine->FogEnable,
00105 Engine->FogR,
00106 Engine->FogG,
00107 Engine->FogB,
00108 Engine->FogStart,
00109 Engine->FogEnd);
00110 }
00111
00112 return GE_TRUE;
00113 }
00114
00115
00116
00117
00118 GENESISAPI geBoolean geEngine_SetFogEnable(geEngine *Engine, geBoolean Enable, geFloat r, geFloat g, geFloat b, geFloat Start, geFloat End)
00119 {
00120 Engine->FogEnable = Enable;
00121
00122 Engine->FogR = r;
00123 Engine->FogG = g;
00124 Engine->FogB = b;
00125
00126 Engine->FogStart = Start;
00127 Engine->FogEnd = End;
00128
00129 return geEngine_UpdateFogEnable(Engine);
00130 }
00131
00132 void geEngine_UpdateGamma(geEngine *Engine)
00133 {
00134 DRV_Driver * RDriver;
00135 geFloat LastBitmapGamma;
00136
00137 assert(Engine);
00138
00139 RDriver = Engine->DriverInfo.RDriver;
00140
00141 LastBitmapGamma = Engine->BitmapGamma;
00142
00143 if ( RDriver && (RDriver->EngineSettings->CanSupportFlags & DRV_SUPPORT_GAMMA) )
00144 {
00145 if ( RDriver->SetGamma(Engine->CurrentGamma) )
00146 Engine->BitmapGamma = 1.0f;
00147 else
00148 Engine->BitmapGamma = Engine->CurrentGamma;
00149 }
00150 else
00151 {
00152 Engine->BitmapGamma = Engine->CurrentGamma;
00153 }
00154
00155 if ( ABS(Engine->BitmapGamma - LastBitmapGamma) < 0.1f )
00156 {
00157 Engine->BitmapGamma = LastBitmapGamma;
00158 }
00159 else
00160 {
00161 int i;
00162
00163
00164 if (!BitmapList_SetGamma(Engine->AttachedBitmaps, Engine->BitmapGamma))
00165 {
00166 geErrorLog_AddString(-1, "geEngine_UpdateGamma: BitmapList_SetGamma for Engine failed", NULL);
00167 }
00168
00169 for (i=0; i< Engine->NumWorlds; i++)
00170 {
00171
00172 if (!BitmapList_SetGamma(Engine->Worlds[i]->AttachedBitmaps, Engine->BitmapGamma ))
00173 {
00174 geErrorLog_AddString(-1, "geEngine_UpdateGamma: BitmapList_SetGamma for World failed", NULL);
00175 }
00176 }
00177 }
00178
00179 }
00180
00181
00182
00183
00184
00185 geBoolean geEngine_BitmapListInit(geEngine *Engine)
00186 {
00187 assert(Engine);
00188 assert(Engine->AttachedBitmaps == NULL);
00189
00190 if ( Engine->AttachedBitmaps == NULL )
00191 {
00192 Engine->AttachedBitmaps = BitmapList_Create();
00193 if ( ! Engine->AttachedBitmaps )
00194 {
00195 geErrorLog_AddString(-1, "geEngine_BitmapListInit: BitmapList_Create failed...", NULL);
00196 return GE_FALSE;
00197 }
00198 }
00199 return GE_TRUE;
00200 }
00201
00202
00203
00204
00205 geBoolean geEngine_BitmapListShutdown(geEngine *Engine)
00206 {
00207 assert(Engine);
00208
00209 if ( Engine->AttachedBitmaps )
00210 {
00211 assert( Engine->DriverInfo.Active || BitmapList_CountMembersAttached(Engine->AttachedBitmaps) == 0 );
00212
00213
00214
00215 BitmapList_Destroy(Engine->AttachedBitmaps);
00216 Engine->AttachedBitmaps = NULL;
00217 }
00218
00219 return GE_TRUE;
00220 }
00221
00222
00223
00224
00225 GENESISAPI geBoolean geEngine_AddBitmap(geEngine *Engine, geBitmap *Bitmap)
00226 {
00227 assert(Engine);
00228 assert(Bitmap);
00229 assert(Engine->AttachedBitmaps);
00230
00231 assert(Engine->FrameState == FrameState_None);
00232
00233 if (!Engine->AttachedBitmaps)
00234 {
00235 geErrorLog_AddString(-1, "geEngine_AddBitmap: AttachedBitmaps is NULL.", NULL);
00236 return GE_FALSE;
00237 }
00238
00239 geBitmap_SetDriverFlags(Bitmap,RDRIVER_PF_2D);
00240
00241
00242 if ( BitmapList_Add(Engine->AttachedBitmaps, (geBitmap *)Bitmap) )
00243 {
00244 Engine->Changed = GE_TRUE;
00245
00246 #ifdef DO_ADDREMOVE_MESSAGES
00247 {
00248 char str[100];
00249 sprintf(str,"Engine_AddBitmap : %08X : new\n",Bitmap);
00250 OutputDebugString(str);
00251 }
00252 #endif
00253 }
00254 else
00255 {
00256 #ifdef DO_ADDREMOVE_MESSAGES
00257 {
00258 char str[100];
00259 sprintf(str,"Engine_AddBitmap : %08X : old\n",Bitmap);
00260 OutputDebugString(str);
00261 }
00262 #endif
00263 }
00264
00265 return GE_TRUE;
00266 }
00267
00268
00269
00270
00271 GENESISAPI geBoolean geEngine_RemoveBitmap(geEngine *Engine, geBitmap *Bitmap)
00272 {
00273 assert(Engine);
00274 assert(Bitmap);
00275 assert(Engine->AttachedBitmaps);
00276
00277
00278
00279 if ( ! Engine->AttachedBitmaps )
00280 return GE_FALSE;
00281
00282 if ( BitmapList_Remove(Engine->AttachedBitmaps,Bitmap) )
00283 {
00284 Engine->Changed = GE_TRUE;
00285
00286 if (!geBitmap_DetachDriver(Bitmap, GE_TRUE))
00287 {
00288 geErrorLog_AddString(-1, "geEngine_RemoveBitmap: geBitmap_DetachDriver failed...", NULL);
00289 return GE_FALSE;
00290 }
00291
00292 #ifdef DO_ADDREMOVE_MESSAGES
00293 {
00294 char str[100];
00295 sprintf(str,"Engine_RemoveBitmap : %08X : removed\n",Bitmap);
00296 OutputDebugString(str);
00297 }
00298 #endif
00299 }
00300 else
00301 {
00302 #ifdef DO_ADDREMOVE_MESSAGES
00303 {
00304 char str[100];
00305 sprintf(str,"Engine_RemoveBitmap : %08X : left\n",Bitmap);
00306 OutputDebugString(str);
00307 }
00308 #endif
00309 }
00310
00311 return GE_TRUE;
00312 }
00313
00314
00315
00317
00318
00319
00320
00321
00323
00324 GENESISAPI geBoolean GENESISCC geEngine_DrawAlphaBitmap(
00325 geEngine * Engine,
00326 geBitmap * pBitmap,
00327 geVec3d * VertUVArray,
00328 geCamera * ClipCamera,
00329 GE_Rect * PixelRect,
00330 GE_Rect * PercentRect,
00331 geFloat Alpha,
00332 GE_RGBA * RGBA_Array
00333 )
00334 {
00335
00336 GE_TLVertex vertex[4];
00337 geFloat fUVAdd = 0.0f;
00338 geFloat fWidthBmp = 0;
00339 geFloat fHeightBmp = 0;
00340 GE_Rect ClipRect = {0,0,0,0};
00341 GE_Rect UseRect = {0,0,0,0};
00342 geVec3d DefaultUVArray[4] = {{0,0,0},{1,0,0},{1,1,0},{0,1,0}};
00343 GE_RGBA DefaultRGBA_Array[4] =
00344 {{255,255,255,Alpha},
00345 {255,255,255,Alpha},
00346 {255,255,255,Alpha},
00347 {255,255,255,Alpha}};
00348 geBitmap_Info TempInfo, TempInfo2;
00349 geFloat UVbreak = 0.0f;
00350
00351 if(pBitmap)
00352 geBitmap_GetInfo(pBitmap, &TempInfo, &TempInfo2);
00353 else
00354 TempInfo.Height = TempInfo.Width = 8;
00355
00356 fWidthBmp = (geFloat)TempInfo.Width;
00357 fHeightBmp = (geFloat)TempInfo.Height;
00358
00359
00360
00361
00362
00363 #if 0
00364
00365
00366 if(!ClipCamera )
00367 {
00368 ClipRect.Top = 0;
00369 ClipRect.Left = 0;
00370 ClipRect.Bottom = CHeight-1;
00371 ClipRect.Right = CWidth-1;
00372 }
00373 else
00374 #endif
00375 geCamera_GetClippingRect( ClipCamera, &ClipRect );
00376
00377 if(!VertUVArray)
00378 VertUVArray = &DefaultUVArray[0];
00379 if(!RGBA_Array)
00380 RGBA_Array = &DefaultRGBA_Array[0];
00381 if(PixelRect)
00382 {
00383 UseRect.Top = PixelRect->Top + ClipRect.Top;
00384 UseRect.Left = PixelRect->Left + ClipRect.Left;
00385 UseRect.Bottom = PixelRect->Bottom + ClipRect.Top;
00386 UseRect.Right = PixelRect->Right + ClipRect.Left;
00387 }
00388 else
00389 {
00390 if(PercentRect)
00391 {
00392 UseRect.Top = ClipRect.Top
00393 + (int32)(0.01f * PercentRect->Top
00394 * (ClipRect.Bottom - ClipRect.Top));
00395 UseRect.Left = ClipRect.Left
00396 + (int32)(0.01f * PercentRect->Left
00397 * (ClipRect.Right - ClipRect.Left));
00398 UseRect.Bottom = ClipRect.Bottom
00399 + (int32)(0.01f * PercentRect->Bottom
00400 * (ClipRect.Bottom - ClipRect.Top));
00401 UseRect.Right = ClipRect.Right
00402 + (int32)(0.01f * PercentRect->Right
00403 * (ClipRect.Right - ClipRect.Left));
00404 }
00405 else
00406 {
00407 UseRect = ClipRect;
00408 }
00409 }
00410
00411 vertex[0].x = (geFloat)UseRect.Left;
00412 vertex[0].y = (geFloat)UseRect.Top;
00413 vertex[0].z = 1.0f;
00414 vertex[0].r = RGBA_Array[0].r;
00415 vertex[0].g = RGBA_Array[0].g;
00416 vertex[0].b = RGBA_Array[0].b;
00417 vertex[0].a = RGBA_Array[0].a;
00418 vertex[0].u = VertUVArray[0].X + UVbreak/fWidthBmp;
00419 vertex[0].v = VertUVArray[0].Y + UVbreak/fHeightBmp;
00420
00421 vertex[1].x = (geFloat)UseRect.Right;
00422 vertex[1].y = (geFloat)UseRect.Top;
00423 vertex[1].z = vertex[0].z;
00424 vertex[1].r = RGBA_Array[1].r;
00425 vertex[1].g = RGBA_Array[1].g;
00426 vertex[1].b = RGBA_Array[1].b;
00427 vertex[1].a = RGBA_Array[1].a;
00428 vertex[1].u = VertUVArray[1].X - UVbreak/fWidthBmp;
00429 vertex[1].v = VertUVArray[1].Y + UVbreak/fHeightBmp;
00430
00431 vertex[2].x = (geFloat)UseRect.Right;
00432 vertex[2].y = (geFloat)UseRect.Bottom;
00433 vertex[2].z = vertex[0].z;
00434 vertex[2].r = RGBA_Array[2].r;
00435 vertex[2].g = RGBA_Array[2].g;
00436 vertex[2].b = RGBA_Array[2].b;
00437 vertex[2].a = RGBA_Array[2].a;
00438 vertex[2].u = VertUVArray[2].X - UVbreak/fWidthBmp;
00439 vertex[2].v = VertUVArray[2].Y - UVbreak/fHeightBmp;
00440
00441 vertex[3].x = (geFloat)UseRect.Left;
00442 vertex[3].y = (geFloat)UseRect.Bottom;
00443 vertex[3].z = vertex[0].z;
00444 vertex[3].r = RGBA_Array[3].r;
00445 vertex[3].g = RGBA_Array[3].g;
00446 vertex[3].b = RGBA_Array[3].b;
00447 vertex[3].a = RGBA_Array[3].a;
00448 vertex[3].u = VertUVArray[3].X + UVbreak/fWidthBmp;
00449 vertex[3].v = VertUVArray[3].Y - UVbreak/fHeightBmp;
00450
00451 if(vertex[0].x < ClipRect.Left )
00452 {
00453 if(vertex[1].x <= ClipRect.Left )
00454 {
00455 geErrorLog_AddString(-1, "Clipping Rect has negative dimension",
00456 NULL);
00457 return GE_FALSE;
00458 }
00459 fUVAdd = ( ClipRect.Left - vertex[0].x ) / fWidthBmp;
00460 fWidthBmp -= ( ClipRect.Left - vertex[0].x );
00461 vertex[0].u += fUVAdd;
00462 vertex[3].u = vertex[0].u;
00463 vertex[0].x = (geFloat)ClipRect.Left;
00464 vertex[3].x = vertex[0].x;
00465 }
00466
00467 if( vertex[0].y < ClipRect.Top )
00468 {
00469 if( vertex[2].y <= ClipRect.Top )
00470 {
00471 geErrorLog_AddString(-1, "Clipping Rect has negative dimension",
00472 NULL);
00473 return GE_FALSE;
00474 }
00475 fUVAdd = ( ClipRect.Top - vertex[0].y ) / fHeightBmp;
00476 fHeightBmp -= ( ClipRect.Top - vertex[0].y );
00477 vertex[0].v += fUVAdd;
00478 vertex[1].v = vertex[0].v;
00479 vertex[0].y = (geFloat)ClipRect.Top;
00480 vertex[1].y = vertex[0].y;
00481 }
00482
00483 if(vertex[1].x > ClipRect.Right )
00484 {
00485 if( vertex[0].x >= ClipRect.Right )
00486 {
00487 geErrorLog_AddString(-1, "Clipping Rect has negative dimension",
00488 NULL);
00489 return GE_FALSE;
00490 }
00491 fUVAdd = ( vertex[1].x - ClipRect.Right ) / fWidthBmp;
00492 vertex[1].u -= fUVAdd;
00493 vertex[2].u = vertex[1].u;
00494 vertex[1].x = (geFloat)ClipRect.Right - 1;
00495 vertex[2].x = vertex[1].x;
00496 }
00497
00498 if( vertex[2].y > ClipRect.Bottom )
00499 {
00500 if( vertex[0].y >= ClipRect.Bottom )
00501 {
00502 geErrorLog_AddString(-1, "Clipping Rect has negative dimension",
00503 NULL);
00504 return GE_FALSE;
00505 }
00506 fUVAdd = ( vertex[2].y - ClipRect.Bottom ) / fHeightBmp;
00507 vertex[2].v -= fUVAdd;
00508 vertex[3].v = vertex[2].v;
00509 vertex[2].y = (geFloat)ClipRect.Bottom - 1;
00510 vertex[3].y = vertex[2].y;
00511 }
00512
00513 geEngine_RenderPoly( Engine,
00514 vertex,
00515 4,
00516 pBitmap,
00517 ( Alpha != 255 ? DRV_RENDER_ALPHA : 0 ) |
00518 DRV_RENDER_CLAMP_UV | DRV_RENDER_FLUSH |
00519 DRV_RENDER_NO_ZMASK | DRV_RENDER_NO_ZWRITE );
00520
00521 return GE_TRUE;
00522 }
00523
00524
00525
00526
00527 GENESISAPI geBoolean geEngine_SetDriverAndMode( geEngine *Engine,
00528 geDriver *Driver,
00529 geDriver_Mode *DriverMode)
00530 {
00531 assert(Engine);
00532 assert(Driver);
00533 assert(DriverMode);
00534
00535
00536
00537
00538 if (!Engine_InitDriver(Engine, Driver, DriverMode))
00539 return GE_FALSE;
00540
00541
00542 geEngine_SetAllWorldChangedFlag(Engine, GE_TRUE);
00543 Engine->Changed = GE_TRUE;
00544
00545 geEngine_UpdateGamma(Engine);
00546 geEngine_UpdateFogEnable(Engine);
00547
00548
00549 #ifdef _DEBUG
00550 #pragma message("Engine :splash screen disabled")
00551 Engine = Engine;
00552 #else
00553
00554 if (DoSplashScreen(Engine, DriverMode) == GE_FALSE)
00555 return GE_FALSE;
00556 #endif
00557
00558 return GE_TRUE;
00559 }
00560
00561
00562
00563
00564 GENESISAPI geDriver_System *geEngine_GetDriverSystem(geEngine *Engine)
00565 {
00566 assert(Engine);
00567
00568 return (geDriver_System*)&Engine->DriverInfo;
00569 }
00570
00571
00572
00573
00574
00575
00576 GENESISAPI geBoolean geEngine_Activate(geEngine *Engine, geBoolean bActive)
00577 {
00578 DRV_Driver *RDriver;
00579
00580 assert(Engine);
00581
00582 RDriver =Engine->DriverInfo.RDriver;
00583
00584 if(Engine->DriverInfo.Active && RDriver)
00585 {
00586
00587 #if 1
00588 if ( RDriver->SetActive )
00589 return RDriver->SetActive(bActive);
00590 #endif
00591 }
00592
00593 return GE_TRUE;
00594 }
00595
00596
00597
00598
00599
00600
00601 GENESISAPI geBoolean geEngine_UpdateWindow(geEngine *Engine)
00602 {
00603 DRV_Driver *RDriver;
00604
00605 RDriver = Engine->DriverInfo.RDriver;
00606
00607 if(Engine->DriverInfo.Active && RDriver)
00608 {
00609 if (RDriver->UpdateWindow )
00610 return RDriver->UpdateWindow();
00611 }
00612
00613 return GE_TRUE;
00614 }
00615
00616
00617
00618
00619 GENESISAPI geBoolean geEngine_ShutdownDriver(geEngine *Engine)
00620 {
00621 Sys_DriverInfo *DrvInfo;
00622
00623 assert(Engine);
00624
00625 DrvInfo = &(Engine->DriverInfo);
00626
00627 assert(DrvInfo);
00628
00629 if (!DrvInfo->Active)
00630 return GE_TRUE;
00631
00632 #if 0 // <>
00633 #ifdef _DEBUG
00634 OutputDebugString("geEngine_ShutdownDriver\n");
00635 #endif
00636 #endif
00637
00638
00639 if (!geEngine_ResetDriver(Engine))
00640 {
00641 geErrorLog_AddString(-1, "geEngine_ShutdownDriver: geEngine_ResetDriver failed.", NULL);
00642 return GE_FALSE;
00643 }
00644
00645
00646 DrvInfo->RDriver->Shutdown();
00647
00648 if (!FreeLibrary(DrvInfo->DriverHandle) )
00649 return GE_FALSE;
00650
00651 DrvInfo->Active = GE_FALSE;
00652 DrvInfo->RDriver = NULL;
00653
00654 return GE_TRUE;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663 GENESISAPI void GENESISCC geEngine_RenderPoly(const geEngine *Engine,
00664 const GE_TLVertex *Points, int NumPoints, const geBitmap *Texture, uint32 Flags)
00665 {
00666 geBoolean Ret;
00667
00668 assert(Engine && Points );
00669
00670 if ( Texture )
00671 {
00672 geRDriver_THandle * TH;
00673
00674
00675
00676
00677
00678
00679 TH = geBitmap_GetTHandle(Texture);
00680 assert(TH);
00681
00682 Ret = Engine->DriverInfo.RDriver->RenderMiscTexturePoly((DRV_TLVertex *)Points,
00683 NumPoints,TH,Flags);
00684 }
00685 else
00686 {
00687 Ret = Engine->DriverInfo.RDriver->RenderGouraudPoly((DRV_TLVertex *)Points,
00688 NumPoints,Flags);
00689 }
00690
00691 assert(Ret == GE_TRUE);
00692 }
00693
00694 GENESISAPI void GENESISCC geEngine_RenderPolyArray(const geEngine *Engine, const GE_TLVertex ** pPoints, int * pNumPoints, int NumPolys,
00695 const geBitmap *Texture, uint32 Flags)
00696 {
00697 geBoolean Ret;
00698 int pn;
00699 DRV_Driver * Driver;
00700
00701 assert(Engine && pPoints && pNumPoints );
00702
00703 Driver = Engine->DriverInfo.RDriver;
00704 assert(Driver);
00705
00706 if ( Texture )
00707 {
00708 geRDriver_THandle * TH;
00709
00710 TH = geBitmap_GetTHandle(Texture);
00711 assert(TH);
00712
00713 for(pn=0;pn<NumPolys;pn++)
00714 {
00715 assert(pPoints[pn]);
00716 Ret = Driver->RenderMiscTexturePoly((DRV_TLVertex *)pPoints[pn],
00717 pNumPoints[pn],TH,Flags);
00718 assert(Ret);
00719 }
00720 }
00721 else
00722 {
00723 for(pn=0;pn<NumPolys;pn++)
00724 {
00725 assert(pPoints[pn]);
00726 Ret = Driver->RenderGouraudPoly((DRV_TLVertex *)pPoints[pn],
00727 pNumPoints[pn],Flags);
00728 assert(Ret);
00729 }
00730 }
00731
00732 }
00733
00734
00735
00736
00737 GENESISAPI geBoolean GENESISCC geEngine_DrawBitmap(const geEngine *Engine,
00738 const geBitmap *Bitmap,
00739 const geRect * Source, uint32 x, uint32 y)
00740 {
00741 geRDriver_THandle * TH;
00742 geBoolean Ret;
00743
00744
00745
00746
00747 #pragma message("Engine : Make the drivers use geRect, JP")
00748
00749 assert(Engine);
00750 assert(Bitmap);
00751
00752 assert(Engine->AttachedBitmaps);
00753 assert(BitmapList_Has(Engine->AttachedBitmaps, (geBitmap *)Bitmap) == GE_TRUE);
00754
00755 TH = geBitmap_GetTHandle(Bitmap);
00756 assert(TH);
00757
00758
00759
00760 if (Source)
00761 {
00762 RECT rect;
00763
00764 rect.left = Source->Left;
00765 rect.top = Source->Top;
00766 rect.right = Source->Right;
00767 rect.bottom = Source->Bottom;
00768
00769 Ret = Engine->DriverInfo.RDriver->DrawDecal(TH, &rect, x,y);
00770 }
00771 else
00772 Ret = Engine->DriverInfo.RDriver->DrawDecal(TH, NULL, x,y);
00773
00774 if ( ! Ret )
00775 {
00776 geErrorLog_AddString(-1,"geEngine_DrawBitmap : DrawDecal failed", NULL);
00777 }
00778
00779 return Ret;
00780 }
00781
00782
00783
00784
00785 geBoolean geEngine_RebuildFastWorldList(geEngine *Engine)
00786 {
00787 int32 i;
00788 geEngine_WorldList *pWorldList;
00789
00790 Engine->NumWorlds = 0;
00791
00792 pWorldList = Engine->WorldList;
00793
00794 for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
00795 {
00796 if (pWorldList->RefCount > 0)
00797 {
00798 assert(pWorldList->World);
00799
00800 Engine->Worlds[Engine->NumWorlds++] = pWorldList->World;
00801
00802 assert(Engine->NumWorlds <= ENGINE_MAX_WORLDS);
00803 }
00804 }
00805
00806 return GE_TRUE;
00807 }
00808
00809
00810
00811
00812 GENESISAPI geBoolean geEngine_AddWorld(geEngine *Engine, geWorld *World)
00813 {
00814 int32 i;
00815 geEngine_WorldList *pWorldList;
00816
00817 assert(Engine);
00818 assert(World);
00819
00820
00821 pWorldList = Engine->WorldList;
00822 for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
00823 {
00824 if (pWorldList->World == World)
00825 {
00826 assert(pWorldList->RefCount > 0);
00827 pWorldList->RefCount++;
00828
00829 #ifdef DO_ADDREMOVE_MESSAGES
00830 {
00831 char str[100];
00832 sprintf(str,"Engine_AddWorld : %08X : old\n",World);
00833 OutputDebugString(str);
00834 }
00835 #endif
00836
00837 return GE_TRUE;
00838 }
00839
00840 }
00841
00842 #ifdef DO_ADDREMOVE_MESSAGES
00843 {
00844 char str[100];
00845 sprintf(str,"Engine_AddWorld : %08X : new\n",World);
00846 OutputDebugString(str);
00847 }
00848 #endif
00849
00850
00851 pWorldList = Engine->WorldList;
00852 for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
00853 {
00854 if (!pWorldList->RefCount)
00855 break;
00856 }
00857
00858 if (i == ENGINE_MAX_WORLDS)
00859 {
00860 geErrorLog_AddString(-1, "geEngine_AddWorld: Out of slots.", NULL);
00861 return GE_FALSE;
00862 }
00863
00864
00865 pWorldList->World = World;
00866 pWorldList->RefCount = 1;
00867
00868
00869 geEngine_RebuildFastWorldList(Engine);
00870 Engine->Changed = GE_TRUE;
00871 World->Changed = GE_TRUE;
00872
00873 if (!geWorld_CreateRef(World))
00874 {
00875 geErrorLog_AddString(-1, "geEngine_AddWorld: geWorld_CreateRef failed...", NULL);
00876 return GE_FALSE;
00877 }
00878
00879 return GE_TRUE;
00880 }
00881
00882
00883
00884
00885 GENESISAPI geBoolean geEngine_RemoveWorld(geEngine *Engine, geWorld *World)
00886 {
00887 int32 i;
00888 geEngine_WorldList *pWorldList;
00889
00890 assert(Engine);
00891 assert(World);
00892
00893
00894 pWorldList = Engine->WorldList;
00895 for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
00896 {
00897 if (pWorldList->World == World)
00898 break;
00899 }
00900
00901 if (i == ENGINE_MAX_WORLDS)
00902 {
00903 geErrorLog_AddString(-1, "geEngine_RemoveWorld: World not found.", NULL);
00904 return GE_FALSE;
00905 }
00906
00907 assert(pWorldList->RefCount > 0);
00908
00909
00910 pWorldList->RefCount--;
00911
00912
00913 if (pWorldList->RefCount == 0)
00914 {
00915
00916 #ifdef DO_ADDREMOVE_MESSAGES
00917 {
00918 char str[100];
00919 sprintf(str,"Engine_RemoveWorld : %08X : removed\n",World);
00920 OutputDebugString(str);
00921 }
00922 #endif
00923
00924
00925 if (Engine->DriverInfo.Active)
00926 {
00927 if (!geWorld_DetachAll(World))
00928 {
00929 geErrorLog_AddString(-1, "geEngine_RemoveWorld: geWorld_DetachAll failed.", NULL);
00930 return GE_FALSE;
00931 }
00932 }
00933
00934
00935 memset(pWorldList, 0, sizeof(*pWorldList));
00936
00937
00938 geEngine_RebuildFastWorldList(Engine);
00939
00940
00941 Engine->Changed = GE_TRUE;
00942
00943
00944 geWorld_Free(World);
00945 }
00946 else
00947 {
00948 #ifdef DO_ADDREMOVE_MESSAGES
00949 {
00950 char str[100];
00951 sprintf(str,"Engine_RemoveWorld : %08X : left\n",World);
00952 OutputDebugString(str);
00953 }
00954 #endif
00955 }
00956
00957 return GE_TRUE;
00958 }
00959
00960
00961
00962
00963
00964 geBoolean geEngine_RemoveAllWorlds(geEngine *Engine)
00965 {
00966 int32 i;
00967 geEngine_WorldList *pWorldList;
00968 geWorld *World;
00969
00970 assert(Engine);
00971
00972
00973 pWorldList = Engine->WorldList;
00974 for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
00975 {
00976 World = pWorldList->World;
00977 if ( World )
00978 {
00979 assert(pWorldList->RefCount > 0);
00980
00981 if (Engine->DriverInfo.Active)
00982 {
00983 if (!geWorld_DetachAll(World))
00984 {
00985 geErrorLog_AddString(-1, "geEngine_RemoveWorld: geWorld_DetachAll failed.", NULL);
00986 return GE_FALSE;
00987 }
00988 }
00989
00990 assert( World->RefCount >= 1 );
00991
00992
00993 geWorld_Free(World);
00994 }
00995 memset(pWorldList, 0, sizeof(*pWorldList));
00996 }
00997
00998
00999 geEngine_RebuildFastWorldList(Engine);
01000 Engine->Changed = GE_TRUE;
01001
01002 return GE_TRUE;
01003 }
01004
01005
01006
01007
01008 geBoolean geEngine_HasWorld(const geEngine *Engine, const geWorld *World)
01009 {
01010 int32 i;
01011 const geEngine_WorldList *pWorldList;
01012
01013 assert(Engine);
01014 assert(World);
01015
01016
01017 pWorldList = Engine->WorldList;
01018 for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
01019 {
01020 if (pWorldList->World == World)
01021 {
01022 assert(pWorldList->RefCount > 0);
01023 return GE_TRUE;
01024 }
01025 }
01026
01027 return GE_FALSE;
01028 }
01029
01030
01031
01032
01033 geBoolean geEngine_DetachAllWorlds(geEngine *Engine)
01034 {
01035 int32 i;
01036 geBoolean Ret;
01037
01038 Ret = GE_TRUE;
01039
01040 for (i=0; i< Engine->NumWorlds; i++)
01041 {
01042 if (!geWorld_DetachAll(Engine->Worlds[i]))
01043 {
01044 geErrorLog_AddString(-1, "geEngine_DetachAllWorlds: geWorld_DetachAll failed.", NULL);
01045 Ret = GE_FALSE;
01046 }
01047
01048 if (!geEngine_DestroyWorldLightmapTHandles(Engine, Engine->Worlds[i]))
01049 {
01050 geErrorLog_AddString(-1, "geEngine_DetachAllWorlds: geEngine_DestroyWorldLightmapTHandles failed.", NULL);
01051 Ret = GE_FALSE;
01052 }
01053 }
01054
01055 return Ret;
01056 }
01057
01058
01059
01060
01061 geBoolean geEngine_CreateWorldLightmapTHandles(geEngine *Engine, geWorld *World)
01062 {
01063 DRV_Driver *RDriver;
01064 int32 i;
01065 World_BSP *BSP;
01066 GBSP_BSPData *BSPData;
01067 #ifdef _DEBUG
01068 int CreatedCount = 0;
01069 #endif
01070
01071 assert(Engine);
01072 assert(World);
01073
01074 BSP = World->CurrentBSP;
01075 BSPData = &BSP->BSPData;
01076 RDriver = Engine->DriverInfo.RDriver;
01077
01078
01079
01080
01081 World_SetEngine(Engine);
01082 World_SetWorld(World);
01083 World_SetGBSP(World->CurrentBSP);
01084
01085 for (i=0; i<BSPData->NumGFXFaces; i++)
01086 {
01087 BOOL D;
01088 DRV_LInfo *pLInfo;
01089
01090 pLInfo = &BSP->SurfInfo[i].LInfo;
01091
01092 if ((pLInfo->Face == -1))
01093 continue;
01094
01095 if (!(BSP->SurfInfo[i].Flags & SURFINFO_LIGHTMAP))
01096 continue;
01097
01098 assert(!pLInfo->THandle);
01099
01100 if (pLInfo->THandle)
01101 continue;
01102
01103 Light_SetupLightmap(pLInfo, &D);
01104
01105
01106 pLInfo->THandle = Engine_CreateTHandle(Engine,pLInfo->Width, pLInfo->Height, 1, ENGINE_PF_LIGHTMAP);
01107
01108 if (!pLInfo->THandle)
01109 {
01110 geErrorLog_AddString(-1, RDriver->LastErrorStr, NULL);
01111 geErrorLog_AddString(-1, "geEngine_CreateWorldTHandles: Engine_CreateTHandle failed...\n", NULL);
01112 return GE_FALSE;
01113 }
01114
01115 #ifdef _DEBUG
01116 CreatedCount ++;
01117 #endif
01118 }
01119
01120 #ifdef _DEBUG
01121 Log_Printf("geEngine_CreateWorldLightmapTHandles:Created %d of %d\n",CreatedCount,BSPData->NumGFXFaces);
01122 #endif
01123
01124 return GE_TRUE;
01125 }
01126
01127
01128
01129
01130 geBoolean geEngine_DestroyWorldLightmapTHandles(geEngine *Engine, geWorld *World)
01131 {
01132 DRV_Driver *RDriver;
01133 int32 i;
01134 World_BSP *BSP;
01135 GBSP_BSPData *BSPData;
01136 geBoolean Ret;
01137 int32 Handle1=1768710981;
01138 int32 Handle2=0x21657370;
01139 #ifdef _DEBUG
01140 int DestroyedCount = 0;
01141 #endif
01142
01143 assert(Engine);
01144 assert(World);
01145
01146 Ret = GE_TRUE;
01147
01148 BSP = World->CurrentBSP;
01149 BSPData = &BSP->BSPData;
01150 RDriver = Engine->DriverInfo.RDriver;
01151
01152
01153
01154
01155 World_SetEngine(Engine);
01156 World_SetWorld(World);
01157 World_SetGBSP(World->CurrentBSP);
01158
01159 for (i=0; i<BSPData->NumGFXFaces; i++)
01160 {
01161 DRV_LInfo *pLInfo;
01162
01163 pLInfo = &BSP->SurfInfo[i].LInfo;
01164
01165 if ((pLInfo->Face == -1))
01166 continue;
01167
01168 if (!(BSP->SurfInfo[i].Flags & SURFINFO_LIGHTMAP))
01169 continue;
01170
01171 if (!pLInfo->THandle)
01172 continue;
01173
01174 if (!RDriver->THandle_Destroy(pLInfo->THandle))
01175 Ret = GE_FALSE;
01176
01177 pLInfo->THandle = NULL;
01178
01179 #ifdef _DEBUG
01180 DestroyedCount ++;
01181 #endif
01182 }
01183
01184 #ifdef _DEBUG
01185 Log_Printf("geEngine_DestroyWorldLightmapTHandles: Freed %d of %d\n",DestroyedCount,BSPData->NumGFXFaces);
01186 #endif
01187
01188 return Ret;
01189 }
01190
01191
01192
01193
01194 geBoolean geEngine_AttachAllWorlds(geEngine *Engine)
01195 {
01196 int32 i;
01197 DRV_Driver *RDriver;
01198
01199 assert(Engine);
01200
01201 RDriver = Engine->DriverInfo.RDriver;
01202
01203 for (i=0; i< Engine->NumWorlds; i++)
01204 {
01205 if (!geWorld_AttachAll(Engine->Worlds[i], RDriver, Engine->BitmapGamma ))
01206 {
01207 geErrorLog_AddString(-1, "geEngine_AttachAllWorlds: geWorld_AttachAll failed.", NULL);
01208 return GE_FALSE;
01209 }
01210
01211 if (!geEngine_CreateWorldLightmapTHandles(Engine, Engine->Worlds[i]))
01212 {
01213 geErrorLog_AddString(-1, "geEngine_AttachAllWorlds: geEngine_CreateWorldLightmapTHandles failed.", NULL);
01214 return GE_FALSE;
01215 }
01216
01217 }
01218
01219 return GE_TRUE;
01220 }
01221
01222
01223
01224
01225 geBoolean geEngine_AttachAll(geEngine *Engine)
01226 {
01227 DRV_Driver *RDriver;
01228
01229 assert( Engine );
01230
01231 RDriver = Engine->DriverInfo.RDriver;
01232 assert( RDriver );
01233
01234
01235 if (!Engine->DriverInfo.Active)
01236 return GE_TRUE;
01237
01238
01239 if (!BitmapList_AttachAll(Engine->AttachedBitmaps, RDriver, Engine->BitmapGamma))
01240 {
01241 geErrorLog_AddString(-1, "geEngine_AttachAll: BitmapList_AttachAll for Engine failed...", NULL);
01242 return GE_FALSE;
01243 }
01244
01245
01246 if (!geEngine_AttachAllWorlds(Engine))
01247 {
01248 geErrorLog_AddString(-1, "geEngine_AttachAll: geEngine_AttachAllWorlds failed.", NULL);
01249 return GE_FALSE;
01250 }
01251
01252 return GE_TRUE;
01253 }
01254
01255
01256
01257
01258 geBoolean geEngine_DetachAll(geEngine *Engine)
01259 {
01260 assert(Engine);
01261
01262
01263 if (!BitmapList_DetachAll(Engine->AttachedBitmaps))
01264 {
01265 geErrorLog_AddString(-1, "geEngine_DetachAll: BitmapList_DetachAll failed for engine.", NULL);
01266 return GE_FALSE;
01267 }
01268
01269
01270 if (!geEngine_DetachAllWorlds(Engine))
01271 {
01272 geErrorLog_AddString(-1, "geEngine_DetachAll: geEngine_DetachAllWorlds failed for engine.", NULL);
01273 return GE_FALSE;
01274 }
01275
01276 return GE_TRUE;
01277 }
01278
01279
01280
01281
01282 geBoolean geEngine_ResetDriver(geEngine *Engine)
01283 {
01284 assert(Engine != NULL);
01285 assert(Engine->DriverInfo.RDriver);
01286
01287
01288 if (!geEngine_DetachAll(Engine))
01289 {
01290 geErrorLog_AddString(-1, "geEngine_ResetDriver: geEngine_DetachAll failed.", NULL);
01291 return GE_FALSE;
01292 }
01293
01294
01295 if (!Engine->DriverInfo.RDriver->Reset())
01296 {
01297 geErrorLog_AddString(-1, "geEngine_ResetDriver: Engine->DriverInfo.RDriver->Reset() failed.", NULL);
01298 return GE_FALSE;
01299 }
01300
01301 geEngine_UpdateFogEnable(Engine);
01302
01303 return GE_TRUE;
01304 }
01305
01306
01307
01308
01309 geBoolean geEngine_InitFonts(geEngine *Engine)
01310 {
01311 Sys_FontInfo *Fi;
01312
01313 assert(Engine);
01314
01315 Fi = &Engine->FontInfo;
01316
01317 assert(Fi->FontBitmap == NULL);
01318
01319
01320 {
01321 geVFile * MemFile;
01322 geVFile_MemoryContext Context;
01323
01324 {
01325 extern unsigned char font_bmp[];
01326 extern int font_bmp_length;
01327
01328 Context.Data = font_bmp;
01329 Context.DataLength = font_bmp_length;
01330
01331 MemFile = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_MEMORY, NULL, &Context, GE_VFILE_OPEN_READONLY);
01332 }
01333
01334 if (!MemFile)
01335 {
01336 geErrorLog_AddString(-1,"InitFonts : geVFile_OpenNewSystem Memory fontbmp failed.", NULL);
01337 return GE_FALSE;
01338 }
01339
01340 if ( ! (Fi->FontBitmap = geBitmap_CreateFromFile(MemFile)) )
01341 {
01342 geErrorLog_AddString(-1,"InitFonts : geBitmap_CreateFromFile failed.", NULL);
01343 goto fail;
01344 }
01345
01346 #if 0
01347 #pragma message("Engine : fonts will have alpha once Decals do : CB");
01348
01349
01350 {
01351 geBitmap * FontAlpha;
01352 FontAlpha = geBitmap_Create( geBitmap_Width(Fi->FontBitmap), geBitmap_Height(Fi->FontBitmap), 1, GE_PIXELFORMAT_8BIT_GRAY );
01353 if ( FontAlpha )
01354 {
01355 if ( geBitmap_BlitBitmap(Fi->FontBitmap,FontAlpha) )
01356 {
01357 if ( ! geBitmap_SetAlpha( Fi->FontBitmap, FontAlpha ) )
01358 {
01359 geErrorLog_AddString(-1,"InitFonts : SetAlpha failed : non-fatal", NULL);
01360 }
01361 }
01362 else
01363 {
01364 geErrorLog_AddString(-1,"InitFonts : BlitBitmap failed : non-fatal", NULL);
01365 }
01366 geBitmap_Destroy(&FontAlpha);
01367 }
01368 }
01369 #endif
01370
01371 if (!geBitmap_SetColorKey(Fi->FontBitmap, GE_TRUE, 0, GE_FALSE))
01372 {
01373 geErrorLog_AddString(-1,"InitFonts : geBitmap_SetColorKey failed.", NULL);
01374 goto fail;
01375 }
01376
01377 if ( ! geEngine_AddBitmap(Engine,Fi->FontBitmap) )
01378 {
01379 geErrorLog_AddString(-1,"InitFonts : geEngine_AddBitmap failed.", NULL);
01380 goto fail;
01381 }
01382
01383 goto success;
01384
01385 fail:
01386
01387 geVFile_Close(MemFile);
01388 return GE_FALSE;
01389
01390 success:
01391
01392 geVFile_Close(MemFile);
01393 }
01394
01395
01396
01397
01398 {
01399 int PosX, PosY, Width, i;
01400
01401 PosX = 0;
01402 PosY = 0;
01403 Width = 128*8;
01404
01405 for (i=0; i< 128; i++)
01406 {
01407 Fi->FontLUT1[i] = (PosX<<16) | PosY;
01408 PosX+=8;
01409
01410 if (PosX >= Width)
01411 {
01412 PosY += 14;
01413 PosX = 0;
01414 }
01415 }
01416 }
01417
01418 return GE_TRUE;
01419 }
01420
01421
01422
01423
01424 geBoolean geEngine_ShutdownFonts(geEngine *Engine)
01425 {
01426 Sys_FontInfo *Fi;
01427
01428 assert(Engine);
01429
01430 Fi = &Engine->FontInfo;
01431
01432 if (Fi->FontBitmap)
01433 {
01434 if (!geEngine_RemoveBitmap(Engine, Fi->FontBitmap))
01435 {
01436 geErrorLog_AddString(-1, "geEngine_ShutdownFonts: geEngine_RemoveBitmap failed.", NULL);
01437 return GE_FALSE;
01438 }
01439
01440 geBitmap_Destroy(&Fi->FontBitmap);
01441 }
01442
01443 return GE_TRUE;
01444 }
01445
01446
01447
01448
01449
01450 void geEngine_SetAllWorldChangedFlag(geEngine *Engine, geBoolean Flag)
01451 {
01452 int32 i;
01453
01454 for (i=0; i< Engine->NumWorlds; i++)
01455 Engine->Worlds[i]->Changed = Flag;
01456 }
01457
01458
01459
01460
01461
01462 HINSTANCE geEngine_LoadLibrary( const char * lpLibFileName, const char *DriverDirectory)
01463 {
01464 char Buff[_MAX_PATH];
01465 char *StrEnd;
01466 HINSTANCE Library;
01467
01468
01469 strcpy(Buff, DriverDirectory);
01470 StrEnd = Buff + strlen(Buff) - 1;
01471 if ( *StrEnd != '\\' && *StrEnd != '/' && *StrEnd != ':' )
01472 {
01473 strcat(Buff,"\\");
01474 }
01475 strcat(Buff, lpLibFileName);
01476 Library = LoadLibrary(Buff);
01477 if ( Library )
01478 return Library;
01479
01480 #pragma message("Engine : LoadLibrary : need geConfig_GetDriverDir")
01481 #ifdef LOADLIBRARY_HARDCODES
01482 #pragma message("Engine : using LoadLibrary HardCodes : curdir, q:\\genesis, c:\\genesis")
01483
01484
01485
01486 getcwd(Buff,_MAX_PATH);
01487 StrEnd = Buff + strlen(Buff) - 1;
01488 if ( *StrEnd != '\\' && *StrEnd != '/' && *StrEnd != ':' )
01489 {
01490 strcat(Buff,"\\");
01491 }
01492 strcat(Buff, lpLibFileName);
01493 Library = LoadLibrary(Buff);
01494 if ( Library )
01495 return Library;
01496
01497
01498
01499 strcpy(Buff, "q:\\genesis");
01500 StrEnd = Buff + strlen(Buff) - 1;
01501 if ( *StrEnd != '\\' && *StrEnd != '/' && *StrEnd != ':' )
01502 {
01503 strcat(Buff,"\\");
01504 }
01505 strcat(Buff, lpLibFileName);
01506 Library = LoadLibrary(Buff);
01507 if ( Library )
01508 return Library;
01509
01510
01511
01512 strcpy(Buff, "c:\\genesis");
01513 StrEnd = Buff + strlen(Buff) - 1;
01514 if ( *StrEnd != '\\' && *StrEnd != '/' && *StrEnd != ':' )
01515 {
01516 strcat(Buff,"\\");
01517 }
01518 strcat(Buff, lpLibFileName);
01519 Library = LoadLibrary(Buff);
01520 if ( Library )
01521 return Library;
01522 #endif
01523
01524 return NULL;
01525 }
01526
01527
01528 extern GInfo GlobalInfo;
01529
01530
01531
01532
01533
01534 static geBoolean Engine_InitDriver( geEngine *Engine,
01535 geDriver *Driver,
01536 geDriver_Mode *DriverMode)
01537 {
01538 Sys_DriverInfo *DrvInfo;
01539 DRV_Hook *Hook;
01540 DRV_DriverHook DLLDriverHook;
01541 DRV_Driver *RDriver;
01542
01543 assert(Engine != NULL);
01544 assert(Driver != NULL);
01545 assert(DriverMode != NULL);
01546
01547 DrvInfo = &Engine->DriverInfo;
01548
01549
01550
01551
01552 if (! geEngine_ShutdownDriver(Engine))
01553 {
01554 geErrorLog_AddString(-1, "Engine_InitDriver: geEngine_ShutdownDriver failed.", NULL);
01555 return GE_FALSE;
01556 }
01557
01558 if (DrvInfo->Active)
01559 {
01560 geErrorLog_Add(GE_ERR_DRIVER_ALLREADY_INITIALIZED, NULL);
01561 return GE_FALSE;
01562 }
01563
01564 DrvInfo->CurDriver = Driver;
01565 DrvInfo->CurMode = DriverMode;
01566
01567 DrvInfo->DriverHandle = geEngine_LoadLibrary(Driver->FileName, Engine->DriverDirectory);
01568
01569 if (!DrvInfo->DriverHandle)
01570 {
01571 geErrorLog_Add(GE_ERR_DRIVER_NOT_FOUND, NULL);
01572 return GE_FALSE;
01573 }
01574
01575 #ifdef LINK_STATIC_DRIVER
01576 {
01577 extern BOOL DriverHook(DRV_Driver **Driver);
01578 Hook = (DRV_Hook*)DriverHook;
01579 }
01580 #else
01581 Hook = (DRV_Hook*)GetProcAddress(DrvInfo->DriverHandle, "DriverHook");
01582 #endif
01583
01584 if (!Hook)
01585 {
01586 geErrorLog_Add(GE_ERR_INVALID_DRIVER, NULL);
01587 return GE_FALSE;
01588 }
01589
01590 if (!Hook(&DrvInfo->RDriver))
01591 {
01592 DrvInfo->RDriver = NULL;
01593 geErrorLog_Add(GE_ERR_INVALID_DRIVER, NULL);
01594 return GE_FALSE;
01595 }
01596
01597
01598 RDriver = DrvInfo->RDriver;
01599
01600 if (RDriver->VersionMajor != DRV_VERSION_MAJOR || RDriver->VersionMinor != DRV_VERSION_MINOR)
01601 {
01602 geErrorLog_Add(GE_ERR_INVALID_DRIVER, NULL);
01603 return GE_FALSE;
01604 }
01605
01606
01607 RDriver->SetupLightmap = Light_SetupLightmap;
01608 RDriver->GlobalInfo = &GlobalInfo;
01609
01610 strcpy(DLLDriverHook.AppName, Engine->AppName);
01611
01612
01613
01614
01615
01616 DLLDriverHook.Driver = Driver->Id;
01617 strcpy(DLLDriverHook.DriverName, Driver->Name);
01618 DLLDriverHook.Mode = DriverMode->Id;
01619 DLLDriverHook.Width = DriverMode->Width;
01620 DLLDriverHook.Height = DriverMode->Height;
01621 DLLDriverHook.hWnd = Engine->hWnd;
01622 strcpy(DLLDriverHook.ModeName, DriverMode->Name);
01623
01624 if (!RDriver->Init(&DLLDriverHook))
01625 {
01626 geErrorLog_Add(GE_ERR_DRIVER_INIT_FAILED, NULL);
01627 geErrorLog_AddString(-1, RDriver->LastErrorStr , NULL);
01628 return GE_FALSE;
01629 }
01630
01631 DrvInfo->Active = GE_TRUE;
01632
01633 Engine_SetupPixelFormats(Engine);
01634
01635 Engine->Changed = GE_TRUE;
01636
01637 return GE_TRUE;
01638 }
01639
01640
01641
01642
01643 static geBoolean geEngine_Prep(geEngine *Engine)
01644 {
01645 geBoolean WorldChanged;
01646 int32 i;
01647
01648 assert(Engine);
01649
01650
01651 WorldChanged = GE_FALSE;
01652
01653 for (i=0; i< Engine->NumWorlds; i++)
01654 {
01655 if (Engine->Worlds[i]->Changed)
01656 WorldChanged = GE_TRUE;
01657 }
01658
01659
01660 if (!WorldChanged && !Engine->Changed)
01661 return GE_TRUE;
01662
01663
01664 if (!geEngine_ResetDriver(Engine))
01665 {
01666 geErrorLog_AddString(-1,"geEngine_Prep : geEngine_ResetDriver", NULL);
01667 return GE_FALSE;
01668 }
01669
01670
01671 if (!geEngine_AttachAll(Engine))
01672 {
01673 geErrorLog_AddString(-1,"geEngine_Prep : geEngine_AttachAll failed", NULL);
01674 return GE_FALSE;
01675 }
01676
01677
01678 geEngine_SetAllWorldChangedFlag(Engine, GE_FALSE);
01679 Engine->Changed = GE_FALSE;
01680
01681 return GE_TRUE;
01682 }
01683
01684
01685
01686
01687 GENESISAPI geBoolean geEngine_RenderWorld(geEngine *Engine, geWorld *World, geCamera *Camera, geFloat Time)
01688 {
01689 Sys_DriverInfo *DInfo;
01690 int32 Width, Height;
01691
01692 assert(Engine != NULL);
01693 assert(World != NULL);
01694 assert(Camera != NULL);
01695
01696 assert(geEngine_HasWorld(Engine, World) == GE_TRUE);
01697
01698 assert(Engine->Changed == GE_FALSE);
01699 assert(World->Changed == GE_FALSE);
01700
01701 if (!World || !Camera)
01702 {
01703 geErrorLog_Add(GE_ERR_INVALID_PARMS, NULL);
01704 return GE_FALSE;
01705 }
01706
01707 DInfo = &Engine->DriverInfo;
01708
01709
01710 assert(DInfo->CurMode);
01711
01712 Width = DInfo->CurMode->Width;
01713 Height = DInfo->CurMode->Height;
01714
01715 if (Width != -1 && Height != -1)
01716 {
01717 geFloat CameraWidth,CameraHeight;
01718
01719 geCamera_GetWidthHeight(Camera,&CameraWidth,&CameraHeight);
01720
01721 if (CameraWidth > Width || CameraHeight > Height)
01722 {
01723 geErrorLog_Add(GE_ERR_INVALID_CAMERA, NULL);
01724 return GE_FALSE;
01725 }
01726 }
01727
01728 if (!World_WorldRenderQ(Engine, World, Camera))
01729 return GE_FALSE;
01730
01731 return GE_TRUE;
01732 }
01733
01734
01735
01736
01737 GENESISAPI geBoolean geEngine_BeginFrame(geEngine *Engine, geCamera *Camera, geBoolean ClearScreen)
01738 {
01739 RECT DrvRect, *pDrvRect;
01740 geRect gDrvRect;
01741
01742 assert(Engine != NULL);
01743
01744 assert(Engine->FrameState == FrameState_None);
01745
01746 Engine->FrameState = FrameState_Begin;
01747
01748
01749 if (!Engine->DriverInfo.Active)
01750 {
01751 geErrorLog_Add(GE_ERR_DRIVER_NOT_INITIALIZED, NULL);
01752 return GE_FALSE;
01753 }
01754
01755 assert(Engine->DriverInfo.RDriver != NULL);
01756
01757
01758 if (!geEngine_Prep(Engine))
01759 return FALSE;
01760
01761
01762 QueryPerformanceCounter(&Engine->CurrentTic);
01763
01764
01765 memset(&Engine->DebugInfo, 0, sizeof(Engine->DebugInfo));
01766
01767 if(Camera)
01768 {
01769 geCamera_GetClippingRect(Camera, &gDrvRect);
01770
01771 DrvRect.left =gDrvRect.Left;
01772 DrvRect.top =gDrvRect.Top;
01773 DrvRect.right =gDrvRect.Right;
01774 DrvRect.bottom =gDrvRect.Bottom;
01775
01776 pDrvRect = &DrvRect;
01777 }
01778 else
01779 pDrvRect = NULL;
01780
01781 if (!Engine->DriverInfo.RDriver->BeginScene( ClearScreen , TRUE, pDrvRect))
01782 {
01783 geErrorLog_Add(GE_ERR_DRIVER_BEGIN_SCENE_FAILED, NULL);
01784 return GE_FALSE;
01785 }
01786
01787 return GE_TRUE;
01788 }
01789
01790 extern int32 NumExactCast;
01791 extern int32 NumBBoxCast;
01792 extern int32 NumGetContents;
01793
01794
01795
01796
01797 GENESISAPI geBoolean geEngine_EndFrame(geEngine *Engine)
01798 {
01799 LARGE_INTEGER NowTic, DeltaTic;
01800 geFloat Fps;
01801
01802
01803 assert(Engine != NULL);
01804
01805 assert(Engine->FrameState == FrameState_Begin);
01806
01807 Engine->FrameState = FrameState_None;
01808
01809 if (!Engine->DriverInfo.Active)
01810 {
01811 geErrorLog_Add(GE_ERR_DRIVER_NOT_INITIALIZED, NULL);
01812 return GE_FALSE;
01813 }
01814
01815 assert(Engine->DriverInfo.RDriver != NULL);
01816
01817
01818
01819
01820 Engine_DrawFontBuffer(Engine);
01821
01822 if (!Engine->DriverInfo.RDriver->EndScene())
01823 {
01824 geErrorLog_Add(GE_ERR_DRIVER_END_SCENE_FAILED, NULL);
01825 return GE_FALSE;
01826 }
01827
01828 QueryPerformanceCounter(&NowTic);
01829
01830
01831 SubLarge(&Engine->CurrentTic, &NowTic, &DeltaTic);
01832
01833 if (DeltaTic.LowPart > 0)
01834 Fps = (geFloat)Engine->CPUInfo.Freq / (geFloat)DeltaTic.LowPart;
01835 else
01836 Fps = 100.0f;
01837
01838 if (Engine->DisplayFrameRateCounter == GE_TRUE)
01839 {
01840 #define MAX_FPS_ARRAY 20
01841
01842 geFloat AverageFps;
01843
01844 static geFloat FpsArray[MAX_FPS_ARRAY];
01845 static int32 NumFps = 0, i;
01846
01847
01848 FpsArray[(NumFps++) % MAX_FPS_ARRAY] = Fps;
01849
01850 for (AverageFps = 0.0f, i=0; i<MAX_FPS_ARRAY; i++)
01851 AverageFps += FpsArray[i];
01852
01853 AverageFps *= (1.0f/(geFloat)MAX_FPS_ARRAY);
01854
01855
01856 Engine->DebugInfo.RenderedPolys = Engine->DriverInfo.RDriver->NumRenderedPolys;
01857
01858 geEngine_Printf(Engine, 2,2+15*0, "Fps : %2.2f / %2.2f", Fps, AverageFps);
01859 geEngine_Printf(Engine, 2,2+15*1, "Polys : %4i/%4i/%4i", Engine->DebugInfo.TraversedPolys, Engine->DebugInfo.SentPolys, Engine->DebugInfo.RenderedPolys);
01860
01861 geEngine_Printf(Engine, 2,2+15*2, "Mirrors: %3i", Engine->DebugInfo.NumMirrors);
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876 geEngine_Printf(Engine, 2,2+15*3, "Actors : %3i, Models: %3i", Engine->DebugInfo.NumActors, Engine->DebugInfo.NumModels);
01877 geEngine_Printf(Engine, 2,2+15*4, "DLights: %3i", Engine->DebugInfo.NumDLights);
01878 geEngine_Printf(Engine, 2,2+15*5, "Fog : %3i", Engine->DebugInfo.NumFog);
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898 }
01899
01900
01901 Engine_Tick(Engine);
01902
01903 return GE_TRUE;
01904 }
01905
01906
01907
01908
01909 static void Engine_Tick(geEngine *Engine)
01910 {
01911 int32 i;
01912
01913 for (i=0; i< 20; i++)
01914 {
01915 if (Engine->WaveDir[i] == 1)
01916 Engine->WaveTable[i] += 14;
01917 else
01918 Engine->WaveTable[i] -= 14;
01919 if (Engine->WaveTable[i] < 50)
01920 {
01921 Engine->WaveTable[i] += 14;
01922 Engine->WaveDir[i] = 1;
01923 }
01924 if (Engine->WaveTable[i] > 255)
01925 {
01926 Engine->WaveTable[i] -= 14;
01927 Engine->WaveDir[i] = 0;
01928 }
01929 }
01930 }
01931
01932
01933
01934
01935 static void Engine_DrawFontBuffer(geEngine *Engine)
01936 {
01937 geRect Rect;
01938 int32 i, x, y, w, StrLength;
01939 Sys_FontInfo *Fi;
01940 char *Str;
01941 int32 FontWidth,FontHeight;
01942
01943 Fi = &Engine->FontInfo;
01944
01945 if ( Fi->NumStrings == 0)
01946 return;
01947
01948 FontWidth = 8;
01949 FontHeight = 15;
01950
01951 for (i=0; i< Fi->NumStrings; i++)
01952 {
01953 x = Fi->ClientStrings[i].x;
01954 y = Fi->ClientStrings[i].y;
01955 Str = Fi->ClientStrings[i].String;
01956 StrLength = strlen(Str);
01957
01958 for (w=0; w< StrLength; w++)
01959 {
01960
01961
01962
01963
01964
01965
01966 Rect.Left = (Fi->FontLUT1[*Str]>>16);
01967 Rect.Right = Rect.Left + FontWidth - 1;
01968 Rect.Top = (Fi->FontLUT1[*Str]&0xffff);
01969 Rect.Bottom = Rect.Top + FontHeight - 1;
01970
01971 if ( ! geEngine_DrawBitmap(Engine, Fi->FontBitmap, &Rect, x, y) )
01972 {
01973 geEngine_Printf(Engine, 10, 50, "Could not draw font...\n");
01974 geErrorLog_AddString(-1,"DrawFontBuffer : Could not draw font...\n", NULL);
01975 }
01976
01977 x += FontWidth;
01978 Str++;
01979 }
01980 }
01981
01982 Fi->NumStrings = 0;
01983 }
01984
01985 static void SubLarge(LARGE_INTEGER *start, LARGE_INTEGER *end, LARGE_INTEGER *delta)
01986 {
01987 _asm {
01988 mov ebx,dword ptr [start]
01989 mov esi,dword ptr [end]
01990
01991 mov eax,dword ptr [esi+0]
01992 sub eax,dword ptr [ebx+0]
01993
01994 mov edx,dword ptr [esi+4]
01995 sbb edx,dword ptr [ebx+4]
01996
01997 mov ebx,dword ptr [delta]
01998 mov dword ptr [ebx+0],eax
01999 mov dword ptr [ebx+4],edx
02000 }
02001 }
02002
02003
02004
02005
02006
02007 geBoolean geEngine_Puts(geEngine *Engine, int32 x, int32 y, const char *String)
02008 {
02009 Sys_FontInfo *Fi;
02010
02011 Fi = &Engine->FontInfo;
02012
02013 if (strlen(String) > MAX_CLIENT_STRING_LEN)
02014 return GE_FALSE;
02015
02016 if (Fi->NumStrings >= MAX_CLIENT_STRINGS)
02017 return GE_FALSE;
02018
02019 strcpy(Fi->ClientStrings[Fi->NumStrings].String, String);
02020
02021 Fi->ClientStrings[Fi->NumStrings].x = x;
02022 Fi->ClientStrings[Fi->NumStrings].y = y;
02023
02024 Fi->NumStrings++;
02025
02026 return TRUE;
02027 }
02028
02029
02030
02031
02032 GENESISAPI geBoolean geEngine_Printf(geEngine *Engine, int32 x, int32 y, const char *String, ...)
02033 {
02034 va_list ArgPtr;
02035 char TempStr[1024];
02036
02037 va_start(ArgPtr, String);
02038 vsprintf(TempStr, String, ArgPtr);
02039 va_end(ArgPtr);
02040
02041 return geEngine_Puts(Engine, x, y, TempStr);
02042 }
02043
02044
02045
02046
02047
02048 static BOOL Hack_EnumCallBack(const geRDriver_PixelFormat *Format, void *Context)
02049 {
02050 geRDriver_PixelFormat ** pPixelArrayPtr;
02051 pPixelArrayPtr = Context;
02052 #if 0
02053 *(*pPixelArrayPtr)++ = *Format;
02054 #else
02055 **pPixelArrayPtr = *Format;
02056 (*pPixelArrayPtr) += 1;
02057 #endif
02058 return 1;
02059 }
02060
02061 static geRDriver_PixelFormat * Hack_FindPixelFormat(geRDriver_PixelFormat * PixelFormats,int ArrayLen,uint32 Flags,geBoolean NeedsAlpha)
02062 {
02063 int cnt;
02064 geRDriver_PixelFormat * pf;
02065
02066 for(cnt=ArrayLen,pf = PixelFormats;cnt--;pf++)
02067 {
02068 if ( ! NeedsAlpha || ( NeedsAlpha && (gePixelFormat_HasAlpha(pf->PixelFormat) || pf->Flags & RDRIVER_PF_HAS_ALPHA) ) )
02069 {
02070 if( pf->Flags == Flags )
02071 {
02072 return pf;
02073 }
02074 }
02075 }
02076 for(cnt=ArrayLen,pf = PixelFormats;cnt--;pf++)
02077 {
02078 if ( ! NeedsAlpha || ( NeedsAlpha && (gePixelFormat_HasAlpha(pf->PixelFormat) || pf->Flags & RDRIVER_PF_HAS_ALPHA) ) )
02079 {
02080 if( pf->Flags & Flags )
02081 {
02082 return pf;
02083 }
02084 }
02085 }
02086
02087 for(cnt=ArrayLen,pf = PixelFormats;cnt--;pf++)
02088 {
02089 if( pf->Flags == Flags )
02090 {
02091 return pf;
02092 }
02093 }
02094 for(cnt=ArrayLen,pf = PixelFormats;cnt--;pf++)
02095 {
02096 if( pf->Flags & Flags )
02097 {
02098 return pf;
02099 }
02100 }
02101
02102 return NULL;
02103 }
02104
02105 geBoolean Engine_SetupPixelFormats(geEngine *Engine)
02106 {
02107 geRDriver_PixelFormat PixelFormatsArray[100],*PixelArrayPtr;
02108 int PixelFormatsLen;
02109
02110 PixelArrayPtr = PixelFormatsArray;
02111
02112 Engine->DriverInfo.RDriver->EnumPixelFormats(Hack_EnumCallBack , &PixelArrayPtr);
02113
02114 PixelFormatsLen = ((uint32)PixelArrayPtr - (uint32)PixelFormatsArray)/sizeof(geRDriver_PixelFormat);
02115 assert(PixelFormatsLen > 0);
02116
02117 #define SetupPF( type, flag, alpha ) \
02118 if ( PixelArrayPtr = Hack_FindPixelFormat(PixelFormatsArray,PixelFormatsLen,flag,alpha) ) \
02119 { \
02120 Engine->PixelFormats[type] = *PixelArrayPtr; \
02121 Engine->HasPixelFormat[type] = GE_TRUE; \
02122 } \
02123 else \
02124 { \
02125 Engine->HasPixelFormat[type] = GE_FALSE; \
02126 }
02127
02128 SetupPF( ENGINE_PF_WORLD, RDRIVER_PF_COMBINE_LIGHTMAP,0);
02129 SetupPF( ENGINE_PF_LIGHTMAP, RDRIVER_PF_LIGHTMAP,0);
02130 SetupPF( ENGINE_PF_USER, RDRIVER_PF_3D,0);
02131 SetupPF( ENGINE_PF_USER_ALPHA, RDRIVER_PF_3D,1);
02132 SetupPF( ENGINE_PF_DECAL, RDRIVER_PF_2D,0);
02133 SetupPF( ENGINE_PF_PALETTE, RDRIVER_PF_PALETTE,0);
02134 SetupPF( ENGINE_PF_ALPHA_CHANNEL,RDRIVER_PF_ALPHA,0);
02135
02136 return GE_TRUE;
02137 }
02138
02139
02140
02141
02142
02143 geRDriver_THandle * Engine_CreateTHandle(geEngine *Engine,int Width,int Height,int Mips, int EngineTexType)
02144 {
02145 geRDriver_THandle * THandle;
02146
02147 if ( ! Engine->HasPixelFormat[EngineTexType] )
02148 {
02149
02150 return NULL;
02151 }
02152
02153 THandle = Engine->DriverInfo.RDriver->THandle_Create(Width,Height,Mips,&(Engine->PixelFormats[EngineTexType]));
02154
02155 if (! THandle )
02156 return NULL;
02157
02158 if ( gePixelFormat_HasPalette(Engine->PixelFormats[EngineTexType].PixelFormat) )
02159 {
02160 geRDriver_THandle * PalHandle;
02161 PalHandle = Engine->DriverInfo.RDriver->THandle_Create(256,1,1,&(Engine->PixelFormats[ENGINE_PF_PALETTE]));
02162 if ( ! PalHandle )
02163 {
02164 Engine->DriverInfo.RDriver->THandle_Destroy(THandle);
02165 return NULL;
02166 }
02167 Engine->DriverInfo.RDriver->THandle_SetPalette(THandle,PalHandle);
02168
02169 #ifdef _DEBUG
02170 {
02171 geRDriver_THandleInfo Info;
02172 (Engine->DriverInfo.RDriver)->THandle_GetInfo(PalHandle,0,&Info);
02173 assert(Info.Width == 256);
02174 assert(Info.Height == 1);
02175 }
02176 #endif
02177 }
02178
02179 if ( (Engine->PixelFormats[EngineTexType].Flags) & RDRIVER_PF_HAS_ALPHA )
02180 {
02181 geRDriver_THandle * AlphaHandle;
02182 assert( Engine->PixelFormats[ENGINE_PF_ALPHA_CHANNEL].Flags & RDRIVER_PF_ALPHA );
02183 assert( ! (Engine->PixelFormats[ENGINE_PF_ALPHA_CHANNEL].Flags & RDRIVER_PF_HAS_ALPHA) );
02184 AlphaHandle = Engine_CreateTHandle(Engine,Width,Height,Mips,ENGINE_PF_ALPHA_CHANNEL);
02185 if ( ! AlphaHandle )
02186 {
02187 Engine->DriverInfo.RDriver->THandle_Destroy(THandle);
02188 return NULL;
02189 }
02190 Engine->DriverInfo.RDriver->THandle_SetAlpha(THandle,AlphaHandle);
02191 }
02192
02193 return THandle;
02194 }
02195
02196 void Engine_DestroyTHandle(geEngine *Engine,geRDriver_THandle * THandle)
02197 {
02198 Engine->DriverInfo.RDriver->THandle_Destroy(THandle);
02199 }