Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

engine.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  Engine.c                                                                            */
00003 /*                                                                                      */
00004 /*  Author: Charles Bloom/John Pollard                                                  */
00005 /*  Description: Maintains the driver interface, as well as the bitmaps attached                */
00006 /*                                      to the driver.                                                                                                          */
00007 /*                                                                                      */
00008 /*  The contents of this file are subject to the Genesis3D Public License               */
00009 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00010 /*  compliance with the License. You may obtain a copy of the License at                */
00011 /*  http://www.genesis3d.com                                                            */
00012 /*                                                                                      */
00013 /*  Software distributed under the License is distributed on an "AS IS"                 */
00014 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00015 /*  the License for the specific language governing rights and limitations              */
00016 /*  under the License.                                                                  */
00017 /*                                                                                      */
00018 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00019 /*Genesis3D Version 1.1 released November 15, 1999                            */
00020 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00021 /*                                                                                      */
00022 /****************************************************************************************/
00023 
00024 //#define DONT_DO_SPLASH // CB hack
00025 
00026 #define WIN32_LEAN_AND_MEAN
00027 #include <windows.h>
00028 #include <mmsystem.h> //timeGetTime
00029 #include <stdlib.h> // _MAX_PATH
00030 #include <direct.h>     // getcwd
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 //#define DO_ADDREMOVE_MESSAGES
00043 #ifndef _DEBUG
00044 #undef DO_ADDREMOVE_MESSAGES
00045 #endif
00046 
00047 extern  geBoolean       DoSplashScreen(geEngine *Engine, geDriver_Mode *Mode);
00048 
00049 //============================
00050 //      Internal Protos
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 //      geEngine_SetGamma
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 //      geEngine_GetGamma
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;//Engine->DriverInfo.RDriver->GetGamma(Gamma);
00095 }
00096 
00097 //=====================================================================================
00098 //      geEngine_UpdateFogEnable
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 //      geEngine_SetFogEnable
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                 // Attach all the bitmaps for the engine
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                         // <> sleazy to peak into World like this
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 //      geEngine_BitmapListInit
00183 //      Initializes the engine bitmaplist
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 //      geEngine_BitmapListShutdown
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                 //BitmapList_DetachAll(Engine->AttachedBitmaps);
00214                 // Destroy detaches for you!
00215                 BitmapList_Destroy(Engine->AttachedBitmaps);
00216                 Engine->AttachedBitmaps = NULL;
00217         }
00218 
00219         return GE_TRUE;
00220 }
00221 
00222 //================================================================================
00223 //      geEngine_AddBitmap
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         // Add bitmap to the lit of bitmaps attached to the engine
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 //      geEngine_RemoveBitmap
00270 //================================================================================
00271 GENESISAPI geBoolean geEngine_RemoveBitmap(geEngine *Engine, geBitmap *Bitmap)
00272 {
00273         assert(Engine);
00274         assert(Bitmap);
00275         assert(Engine->AttachedBitmaps);
00276 
00277 //      assert(Engine->FrameState == FrameState_None);
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 //      DrawAlphaBitmap
00315 
00317 //  
00318 //  geEngine_DrawAlphaBitmap()
00319 //  
00320 //  Draw a btimap with alpha transparancy
00321 //  
00323 
00324 GENESISAPI geBoolean GENESISCC geEngine_DrawAlphaBitmap(        
00325                 geEngine * Engine,
00326                 geBitmap * pBitmap,
00327                 geVec3d * VertUVArray,
00328                 geCamera * ClipCamera,  // if null, uses full screen
00329                 GE_Rect * PixelRect,            // pixels in the "camera" view
00330                 GE_Rect * PercentRect,  // percent of the "camera" view
00331                 geFloat   Alpha,
00332                 GE_RGBA * RGBA_Array
00333                 )
00334 {
00335 // set up variables
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 // Clip 2d viewport
00361 //
00362 
00363 #if 0
00364 //      eaa3 01/14/2001 Right now, you have to pass the camera in.
00365 //      ..I'll fix it eventually...
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 //      geEngine_SetDriverAndMode
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         // init calls _Reset and eventually it gets down and Detaches all
00536 
00537         //      Set up the Render Driver
00538         if (!Engine_InitDriver(Engine, Driver, DriverMode))
00539                 return GE_FALSE;
00540 
00541         // Force a Driver update
00542         geEngine_SetAllWorldChangedFlag(Engine, GE_TRUE);
00543         Engine->Changed = GE_TRUE;
00544 
00545         geEngine_UpdateGamma(Engine);
00546         geEngine_UpdateFogEnable(Engine);
00547 
00548 //#ifdef DONT_DO_SPLASH
00549 #ifdef _DEBUG
00550         #pragma message("Engine :splash screen disabled")
00551         Engine = Engine;
00552 #else
00553         // Do the splash screen
00554         if      (DoSplashScreen(Engine, DriverMode) == GE_FALSE)
00555                 return GE_FALSE;
00556 #endif
00557 
00558         return GE_TRUE;
00559 }
00560 
00561 //=====================================================================================
00562 //      geEngine_GetDriverSystem
00563 //=====================================================================================
00564 GENESISAPI geDriver_System *geEngine_GetDriverSystem(geEngine *Engine)
00565 {
00566         assert(Engine);
00567 
00568         return (geDriver_System*)&Engine->DriverInfo;
00569 }
00570 
00571 //=====================================================================================
00572 //      geEngine_Activate
00573 //              this hits the drivers activation code to manage
00574 //              surfaces and exclusive modes for devices (WM_ACTIVATEAPP)
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                 // <> this can sometimes be a pain for debugging
00587                 #if 1
00588                 if ( RDriver->SetActive )
00589                         return RDriver->SetActive(bActive);
00590                 #endif
00591         }
00592 
00593         return  GE_TRUE;
00594 }
00595 
00596 //====================================================================================
00597 //      geEngine_UpdateWindow
00598 //              this call updates the drivers with a new rect to blit to
00599 //              (usually the result of a window move or resize)
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 //      geEngine_ShutdownDriver
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;                 // Just return true, and don't do nothing
00631 
00632         #if 0 // <>     
00633         #ifdef _DEBUG
00634         OutputDebugString("geEngine_ShutdownDriver\n");
00635         #endif
00636         #endif
00637 
00638         // First, reset the driver
00639         if (!geEngine_ResetDriver(Engine))
00640         {
00641                 geErrorLog_AddString(-1, "geEngine_ShutdownDriver:  geEngine_ResetDriver failed.", NULL);
00642                 return GE_FALSE;
00643         }
00644 
00645         // Shutdown the driver
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 //      geEngine_RenderPoly
00659 //              World MUST ne passed in if using a texture, as it is a container object for ALL 3d textures
00660 //              * stop passing World ?
00661 //              * cut the Flags parameter and pass in zero ?
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 //              assert(World);
00675 //              assert(geEngine_HasWorld(Engine, World) == GE_TRUE);
00676 //              assert(World->AttachedBitmaps);
00677 //              assert(BitmapList_Has(World->AttachedBitmaps, (geBitmap*)Texture) == GE_TRUE);
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 //      geEngine_DrawBitmap
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         //#pragma message("make geRect the same as RECT, or don't use RECT!?")
00745         // The drivers once did not include genesis .h's
00746         // (D3D uses RECT so thats why the drivers adopted RECT's...)
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         //Ret = Engine->DriverInfo.RDriver->Drawdecal(TH,(RECT *)Source,x,y);
00759 
00760         if (Source)             // Source CAN be NULL!!!
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 //      geEngine_RebuildFastWorldList
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 // geEngine_AddWorld
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         // Try to find it in the list first
00821         pWorldList = Engine->WorldList;
00822         for (i=0; i< ENGINE_MAX_WORLDS; i++, pWorldList++)
00823         {
00824                 if (pWorldList->World == World) // World is allready in list
00825                 {
00826                         assert(pWorldList->RefCount > 0);               // There should allready be a ref count!!!
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         // Not found, add a new one
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         // Save the info for the first time
00865         pWorldList->World = World;
00866         pWorldList->RefCount = 1;
00867 
00868         // Re-build the fast list of worlds
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 // geEngine_RemoveWorld
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         // Try to find it in the list 
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         // Decrease the reference count on the worldlist
00910         pWorldList->RefCount--;
00911 
00912         // When the ref count gos to zero, remove the world for good
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                 // Detach all the bitmaps in the world before finally removing it
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                 // Clear this pWorldList slot
00935                 memset(pWorldList, 0, sizeof(*pWorldList));
00936                 
00937                 // Re-build the fast list of worlds
00938                 geEngine_RebuildFastWorldList(Engine);
00939 
00940                 // Force an update
00941                 Engine->Changed = GE_TRUE;
00942                 
00943                 // Free the world (decrease it's reference count)
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 // geEngine_RemoveAllWorlds
00963 //====================================================================================
00964 geBoolean geEngine_RemoveAllWorlds(geEngine *Engine)
00965 {
00966         int32                           i;
00967         geEngine_WorldList      *pWorldList;
00968         geWorld                         *World;
00969 
00970         assert(Engine);
00971 
00972         // Try to find it in the list 
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                         // Free the world (decrease it's reference count)
00993                         geWorld_Free(World);
00994                 }
00995                 memset(pWorldList, 0, sizeof(*pWorldList));
00996         }
00997                 
00998         // Force an update
00999         geEngine_RebuildFastWorldList(Engine);
01000         Engine->Changed = GE_TRUE;
01001 
01002         return GE_TRUE;
01003 }
01004 
01005 //=====================================================================================
01006 //      geEngine_HasWorld
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         // Try to find it in the list 
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 //      geEngine_DetachAllWorlds
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 //      geEngine_CreateWorldLightmapTHandles
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         //      Create all the lightmap thandles
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);               // This should be true!!!
01099                 
01100                 if (pLInfo->THandle)
01101                         continue;
01102                 
01103                 Light_SetupLightmap(pLInfo, &D);
01104 
01105                 // {} _LIGHTMAP_
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 //      geEngine_DestroyWorldLightmapTHandles
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         //      Create all the lightmap thandles
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 //      geEngine_AttachAllWorlds
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 //      geEngine_AttachAll
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     // If current driver is not active, then split
01235         if (!Engine->DriverInfo.Active)
01236         return GE_TRUE;
01237 
01238         // Attach all the bitmaps for the engine
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         // Attach all the bitmaps for the world
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 //      geEngine_DetachAll
01257 //=====================================================================================
01258 geBoolean geEngine_DetachAll(geEngine *Engine)
01259 {
01260         assert(Engine);
01261 
01262         // Shutdown all the geBitmaps
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         // Detach all the bitmaps that belong to all the currently connected worlds
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 //      geEngine_ResetDriver
01281 //=====================================================================================
01282 geBoolean geEngine_ResetDriver(geEngine *Engine)
01283 {
01284         assert(Engine != NULL);
01285         assert(Engine->DriverInfo.RDriver);
01286 
01287         // To be safe, detach all things from the current driver
01288         if (!geEngine_DetachAll(Engine))
01289         {
01290                 geErrorLog_AddString(-1, "geEngine_ResetDriver:  geEngine_DetachAll failed.", NULL);
01291                 return GE_FALSE;
01292         }
01293 
01294         // Reset the driver
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 //      geEngine_InitFonts
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         // Load the bitmap
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                 // <> CB : give fonts alpha so they look purty
01349                 //                      pointless right now cuz we don't get enum'ed a _2D_ type with alpha
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         //      Setup font lookups
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 //      geEngine_ShutdownFonts
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 //      geEngine_SetAllWorldChangedFlag
01448 //      Forces all worlds to be uploaded to the card again
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 //      geEngine_LoadLibrary
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;                // AHH!!!  Get rid of this!!!
01529 
01530 //=====================================================================================
01531 //      EngineInitDriver
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         //#pragma message("Engine : DriverMode is changing, do Bitmap re-attaches")
01550         // _Shutdown calls _Reset which detaches all
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         // Get a handy pointer to the driver
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         // We MUST set this! So driver can setup lightmap data when needed...
01607         RDriver->SetupLightmap = Light_SetupLightmap;
01608         RDriver->GlobalInfo = &GlobalInfo;
01609 
01610         strcpy(DLLDriverHook.AppName, Engine->AppName);
01611 
01612         //
01613         //      Setup what driver they want
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); // <> temp hack
01634 
01635         Engine->Changed = GE_TRUE;
01636 
01637         return GE_TRUE;
01638 }
01639 
01640 //=====================================================================================
01641 //      geEngine_Prep
01642 //=====================================================================================
01643 static  geBoolean geEngine_Prep(geEngine *Engine)
01644 {
01645         geBoolean               WorldChanged;
01646         int32                   i;
01647 
01648         assert(Engine);
01649 
01650         // See if any of the attached worlds has changed...
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         // Check to see if the world has changed
01660         if (!WorldChanged && !Engine->Changed)          
01661                 return GE_TRUE;         // Nothing to do if any of the worlds (and engine) has not changed
01662 
01663         // Throw everything off the card...
01664         if (!geEngine_ResetDriver(Engine))
01665         {
01666                 geErrorLog_AddString(-1,"geEngine_Prep : geEngine_ResetDriver", NULL);
01667                 return GE_FALSE;
01668         }
01669         
01670         // Attach all the current bitmaps to the current driver
01671         if (!geEngine_AttachAll(Engine))
01672         {
01673                 geErrorLog_AddString(-1,"geEngine_Prep : geEngine_AttachAll failed", NULL);
01674                 return GE_FALSE;
01675         }
01676         
01677         // Reset all the changed flags
01678         geEngine_SetAllWorldChangedFlag(Engine, GE_FALSE);
01679         Engine->Changed = GE_FALSE;
01680         
01681         return GE_TRUE;
01682 }
01683 
01684 //=====================================================================================
01685 //      geEngine_RenderWorld
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);    // You have to add the world to the engine before rendering!
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         // This must not be NULL, or there is not a true current driver mode set
01710         assert(DInfo->CurMode);
01711 
01712         Width = DInfo->CurMode->Width;
01713         Height = DInfo->CurMode->Height;
01714 
01715         if (Width != -1 && Height != -1)                // If not in window mode...
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 //      geEngine_BeginFrame
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         // Make sure the driver is avtive
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         // Make sure we have everything finalized with this world so the engine can render it
01758         if (!geEngine_Prep(Engine))
01759                 return FALSE;
01760 
01761         // Do some timing stuff
01762         QueryPerformanceCounter(&Engine->CurrentTic);
01763 
01764         // Clear some debug info
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 //      geEngine_EndFrame
01796 //===================================================================================
01797 GENESISAPI geBoolean geEngine_EndFrame(geEngine *Engine)
01798 {
01799         LARGE_INTEGER           NowTic, DeltaTic;
01800         geFloat                         Fps;
01801         //DRV_Debug                     *Debug;
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         //Debug = (DRV_Debug*)Engine->DriverInfo.RDriver->LoadMiscTexture;
01818         //geEngine_Printf(Engine, 2, 20, "LMap Cycles = %i", Debug->LMapCount[0][0]);
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         //CurrentFrequency = ((geFloat)PR_EntireFrame.ElapsedCycles/200.0f)
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)                 // Dieplay debug info
01839         {
01840                 #define                         MAX_FPS_ARRAY           20
01841 
01842                 geFloat                         AverageFps;
01843                 //DRV_CacheInfo         *pCacheInfo;
01844                 static geFloat          FpsArray[MAX_FPS_ARRAY];
01845                 static int32            NumFps = 0, i;
01846 
01847                 // Changed Average Fps to go accross last n frames, JP...
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                 // Grab some driver debug info
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                 pCacheInfo = Engine->DriverInfo.RDriver->CacheInfo;
01864 
01865                 if (pCacheInfo)
01866                 {
01867                         geEngine_Printf(Engine, 2, 2+15*3, "Cache:  %4i/%4i/%4i/%4i/%4i", 
01868                                                                                         pCacheInfo->CacheFull,
01869                                                                                         pCacheInfo->CacheRemoved,
01870                                                                                         pCacheInfo->CacheFlushes,
01871                                                                                         pCacheInfo->TexMisses,
01872                                                                                         pCacheInfo->LMapMisses);
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 //              geEngine_Printf(Engine, 2,2+15*7, "LMap1  : %3i, LMap2  : %3i", Engine->DebugInfo.LMap1, Engine->DebugInfo.LMap2);
01880 /*
01881                 // For now, just display debug info for the first world...
01882                 if (Engine->NumWorlds)
01883                 {
01884                         geWorld_DebugInfo       *Info;
01885                         
01886                         Info = &Engine->Worlds[0]->DebugInfo;
01887                         geEngine_Printf(Engine, 2, 2+15*8, "Nodes: %3i/%3i, Leafs: %3i/%3i, Userp: %3i/%3i", Info->NumNodesTraversed1, Info->NumNodesTraversed2, Info->NumLeafsHit1, Info->NumLeafsHit2, Info->NumLeafsWithUserPolys, Info->NumUserPolys);
01888                         geEngine_Printf(Engine, 2, 2+15*9, "Cast: %3i/%3i, GetC: %3i: %i",  NumExactCast, NumBBoxCast, NumGetContents);
01889 
01890                         memset(Info, 0, sizeof(*Info));
01891 
01892                         NumExactCast = 0;
01893                         NumBBoxCast = 0;
01894                         NumGetContents = 0;
01895 
01896                 }
01897 */
01898         }
01899 
01900         // Do an engine frame
01901         Engine_Tick(Engine);
01902 
01903         return GE_TRUE;
01904 }
01905 
01906 //===================================================================================
01907 //      Engine_Tick
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 //      Engine_DrawFontBuffer
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                         Rect.left = (Fi->FontLUT1[*Str]>>16)+1;
01962                         Rect.right = Rect.left+16;
01963                         Rect.top = (Fi->FontLUT1[*Str]&0xffff)+1;
01964                         Rect.bottom = Rect.top+16;
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                         //x+= 16;
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 // geEngine_Puts
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 //      geEngine_Printf
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 //      Engine_CreateTHandle
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                 //{} assert( Engine->HasPixelFormat[EngineTexType] );
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 }

Generated on Tue Sep 30 12:35:41 2003 for GTestAndEngine by doxygen 1.3.2