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

Client.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  Client.c                                                                            */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description:                                                                        */
00006 /*                                                                                      */
00007 /*  Copyright (c) 1997, 1999, Eclipse Entertainment; All rights reserved.               */
00008 /*                                                                                      */
00009 /*  See the accompanying file LICENSE.TXT for terms on the use of this library.         */
00010 /*  This library is distributed in the hope that it will be useful but WITHOUT          */
00011 /*  ANY WARRANTY OF ANY KIND and without any implied warranty of MERCHANTABILITY        */
00012 /*  or FITNESS FOR ANY PURPOSE.  Refer to LICENSE.TXT for more details.                 */
00013 /*                                                                                      */
00014 /****************************************************************************************/
00015 #include <Windows.h>
00016 #include <Assert.h>
00017 #include <Math.h>
00018 
00019 #include "Client.h"
00020 
00021 #include "Buffer.h"
00022 #include "Gmenu.h"
00023 #include "cd.h"
00024 
00025 LARGE_INTEGER                   g_Freq, g_OldTick, g_CurTick;
00026 
00027 #define NUM_AVG                 10
00028 static float                    AvgTime[NUM_AVG];
00029 static int32                    CurAvg;
00030 
00031 static void SubLarge(LARGE_INTEGER *start, LARGE_INTEGER *end, LARGE_INTEGER *delta)
00032 {
00033         _asm {
00034                 mov ebx,dword ptr [start]
00035                 mov esi,dword ptr [end]
00036 
00037                 mov eax,dword ptr [esi+0]
00038                 sub eax,dword ptr [ebx+0]
00039 
00040                 mov edx,dword ptr [esi+4]
00041                 sbb edx,dword ptr [ebx+4]
00042 
00043                 mov ebx,dword ptr [delta]
00044                 mov dword ptr [ebx+0],eax
00045                 mov dword ptr [ebx+4],edx
00046         }
00047 }
00048 
00049 #define BEGIN_TIMER()           QueryPerformanceCounter(&g_OldTick)
00050                                 
00051 #define END_TIMER(g)                                                                                    \
00052                                 {                                                                                               \
00053                                         LARGE_INTEGER   DeltaTick;                                      \
00054                                         float                   ElapsedTime, Total;                     \
00055                                         int32                   i;                                                      \
00056                                                                                                                                 \
00057                                         QueryPerformanceCounter(&g_CurTick);            \
00058                                         SubLarge(&g_OldTick, &g_CurTick, &DeltaTick);   \
00059                                                                                                                                 \
00060                                         if (DeltaTick.LowPart > 0)                                      \
00061                                                 ElapsedTime =  1.0f / (((float)g_Freq.LowPart / (float)DeltaTick.LowPart));             \
00062                                         else                                                                            \
00063                                                 ElapsedTime = 0.001f;                                   \
00064                                                                                                                                 \
00065                                         AvgTime[CurAvg] = ElapsedTime;                          \
00066                                         CurAvg++;                                                                       \
00067                                         CurAvg %= NUM_AVG;                                                      \
00068                                                                                                                                 \
00069                                         for (Total = 0.0f, i=0; i< NUM_AVG; i++)        \
00070                                                 Total += AvgTime[i];                                    \
00071                                                                                                                                 \
00072                                         Total *= (1.0f/ NUM_AVG);                                       \
00073                                                                                                                                 \
00074                                         geEngine_Printf(GameMgr_GetEngine(g), 1, 50, "Timer ms: %2.3f/%2.3f", ElapsedTime, Total);      \
00075                                 }
00076 extern  geVFile *MainFS;
00077 extern  geFloat EffectScale;
00078 
00079 static  int32 NumUpdates = 0;           // For status bar updating...
00080 
00081 #ifdef _DEBUG
00082         Fx_Player *PLAYER_TO_FXPLAYER(Client_Client *Client, GPlayer *Player)
00083         {
00084                 uint32 Index;
00085 
00086                 assert(Client_IsValid(Client) == GE_TRUE);
00087                 assert(Player);
00088 
00089                 assert(Player >= Client->Players);
00090 
00091                 Index = Player - Client->Players;
00092 
00093                 assert(Index < NETMGR_MAX_PLAYERS);
00094 
00095                 return &Client->FxPlayers[Index];
00096         }
00097 
00098         Fx_Player *TEMP_PLAYER_TO_FXPLAYER(Client_Client *Client, GPlayer *Player)
00099         {
00100                 uint32 Index;
00101 
00102                 assert(Client_IsValid(Client) == GE_TRUE);
00103                 assert(Player);
00104 
00105                 assert(Player >= Client->TempPlayers);
00106 
00107                 Index = Player - Client->TempPlayers;
00108 
00109                 assert(Index < CLIENT_MAX_TEMP_PLAYERS);
00110 
00111                 return &Client->FxPlayers[Index];
00112         }
00113 
00114         uint32 CLIENT_GPLAYER_TO_INDEX(Client_Client *Client, GPlayer *Player)
00115         {
00116                 uint32          Index;
00117 
00118                 assert(Client_IsValid(Client) == GE_TRUE);
00119                 assert(Player);
00120 
00121                 assert(Player >= Client->Players);
00122                 
00123                 Index = (Player - Client->Players);
00124 
00125                 assert(Index < NETMGR_MAX_PLAYERS);
00126 
00127                 return Index;
00128         }
00129 
00130         uint32 CLIENT_TEMP_GPLAYER_TO_INDEX(Client_Client *Client, GPlayer *Player)
00131         {
00132                 uint32          Index;
00133 
00134                 assert(Client_IsValid(Client) == GE_TRUE);
00135                 assert(Player);
00136 
00137                 assert(Player >= Client->TempPlayers);
00138                 
00139                 Index = (Player - Client->TempPlayers);
00140 
00141                 assert(Index < CLIENT_MAX_TEMP_PLAYERS);
00142 
00143                 return Index;
00144         }
00145 #else
00146         #define PLAYER_TO_FXPLAYER(c, p) (&(c)->FxPlayers[(p) - (c)->Players])
00147         #define TEMP_PLAYER_TO_FXPLAYER(c, p) (&(c)->TempFxPlayers[(p) - (c)->TempPlayers])
00148         #define CLIENT_GPLAYER_TO_INDEX(c, p) ((p) - (c)->Players)
00149         #define CLIENT_TEMP_GPLAYER_TO_INDEX(c, p) ((p) - (c)->TempPlayers)
00150 #endif
00151 
00152 #define REFRESH_TIMES (4)
00153 
00154 //#define SMALL_CLIENT_CUTOFF_HEIGHT (200)
00155 #define PREDICT_CLIENT
00156 
00157 void            GenVS_Error(const char *Msg, ...);
00158 
00159 //=====================================================================================
00160 //      Local Static functions
00161 //=====================================================================================
00162 static BOOL IsKeyDown(int KeyCode, HWND hWnd);
00163 BOOL NewKeyDown(int KeyCode, HWND hWnd);
00164 geBoolean ReadServerMessages(Client_Client *Client, GameMgr *GMgr, float Time);
00165 static void UpdatePlayers(Client_Client *Client, float Time);
00166 static geBoolean RenderWorld(Client_Client *Client, GameMgr *GMgr, float Time);
00167 static void SetupCamera(geCamera *Camera, GE_Rect *Rect, geXForm3d *XForm);
00168 static void ParsePlayerDataLocally(Client_Client *Client, Buffer_Data *Buffer, geBoolean Fake);
00169 static void Client_SetupGenVSI(Client_Client *Client);
00170 static geBoolean Client_MovePlayerModel(Client_Client *Client, GPlayer *Player, const geXForm3d *DestXForm);
00171 static geBoolean CheckClientPlayerChanges(Client_Client *Client, GPlayer *Player, geBoolean TempPlayer);
00172 void Client_DestroyPlayer(Client_Client *Client, GPlayer *Player);
00173 
00174 #define M_PI    (3.14159f)
00175 #define PI_2    (M_PI*2.0f)
00176 #define M_PI2   (PI_2)
00177 
00178 uint8           SData[5000];
00179 Buffer_Data     SendBuffer;
00180 
00181 //=====================================================================================
00182 //      Client_Create
00183 //=====================================================================================
00184 Client_Client *Client_Create(   geEngine        *Engine, 
00185                                                                 Client_Mode Mode, 
00186                                                                 GameMgr         *GMgr, 
00187                                                                 NetMgr          *NMgr, 
00188                                                                 VidMode         VidMode,
00189                                                                 int32           DemoMode,
00190                                                                 const char      *DemoName,
00191                                                                 geBoolean       MultiPlayer)
00192 {
00193         geRect          Rect = {0, 0, 0, 0};
00194 
00195         Client_Client   *NewClient;
00196 
00197         NewClient = GE_RAM_ALLOCATE_STRUCT(Client_Client);
00198 
00199         assert(NewClient != NULL);
00200         
00201         if (!NewClient)
00202                 return NULL;
00203 
00204         // We can't clear the client array in SetDefaults.  Because (more)
00205         // Host_SetWorld calls Client_NewWorldDefaults, and that would clear some things like Camera, etc (more)
00206         // that need to hang around.
00207         memset(NewClient, 0, sizeof(Client_Client));
00208 
00209         // Set the sanity check signatures
00210         NewClient->Self1 = NewClient;
00211         NewClient->Self2 = NewClient;
00212 
00213         NewClient->MultiPlayer = MultiPlayer;
00214 
00215         // The client is current disconnected
00216         NewClient->NetState = NetState_Disconnected;
00217 
00218         // Save thes objects
00219         NewClient->GMgr = GMgr;
00220         NewClient->NMgr = NMgr;
00221 
00222         // Save the mode we will operate in...
00223         NewClient->Mode = Mode;
00224 
00225         // And the vidmode
00226         NewClient->VidMode = VidMode;
00227 
00228         // Set some defaults that won't effect anystate of the client
00229         Client_NewWorldDefaults(NewClient);
00230         
00231         // Set initial view xform and player
00232         geXForm3d_SetIdentity(&NewClient->ViewXForm);   
00233         NewClient->ViewPlayer = -1;
00234         NewClient->ClientPlayer = -1;
00235 
00236         NewClient->Engine = Engine;
00237 
00238         NewClient->Time = 0.0f; 
00239 
00240         NewClient->CurrentWeapon = 0;
00241 
00242         Buffer_Set(&SendBuffer, SData, 5000);
00243 
00244         // Setup the status bar...
00245         if (!Client_CreateStatusBar(NewClient, VidMode))
00246         {
00247                 geErrorLog_AddString(-1, "Client_Create:  Client_CreateStatusBar failed.", NULL);
00248                 goto ExitWithError;
00249         }
00250 
00251         // Setup the GenVSI interface
00252         Client_SetupGenVSI(NewClient);
00253 
00254         // Setup the demo system
00255         if (!Client_SetupDemos(NewClient, DemoMode, DemoName))
00256                 NewClient->Demo.Mode = CLIENT_DEMO_NONE;
00257 
00258         // Call the client main code in the game stuff
00259         Client_Main(&NewClient->GenVSI);
00260         Console_Printf(GameMgr_GetConsole(GMgr), "Client_Create:  Client_Main initialized...\n");
00261 
00262         QueryPerformanceFrequency(&g_Freq);
00263 
00264         return NewClient;
00265 
00266         ExitWithError:
00267         {
00268                 if (NewClient)
00269                 {
00270                         Client_FreeALLResources(NewClient);
00271                         Client_Destroy(NewClient);
00272                 }
00273 
00274                 return NULL;
00275         }
00276 }
00277 
00278 //=====================================================================================
00279 //      Client_Destroy
00280 //=====================================================================================
00281 void Client_Destroy(Client_Client *Client)
00282 {
00283         assert(Client_IsValid(Client) == GE_TRUE);
00284 
00285         Client_FreeALLResources(Client);
00286 
00287         if (Client->Demo.File != NULL)
00288                 fclose (Client->Demo.File);
00289 
00290         geRam_Free(Client);
00291 }
00292 
00293 
00294 //=====================================================================================
00295 //      Client_IsValid
00296 //=====================================================================================
00297 geBoolean Client_IsValid(const Client_Client *Client)
00298 {
00299         if (!Client)
00300                 return GE_FALSE;
00301 
00302         if (Client->Self1 != Client)
00303                 return GE_FALSE;
00304 
00305         if (Client->Self2 != Client)
00306                 return GE_FALSE;
00307 
00308         return GE_TRUE;
00309 }
00310 
00311 #define CONSOLE_HEIGHT_320 (30)
00312 #define CONSOLE_HEIGHT_640 (60)
00313 
00314 //=====================================================================================
00315 //      Client_CreateStatusBar
00316 //=====================================================================================
00317 geBoolean Client_CreateStatusBar(Client_Client *Client, VidMode VidMode)
00318 {
00319         int32   i, k;
00320         int     Width,Height;
00321         int     LeftElementWidth,ElementHeight,RightElementWidth,PrintOffsX,PrintOffsY,Left;
00322         char    BmpPath[MAX_PATH];
00323 
00324         assert(Client_IsValid(Client) == GE_TRUE);
00325         assert(Client->Engine);
00326 
00327         VidMode_GetResolution(VidMode,&Width,&Height);
00328         
00329         if (Width < SMALL_CONSOLE_CUTOFF_WIDTH)
00330                 {
00331                         strcpy(BmpPath,"320x240");
00332                         LeftElementWidth    = 56;
00333                         RightElementWidth   = 52;
00334                         ElementHeight       = CONSOLE_HEIGHT_320;
00335                         PrintOffsX          = 18;
00336                         PrintOffsY          = 10;
00337                         Left                            = (Width-320)/2;
00338                 }
00339         else
00340                 {
00341                         strcpy(BmpPath,"640x480");
00342                         LeftElementWidth    = 112;
00343                         RightElementWidth   = 104;
00344                         ElementHeight       = CONSOLE_HEIGHT_640;
00345                         PrintOffsX          = 36;
00346                         PrintOffsY          = 22;
00347                         Left                            = (Width-640)/2;
00348                 }
00349 
00350         for (i=0; i<6; i++)
00351                 {
00352                         if (i<2)
00353                                 {
00354                                         Client->StatusBar.Elements[i].XPos = Left + LeftElementWidth*i;
00355                                 }
00356                         else
00357                                 {
00358                                         Client->StatusBar.Elements[i].XPos = Left + LeftElementWidth*2 + RightElementWidth*(i-2);
00359                                 }
00360 
00361                         Client->StatusBar.Elements[i].YPos       = Height - 1 - ElementHeight;
00362                         Client->StatusBar.Elements[i].Print1XPos = Client->StatusBar.Elements[i].XPos + PrintOffsX;
00363                         Client->StatusBar.Elements[i].Print1YPos = Height - 1 - PrintOffsY;
00364                 }
00365 
00366 
00367         for (i=0; i<6; i++)
00368         {
00369                 for (k=0; k<3; k++)
00370                 {
00371                         char            Name[64];
00372 
00373                         sprintf(Name, "Bmp\\SBar\\%s\\SBar%i-%i.Bmp", BmpPath, i, k);
00374 
00375                         assert(Client->StatusBar.Elements[i].Bitmaps[k] == NULL);
00376                         
00377                         Client->StatusBar.Elements[i].Bitmaps[k] = geBitmap_CreateFromFileName(MainFS, Name);
00378 
00379                         if (!Client->StatusBar.Elements[i].Bitmaps[k])
00380                         {
00381                                 geErrorLog_AddString(-1, "Client_CreateStatusBar:  Could not load status bar element:", Name);
00382                                 goto ExitWithError;
00383                         }
00384 
00385                         if (!geEngine_AddBitmap(Client->Engine, Client->StatusBar.Elements[i].Bitmaps[k]))
00386                         {
00387                                 geErrorLog_AddString(-1, "Client_CreateStatusBar:  geEngine_AddBitmap failed.", NULL);
00388                                 goto ExitWithError;
00389                         }
00390 
00391                 }
00392         }
00393 
00394         return GE_TRUE;
00395 
00396         ExitWithError:
00397         {
00398                 Client_FreeALLResources(Client);
00399                 return GE_FALSE;
00400         }
00401 }
00402 
00403 //=====================================================================================
00404 //      Client_DestroyStatusBar
00405 //=====================================================================================
00406 void Client_DestroyStatusBar(Client_Client *Client)
00407 {
00408         int32           i, k;
00409 
00410         assert(Client_IsValid(Client) == GE_TRUE);
00411 
00412         // Delete the status bar bitmaps bitmaps
00413         for (i=0; i<6; i++)
00414         {
00415                 for (k=0; k<3; k++)
00416                 {
00417                         if (!Client->StatusBar.Elements[i].Bitmaps[k])
00418                                 continue;
00419 
00420                         if (!geEngine_RemoveBitmap(Client->Engine, Client->StatusBar.Elements[i].Bitmaps[k]))
00421                         {
00422                                 geErrorLog_AddString(-1, "Client_DestroyConsole:  geEngine_RemoveBitmap failed.", NULL);
00423                                 assert(0);
00424                         }
00425 
00426                         geBitmap_Destroy(&Client->StatusBar.Elements[i].Bitmaps[k]);
00427                         Client->StatusBar.Elements[i].Bitmaps[k] = NULL;
00428                 }
00429         }
00430 }
00431 
00432 //=====================================================================================
00433 //      SetPlayerDefaults
00434 //=====================================================================================
00435 static void SetPlayerDefaults(GPlayer *Player)
00436 {
00437         //memset(Player, 0, sizeof(GPlayer));
00438 
00439         Player->OldScale =
00440         Player->Scale    = 1.0f;
00441 
00442         Player->OldViewFlags = VIEW_TYPE_NONE;
00443         Player->OldViewFlags2 = VIEW_TYPE_NONE;
00444         Player->ViewFlags = VIEW_TYPE_NONE;
00445 
00446         Player->OldViewIndex = 0xffff;
00447         Player->OldViewIndex2 = 0xffff;
00448         Player->ViewIndex = 0xffff;
00449 
00450         Player->OldControlIndex = 0xffff;
00451         Player->OldTriggerIndex = 0xffff;
00452         Player->ControlIndex = 0xffff;
00453         Player->TriggerIndex = 0xffff;
00454 
00455         Player->UpdateTime = -1.0f;
00456 
00457         Player->Mesh = NULL;
00458         Player->Actor = NULL;
00459         Player->Light = NULL;
00460         Player->Poly = NULL;
00461 
00462         Player->OldMotionIndex  = 
00463         Player->MotionIndex             = GAMEMGR_MOTION_INDEX_NONE;
00464 
00465         Player->ActorDef = NULL;
00466 }
00467 
00468 //=====================================================================================
00469 //      Client_DestroyALLPlayers
00470 //=====================================================================================
00471 void Client_DestroyALLPlayers(Client_Client *Client)
00472 {
00473         int32           i;
00474         GPlayer         *Player;
00475 
00476         assert(Client_IsValid(Client) == GE_TRUE);
00477 
00478         // Destroy all normal players
00479         Player = Client->Players;
00480 
00481         for (i=0; i< NETMGR_MAX_PLAYERS; i++, Player++)
00482         {
00483                 if (!Player->Active)
00484                         continue;
00485 
00486                 Client_DestroyPlayer(Client, Player);
00487         }
00488 
00489         // Now destroy all temp players (if any)
00490         Player = Client->TempPlayers;
00491 
00492         for (i=0; i< CLIENT_MAX_TEMP_PLAYERS; i++, Player++)
00493         {
00494                 if (!Player->Active)
00495                         continue;
00496 
00497                 Client_DestroyTempPlayer(Client, Player);
00498         }
00499 }
00500 
00501 //=====================================================================================
00502 //      Client_FreeALLResources
00503 //=====================================================================================
00504 void Client_FreeALLResources(Client_Client *Client)
00505 {
00506         geBoolean       Ret;
00507 
00508         assert(Client_IsValid(Client) == GE_TRUE);
00509 
00510         Ret = GE_TRUE;
00511 
00512         // Destroy the status bar
00513         Client_DestroyStatusBar(Client);
00514 
00515         // Delete any active players that might by laying around
00516         Client_DestroyALLPlayers(Client);
00517 
00518         // Delete the move list
00519         while (Client_PeekMove(Client))
00520                 Client_RemoveFirstMove(Client);
00521 
00522         assert(Ret == GE_TRUE);
00523 }
00524 
00525 //=====================================================================================
00526 //      Client_FreeResourcesForNewWorld
00527 //=====================================================================================
00528 void Client_FreeResourcesForNewWorld(Client_Client *Client)
00529 {
00530         // Delete any active players that might by laying around
00531         Client_DestroyALLPlayers(Client);
00532 
00533         // Delete the move list
00534         while (Client_PeekMove(Client))
00535                 Client_RemoveFirstMove(Client);
00536 }
00537 
00538 static int32 LastPlayer = -1;
00539 
00540 //=====================================================================================
00541 //      Client_NewWorldDefaults
00542 //=====================================================================================
00543 void Client_NewWorldDefaults(Client_Client *Client)
00544 {
00545         int32           i;
00546 
00547         assert(Client_IsValid(Client) == GE_TRUE);
00548 
00549         // Set the default on all players
00550         for (i=0; i< NETMGR_MAX_PLAYERS; i++)
00551                 SetPlayerDefaults(&Client->Players[i]);
00552 
00553         Client->Time = 0.0f;
00554         Client->NetTime = 0.0f;
00555         Client->OldNetTime = 0.0f;
00556         //Client->ClientPlayer = -1;
00557         LastPlayer = -1;
00558 
00559         // Make sure the status bar updates between world cahnges...
00560         NumUpdates = REFRESH_TIMES;             
00561 }
00562 
00563 //=====================================================================================
00564 //      PrintClientScores
00565 //=====================================================================================
00566 static geBoolean PrintClientScores(Client_Client *Client)
00567 {
00568         int32                           i, k, j, Total;
00569         int32                           Sorted[NETMGR_MAX_CLIENTS];
00570         int32                           SortedScores[NETMGR_MAX_CLIENTS];
00571         Client_ClientInfo       *ClientInfo;
00572         char                            *Name;
00573         int32                           Score;
00574         int                                     Width,Height;
00575 
00576         assert(Client_IsValid(Client) == GE_TRUE);
00577 
00578         // Sort the clients by score
00579         Total = 0;
00580         ClientInfo = Client->ClientInfo;
00581 
00582         for (i=0 ; i<NETMGR_MAX_CLIENTS; i++, ClientInfo++)
00583         {
00584                 if (!ClientInfo->Active)
00585                         continue;
00586 
00587                 Score = ClientInfo->Score;
00588 
00589                 for (j=0 ; j<Total ; j++)
00590                 {
00591                         if (Score > SortedScores[j])
00592                                 break;
00593                 }
00594 
00595                 for (k=Total ; k>j ; k--)
00596                 {
00597                         Sorted[k] = Sorted[k-1];
00598                         SortedScores[k] = SortedScores[k-1];
00599                 }
00600                 Sorted[j] = i;
00601                 SortedScores[j] = Score;
00602                 Total++;
00603         }
00604 
00605         VidMode_GetResolution(Client->VidMode,&Width,&Height);
00606 
00607         for (i=0; i< Total; i++)
00608         {
00609                 int Line;
00610                 ClientInfo = &Client->ClientInfo[Sorted[i]];
00611 
00612                 Name = ClientInfo->Name;
00613                 Score = ClientInfo->Score;
00614 
00615                 if (Width < SMALL_CONSOLE_CUTOFF_WIDTH)
00616                         Line = i+((Height-30)/6)-9;
00617                 else
00618                         Line = i+((Height-60)/15)-9;
00619 
00620                 if (!Console_XYPrintf(GameMgr_GetConsole(Client->GMgr), 0, Line, 0, "%12s: %4i", Name, Score))
00621                                         return GE_FALSE;
00622         }
00623         
00624         // Go ahead and print ping time here
00625         if (Width < SMALL_CONSOLE_CUTOFF_WIDTH)
00626         {
00627                 if (Client->MultiPlayer)
00628                 {
00629                         if (!Console_XYPrintf(GameMgr_GetConsole(Client->GMgr), (Width/6)-13, ((Height-30)/6)-2, 0, "Ping: %2.2f", Client->Ping*1000.0f))
00630                                 return GE_FALSE;
00631                 }
00632         }
00633         else
00634         {
00635                 if (Client->MultiPlayer)
00636                 {
00637                         if (!Console_XYPrintf(GameMgr_GetConsole(Client->GMgr), (Width/9)-13, ((Height-60)/16)-1, 0, "Ping: %2.2f", Client->Ping*1000.0f))
00638                                 return GE_FALSE;
00639                 }
00640         }
00641 
00642         return GE_TRUE;
00643 }
00644 
00645 //=====================================================================================
00646 //      PrintCrossHair
00647 //=====================================================================================
00648 static void PrintCrossHair(Client_Client *Client)
00649 {
00650         int                                     Width,Height;
00651 
00652         VidMode_GetResolution(Client->VidMode,&Width,&Height);
00653 
00654         if (Width < SMALL_CONSOLE_CUTOFF_WIDTH)
00655         {
00656                 if (!Console_XYPrintf(GameMgr_GetConsole(Client->GMgr), ((Width/6)/2), (((Height-30)/6)/2), 0, "*"))
00657                         GenVS_Error("PrintCrossHair:  Console_XYPrintf failed.\n");
00658         }
00659         else
00660         {
00661                 if (!Console_XYPrintf(GameMgr_GetConsole(Client->GMgr), ((Width/9)/2), (((Height-60)/15)/2)-1, 0, "+"))
00662                         GenVS_Error("PrintCrossHair:  Console_XYPrintf failed.\n");
00663         }
00664 }
00665 
00666 //=====================================================================================
00667 //      DrawStatusBar
00668 //=====================================================================================
00669 static geBoolean DrawStatusBar(Client_Client *Client)
00670 {
00671         Client_ClientInfo       *ClientInfo;
00672         uint32                          Ammo;
00673         geBoolean                       HasItem;
00674         int32                           i;
00675         int32                           Val[6];
00676 
00677         assert(Client_IsValid(Client) == GE_TRUE);
00678 
00679         ClientInfo = &Client->ClientInfo[Client->ClientIndex];
00680 
00681         Val[0] = ClientInfo->Health;
00682         Val[1] = Client->Inventory[16] & ((1<<15)-1);
00683 
00684         // Totally %$%^% hacked!!!
00685         for (i=0; i< 2; i++)
00686         {
00687                 geBitmap                                *Bitmap;
00688                 Client_StatusElement    *Element;
00689 
00690                 Element = &Client->StatusBar.Elements[i];
00691 
00692                 //if (Val[i] < Element->Low)
00693                 //      Texture = Element->Textures[STATE_Warning];
00694                 //else
00695                         Bitmap = Element->Bitmaps[STATE_Normal];
00696 
00697                 geEngine_DrawBitmap(Client->Engine, Bitmap, NULL, Element->XPos, Element->YPos);
00698         }
00699 
00700         for (i=0; i< 4; i++)
00701         {
00702                 geBitmap                                *Bitmap;
00703                 Client_StatusState              State;
00704                 Client_StatusElement    *Element;
00705 
00706                 Element = &Client->StatusBar.Elements[i+2];
00707 
00708                 Ammo = Client->Inventory[i];
00709 
00710                 HasItem = (Ammo & (1<<15));
00711 
00712                 Ammo &= 0xff;
00713 
00714                 if (i == 0)             // Always have blaster...
00715                 {
00716                         HasItem = GE_TRUE;
00717                         Ammo = 99;
00718                 }
00719 
00720                 if (!HasItem)
00721                 {
00722                         State = STATE_Disable;
00723                 }
00724                 else if (i == Client->CurrentWeapon)
00725                 {
00726                         //if ((int32)Ammo < Element->Low)
00727                         //      State = STATE_Warning;
00728                         //else
00729                                 State = STATE_Selected;
00730                 }
00731                 else
00732                 {
00733                         //if ((int32)Ammo < Element->Low)
00734                         //      State = STATE_Warning;
00735                         //else
00736                                 State = STATE_Normal;
00737                 }
00738                                                                 
00739                 Element->State = State;
00740 
00741                 Bitmap = Element->Bitmaps[State];
00742                 
00743                 geEngine_DrawBitmap(Client->Engine, Bitmap, NULL, Element->XPos, Element->YPos);
00744 
00745                 Val[i+2] = Ammo;
00746         }
00747 
00748         for (i=0; i<6; i++)
00749         {
00750                 char    Temp[32];
00751                 int32   XPos, YPos;
00752 
00753                 if (i==2)
00754                         strcpy(Temp, "Inf");
00755                 else
00756                         sprintf(Temp, "%i", Val[i]);
00757 
00758                 XPos = Client->StatusBar.Elements[i].Print1XPos;
00759                 YPos = Client->StatusBar.Elements[i].Print1YPos;
00760 
00761                 Console_XYPrintf(GameMgr_GetConsole(Client->GMgr), XPos, YPos, 1, "%s", Temp);
00762         }
00763 
00764         return GE_TRUE;
00765 
00766 }
00767 
00768 //=====================================================================================
00769 //      Client_RefreshStatusBar
00770 //=====================================================================================
00771 void Client_RefreshStatusBar(int32 NumPages)
00772 {
00773         NumPages;
00774         NumUpdates = REFRESH_TIMES;
00775 }
00776 
00777 //=====================================================================================
00778 //=====================================================================================
00779 static void UpdateStatusBar(Client_Client *Client)
00780 {
00781         Client_ClientInfo       *ClientInfo;
00782         int32                           i;
00783 
00784         assert(Client_IsValid(Client) == GE_TRUE);
00785         assert(Client->ClientIndex >= 0 && Client->ClientIndex < NETMGR_MAX_CLIENTS);
00786 
00787         ClientInfo = &Client->ClientInfo[Client->ClientIndex];
00788 
00789         for (i=0; i<4; i++)
00790         {
00791                 if (Client->Inventory[i] != Client->OldInventory[i])
00792                 {
00793                         Client->OldInventory[i] = Client->Inventory[i];
00794                         NumUpdates = REFRESH_TIMES;             
00795                         break;
00796                 }
00797         }
00798 
00799         for (i=16; i<17; i++)
00800         {
00801                 if (Client->Inventory[i] != Client->OldInventory[i])
00802                 {
00803                         NumUpdates = REFRESH_TIMES;             
00804                         break;
00805                 }
00806         }
00807 
00808         for (i=0; i<4; i++)
00809         {
00810                 if (Client->Inventory[i] != Client->OldInventory[i])
00811                 {
00812                         Client->OldInventory[i] = Client->Inventory[i];
00813                         NumUpdates = REFRESH_TIMES;             
00814                         break;
00815                 }
00816         }
00817 
00818         if (Client->CurrentWeapon != Client->OldWeapon)
00819         {
00820                 Client->OldWeapon = Client->CurrentWeapon;
00821                 NumUpdates = REFRESH_TIMES;
00822         }
00823 
00824         if (ClientInfo->OldHealth != ClientInfo->Health)
00825         {
00826                 ClientInfo->OldHealth = ClientInfo->Health;
00827                 NumUpdates = REFRESH_TIMES;
00828         }
00829 
00830         if (NumUpdates <= 0)
00831                 return;         // Nothing to do...
00832 
00833         if (!DrawStatusBar(Client))
00834                 GenVS_Error("UpdateStatusBar: Could not draw the status bar.");
00835 
00836         NumUpdates--;
00837 }
00838 
00839 //=====================================================================================
00840 //      ControlTempPlayers
00841 //=====================================================================================
00842 static void ControlTempPlayers(Client_Client *Client, float Time)
00843 {
00844         int32           i;
00845         GPlayer         *Player;
00846 
00847         assert(Client_IsValid(Client) == GE_TRUE);
00848 
00849         Player = Client->TempPlayers;
00850 
00851         for (i=0; i<CLIENT_MAX_TEMP_PLAYERS; i++, Player++)
00852         {
00853                 if (!Player->Active)
00854                         continue;
00855 
00856                 if (!Player->Control)
00857                         continue;
00858 
00859                 Player->Control(&Client->GenVSI, Player, Time);
00860 
00861                 if (!Fx_PlayerSetFxFlags(GameMgr_GetFxSystem(Client->GMgr), TEMP_PLAYER_TO_FXPLAYER(Client, Player), Player->FxFlags))
00862                         GenVS_Error("Client_ControlTempPlayers:  Could not set fx flags.\n");
00863 
00864                 Player->Pos = Player->XForm.Translation;
00865                 geXForm3d_GetEulerAngles(&Player->XForm, &Player->Angles);
00866                 
00867                 Client_UpdateSinglePlayer(Client, Player, 1.0f,  Time, GE_TRUE);
00868         }
00869 }
00870 
00871 //=====================================================================================
00872 //      Client_Frame
00873 //      Sends movement for this machine
00874 //      Renders the world
00875 //=====================================================================================
00876 geBoolean Client_Frame(Client_Client *Client, float Time)
00877 {
00878         assert(Client_IsValid(Client) == GE_TRUE);
00879 
00880         Client->Time += Time;                                           // Update client time
00881 
00882         // Read and process msg's from the server
00883         if (!ReadServerMessages(Client, Client->GMgr, Time))            
00884                 GenVS_Error("Client_Frame:  ReadServerMessages failed.\n");
00885 
00886         if (Client->Demo.Mode != CLIENT_DEMO_PLAY)
00887         {
00888                 // If the world is loaded and we have the go from server, start sending move cmd's
00889                 if (Client->NetState == NetState_WorldActive)
00890                 {
00891                         if (!Client_SendMove(Client, Time))                     // Send movement commands
00892                                 GenVS_Error("Client_Frame:  Client_SendMove failed.\n");
00893                 }
00894 
00895                 ControlTempPlayers(Client, Time);
00896         }
00897 
00898         return GE_TRUE;
00899 }
00900 
00901 //=====================================================================================
00902 //      Client_RenderFrame
00903 //=====================================================================================
00904 geBoolean Client_RenderFrame(Client_Client *Client, float Time)
00905 {
00906         assert(Client_IsValid(Client) == GE_TRUE);
00907 
00908         if (Client->NetState != NetState_WorldActive)           // If no world currently set, then return...
00909                 return GE_TRUE;
00910 
00911         if (!RenderWorld(Client, Client->GMgr, Time))
00912                 GenVS_Error("Client_RenderFrame:  RenderWorld failed.\n");
00913 
00914         //if (Client->MultiPlayer)
00915         {
00916                 if (!PrintClientScores(Client))
00917                         GenVS_Error("Client_RenderFrame:  PrintClientScores failed.\n");
00918         }
00919         
00920         PrintCrossHair(Client);
00921 
00922         UpdateStatusBar(Client);
00923 
00924         return GE_TRUE;
00925 }
00926 
00927 extern  float   GlobalMouseSpeedX;
00928 extern  float   GlobalMouseSpeedY;
00929 
00930 extern int32            KeyLut[256];
00931 extern geBoolean        MouseInvert;
00932 
00933 
00934 //=====================================================================================
00935 //      Client_MoveClientLocally
00936 //=====================================================================================
00937 static void Client_MoveClientLocally(Client_Client *Client, Client_Move *Move)
00938 {
00939         GPlayer *Player;
00940 
00941         assert(Client_IsValid(Client) == GE_TRUE);
00942         assert(Client->ClientPlayer != -1);
00943 
00944         if (!GameMgr_GetWorld(Client->GMgr))
00945                 return;
00946 
00947         // Fill the client with this move, so when the game code calls the GneVSI_GetClientMove, we will be able to
00948         // fullfill the request...
00949         Client->Move.MoveTime = Move->Time;
00950         Client->Move.ForwardSpeed = Move->ForwardSpeed;
00951         Client->Move.Angles.X = Move->Pitch;
00952         Client->Move.Angles.Y = Move->Yaw;
00953         Client->Move.Angles.Z = 0.0f;
00954         Client->Move.ButtonBits = Move->ButtonBits;
00955         Client->Move.Weapon = Move->CurrentWeapon;
00956         Client->Move.PingTime = Move->Delta;
00957 
00958         Player = &Client->Players[Client->ClientPlayer];
00959 
00960         if (Player->Control)
00961                 Player->Control(&Client->GenVSI, Player, Move->Delta);
00962 
00963         Player->Pos = Player->XForm.Translation;
00964 }
00965 
00966 int32           NumMoves = 0;
00967 
00968 //=====================================================================================
00969 //      Client_AddMove
00970 //=====================================================================================
00971 void Client_AddMove(Client_Client *Client, Client_Move *Move)
00972 {
00973         Client_Move             *NewMove, *Last;
00974         
00975         NewMove = GE_RAM_ALLOCATE_STRUCT(Client_Move);  
00976         
00977         if (!NewMove)
00978                 GenVS_Error("Client_AddMove:  Out of memory.\n");
00979 
00980         *NewMove = *Move;
00981 
00982         NewMove->Next = NULL;
00983         
00984         Last = Client->LastMove;
00985 
00986         if (!Last)
00987                 Client->MoveStack = NewMove;    
00988         else
00989                 Last->Next = NewMove;
00990         
00991         Client->LastMove = NewMove;
00992 
00993         NumMoves++;
00994 
00995         if (NumMoves >= 1000)
00996                 GenVS_Error("NumMoves > 1000.\n");
00997 }
00998 
00999 //=====================================================================================
01000 //      Client_PeekMove
01001 //=====================================================================================
01002 Client_Move *Client_PeekMove(Client_Client *Client)
01003 {
01004         assert(Client_IsValid(Client) == GE_TRUE);
01005 
01006         return Client->MoveStack;
01007 }
01008 
01009 //=====================================================================================
01010 //      Client_RemoveFirstMove
01011 //=====================================================================================
01012 void Client_RemoveFirstMove(Client_Client *Client)
01013 {
01014         Client_Move             *Next;
01015 
01016         assert(Client_IsValid(Client) == GE_TRUE);
01017 
01018         NumMoves--;
01019 
01020         if (NumMoves < 0)
01021                 GenVS_Error("NumMove < 0.\n");
01022 
01023         if (!Client->MoveStack)
01024                 GenVS_Error("Client_RemoveFirstMove:  No more moves left...");
01025 
01026         Next = Client->MoveStack->Next;
01027 
01028         geRam_Free(Client->MoveStack);
01029         
01030         if (Next)
01031                 Client->MoveStack = Next;
01032         else
01033         {
01034                 Client->MoveStack = NULL;
01035                 Client->LastMove = NULL;
01036         }
01037 }
01038 
01039 //=====================================================================================
01040 //      Client_ValidateWeapon
01041 //=====================================================================================
01042 void Client_ValidateWeapon(Client_Client *Client)
01043 {
01044         int32                   i;
01045 
01046         assert(Client_IsValid(Client) == GE_TRUE);
01047 
01048         for (i=0; i<5; i++)
01049         {
01050                 geBoolean       HasItem;
01051 
01052                 HasItem = (Client->Inventory[Client->CurrentWeapon] & (1<<15));
01053 
01054                 if (!HasItem && Client->CurrentWeapon != 0)
01055                 {
01056                         Client->CurrentWeapon++;
01057                         Client->CurrentWeapon %= 4;
01058                         continue;
01059                 }
01060                 
01061                 assert(Client->CurrentWeapon >= 0 && Client->CurrentWeapon <= 3);
01062 
01063                 return;
01064         }
01065         
01066         // Should'nt get here!!!!!  There is allways the default weapon...
01067         assert(!"No best weapon!!!");
01068 }
01069 
01070 //=====================================================================================
01071 //      Client_SendMove
01072 //      Sends clients intentions to the server (through the supplied host)
01073 //=====================================================================================
01074 geBoolean Client_SendMove(Client_Client *Client, float Time)
01075 {
01076         Buffer_Data             Buffer;
01077         uint8                   Data[512];
01078         uint16                  ButtonBits;
01079         HWND                    hWnd;
01080 
01081         assert(Client_IsValid(Client) == GE_TRUE);
01082 
01083         if (GMenu_IsAMenuActive() == GE_TRUE)
01084                 return GE_TRUE;
01085 
01086         hWnd = GameMgr_GethWnd(Client->GMgr);
01087         
01088         //if (Client->ClientPlayer == -1)
01089         //      return GE_TRUE;
01090 
01091         Buffer_Set(&Buffer, Data, 512);
01092 
01093         ButtonBits = 0;
01094 
01095         // Change forward/back motion
01096         if (IsKeyDown(KeyLut[VK_UP], hWnd))
01097                 Client->ForwardSpeed = 4000.0f;
01098         else if (IsKeyDown(KeyLut[VK_DOWN], hWnd))
01099                 Client->ForwardSpeed = -4000.0f;
01100         else
01101                 Client->ForwardSpeed = 0.0f;
01102 
01103         if (MouseInvert)
01104                 Client->Angles.X -= GlobalMouseSpeedY;
01105         else
01106                 Client->Angles.X += GlobalMouseSpeedY;
01107 
01108         Client->Angles.Y += GlobalMouseSpeedX;
01109 
01110         if (Client->Angles.X > 1.3f)
01111                 Client->Angles.X = 1.3f;
01112         else if (Client->Angles.X < -1.3f)
01113                 Client->Angles.X = -1.3f;
01114 
01115         GlobalMouseSpeedX = 0.0f;
01116         GlobalMouseSpeedY = 0.0f;
01117 
01118         if (IsKeyDown(KeyLut[VK_LEFT], hWnd))
01119                 ButtonBits |= HOST_BUTTON_LEFT;
01120 
01121         if (IsKeyDown(KeyLut[VK_RIGHT], hWnd))
01122                 ButtonBits |= HOST_BUTTON_RIGHT;
01123 
01124         // Do misc move actions
01125         if (NewKeyDown(KeyLut[VK_RBUTTON], hWnd))
01126                 ButtonBits |= HOST_BUTTON_JUMP;
01127 
01128         if (IsKeyDown(KeyLut[VK_LBUTTON], hWnd))
01129         {
01130                 ButtonBits |= HOST_BUTTON_FIRE;
01131         }
01132         
01133         if (IsKeyDown('1', hWnd))
01134         {
01135                 Client->CurrentWeapon = 0;
01136         }
01137         else if (IsKeyDown('2', hWnd))
01138         {
01139                 Client->CurrentWeapon = 1;
01140         }
01141         else if (IsKeyDown('3', hWnd))
01142         {
01143                 Client->CurrentWeapon = 2;
01144         }
01145         else if (IsKeyDown('4', hWnd))
01146         {
01147                 Client->CurrentWeapon = 3;
01148         }
01149         else if (NewKeyDown(KeyLut[VK_CONTROL], hWnd))
01150         {
01151                 Client->CurrentWeapon ++;
01152                 Client->CurrentWeapon %= 4;
01153                 
01154                 Client_ValidateWeapon(Client);
01155         }
01156         
01157         Client->ButtonBits = ButtonBits;
01158 
01159         Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_MOVE);                       // Let server know we're moving
01160         Buffer_FillFloat(&Buffer, Client->Time);                                // Current Time
01161         Buffer_FillFloat(&Buffer, Client->ServerPingBack);              // Current Time
01162         Buffer_FillFloat(&Buffer, Client->ForwardSpeed);                // Current Speed
01163         Buffer_FillFloat(&Buffer, Client->Angles.X);                    // Pitch
01164         Buffer_FillFloat(&Buffer, Client->Angles.Y);                    // Yaw
01165         Buffer_FillShort(&Buffer, ButtonBits);                                  // Current Buttons
01166 
01167         if (ButtonBits & HOST_BUTTON_FIRE)
01168         {
01169                 assert(Client->CurrentWeapon >= 0 && Client->CurrentWeapon <= 65535);
01170                 Buffer_FillShort(&Buffer, (uint16)Client->CurrentWeapon);               // Send Current Weapon if firing
01171         }
01172 
01173 #ifdef CALC_ERROR
01174         if (Client->ClientPlayer >= 0)
01175         {
01176                 GPlayer         *Player;
01177 
01178                 Player = &Client->Players[Client->ClientPlayer];
01179                 Buffer_FillAngle(&Buffer, Player->Pos); 
01180         }
01181         else
01182         {
01183                 geVec3d         FakePos = {0.0f, 0.0f, 0.0f};
01184 
01185                 Buffer_FillAngle(&Buffer, FakePos);     
01186         }
01187 #endif
01188 
01189 //BEGIN_TIMER();
01190 #if 1
01191         if (!NetMgr_SendServerMessage(Client->NMgr, &Buffer, GE_FALSE))
01192                 GenVS_Error("Client_SendMove:  NetMgr_SendServerMessage failed.\n");
01193 #else
01194         if (Client->Mode == ClientMode_Dumb)
01195         {
01196                 // Send the move intention to the server for processing
01197                 if (!NetMgr_SendServerMessage(Client->NMgr, &Buffer, GE_FALSE))
01198                         GenVS_Error("Client_SendMove:  NetMgr_SendServerMessage failed.\n");
01199         }
01200         else if (Client->Time >= Client->NextSend)
01201         {
01202                 Buffer_FillBuffer(&SendBuffer, &Buffer);
01203 
01204                 // Send the move intention to the server for processing
01205                 if (!NetMgr_SendServerMessage(Client->NMgr, &SendBuffer, GE_FALSE))
01206                         GenVS_Error("Client_SendMove:  NetMgr_SendServerMessage failed.\n");
01207 
01208                 Buffer_Set(&SendBuffer, SData, 5000);
01209 
01210                 //Client->NextSend = Client->Time + (float)(rand()%100) * (1/100.0f) * 0.5f + 0.25f;
01211                 //Client->NextSend = Client->Time + 0.5f;
01212                 Client->NextSend = Client->Time;
01213         }
01214 #endif
01215 //END_TIMER(Client->GMgr);
01216 
01217         // Send the message directly to our proxy player so we can begin moving NOW
01218         if (Client->Mode == ClientMode_Proxy && Client->ClientPlayer != -1)
01219         {
01220                 Client_Move             Move;
01221                 GPlayer         *Player;
01222 
01223                 Player = &Client->Players[Client->ClientPlayer];
01224 
01225                 Move.Time = Client->Time;
01226                 Move.Delta = Time;
01227                 Move.ForwardSpeed = Client->ForwardSpeed;
01228                 Move.Pitch = Client->Angles.X;
01229                 Move.Yaw = Client->Angles.Y;
01230                 Move.Pos = Player->Pos;                                                         // So we know our position at this time...
01231                 Move.ButtonBits = ButtonBits;
01232                 Move.CurrentWeapon = Client->CurrentWeapon;
01233 
01234         #ifdef PREDICT_CLIENT
01235 
01236                 Client_MoveClientLocally(Client, &Move);
01237                         
01238                 //geEngine_Printf(Host->Engine, 2, 35, "Inventory: %i, %i", Player->InventoryHas[Client->CurrentWeapon], Player->Inventory[Client->CurrentWeapon]);
01239 
01240                 // Remember this move, so when we get an update that is older then where we
01241                 // are actually at, we can replay all the moves after the update, and "catch"
01242                 // back up...
01243                 Client_AddMove(Client, &Move);
01244         #endif
01245         }
01246 
01247         return GE_TRUE;
01248 }
01249 
01250 //=====================================================================================
01251 //      IsKeyDown
01252 //=====================================================================================
01253 static geBoolean IsKeyDown(int KeyCode, HWND hWnd)
01254 {
01255         //if (GetFocus() == hWnd)
01256                 if (GetAsyncKeyState(KeyCode) & 0x8000)
01257                         return GE_TRUE;
01258 
01259         return GE_FALSE;
01260 }
01261 
01262 //=====================================================================================
01263 //      NewKeyDown
01264 //=====================================================================================
01265 geBoolean NewKeyDown(int KeyCode, HWND hWnd)
01266 {
01267         //if (GetFocus() == hWnd)
01268         if (GetAsyncKeyState(KeyCode) & 1)
01269                         return GE_TRUE;
01270 
01271         return GE_FALSE;
01272 }
01273 
01274 //===========================================================================
01275 //      SetClientProxyPlayer
01276 //===========================================================================
01277 static void SetClientProxyPlayer(Client_Client *Client, int32 Player)
01278 {
01279         GPlayer                 *PPlayer;
01280 
01281         assert(Client_IsValid(Client) == GE_TRUE);
01282 
01283         if (Client->Mode != ClientMode_Proxy)
01284                 return;
01285 
01286         Client->ClientPlayer = Player;
01287 
01288         // If the player already exist, we must make sure we can't see it
01289         if (Client->Players[Player].Actor)
01290         {
01291                 geWorld         *World;
01292 
01293                 World = GameMgr_GetWorld(Client->GMgr);
01294                                                         
01295                 assert(World);
01296 
01297                 geWorld_SetActorFlags(World, Client->Players[Player].Actor, GE_ACTOR_RENDER_MIRRORS|GE_ACTOR_COLLIDE);
01298         }
01299                                 
01300         PPlayer = &Client->Players[Player];
01301 
01302         PPlayer->Active = GE_TRUE;              // Set this?  Should be set automatically when updated by server
01303 
01304         PPlayer->Owner = NULL;
01305         
01306         PPlayer->ClientHandle = Client->ClientIndex;
01307         
01308         // Hard coded for now!  Should be passed accross network via GenVSI_SetWeaponOffset
01309         PPlayer->GunOffset.X = 0.0f;
01310         PPlayer->GunOffset.Y = 130.0f;
01311         PPlayer->GunOffset.Z = 0.0f;
01312 }
01313 
01314 geBoolean MHack = GE_TRUE;
01315 
01316 int32           TotalMsgBytes;
01317 geBoolean NetPlayGetNumMessages(int32 *NumMsgSend, int32 *NumBytesSend, int32 *NumMsgRec, int32 *NumBytesRec);
01318 
01319 //===========================================================================
01320 //      ReadServerMessages
01321 //      Read ALL mesages from server
01322 //===========================================================================
01323 static geBoolean ReadServerMessages(Client_Client *Client, GameMgr *GMgr, float Time)
01324 {
01325         uint8                   Type;
01326         Buffer_Data             Buffer;
01327 
01328         assert(Client_IsValid(Client) == GE_TRUE);
01329 
01330         MHack = GE_FALSE;
01331 
01332         Client->ServerPingBack = -1.0f;         // Reset ping back variable
01333 
01334         // Keep on reading till there is no more messages...
01335         // We have to process every message just in case they are critical ones
01336         while (Client_ReadServerMessages(Client, &Buffer))
01337         {
01338                 assert(Buffer.Size < NETMGR_LOCAL_MSG_BUFFER_SIZE);
01339                 assert(Buffer.Size >= 0);
01340 
01341                 TotalMsgBytes += Buffer.Size;
01342 
01343                 // Keep reading till end of buffer
01344                 while (Buffer.Pos < Buffer.Size)
01345                 {
01346                         // Get the type of message...
01347                         Buffer_GetByte(&Buffer, &Type);
01348 
01349                         //geEngine_Printf(GameMgr_GetEngine(Client->GMgr), 2, 380, "Msg Type: %i", Type);
01350 
01351                         switch(Type)
01352                         {
01353                                 case NETMGR_MSG_VERSION:
01354                                 {
01355                                         uint32          VersionMajor, VersionMinor;
01356 
01357                                         Buffer_GetLong(&Buffer, &VersionMajor);
01358                                         Buffer_GetLong(&Buffer, &VersionMinor);
01359 
01360                                         if (VersionMajor != NETMGR_VERSION_MAJOR || VersionMinor != NETMGR_VERSION_MINOR)
01361                                                 GenVS_Error("Wrong Server Version:  %i.%i", VersionMajor, VersionMinor);
01362 
01363                                         break;
01364                                 }
01365 
01366                                 case NETMGR_MSG_TIME:
01367                                 {
01368                                         Client->TempTime = 0.0f;
01369                                         Client->OldNetTime = Client->NetTime;
01370                                         Buffer_GetFloat(&Buffer, &Client->NetTime);
01371 
01372                                         if (Client->NetTime >= Client->OldNetTime)
01373                                                 Client->NetTimeGood = GE_TRUE;
01374                                         else
01375                                                 Client->NetTimeGood = GE_FALSE;
01376                                         
01377                                         Client->ServerPingBack = Client->NetTime;               // So server can calc ping times
01378 
01379                                         Buffer_GetFloat(&Buffer, &Client->Ping);
01380 
01381                                         break;
01382                                 }
01383 
01384                                 case NETMGR_MSG_PLAYER_DATA:
01385                                 {
01386                                         if (Client->NetState != NetState_WorldActive)
01387                                                 GenVS_Error("ReadServerMessages:  Client->NetState != NetState_WorldActive\n");
01388 
01389                                         // If we are in the middle of a world change, or the net time is bad, do a fake update
01390                                         if (!Client->NetTimeGood || Client->NetState != NetState_WorldActive)
01391                                                 ParsePlayerDataLocally(Client, &Buffer, GE_TRUE);
01392                                         else
01393                                                 ParsePlayerDataLocally(Client, &Buffer, GE_FALSE);
01394 
01395                                         break;
01396                                 }
01397 
01398                                 case NETMGR_MSG_NEW_WORLD_PLAYER_DATA:
01399                                 {
01400                                         if (Client->NetState != NetState_WorldChange)
01401                                                 GenVS_Error("ReadServerMessages:  Client->NetState != NetState_WorldChange\n");
01402 
01403                                         ParsePlayerDataLocally(Client, &Buffer, GE_FALSE);
01404                                         break;
01405                                 }
01406 
01407                                 case NETMGR_MSG_VIEW_PLAYER:
01408                                 {
01409                                         uint16          Player;
01410                                         GPlayer         *pPlayer;
01411                                         int32           OldViewPlayer;
01412 
01413                                         Buffer_GetShort(&Buffer, &Player);
01414 
01415                                         assert(Player != 0);    // For debugging, it could be possible, but not likely...
01416                                                                                         // Usually the view player will the client...
01417 
01418                                         OldViewPlayer = Client->ViewPlayer;
01419 
01420                                         Client->ViewPlayer = (int32)Player;
01421                                         
01422                                         if (OldViewPlayer != -1)
01423                                         {
01424                                                 pPlayer = &Client->Players[OldViewPlayer];
01425                                                 
01426                                                 if (pPlayer->Actor)
01427                                                 {
01428                                                         pPlayer->OldViewIndex2 = 0xffff;
01429                                                         CheckClientPlayerChanges(Client, pPlayer, GE_FALSE);
01430                                                 }
01431                                         }
01432 
01433                                         // Force it to rewcreate the actor that represents this player (kind of a hack)
01434                                         pPlayer = &Client->Players[Player];
01435                                         
01436                                         if (pPlayer->Actor)
01437                                         {
01438                                                 pPlayer->OldViewIndex2 = 0xffff;
01439                                                 CheckClientPlayerChanges(Client, pPlayer, GE_FALSE);
01440                                         }
01441 
01442                                         //Console_Printf(GameMgr_GetConsole(Client->GMgr), "View Player assigned by server: %i\n", Player);
01443                                         break;
01444                                 }
01445 
01446                                 case NETMGR_MSG_SET_WORLD:
01447                                 {
01448                                         char            Name[256];
01449 
01450                                         assert( Client->NetState == NetState_WorldChange);              // The world should be in the middle of a change to get this message
01451 
01452                                         Buffer_GetString(&Buffer, Name);
01453 
01454                                         assert(Name[0]);
01455 
01456                                         if (!Name[0])
01457                                                 GenVS_Error("ReadServerMessages:  No World Name!\n");
01458 
01459                                         if (Client->Mode == ClientMode_Dumb)
01460                                                 break;  // World allready loaded if server on same machine 
01461 
01462                                         Client_FreeResourcesForNewWorld(Client);
01463                                         Client_NewWorldDefaults(Client);
01464 
01465                                         if (!GameMgr_SetWorld(GMgr, Name))
01466                                                 GenVS_Error("ReadServerMessages:  GameMgr_SetWorld failed.\n");
01467                                         break;
01468                                 }
01469 
01470                                 case NETMGR_MSG_ACTOR_INDEX:
01471                                 {
01472                                         int32           ActorIndex;
01473                                         char            ActorName[GAMEMGR_MAX_ACTOR_NAME];
01474                                         
01475                                         Buffer_GetSLong(&Buffer, &ActorIndex);
01476                                         Buffer_GetString(&Buffer, ActorName);
01477 
01478                                         if (Client->Mode == ClientMode_Dumb)
01479                                                 break;                  // Server already issued the load, just ignore
01480                                         
01481                                         if (!GameMgr_SetActorIndex(GMgr, ActorIndex, ActorName))
01482                                                 GenVS_Error("ReadServerMessages:  GameMgr_SetActorIndex failed.\n");
01483         
01484                                         break;
01485                                 }
01486 
01487                                 case NETMGR_MSG_MOTION_INDEX:
01488                                 {
01489                                         GameMgr_MotionIndex             MotionIndex;
01490                                         char                                    MotionName[GAMEMGR_MAX_MOTION_NAME];
01491                                         
01492                                         Buffer_GetSLong(&Buffer, &MotionIndex);
01493                                         Buffer_GetString(&Buffer, MotionName);
01494 
01495                                         if (Client->Mode == ClientMode_Dumb)
01496                                                 break;                  // Server already issued the load, just ignore
01497                                         
01498                                         if (!GameMgr_SetMotionIndexDef(Client->GMgr, MotionIndex, MotionName))
01499                                                 GenVS_Error("ReadServerMessages:  GameMgr_SetMotionIndexDef failed.\n");
01500 
01501                                         break;
01502                                 }
01503 
01504                                 case NETMGR_MSG_BONE_INDEX:
01505                                 {
01506                                         int32                                   BoneIndex;
01507                                         char                                    BoneName[GAMEMGR_MAX_BONE_NAME];
01508                                         
01509                                         Buffer_GetSLong(&Buffer, &BoneIndex);
01510                                         Buffer_GetString(&Buffer, BoneName);
01511 
01512                                         if (Client->Mode == ClientMode_Dumb)
01513                                                 break;                  // Server already issued the load, just ignore
01514                                         
01515                                         if (!GameMgr_SetBoneIndex(Client->GMgr, BoneIndex, BoneName))
01516                                                 GenVS_Error("ReadServerMessages:  GameMgr_SetBoneIndex failed.\n");
01517 
01518                                         break;
01519                                 }
01520 
01521                                 case NETMGR_MSG_TEXTURE_INDEX:
01522                                 {
01523                                         int32           Index;
01524                                         char            FileName[256];
01525                                         char            AFileName[256];
01526 
01527                                         assert(Client->NetState == NetState_WorldChange);
01528 
01529                                         Buffer_GetSLong(&Buffer, &Index);
01530                                         Buffer_GetString(&Buffer, FileName);
01531                                         Buffer_GetString(&Buffer, AFileName);
01532                                         
01533                                         if (Client->Mode == ClientMode_Dumb)
01534                                                 break;                  // Server already issued the load, just ignore
01535 
01536                                         if (!GameMgr_SetTextureIndex(Client->GMgr, Index, FileName, AFileName))
01537                                                 GenVS_Error("ReadServerMessages:  GameMgr_SetTextureIndex failed.\n");
01538 
01539                                         break;
01540                                 }
01541 
01542                                 case NETMGR_MSG_SOUND_INDEX:
01543                                 {
01544                                         int32           Index;
01545                                         char            FileName[GAMEMGR_MAX_FILENAME];
01546 
01547                                         Buffer_GetSLong(&Buffer, &Index);
01548                                         Buffer_GetString(&Buffer, FileName);
01549                                         
01550                                         if (Client->Mode == ClientMode_Dumb)
01551                                                 break;                  // Server already issued the load, just ignore
01552 
01553                                         if (!GameMgr_SetSoundIndex(Client->GMgr, Index, FileName))
01554                                                 GenVS_Error("ReadServerMessages:  GameMgr_SetSoundIndex failed.\n");
01555 
01556                                         break;
01557                                 }
01558 
01559                                 case NETMGR_MSG_CD_TRACK:
01560                                 {
01561                                         uint8   Track, Smin, Ssec, Emin, Esec;
01562 
01563                                         Buffer_GetByte(&Buffer, &Track);
01564                                         Buffer_GetByte(&Buffer, &Smin);
01565                                         Buffer_GetByte(&Buffer, &Ssec);
01566                                         Buffer_GetByte(&Buffer, &Emin);
01567                                         Buffer_GetByte(&Buffer, &Esec);
01568 
01569                                         Track = 1;
01570                                         Smin = 0;
01571                                         Ssec = 0;
01572                                         Emin = 2;
01573                                         Esec = 42;
01574 
01575                                         //PlayCDTrack(GameMgr_GetCdID(Client->GMgr), 0, Track, Smin, Ssec, Emin, Esec);
01576                                         break;
01577                                 }
01578                                 
01579                                 case NETMGR_MSG_PLAY_SOUND_INDEX:
01580                                 {
01581                                         uint16                          SoundIndex;
01582                                         geVec3d                         Pos;
01583                                         geWorld                         *World;
01584                                         GameMgr_SoundIndex      *pSoundIndex;
01585                                         geSound_System          *SoundSys;
01586 
01587                                         Buffer_GetShort(&Buffer, &SoundIndex);
01588                                         Buffer_GetPos(&Buffer, &Pos);
01589                                         
01590                                         World = GameMgr_GetWorld(Client->GMgr);
01591 
01592                                         if (!World)
01593                                                 break;
01594 
01595                                         SoundSys = GameMgr_GetSoundSystem(Client->GMgr);
01596                                         //assert(SoundSys);
01597 
01598                                         if (SoundSys)
01599                                         {
01600                                                 pSoundIndex = GameMgr_GetSoundIndex(Client->GMgr, SoundIndex);
01601 
01602                                                 if (pSoundIndex->SoundDef)
01603                                                 {
01604                                                         float   Vol, Pan, Freq;
01605 
01606                                                         geSound3D_GetConfig(World, &Client->ViewXForm, &Pos, 500.0f, 2.0f, &Vol, &Pan, &Freq);
01607                                                         geSound_PlaySoundDef(SoundSys, pSoundIndex->SoundDef, Vol, Pan, Freq, GE_FALSE);
01608                                                 }
01609                                         }
01610                                         
01611                                         break;
01612                                 }
01613 
01614                                 case NETMGR_MSG_CLIENT_INDEX:
01615                                 {
01616                                         uint8           ClientIndex;
01617                                         Buffer_GetByte(&Buffer, &ClientIndex);
01618                                         
01619                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01620                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01621                                         
01622                                         Client->ClientIndex = (int32)ClientIndex;
01623 
01624                                         break;
01625                                 }
01626 
01627                                 case NETMGR_MSG_CLIENT_ACTIVE:
01628                                 {
01629                                         uint8           ClientIndex, Active;
01630                                         Buffer_GetByte(&Buffer, &ClientIndex);
01631                                         
01632                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01633                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01634                                         
01635                                         Buffer_GetByte(&Buffer, &Active);
01636 
01637                                         Client->ClientInfo[ClientIndex].Active = (geBoolean)Active;
01638                                         break;
01639                                 }
01640 
01641                                 case NETMGR_MSG_CLIENT_NAME:
01642                                 {
01643                                         uint8           ClientIndex;
01644                                         Buffer_GetByte(&Buffer, &ClientIndex);
01645                                         
01646                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01647                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01648                                         
01649                                         Buffer_GetString(&Buffer, Client->ClientInfo[ClientIndex].Name);
01650                                         break;
01651                                 }
01652 
01653                                 case NETMGR_MSG_CLIENT_SCORE:
01654                                 {
01655                                         uint8           ClientIndex;
01656                                         Buffer_GetByte(&Buffer, &ClientIndex);
01657                                         
01658                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01659                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01660                                         
01661                                         Buffer_GetSLong(&Buffer, &Client->ClientInfo[ClientIndex].Score);
01662                                         break;
01663                                 }
01664 
01665                                 case NETMGR_MSG_CLIENT_HEALTH:
01666                                 {
01667                                         uint8           ClientIndex;
01668                                         Buffer_GetByte(&Buffer, &ClientIndex);
01669                                         
01670                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01671                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01672                                         
01673                                         Buffer_GetSLong(&Buffer, &Client->ClientInfo[ClientIndex].Health);
01674                                         break;
01675                                 }
01676 
01677                                 case NETMGR_MSG_CLIENT_INVENTORY:
01678                                 {
01679                                         uint8           ClientIndex, Slot;
01680                                         uint16          Val;
01681                                         Buffer_GetByte(&Buffer, &ClientIndex);
01682                                         
01683                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01684                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01685                                         
01686                                         Buffer_GetByte(&Buffer, &Slot);
01687                                         Buffer_GetShort(&Buffer, &Val);
01688                                         Client->Inventory[Slot] = Val;
01689                                         
01690                                         if (Client->ClientPlayer != -1)
01691                                         {
01692                                                 GPlayer         *Player;
01693                                                 int32           Ammo;
01694                                                 geBoolean       HasItem;
01695 
01696                                                 Player = &Client->Players[Client->ClientPlayer];
01697 
01698                                                 Ammo = Client->Inventory[Slot];
01699 
01700                                                 HasItem = (Val & (1<<15))>>15;
01701                                                 Val &= 0xff;
01702 
01703                                                 Player->Inventory[Slot] = Val;
01704                                                 Player->InventoryHas[Slot] = HasItem;
01705                                         }
01706                                 
01707                                         break;
01708                                 }
01709                                 
01710                                 case NETMGR_MSG_CLIENT_WEAPON:
01711                                 {
01712                                         uint8           ClientIndex;
01713 
01714                                         Buffer_GetByte(&Buffer, &ClientIndex);
01715                                         
01716                                         if (ClientIndex >= NETMGR_MAX_CLIENTS)
01717                                                 GenVS_Error("ReadServerMessages:  Bad client index number.\n");
01718 
01719                                         Buffer_GetShort(&Buffer, &Client->CurrentWeapon);
01720                                         break;
01721                                 }
01722 
01723                                 case NETMGR_MSG_SPAWN_FX:
01724                                 {
01725                                         uint8                   Type, Sound;
01726                                         geVec3d                 Pos;
01727                                         geWorld                 *World;
01728                                         geSound_System  *SoundSys;
01729                                         GameMgr_SoundIndex      *pSoundIndex;
01730 
01731                                         Buffer_GetPos(&Buffer, &Pos);
01732                                         Buffer_GetByte(&Buffer, &Type);
01733                                         Buffer_GetByte(&Buffer, &Sound);
01734 
01735                                         World = GameMgr_GetWorld(Client->GMgr);
01736                                         if (!World)
01737                                                 break;
01738 
01739                                         if (!Fx_SpawnFx(GameMgr_GetFxSystem(Client->GMgr), &Pos, Type))
01740                                                 GenVS_Error("[CLIENT] ReadServerMessages:  Could not spawn fx:  %i.\n", Type);
01741 
01742                                         if (Sound == 255)
01743                                                 break;
01744 
01745                                         SoundSys = GameMgr_GetSoundSystem(Client->GMgr);
01746 
01747                                         if (SoundSys)
01748                                         {
01749                                                 pSoundIndex = GameMgr_GetSoundIndex(Client->GMgr, Sound);
01750 
01751                                                 if (pSoundIndex->SoundDef)
01752                                                 {
01753                                                         float   Vol, Pan, Freq;
01754 
01755                                                         assert(pSoundIndex->Active == GE_TRUE);
01756 
01757                                                         geSound3D_GetConfig(World, &Client->ViewXForm, &Pos, 500.0f, 2.0f, &Vol, &Pan, &Freq);
01758                                                                 geSound_PlaySoundDef(SoundSys, pSoundIndex->SoundDef, Vol, Pan, Freq, GE_FALSE);
01759                                                 }
01760                                         }
01761 
01762                                         break;
01763                                 }
01764 
01765 
01766                                 case NETMGR_MSG_HEADER_PRINTF:
01767                                 {
01768                                         char    Str[256];
01769 
01770                                         Buffer_GetString(&Buffer, Str);
01771 
01772                                         Console_HeaderPrintf(GameMgr_GetConsole(Client->GMgr), Str);
01773 
01774                                         break;
01775                                 }
01776 
01777                                 case NETMGR_MSG_CLIENT_PLAYER_INDEX:
01778                                 {
01779                                         int32           PlayerIndex;
01780 
01781                                         Buffer_GetSLong(&Buffer, &PlayerIndex);
01782 
01783                                         SetClientProxyPlayer(Client, PlayerIndex);
01784                                         break;
01785                                 }
01786 
01787                                 case NETMGR_MSG_NET_STATE_CHANGE:
01788                                 {
01789                                         NetMgr_NetState NetState;
01790 
01791                                         Buffer_GetSLong(&Buffer, &NetState);
01792 
01793                                         if (!Client_ChangeNetState(Client, NetState))
01794                                                 GenVS_Error("ReadServerMessages:  Client_ChangeNetState failed.\n");
01795 
01796                                         break;
01797                                 }
01798 
01799                                 case NETMGR_MSG_SHUTDOWN:
01800                                 {
01801                                         GenVS_Error("Lost connection with server!!!");
01802                                 }
01803 
01804                                 default:
01805                                 {
01806                                         GenVS_Error("Unknown message from server: %i\n", Type);
01807                                 }
01808                         }
01809                 }
01810 
01811                 // Draw every frame if full speed is set
01812                 if (Client->Demo.Mode == CLIENT_DEMO_PLAY && !Client->Demo.OriginalSpeed)
01813                         break;
01814         }
01815 
01816         // Update the players.  NOTE - This is where this client's view xform gets built.
01817         UpdatePlayers(Client, Time);
01818         
01819 #if 0
01820         {
01821                 /*
01822                 int32   NumMsgSend, NumBytesSend, NumMsgRec, NumBytesRec;
01823 
01824                 if (!NetPlayGetNumMessages(&NumMsgSend, &NumBytesSend, &NumMsgRec, &NumBytesRec))
01825                         GenVS_Error("ReadServerMessages:  NetPlayGetNumMessages failed.\n");
01826                 geEngine_Printf(GameMgr_GetEngine(Client->GMgr), 2, 380, "Msg Queue: %i, %i, %i, %i", NumMsgSend, NumBytesSend, NumMsgRec, NumBytesRec);
01827                 */
01828                 geEngine_Printf(GameMgr_GetEngine(Client->GMgr), 2, 400, "Bytes Received: %i", TotalMsgBytes);
01829         }
01830 #endif
01831 
01832         return GE_TRUE;
01833 }
01834 
01835 //===========================================================================
01836 //      UpdateProxyPlayer
01837 //      On each update from the server, make sure the PROXY players on the
01838 //      PROXY server are up to snuff with the BOSS server...
01839 //===========================================================================
01840 static void UpdateProxyPlayer(Client_Client *Client, GPlayer *Player)
01841 {
01842         int32           PlayerIndex;
01843         geXForm3d       XForm;
01844         GPlayer         *Player2;
01845         int32           i;
01846 
01847         assert(Client_IsValid(Client) == GE_TRUE);
01848 
01849         PlayerIndex = (int32)(Player - Client->Players);
01850 
01851         // Set this player where the server says the player is...
01852         Client_UpdateSinglePlayer(Client, Player, 1.0f, 1.0f, GE_FALSE);
01853 
01854         // If this player, is our client player, replay all the moves that have happened since this update
01855         if (PlayerIndex == Client->ClientPlayer)
01856         {
01857                 Client_Move *Move, *CMove;
01858                 int32           NumMoves2;
01859 
01860                 MHack = GE_TRUE;
01861                 
01862                 geXForm3d_SetEulerAngles(&XForm, &Player->Angles);
01863                 XForm.Translation = Player->Pos;
01864                 Player->LastGoodPos = Player->Pos;
01865 
01866                 Player->XForm = XForm;  
01867 
01868                 //if (LastPlayer != PlayerIndex && LastPlayer != -1)
01869                 //      GenVS_Error("LastPlayer != PlayerIndex");
01870                 
01871                 LastPlayer = PlayerIndex;
01872 
01873                 Move = Client_PeekMove(Client);
01874 
01875                 // Take all the clients moves after this message, and re-run them.
01876                 // We must do this since the server might think we are somewhere in the past, and we
01877                 // need to predict (from the servers position) where we are now...
01878                 for (Move = Client_PeekMove(Client); Move; Move = Client_PeekMove(Client))
01879                 {
01880                         if (Move->Time > Player->SpawnTime)             // Look for moves after this update
01881                                 break;
01882 
01883                         Client_RemoveFirstMove(Client);
01884                 }
01885 
01886                 NumMoves2 = 0;
01887 
01888                 // Re-run all the moves from this time on
01889                 for (CMove = Move; CMove; CMove = CMove->Next)
01890                 {
01891                         NumMoves2++;
01892 
01893                         Client_MoveClientLocally(Client, CMove);
01894                 }
01895                 
01896                 // Destroy all temp players that are before this update
01897                 Player2 = Client->TempPlayers;
01898 
01899                 for (i=0; i< CLIENT_MAX_TEMP_PLAYERS; i++, Player2++)
01900                 {
01901                         if (!Player2->Active)
01902                                 continue;
01903 
01904                         if (Player->SpawnTime < Player2->SpawnTime)     
01905                                 continue;
01906 
01907                         Client_DestroyTempPlayer(Client, Player2);
01908                 }
01909 
01910         }
01911 }
01912 
01913 #define CLIENT_POLY_FLAGS       (GE_RENDER_DEPTH_SORT_BF)
01914 //#define CLIENT_POLY_FLAGS     (GE_RENDER_DO_NOT_OCCLUDE_OTHERS)
01915 
01916 //===========================================================================
01917 //      CheckClientPlayerChanges
01918 //      Simply sees what has changed in a client player.  Stuff like different mesh/actors,
01919 //      lights, etc. 
01920 //===========================================================================
01921 static geBoolean CheckClientPlayerChanges(Client_Client *Client, GPlayer *Player, geBoolean TempPlayer)
01922 {
01923         int32           ViewFlags;
01924         int32           ViewIndex;
01925         int32           PlayerIndex;
01926         geVec3d         PlayerPos;
01927         geWorld         *World;
01928 
01929         assert(Client_IsValid(Client) == GE_TRUE);
01930 
01931         World = GameMgr_GetWorld(Client->GMgr);
01932         assert(World);          // This better be true to be here!!!
01933 
01934         if (TempPlayer) 
01935                 PlayerIndex = CLIENT_TEMP_GPLAYER_TO_INDEX(Client, Player);
01936         else
01937                 PlayerIndex = CLIENT_GPLAYER_TO_INDEX(Client, Player);
01938 
01939         ViewFlags = Player->ViewFlags;
01940         ViewIndex = Player->ViewIndex;
01941 
01942         PlayerPos = Player->Pos;
01943 
01944         if (ViewFlags & VIEW_TYPE_ACTOR)
01945         {
01946                 if (ViewIndex == 0xffff)                                                        // Remove old actors if they are attached...
01947                 {
01948                         if (Player->Actor)
01949                         {
01950                                 geWorld_RemoveActor(World, Player->Actor);
01951                                 geActor_Destroy(&Player->Actor);
01952                                 Player->Actor = NULL;
01953                         }
01954                 }                                                       
01955                 else if (Player->OldViewIndex2 != ViewIndex)            // if the Index changed, then make sure it gets applied
01956                 {
01957                         geActor_Def                     *ActorDef;
01958                         GameMgr_ActorIndex      *ActorIndex;
01959                         geVec3d                         Normal = {0.0f, 1.0f, 0.0f};
01960                         geVec3d                         Mins;
01961                         geVec3d                         Maxs;
01962                         geExtBox                        ExtBox;
01963                         geVec3d                         NullVec = {0.0f, 0.0f, 0.0f};
01964 
01965                         ActorIndex = GameMgr_GetActorIndex(Client->GMgr, ViewIndex);
01966 
01967                         assert(ActorIndex->Active == GE_TRUE);
01968 
01969                         ActorDef = ActorIndex->ActorDef;
01970 
01971                         assert(ActorDef);
01972 
01973                         if (Player->Actor)                                                              // Remove any old actors...
01974                         {
01975                                 geWorld_RemoveActor(World, Player->Actor);
01976                                 geActor_Destroy(&Player->Actor);
01977                                 Player->Actor = NULL;
01978                         }
01979                         
01980                         Mins = Player->Mins;             
01981                         Maxs = Player->Maxs;             
01982 
01983                         assert(geVec3d_Compare(&Mins, &NullVec, 0.01f) == GE_FALSE);
01984                         assert(geVec3d_Compare(&Maxs, &NullVec, 0.01f) == GE_FALSE);
01985                         
01986                         Player->Actor = geActor_Create(ActorDef);
01987 
01988                         if      (!Player->Actor)
01989                                 GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Could not create actor.  ActorDef Name: %s.\n", ActorIndex->FileName);
01990 
01991                         if (Client->ViewPlayer == PlayerIndex && !TempPlayer)                   // Only render viewplayer in mirrors
01992                         {
01993                                 if      (geWorld_AddActor(World, Player->Actor, GE_ACTOR_RENDER_MIRRORS|GE_ACTOR_COLLIDE, 0xffffffff) == GE_FALSE)
01994                                         GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Could not add actor to world.  ActorDef Name: %s.\n", ActorIndex->FileName);
01995                         }
01996                         else
01997                         {
01998                                 if      (geWorld_AddActor(World, Player->Actor, GE_ACTOR_RENDER_NORMAL|GE_ACTOR_COLLIDE, 0xffffffff) == GE_FALSE)
01999                                         GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Could not add actor to world.  ActorDef Name: %s.\n", ActorIndex->FileName);
02000                         }
02001 
02002                         geActor_SetScale(Player->Actor, Player->Scale, Player->Scale, Player->Scale);
02003 
02004                         ExtBox.Min = Mins;
02005                         ExtBox.Max = Maxs;
02006 
02007                         if (!geActor_SetRenderHintExtBox(Player->Actor, &ExtBox, NULL))
02008                                 GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Set actor HintBox failed.\n");
02009                         
02010                         if (!geActor_SetExtBox(Player->Actor, &ExtBox, NULL))
02011                                 GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Set actor AABox failed.\n");
02012 
02013                         if (Client->ViewPlayer == PlayerIndex && !TempPlayer)
02014                         {
02015                                 if (!geActor_SetShadow(Player->Actor, GE_TRUE, 100.0f, GameMgr_GetShadowMap(Client->GMgr), NULL))
02016                                         GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Could not set actor shadow.  ActorDef Name: %s.\n", ActorIndex->FileName);
02017                         }
02018 
02019                         if (!geActor_SetLightingOptions(Player->Actor, GE_TRUE, &Normal, 155.0f, 155.0f, 155.0f, 1.0f, 1.0f, 1.0f, GE_TRUE, 3, NULL, GE_FALSE))
02020                                 GenVS_Error("[CLIENT] CheckClientPlayerChanges:  Could not set actor lighting options.  ActorDef Name: %s.\n", ActorIndex->FileName);
02021 
02022                         geActor_SetUserData(Player->Actor, Player);
02023                         
02024                         Player->ActorDef = ActorDef;
02025                         
02026                 
02027                 }
02028         }
02029         else if (ViewFlags & VIEW_TYPE_MODEL)
02030         {
02031                 if (ViewIndex == 0xffff)
02032                         Player->Model = NULL;
02033                 else
02034                         Player->Model = GameMgr_GetModel(Client->GMgr, ViewIndex);
02035 
02036                 if (Player->Model)
02037                 {
02038                         if (Player->ViewFlags & VIEW_TYPE_MODEL_OPEN)
02039                                 geWorld_OpenModel(World, Player->Model, GE_TRUE);
02040                         else
02041                                 geWorld_OpenModel(World, Player->Model, GE_FALSE);
02042 
02043                         if (Client->Mode == ClientMode_Proxy)
02044                         {
02045                                 geWorld_ModelSetUserData(Player->Model, Player);
02046                         }
02047                 }
02048         }
02049         else if (ViewFlags & VIEW_TYPE_SPRITE)
02050         {
02051                 if (ViewIndex == 0xffff)
02052                 {
02053                         if (Player->Poly)
02054                         {
02055                                 geWorld_RemovePoly(World, Player->Poly);
02056                                 Player->Poly = NULL;
02057                         }
02058                 }
02059                 // if the Index changed, or the Scale changed, then make sure it gets applied
02060                 else if (Player->OldViewIndex2 != ViewIndex || Player->OldScale2 != Player->Scale)              
02061                 {
02062                         geBitmap                                *Bitmap;
02063                         GE_LVertex                              Vert;
02064                         GameMgr_TextureIndex    *TextureIndex;
02065 
02066                         TextureIndex = GameMgr_GetTextureIndex(Client->GMgr, ViewIndex);
02067 
02068                         Bitmap = TextureIndex->TextureDef;
02069 
02070                         assert(Bitmap);
02071 
02072                         if (Bitmap)
02073                         {
02074                                 geVec3d Pos = Player->Pos;
02075 
02076                                 if (Player->Poly)               // Remove any old polys
02077                                         geWorld_RemovePoly(World, Player->Poly);
02078                 
02079                                 Vert.X = Pos.X;
02080                                 Vert.Y = Pos.Y;
02081                                 Vert.Z = Pos.Z;
02082                                 Vert.u = 0.0f;
02083                                 Vert.v = 0.0f;
02084                                 Vert.r = Vert.g = Vert.b = Vert.a = 255.0f;
02085 
02086                                 Player->Poly = 
02087                                         geWorld_AddPoly(World, &Vert, 1, Bitmap, GE_TEXTURED_POINT, 
02088                                                         CLIENT_POLY_FLAGS, Player->Scale * EffectScale);
02089 
02090                                 assert(Player->Poly);
02091                         }
02092                 }
02093         }
02094         
02095         // Lights can be mixed with the others...
02096         if (ViewFlags & VIEW_TYPE_LIGHT)
02097         {
02098                 if (!Player->Light)
02099                 {
02100                         // If the light has not been created yet, create it now...
02101                         Player->Light = geWorld_AddLight(World);
02102 
02103                         // NOTE - That the engine might return NULL.  We are not worried about this, because
02104                         // it juts means there won't be a light for this player...
02105                 }
02106         }
02107         else if (Player->Light)         // Remove the light if there is one...
02108         {
02109                 geWorld_RemoveLight(World, Player->Light);
02110                 Player->Light = NULL;
02111         }
02112 
02113         // Make these flags recent...
02114         Player->OldViewFlags2 = Player->ViewFlags;
02115         Player->OldViewIndex2 = Player->ViewIndex;
02116         Player->OldScale2 = Player->Scale;
02117 
02118         return GE_TRUE;
02119 }
02120 
02121 //=====================================================================================
02122 //      BuildXForm
02123 //=====================================================================================
02124 void BuildXForm(geXForm3d *XForm, const geVec3d *Angles)
02125 {
02126         geVec3d         Pos;
02127 
02128         Pos = XForm->Translation;
02129 
02130         // Clear the matrix
02131         geXForm3d_SetIdentity(XForm);
02132 
02133         // Rotate then translate.
02134         geXForm3d_RotateZ(XForm, Angles->Z);
02135 
02136         geXForm3d_RotateX(XForm, Angles->X);
02137         geXForm3d_RotateY(XForm, Angles->Y);
02138         
02139         geXForm3d_Translate(XForm, Pos.X, Pos.Y, Pos.Z);
02140 
02141 }
02142 
02143 //=====================================================================================
02144 //      BuildClientViewXForm
02145 //      Builds the client view xform
02146 //      Short-curcuits the process by using the local angles that were sent in the last
02147 //      move intention, unless told otherwise by the viewplayer, or demomode...
02148 //=====================================================================================
02149 static void BuildClientViewXForm(Client_Client *Client)
02150 {
02151         geVec3d                 Pos;
02152         GPlayer                 *Player;
02153 
02154         assert(Client_IsValid(Client) == GE_TRUE);
02155 
02156         assert(Client->ViewPlayer >= 0 && Client->ViewPlayer < NETMGR_MAX_PLAYERS);
02157         
02158         Player = &Client->Players[Client->ViewPlayer];
02159 
02160         Client->ViewXForm = Player->XForm;
02161 
02162         if (Client->Demo.Mode != CLIENT_DEMO_PLAY && !(Player->ViewFlags & VIEW_TYPE_FORCE_XFORM))
02163         {
02164                 Pos = Client->ViewXForm.Translation;
02165 
02166                 // Clear the matrix
02167                 geXForm3d_SetIdentity(&Client->ViewXForm);
02168 
02169                 // Rotate then translate.
02170                 geXForm3d_RotateZ(&Client->ViewXForm, Client->Angles.Z);
02171 
02172                 geXForm3d_RotateX(&Client->ViewXForm, Client->Angles.X);
02173                 geXForm3d_RotateY(&Client->ViewXForm, Client->Angles.Y);
02174         
02175                 geXForm3d_Translate(&Client->ViewXForm, Pos.X, Pos.Y, Pos.Z);
02176         }
02177 
02178         // HACK the view height till we get it in 
02179         // Just use a vakue that looks good for now...
02180         Client->ViewXForm.Translation.Y += 140.0f;
02181 }
02182 
02183 //===========================================================================
02184 //      Client_UpdateSinglePlayer
02185 //===========================================================================
02186 geBoolean Client_UpdateSinglePlayer(Client_Client *Client, GPlayer *Player, float Ratio, float Time, geBoolean TempPlayer)
02187 {
02188         geXForm3d               XForm;
02189         geWorld                 *World;
02190 
02191         assert(Client_IsValid(Client) == GE_TRUE);
02192 
02193         World = GameMgr_GetWorld(Client->GMgr);
02194 
02195         // Can't mess with hardly anything if the world is not loaded
02196         // so just return and wait for the world to be loaded...
02197         if (!World)
02198                 return GE_TRUE;
02199 
02200         // Took this out because it was preventing my bots from getting an actor
02201         //if (Client->ViewPlayer == -1)         // Don't do nothing till we know who represents our view
02202         //      return GE_TRUE;
02203         
02204         geXForm3d_SetEulerAngles(&XForm, &Player->Angles);
02205         XForm.Translation = Player->Pos;
02206 
02207         // Save the transform
02208         Player->XForm = XForm;
02209 
02210         // See what has changed recently about the players ViewFlags, ViewIndex, etc...
02211         CheckClientPlayerChanges(Client, Player, TempPlayer);
02212 
02213         // Update any valid world entities that may be attached to this player
02214         if (Player->Light)
02215         {
02216                 GE_RGBA RGBA = {255.0f, 55.0f, 15.0f, 255.0f};
02217                 geWorld_SetLightAttributes(World, Player->Light, 
02218                                                                    &Player->Pos, &RGBA, 320.0f, GE_FALSE);
02219         }
02220 
02221         if (Player->Mesh)
02222         {
02223                 geXForm3d       TXForm;
02224                 geVec3d         In, Up, Lf, Pos;
02225 
02226                 Pos = Player->XForm.Translation;
02227 
02228                 if (Player->ViewFlags & VIEW_TYPE_YAW_ONLY)
02229                 {
02230                         geVec3d_Set(&Up, 0.0f, 1.0f, 0.0f);
02231 
02232                         geXForm3d_GetIn(&Player->XForm, &In);
02233                         geXForm3d_GetLeft(&Player->XForm, &Lf);
02234 
02235                         geVec3d_CrossProduct(&In, &Up, &Lf);
02236                         geVec3d_CrossProduct(&Lf, &Up, &In);
02237 
02238                         geVec3d_Normalize(&Lf);
02239                         geVec3d_Normalize(&In);
02240                 
02241                         geXForm3d_SetFromLeftUpIn(&TXForm, &Lf, &Up, &In);
02242                 }
02243                 else
02244                 {
02245                         TXForm = Player->XForm;
02246                 }
02247 
02248                 TXForm.Translation = Pos;
02249 
02250 #if 0
02251                 geWorld_SetMeshXForm(World, Player->Mesh, &TXForm);
02252                 geWorld_SetMeshFrame(World, Player->Mesh, (int32)Player->FrameTime);
02253 #endif
02254         }
02255 
02256         if (Player->Actor)
02257         {
02258                 geXForm3d                               XForm;
02259                 geVec3d                                 In, Up, Lf, Pos;
02260                 geMotion                                *Motion;
02261                 char                                    *MotionName;
02262                 GameMgr_MotionIndexDef  *MotionIndex;
02263                 
02264                 assert((Player->ViewFlags & VIEW_TYPE_ACTOR));
02265 
02266                 Pos = Player->XForm.Translation;
02267 
02268                 if (Player->ViewFlags & VIEW_TYPE_YAW_ONLY)
02269                 {
02270                         geVec3d_Set(&Up, 0.0f, 1.0f, 0.0f);
02271 
02272                         geXForm3d_GetIn(&Player->XForm, &In);
02273                         geXForm3d_GetLeft(&Player->XForm, &Lf);
02274 
02275                         geVec3d_CrossProduct(&In, &Up, &Lf);
02276                         geVec3d_CrossProduct(&Lf, &Up, &In);
02277 
02278                         geVec3d_Normalize(&Lf);
02279                         geVec3d_Normalize(&In);
02280                 
02281                         geXForm3d_SetFromLeftUpIn(&XForm, &Lf, &Up, &In);
02282                 }
02283                 else
02284                 {
02285                         XForm = Player->XForm;
02286                 }
02287                 
02288                 if (Player->ViewFlags & VIEW_TYPE_ACTOR)
02289                 {
02290                         
02291                         geXForm3d       RXForm;
02292                         geXForm3d_SetXRotation(&RXForm, -(3.14159f/2.0f));
02293                         geXForm3d_Multiply(&XForm, &RXForm, &XForm);
02294                 }
02295                 
02296                 XForm.Translation = Pos;
02297 
02298                 if (Player->MotionIndex == GAMEMGR_MOTION_INDEX_NONE)
02299                 {
02300                         if (!geActor_SetBoneAttachment(Player->Actor, NULL, &XForm))
02301                         {
02302                                 GenVS_Error("Client_UpdateSinglePlayer:  geActor_SetBoneAttachment failed...");
02303                         }
02304                 }
02305                 else
02306                 {
02307                         MotionIndex = GameMgr_GetMotionIndexDef(Client->GMgr, Player->MotionIndex);
02308 
02309                         assert(MotionIndex);
02310                         assert(MotionIndex->Active == GE_TRUE);
02311 
02312                         // Set the base motion and transform
02313                         if (MotionIndex->Active)
02314                         {
02315                                 float FrameTime;
02316                                                         
02317                                 if (Player->FrameTime > Player->OldFrameTime)
02318                                         FrameTime = Player->OldFrameTime + (Player->FrameTime - Player->OldFrameTime) * Ratio;
02319                                 else
02320                                         FrameTime = Player->FrameTime;
02321 
02322                                 MotionName = MotionIndex->MotionName;
02323                         
02324                                 Motion = geActor_GetMotionByName(Player->ActorDef, MotionName);
02325                                 
02326                                 if (!Motion)
02327                                         GenVS_Error("Client_UpdateSinglePlayer:  geActor_GetMotionByName1 failed...");
02328 
02329                                 geActor_SetPose(Player->Actor, Motion, FrameTime, &XForm);
02330                         }
02331                 }
02332 
02333                 // Go through and blend in all the motion hacks...
02334                 {
02335                         int32                           i;
02336                         GPlayer_MotionData      *pMotionData;
02337 
02338                         pMotionData = Player->MotionData;
02339 
02340                         for (i=0; i< Player->NumMotionData; i++, pMotionData++)
02341                         {
02342                                 MotionIndex = GameMgr_GetMotionIndexDef(Client->GMgr, pMotionData->MotionIndex);
02343 
02344                                 assert(MotionIndex->Active == GE_TRUE);
02345 
02346                                 if (!MotionIndex->Active)
02347                                         continue;
02348 
02349                                 Motion = geActor_GetMotionByName(Player->ActorDef, MotionIndex->MotionName);
02350 
02351                                 if (!Motion)
02352                                         GenVS_Error("Client_UpdateSinglePlayer:  geActor_GetMotionByName2 failed...");
02353 
02354                                 geActor_BlendPose(Player->Actor, Motion, pMotionData->MotionTime, &XForm, 1.0f);
02355                         }
02356                 }
02357 
02358                 // Go through and set all the xform hacks for the bones...
02359                 {
02360                         int32                           i;
02361                         GPlayer_XFormData       *pXFormData;
02362                         GameMgr_BoneIndex       *pBoneIndex;
02363                         geXForm3d                       BoneXForm;
02364 
02365                         pXFormData = Player->XFormData;
02366 
02367                         for (i=0; i< Player->NumXFormData; i++, pXFormData++)
02368                         {
02369                                 pBoneIndex = GameMgr_GetBoneIndex(Client->GMgr, pXFormData->BoneIndex);
02370 
02371                                 assert(pBoneIndex->Active == GE_TRUE);
02372 
02373                                 if (!pBoneIndex->Active)
02374                                         continue;
02375 
02376                                 geActor_GetBoneAttachment(Player->Actor, pBoneIndex->BoneName, &BoneXForm);
02377 
02378                                 pXFormData->XForm.Translation = BoneXForm.Translation;
02379 
02380                                 geActor_SetBoneAttachment(Player->Actor, pBoneIndex->BoneName, &pXFormData->XForm);
02381                         }
02382                 }
02383                                 
02384         }
02385 
02386         if (Player->Model)// && !Host->Server)
02387         {
02388                 geWorld_SetModelXForm(World, Player->Model, &XForm);
02389         }
02390 
02391         if (Player->Poly && Player->ViewFlags & VIEW_TYPE_SPRITE)
02392         {
02393                 GE_LVertex      Vert;
02394 
02395                 Vert.X = Player->Pos.X;
02396                 Vert.Y = Player->Pos.Y;
02397                 Vert.Z = Player->Pos.Z;
02398                 Vert.u = 0.0f;
02399                 Vert.v = 0.0f;
02400                 Vert.r = Vert.a = 255.0f;
02401                 Vert.g = Vert.b = 255.0f;
02402 
02403                 gePoly_SetLVertex(Player->Poly, 0, &Vert);
02404         }
02405                         
02406         // Run this players effects
02407         if (TempPlayer)
02408         {
02409                 if (!Fx_PlayerFrame(GameMgr_GetFxSystem(Client->GMgr), TEMP_PLAYER_TO_FXPLAYER(Client, Player), &Player->XForm, Time))
02410                         GenVS_Error("[CLIENT] UpdateSinglePlayer:  Could not run Fx_Player frame.\n");
02411         }
02412         else
02413         {
02414                 if (!Fx_PlayerFrame(GameMgr_GetFxSystem(Client->GMgr), PLAYER_TO_FXPLAYER(Client, Player), &Player->XForm, Time))
02415                         GenVS_Error("[CLIENT] UpdateSinglePlayer:  Could not run Fx_Player frame.\n");
02416         }
02417 
02418         return GE_TRUE;
02419 }
02420 
02421 static void *g_ProcIndex[CLIENT_MAX_PROC_INDEX];
02422 
02423 //===========================================================================
02424 //      Client_GetProcIndex
02425 //===========================================================================
02426 void *Client_GetProcIndex(Client_Client *Client, uint16 Index)
02427 {
02428         assert(Client_IsValid(Client) == GE_TRUE);
02429 
02430         if (Index == CONTROL_INDEX_NONE)
02431                 return NULL;                    // This is NOT an error
02432 
02433         assert( Index >= 0 );
02434         assert( Index < CLIENT_MAX_PROC_INDEX );
02435 
02436         return Client->ProcIndex[Index];
02437 }
02438 
02439 //===========================================================================
02440 //      UpdatePlayers
02441 //===========================================================================
02442 static void UpdatePlayers(Client_Client *Client, float Time)
02443 {
02444         int32                   i;
02445         GPlayer                 *Player;
02446         float                   Ratio, Delta;
02447         geWorld                 *World;
02448 
02449         assert(Client_IsValid(Client) == GE_TRUE);
02450 
02451         World = GameMgr_GetWorld(Client->GMgr);
02452         
02453         if (!World)                             // If no world loaded, then don't do anything...
02454                 return;
02455 
02456         if (Client->ViewPlayer == -1)   // Don't do nothing till we know who represents our view
02457                 return;
02458 
02459         // Find the distance between the last 2 messages from the server
02460         Delta = Client->NetTime - Client->OldNetTime;
02461 
02462         // Try to predict where we will be in between the last 2 messages from the server
02463         if (Delta <= 0.0f)
02464                 Ratio = 1.0f;
02465         else
02466                 Ratio = Client->TempTime / Delta;
02467 
02468         if (Ratio < 0.0f)
02469                 Ratio = 0.0f;
02470         else if (Ratio > 1.0f)
02471                 Ratio = 1.0f;
02472 
02473         // Move from the start of the last message up to the current message...
02474         Client->TempTime += Time;
02475 
02476         for (i=0; i< NETMGR_MAX_PLAYERS; i++)
02477         {
02478                 Player = &Client->Players[i];
02479 
02480                 // If player was not inluded in last update, remove all it's actors/lights/etc from the world
02481                 // and reset this player slot
02482                 if (Player->UpdateTime != Client->NetTime)      
02483                 {
02484                         // Make sure the fx are shutdown for this player
02485                         if (!Fx_PlayerSetFxFlags(GameMgr_GetFxSystem(Client->GMgr), PLAYER_TO_FXPLAYER(Client, Player), 0))
02486                                 GenVS_Error("[CLIENT] UpdatePlayers:  Could not set Fx_Player flags.\n");
02487 
02488                         if (Player->Actor)
02489                         {
02490                                 geWorld_RemoveActor(World, Player->Actor);
02491                                 geActor_Destroy(&Player->Actor);
02492                         }
02493 
02494                         if (Player->Light)
02495                                 geWorld_RemoveLight(World, Player->Light);
02496                         
02497                         if (Player->Poly)
02498                                 geWorld_RemovePoly(World, Player->Poly);
02499 
02500                         // Prepare the player for a fresh renewal later on...
02501                         memset(Player, 0, sizeof(GPlayer));     // Clear the player
02502 
02503                         // Reset player default
02504                         SetPlayerDefaults(Player);
02505                         continue;
02506                 }
02507                 
02508                 Client_UpdateSinglePlayer(Client, Player, 1.0f, Time, GE_FALSE);
02509 
02510         #if 1
02511                 Player->Control = Client_GetProcIndex(Client, Player->ControlIndex);
02512 
02513                 // Call the control code for this player (if it's not this local client), and if not in demo mode
02514                 if (    (Client->Demo.Mode != CLIENT_DEMO_PLAY) 
02515                         &&  (Client->Mode == ClientMode_Proxy)
02516                         &&      (i != Client->ClientPlayer)
02517                         &&  (Player->Control) )
02518                 {
02519                         Player->Control(&Client->GenVSI, Player, Time);
02520                         Player->Pos = Player->XForm.Translation;
02521                 }
02522         #endif
02523                 
02524         
02525         }
02526 
02527         // Build the camera rotation from our local angles, so we can see where we are at...
02528         BuildClientViewXForm(Client);
02529 }
02530 
02531 //=====================================================================================
02532 //      Client_ParsePlayerData
02533 //      If AuxPlayer is not NULL, then that is where the data is read into
02534 //=====================================================================================
02535 GPlayer *Client_ParsePlayerData(Client_Client *Client, Buffer_Data *Buffer, GPlayer *AuxPlayer)
02536 {
02537         uint16                  PlayerIndex;
02538         uint16                  SendFlags, PlayerIndexFlags;
02539         GPlayer                 *pPlayer;
02540 
02541         assert(Client_IsValid(Client) == GE_TRUE);
02542 
02543         Buffer_GetShort(Buffer, &PlayerIndex);
02544 
02545         PlayerIndexFlags = (uint16)(PlayerIndex & (1<<15));
02546         PlayerIndex &= (uint16)0x7FFF;
02547         
02548         if (AuxPlayer)
02549                 pPlayer = AuxPlayer;
02550         else
02551                 pPlayer = &Client->Players[PlayerIndex];
02552 
02553         pPlayer->Active = GE_TRUE;
02554 
02555         pPlayer->UpdateTime = Client->NetTime;          // Make this player recent
02556         
02557         if (!(PlayerIndexFlags & (1<<15)) )
02558         {
02559                 // Fast update, use all old known flags
02560                 pPlayer->SpawnTime = pPlayer->OldSpawnTime;
02561                 pPlayer->ViewFlags = pPlayer->OldViewFlags;
02562                 pPlayer->ViewIndex = pPlayer->OldViewIndex;
02563                 pPlayer->MotionIndex = pPlayer->OldMotionIndex;
02564                 pPlayer->FxFlags = pPlayer->OldFxFlags;
02565 
02566                 if (!AuxPlayer)
02567                 {
02568                         if (!Fx_PlayerSetFxFlags(GameMgr_GetFxSystem(Client->GMgr), PLAYER_TO_FXPLAYER(Client, pPlayer), pPlayer->FxFlags))
02569                                 GenVS_Error("Client_ParsePlayerData:  Fx_PlayerSetFxFlags failed.\n");
02570                 }
02571 
02572                 pPlayer->Pos = pPlayer->OldPos;
02573                 pPlayer->Angles = pPlayer->OldAngles;
02574                 pPlayer->FrameTime = pPlayer->OldFrameTime;
02575                 pPlayer->Scale = pPlayer->OldScale;
02576                 pPlayer->Velocity = pPlayer->OldVelocity;
02577                 pPlayer->State = pPlayer->OldState;
02578                 pPlayer->ControlIndex = pPlayer->OldControlIndex;
02579                 pPlayer->TriggerIndex = pPlayer->OldTriggerIndex;
02580                 pPlayer->Mins = pPlayer->OldMins;
02581                 pPlayer->Maxs = pPlayer->OldMaxs;
02582 
02583                 if (Client->Mode == ClientMode_Proxy)
02584                 {
02585                         // Set the control func here
02586                         if (pPlayer->ControlIndex == 0xffff)
02587                                 pPlayer->Control = NULL;
02588                         else
02589                                 pPlayer->Control = Client->ProcIndex[pPlayer->ControlIndex];
02590 
02591                         // Set the control func here
02592                         if (pPlayer->TriggerIndex == 0xffff)
02593                                 pPlayer->Trigger = NULL;
02594                         else
02595                         {
02596                                 pPlayer->Trigger = Client->ProcIndex[pPlayer->TriggerIndex];
02597                         }
02598                 }
02599 
02600                 return pPlayer;         // Nothing to read, fast update
02601         }
02602         
02603         // See what we need to read for this player
02604         // If somthing changed, we grab it, and store it in the old variable.
02605         // If somthing did not change, we reset it back to the old one..
02606         Buffer_GetShort(Buffer, &SendFlags);
02607 
02608         // Get the data
02609         if (SendFlags & NETMGR_SEND_SPAWN_TIME)
02610         {
02611                 Buffer_GetFloat(Buffer, &pPlayer->SpawnTime);
02612                 pPlayer->OldSpawnTime = pPlayer->SpawnTime;
02613         }
02614         else
02615                 pPlayer->SpawnTime = pPlayer->OldSpawnTime;
02616 
02617         if (SendFlags & NETMGR_SEND_VIEW_FLAGS)
02618         {
02619                 Buffer_GetShort(Buffer, &pPlayer->ViewFlags);
02620                 pPlayer->OldViewFlags = pPlayer->ViewFlags;
02621         }
02622         else
02623                 pPlayer->ViewFlags = pPlayer->OldViewFlags;
02624 
02625         if (SendFlags & NETMGR_SEND_VIEW_INDEX)
02626         {
02627                 Buffer_GetShort(Buffer, &pPlayer->ViewIndex);
02628                 pPlayer->OldViewIndex = pPlayer->ViewIndex;
02629         }
02630         else
02631                 pPlayer->ViewIndex = pPlayer->OldViewIndex;
02632 
02633         if (SendFlags & NETMGR_SEND_MOTION_INDEX)
02634         {
02635                 Buffer_GetByte(Buffer, &pPlayer->MotionIndex);
02636                 pPlayer->OldMotionIndex = pPlayer->MotionIndex;
02637         }
02638         else
02639                 pPlayer->MotionIndex = pPlayer->OldMotionIndex;
02640 
02641         if (SendFlags & NETMGR_SEND_FX_FLAGS)
02642         {
02643                 Buffer_GetShort(Buffer, &pPlayer->FxFlags);
02644                 pPlayer->OldFxFlags = pPlayer->FxFlags;
02645         }
02646         else 
02647                 pPlayer->FxFlags = pPlayer->OldFxFlags;
02648 
02649         if (SendFlags & NETMGR_SEND_POS)
02650         {
02651                 Buffer_GetPos(Buffer, &pPlayer->Pos);
02652                 pPlayer->OldPos = pPlayer->Pos;
02653         }
02654         else
02655                 pPlayer->Pos = pPlayer->OldPos;
02656 
02657         if (SendFlags & NETMGR_SEND_ANGLES)
02658         {
02659                 Buffer_GetAngle(Buffer, &pPlayer->Angles);
02660                 pPlayer->OldAngles = pPlayer->Angles;
02661         }
02662         else
02663                 pPlayer->Angles = pPlayer->OldAngles;
02664 
02665         if (SendFlags & NETMGR_SEND_FRAME_TIME)
02666         {
02667                 Buffer_GetFloat2(Buffer, &pPlayer->FrameTime, 60.0f);
02668                 pPlayer->OldFrameTime = pPlayer->FrameTime;
02669         }
02670         else
02671                 pPlayer->FrameTime = pPlayer->OldFrameTime;
02672 
02673         if (SendFlags & NETMGR_SEND_SCALE)
02674         {
02675                 Buffer_GetFloat2(Buffer, &pPlayer->Scale, 100.0f);
02676                 pPlayer->OldScale = pPlayer->Scale;
02677         }
02678         else
02679                 pPlayer->Scale = pPlayer->OldScale;
02680 
02681         if (SendFlags & NETMGR_SEND_VELOCITY)
02682         {
02683                 Buffer_GetAngle(Buffer, &pPlayer->Velocity);
02684                 pPlayer->OldVelocity = pPlayer->Velocity;
02685         }
02686         else
02687                 pPlayer->Velocity = pPlayer->OldVelocity;
02688 
02689         if (SendFlags & NETMGR_SEND_STATE)
02690         {
02691                 uint8   State;
02692 
02693                 Buffer_GetByte(Buffer, &State);
02694                 pPlayer->State = (GPlayer_PState)State;
02695                 pPlayer->OldState = pPlayer->State;
02696         }
02697         else
02698                 pPlayer->State = pPlayer->OldState;
02699 
02700         if (SendFlags & NETMGR_SEND_CONTROL_INDEX)
02701         {
02702                 pPlayer->OldControlIndex = pPlayer->ControlIndex;
02703                 Buffer_GetShort(Buffer, &pPlayer->ControlIndex);
02704 
02705                 pPlayer->OldControlIndex = pPlayer->ControlIndex;
02706         }
02707         else
02708                 pPlayer->ControlIndex = pPlayer->OldControlIndex;
02709         
02710         if (SendFlags & NETMGR_SEND_TRIGGER_INDEX)
02711         {
02712                 pPlayer->OldTriggerIndex = pPlayer->TriggerIndex;
02713                 Buffer_GetShort(Buffer, &pPlayer->TriggerIndex);
02714 
02715                 pPlayer->OldTriggerIndex = pPlayer->TriggerIndex;
02716         }
02717         else
02718                 pPlayer->TriggerIndex = pPlayer->OldTriggerIndex;
02719 
02720         //      Set control/trigger functions
02721         if (Client->Mode == ClientMode_Proxy)
02722         {
02723                 // Set the control func here
02724                 if (pPlayer->ControlIndex == 0xffff)
02725                         pPlayer->Control = NULL;
02726                 else
02727                         pPlayer->Control = Client->ProcIndex[pPlayer->ControlIndex];
02728 
02729                 // Set the control func here
02730                 if (pPlayer->TriggerIndex == 0xffff)
02731                         pPlayer->Trigger = NULL;
02732                 else
02733                 {
02734                         pPlayer->Trigger = Client->ProcIndex[pPlayer->TriggerIndex];
02735                 }
02736         }
02737 
02738         // Update the players fx system 
02739         if (!AuxPlayer)
02740         {
02741                 if (!Fx_PlayerSetFxFlags(GameMgr_GetFxSystem(Client->GMgr), PLAYER_TO_FXPLAYER(Client, pPlayer), pPlayer->FxFlags))
02742                         GenVS_Error("Client_ParsePlayerData:  Fx_PlayerSetFxFlags failed.\n");
02743         }
02744 
02745         if (SendFlags & NETMGR_SEND_MINS_MAXS)
02746         {
02747                 Buffer_GetPos(Buffer, &pPlayer->Mins);
02748                 Buffer_GetPos(Buffer, &pPlayer->Maxs);
02749 
02750 
02751                 pPlayer->OldMins = pPlayer->Mins;
02752                 pPlayer->OldMaxs = pPlayer->Maxs;
02753         }
02754         else
02755         {
02756                 pPlayer->Mins = pPlayer->OldMins;
02757                 pPlayer->Maxs = pPlayer->OldMaxs;
02758         }
02759 
02760 #if 0
02761         // TOTAL hack for now... (this is a way to get extra xforms in a player for actors
02762         if (pPlayer->ViewFlags & VIEW_TYPE_HACK)
02763         {
02764                 GPlayer_XFormData       *pXFormData;
02765                 int32                           i;
02766                 uint8                           NumXFormData;
02767 
02768                 Buffer_GetByte(Buffer, &NumXFormData);
02769 
02770                 pPlayer->NumXFormData = (uint8)NumXFormData;
02771 
02772                 pXFormData = pPlayer->XFormData;
02773                 
02774                 for (i=0; i<pPlayer->NumXFormData; i++, pXFormData++)
02775                 {
02776                         geVec3d         EulerAngles;
02777 
02778                         Buffer_GetAngle(Buffer, &EulerAngles);
02779                         geXForm3d_SetEulerAngles(&pXFormData->XForm, &EulerAngles);
02780                         Buffer_GetPos(Buffer, &pXFormData->XForm.Translation);
02781                         Buffer_GetByte(Buffer, &pXFormData->BoneIndex);
02782                 }
02783         }
02784         
02785         // TOTAL hack for now... (this is a way to get extra motions in a player for actors
02786         if (pPlayer->ViewFlags & VIEW_TYPE_HACK)
02787         {
02788                 GPlayer_MotionData      *pMotionData;
02789                 int32                           i;
02790                 uint8                           NumMotionData;
02791 
02792                 Buffer_GetByte(Buffer, &NumMotionData);
02793 
02794                 pPlayer->NumMotionData = NumMotionData;
02795 
02796                 pMotionData = pPlayer->MotionData;
02797 
02798                 for (i=0; i<pPlayer->NumMotionData; i++, pMotionData++)
02799                 {
02800                         Buffer_GetFloat(Buffer, &pMotionData->MotionTime);
02801                         Buffer_GetByte(Buffer, &pMotionData->MotionIndex);
02802                 }
02803         }
02804         
02805 #endif
02806         
02807         return pPlayer;
02808 }
02809 
02810 //=====================================================================================
02811 //      ParsePlayerDataLocally
02812 //=====================================================================================
02813 static void ParsePlayerDataLocally(Client_Client *Client, Buffer_Data *Buffer, geBoolean Fake)
02814 {
02815         GPlayer         *Player;
02816 
02817         assert(Client_IsValid(Client) == GE_TRUE);
02818 
02819         if (Fake)
02820         {
02821                 GPlayer         FakePlayer;
02822 
02823                 memset(&FakePlayer, 0, sizeof(GPlayer));
02824 
02825                 Player = Client_ParsePlayerData(Client, Buffer, &FakePlayer);
02826 
02827                 return;
02828         }
02829 
02830         Player = Client_ParsePlayerData(Client, Buffer, NULL);
02831 
02832         if (!Player)
02833                 GenVS_Error("[CLIENT] ParsePlayerDataLocally:  Could not parse data.\n");
02834 
02835 #ifdef PREDICT_CLIENT
02836         // Update the proxy players with this server update
02837         if (Client->Mode == ClientMode_Proxy)
02838                 UpdateProxyPlayer(Client, Player);
02839 #endif
02840 }
02841 
02842 //=====================================================================================
02843 //      RenderWorld
02844 //=====================================================================================
02845 static geBoolean RenderWorld(Client_Client *Client, GameMgr *GMgr, float Time)
02846 {
02847         GE_Rect         Rect;
02848         geCamera        *Camera;
02849         geEngine        *Engine;
02850         geWorld         *World;
02851         int                     Width,Height;
02852 
02853         assert(Client_IsValid(Client) == GE_TRUE);
02854 
02855         World = GameMgr_GetWorld(GMgr);
02856         
02857         if (!World)
02858                 return GE_TRUE;
02859                 
02860         VidMode_GetResolution(Client->VidMode,&Width,&Height);
02861 
02862         Rect.Left = 0;
02863         Rect.Right = Width-1;
02864         Rect.Top = 0;
02865         
02866         if (Width<SMALL_CONSOLE_CUTOFF_WIDTH)
02867                 Rect.Bottom = Height - 1 - CONSOLE_HEIGHT_320;
02868         else
02869                 Rect.Bottom = Height - 1 - CONSOLE_HEIGHT_640;
02870 
02871         Engine = GameMgr_GetEngine(GMgr);
02872         assert(Engine);
02873 
02874         Camera = GameMgr_GetCamera(GMgr);
02875         assert(Camera);
02876 
02877         SetupCamera(Camera, &Rect, &Client->ViewXForm);
02878 
02879         // Run the coronas
02880         if (!Corona_Frame(World, &Client->ViewXForm, Time))
02881                 GenVS_Error("Client_RenderWorld:  Corona_Frame failed.\n");
02882 
02883         // Run the electric stuff
02884         if (!Electric_Frame(World, &Client->ViewXForm, Time))
02885                 GenVS_Error("Client_RenderWorld:  Electric_Frame failed.\n");
02886 
02887         // Run the DynLight stuff
02888         if (!DynLight_Frame(World, &Client->ViewXForm, Time))
02889                 GenVS_Error("Client_RenderWorld:  DynLight_Frame failed.\n");
02890 
02891         // Run the ModelCtl stuff
02892         if (!ModelCtl_Frame(World, &Client->ViewXForm, Time))
02893                 GenVS_Error("Client_RenderWorld:  ModelCtl_Frame failed.\n");
02894 
02895         // Finally, render the world
02896         if (!geEngine_RenderWorld(Engine, World, Camera, Time))
02897                 GenVS_Error("Client_RenderWorld:  geEngine_RenderWorld failed.\n");
02898 
02899         return GE_TRUE;
02900 }
02901 
02902 //=====================================================================================
02903 //      SetupCamera
02904 //=====================================================================================
02905 static void SetupCamera(geCamera *Camera, geRect *Rect, geXForm3d *XForm)
02906 {
02907         geCamera_SetWorldSpaceXForm(Camera, XForm);
02908         geCamera_SetAttributes(Camera, 2.0f, Rect);
02909 }
02910 
02911 //=====================================================================================
02912 //      Client_ChangeNetState
02913 //=====================================================================================
02914 geBoolean Client_ChangeNetState(Client_Client *Client, NetMgr_NetState NewNetState)
02915 {
02916         char            Data[128];
02917         Buffer_Data     Buffer;
02918 
02919         assert(Client_IsValid(Client) == GE_TRUE);
02920 
02921         Client->NetState = NewNetState;
02922                                                                 
02923         // Send the confirm msg to the server
02924         Buffer_Set(&Buffer, Data, 128);
02925         Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_CONFIRM);
02926         Buffer_FillSLong(&Buffer, NewNetState);
02927 
02928         if (!NetMgr_SendServerMessage(Client->NMgr, &Buffer, GE_TRUE))
02929                 GenVS_Error("Client_ChangeNetState:  NetMgr_SendServerMessage failed.\n");
02930 
02931         return GE_TRUE;
02932 }
02933 
02934 //===========================================================================
02935 //      Client_SetDemo
02936 //===========================================================================
02937 geBoolean Client_SetDemo(Client_Client *Client, int32 DemoNum)
02938 {
02939         assert(Client_IsValid(Client) == GE_TRUE);
02940         assert(DemoNum < Client->Demo.NumDemos);
02941         assert(Client->Demo.Mode == CLIENT_DEMO_PLAY);
02942 
02943         // Close down any old demo data files
02944         if (Client->Demo.File)
02945                 fclose(Client->Demo.File);
02946 
02947         // Store current demo num
02948         Client->Demo.CurrentDemo = DemoNum;
02949 
02950         Client->Demo.File = fopen(Client->Demo.DemoNames[Client->Demo.CurrentDemo], "rb");
02951                 
02952         if (!Client->Demo.File)
02953                 GenVS_Error("Client_SetDemo:  Failed to open demo file: %s.\n", Client->Demo.DemoNames[Client->Demo.CurrentDemo]);
02954 
02955         return GE_TRUE;
02956 }
02957 
02958 char    DemoBuffer[NETMGR_LOCAL_MSG_BUFFER_SIZE];
02959 //=====================================================================================
02960 //      Client_ReadServerMessages
02961 //      Keeps on returning true till the clients time passes the hosts current time.
02962 //      This keeps frame rates the same on all machines...
02963 //=====================================================================================
02964 geBoolean Client_ReadServerMessages(Client_Client *Client, Buffer_Data *Buffer)
02965 {
02966         geCSNetMgr_NetMsgType   MsgType;
02967 
02968         assert(Client_IsValid(Client) == GE_TRUE);
02969 
02970         // Reset the buffer pos
02971         Buffer->Pos = 0;
02972 
02973         if (Client->Demo.Mode == CLIENT_DEMO_PLAY)              // If demo play mode, get message from file
02974         {
02975                 geBoolean       Good = GE_FALSE;
02976 
02977                 Buffer->Data = DemoBuffer;
02978 
02979                 assert(Client->Demo.File);
02980                 
02981                 // Make the demo run at it's original recorded speed...
02982                 if (Client->Demo.OriginalSpeed)
02983                         if (Client->Time <= Client->NetTime)
02984                                 return GE_FALSE;        // Wait till client catches up with the demo
02985                 
02986                 if (fread(&Buffer->Size, sizeof(int32), 1, Client->Demo.File) == 1)
02987                 {
02988                         if (Buffer->Size >= NETMGR_LOCAL_MSG_BUFFER_SIZE)
02989                                 GenVS_Error("Client_ReadServerMessages:  Demo Buffer size can't hold data.\n");
02990 
02991                         if (fread(Buffer->Data, sizeof(char), Buffer->Size, Client->Demo.File) == (uint32)Buffer->Size)
02992                                 Good = GE_TRUE;
02993                 }
02994 
02995                 if (!Good)              // End of file, try the beginning...
02996                 {
02997                         Client->Time = 0.0f;
02998                         Client->NetTime = 0.0f;
02999                         
03000                         // Reset the scoreboard between demo changes...
03001                         memset(Client->ClientInfo, 0, sizeof(Client_ClientInfo)*NETMGR_MAX_CLIENTS);
03002 
03003                         if (!Client_SetDemo(Client, (Client->Demo.CurrentDemo+1)%Client->Demo.NumDemos))
03004                         {
03005                                 Client->Demo.Mode = CLIENT_DEMO_NONE;
03006                                 return GE_TRUE;
03007                         }
03008                         
03009                         //GenVS_Error("End of demo.\n");
03010                         fseek(Client->Demo.File, 0, SEEK_SET);
03011 
03012                         if (fread(&Buffer->Size, sizeof(int32), 1, Client->Demo.File) != 1)
03013                                 GenVS_Error("Error reading the demo file.\n");
03014 
03015                         if (fread(Buffer->Data, sizeof(char), Buffer->Size, Client->Demo.File) != (uint32)Buffer->Size)
03016                                 GenVS_Error("Error reading the demo file.\n");
03017                 }
03018 
03019                 return GE_TRUE;
03020         }
03021 
03022         while (1)
03023         {
03024                 if (!NetMgr_ReceiveServerMessage(Client->NMgr, &MsgType, Buffer))
03025                         GenVS_Error("Client_ReadServerMessages:  NetMgr_ReceiveServerMessage failed.\n");
03026 
03027                 if (MsgType == NET_MSG_SESSIONLOST)
03028                         GenVS_Error("Client_ReadServerMessages:  Session was lost.\n");
03029 
03030                 if (MsgType == NET_MSG_NONE)
03031                         return GE_FALSE;
03032 
03033                 if (MsgType == NET_MSG_USER)
03034                         break;
03035         }
03036 
03037         // Check to see if the buffer has data
03038         if (!Buffer->Size)
03039                 return GE_FALSE;
03040 
03041         // Record the message
03042         if (Client->Demo.Mode == CLIENT_DEMO_RECORD)    // Record messages for DemoRecord mode
03043         {
03044                 assert(Client->Demo.File);
03045                 fwrite(&Buffer->Size, 1, sizeof(int32), Client->Demo.File);
03046                 fwrite(Buffer->Data, Buffer->Size, 1, Client->Demo.File);
03047         }
03048 
03049         return GE_TRUE;
03050 }
03051 
03052 char    TempDemoName[CLIENT_MAX_DEMO_NAME_SIZE];
03053 
03054 //===========================================================================
03055 //      ParseDemoName
03056 //===========================================================================
03057 static const char *ParseDemoName(FILE *f)
03058 {
03059         char    *pName;
03060         char    c;
03061 
03062         // Skip white space
03063         while (1)
03064         {
03065                 if (fread(&c, 1, sizeof(char), f) != 1)
03066                         return NULL;
03067 
03068                 if (c != ' ' && c != 0x0d)
03069                         break;
03070         }
03071 
03072         if (c == '\n')
03073                 return NULL;
03074 
03075         pName = TempDemoName;
03076 
03077         *pName++ = c;                   // store the first char
03078 
03079         while (1)
03080         {
03081                 if (fread(&c, 1, sizeof(char), f) != 1)
03082                         return NULL;
03083 
03084                 if (c == 0x0d)
03085                         continue;
03086 
03087                 //if (c == ' ')
03088                 //      continue;                       // Skip white space
03089 
03090                 *pName = c;                     // store it...
03091 
03092                 if ((int32)(pName - TempDemoName) >= CLIENT_MAX_DEMO_NAME_SIZE)
03093                         return NULL;
03094 
03095                 if (c == '\n')
03096                 {
03097                         *pName = 0;
03098                         break;
03099                 }
03100 
03101                 pName++;
03102 
03103         }
03104 
03105         return TempDemoName;
03106 }
03107 
03108 //===========================================================================
03109 //      ReadDemoIni
03110 //===========================================================================
03111 static geBoolean ReadDemoIni(Client_Client *Client)
03112 {
03113         FILE    *f;
03114 
03115         assert(Client_IsValid(Client) == GE_TRUE);
03116 
03117         // Open, and parse out the demo names from the demo data file...
03118         f = fopen("Demo.Ini", "r");
03119 
03120         if (!f)
03121                 return GE_FALSE;
03122 
03123         while (1)
03124         {
03125                 const char      *Name;
03126 
03127                 Name = ParseDemoName(f);
03128 
03129                 if (!Name)
03130                         break;
03131 
03132                 strcpy(Client->Demo.DemoNames[Client->Demo.NumDemos], Name);
03133                 Client->Demo.NumDemos++;
03134 
03135                 if (Client->Demo.NumDemos >= CLIENT_MAX_DEMOS)
03136                         break;          // No more demo slots available
03137         }
03138 
03139         // Close the file
03140         fclose(f);
03141 
03142         // Make sure there is at least one demo
03143         if (Client->Demo.NumDemos <= 0)
03144         {
03145                 Client->Demo.Mode = CLIENT_DEMO_NONE;           // No demos names in demo file...
03146                 return GE_FALSE;
03147         }
03148 
03149         return GE_TRUE;
03150 }
03151 
03152 //===========================================================================
03153 //      Client_SetupDemos
03154 //===========================================================================
03155 geBoolean Client_SetupDemos(Client_Client *Client, int32 Mode, const char *DemoFile)
03156 {
03157         assert(Client);
03158 
03159         assert(Client_IsValid(Client) == GE_TRUE);
03160 
03161         Client->Demo.Mode = Mode;
03162         Client->Demo.OriginalSpeed = GE_TRUE;
03163 
03164         Client->Demo.NumDemos = 0;
03165         Client->Demo.CurrentDemo = 0;
03166 
03167         Client->Demo.File = NULL;
03168         
03169         if (Client->Demo.Mode == CLIENT_DEMO_RECORD)
03170         {
03171                 assert(DemoFile && DemoFile[0]);
03172 
03173                 Client->Demo.File = fopen(DemoFile, "wb");
03174 
03175                 if (!Client->Demo.File)
03176                         return GE_FALSE;
03177 
03178                 return GE_TRUE;
03179         }
03180         else if (Client->Demo.Mode == CLIENT_DEMO_PLAY && DemoFile[0])
03181         {
03182                 Client->Demo.NumDemos = 1;
03183                 Client->Demo.CurrentDemo = 0;
03184                 strcpy(Client->Demo.DemoNames[0], DemoFile);
03185         }
03186         else if (Client->Demo.Mode == CLIENT_DEMO_PLAY && !DemoFile[0])
03187         {
03188                 if (!ReadDemoIni(Client))
03189                         return GE_FALSE;
03190         }
03191 
03192         if (Client->Demo.Mode == CLIENT_DEMO_PLAY)
03193         {
03194                 if (!Client_SetDemo(Client, Client->Demo.CurrentDemo))
03195                         return GE_FALSE;
03196         }
03197 
03198         return GE_TRUE;
03199 }
03200 
03201 //*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
03202 //*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
03203 //*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
03204 //*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
03205 
03206 
03207 //=====================================================================================
03208 //=====================================================================================
03209 static float Client_GetTime(Client_Client *Client)
03210 {
03211         assert(Client_IsValid(Client) == GE_TRUE);
03212 
03213         return GameMgr_GetTime(Client->GMgr);
03214 }
03215 
03216 //=====================================================================================
03217 //      Client_GetWorld
03218 //=====================================================================================
03219 geWorld *Client_GetWorld(Client_Client *Client)
03220 {
03221         assert(Client_IsValid(Client) == GE_TRUE);
03222 
03223         return GameMgr_GetWorld(Client->GMgr);
03224 }
03225 
03226 //=====================================================================================
03227 //      Client_GetClientMove
03228 //=====================================================================================
03229 static GenVSI_CMove *Client_GetClientMove(Client_Client *Client, GenVSI_CHandle ClientHandle)
03230 {
03231         assert(Client_IsValid(Client) == GE_TRUE);
03232 
03233         // Return NULL if it is not us we are controlling
03234         // For now, the game code should return on a NULL move...
03235         if (ClientHandle == Client->ClientIndex)
03236                 return &Client->Move;
03237         else
03238                 return NULL;
03239 }
03240 
03241 //=====================================================================================
03242 //      Client_ProcIndex
03243 //=====================================================================================
03244 static void Client_ProcIndex(Client_Client *Client, uint16 Index, void *Proc)
03245 {
03246         assert(Client_IsValid(Client) == GE_TRUE);
03247         assert(Index >= 0 && Index < 65535);
03248         assert(Index >= 0 && Index < CLIENT_MAX_PROC_INDEX);
03249         
03250         Client->ProcIndex[Index] = Proc;
03251 
03252         g_ProcIndex[Index] = Proc;
03253 }
03254 
03255 //=====================================================================================
03256 //      Server_MovePlayerModel
03257 //=====================================================================================
03258 static geBoolean Client_MovePlayerModel(Client_Client *Client, GPlayer *Player, const geXForm3d *DestXForm)
03259 {
03260         geBoolean       CanMove;
03261         int32           i;
03262         geWorld         *World;
03263 
03264         assert(Client_IsValid(Client) == GE_TRUE);
03265 
03266         World = GameMgr_GetWorld(Client->GMgr);
03267         assert(World);
03268 
03269         CanMove = GE_TRUE;
03270 
03271         for (i=0; i< NETMGR_MAX_PLAYERS; i++)
03272         {
03273                 geVec3d         Mins, Maxs, Pos, Out;
03274                 GPlayer         *Target;
03275 
03276                 Target = &Client->Players[i];
03277 
03278                 if (!Target->Active)                    // Not an active player...
03279                         continue;
03280 
03281                 if (Target->ViewFlags & VIEW_TYPE_MODEL)        // Don't check other models, don't care...
03282                         continue;
03283 
03284                 if (i != Client->ClientPlayer)
03285                         continue;
03286 
03287                 Mins = Target->Mins;
03288                 Maxs = Target->Maxs;
03289 
03290                 Pos = Target->XForm.Translation;
03291 
03292                 // Test the models move intentions agianst all the players in the level
03293                 if (!geWorld_TestModelMove(World, Player->Model, DestXForm, &Mins, &Maxs, &Pos, &Out))
03294                 {
03295                         CanMove = GE_FALSE;             // Can't move, would've pushed player into world
03296 
03297                         // The model was blocked by player target
03298                         if (Player->Blocked)    // Call the blocked callback, and tell Player that Target is in the way..
03299                         {
03300                                 Player->Blocked(&Client->GenVSI, Player, Target);
03301                         }
03302 
03303                 }
03304                 else
03305                 {
03306                         Target->XForm.Translation = Out;
03307                         Target->Pos = Out;
03308                         Target->LastGoodPos = Out;
03309                 }
03310         }
03311 
03312         if (CanMove)
03313         {
03314                 if (World)
03315                         geWorld_SetModelXForm(World, Player->Model, DestXForm);
03316                 else
03317                         Console_Printf(GameMgr_GetConsole(Client->GMgr), "Client_MovePlayerModel:  No world!\n");
03318 
03319                 Player->Pos = DestXForm->Translation;
03320                 Player->XForm.Translation = DestXForm->Translation;
03321         }
03322 
03323         return CanMove;
03324 }
03325 
03326 
03327 //=====================================================================================
03328 //      Client_SpawnTempPlayer
03329 //=====================================================================================
03330 static GPlayer *Client_SpawnTempPlayer(Client_Client *Client, const char *ClassName)
03331 {
03332         int32           i;
03333 
03334         assert(Client_IsValid(Client) == GE_TRUE);
03335         assert(strlen(ClassName) < MAX_CLASS_NAME_SIZE);
03336 
03337         for (i=0; i< CLIENT_MAX_TEMP_PLAYERS; i++)
03338         {
03339                 if (!Client->TempPlayers[i].Active)
03340                         break;
03341         }
03342 
03343         if (i >= CLIENT_MAX_TEMP_PLAYERS)
03344         {
03345                 GenVS_Error("Client_SpawnTempPlayer: Failed to add player!!!\n");
03346                 return NULL;
03347         }
03348 
03349         memset(&Client->TempPlayers[i], 0, sizeof(GPlayer));
03350 
03351         SetPlayerDefaults(&Client->TempPlayers[i]);
03352 
03353         Client->TempPlayers[i].Active = GE_TRUE;
03354         Client->TempPlayers[i].SpawnTime = Client->Move.MoveTime;
03355 
03356         return &Client->TempPlayers[i];
03357 }
03358 
03359 //=====================================================================================
03360 //      Client_DestroyPlayerWorldObjects
03361 //=====================================================================================
03362 void Client_DestroyPlayerWorldObjects(Client_Client *Client, GPlayer *Player)
03363 {
03364         geBoolean       Ret;
03365         geWorld         *World;
03366 
03367         World = GameMgr_GetWorld(Client->GMgr);
03368 
03369         if (Player->Actor)
03370         {
03371                 assert(World);
03372                 Ret = geWorld_RemoveActor(World, Player->Actor);
03373                 assert(Ret == GE_TRUE);
03374                 geActor_Destroy(&Player->Actor);
03375         }
03376 
03377         if (Player->Light)
03378         {
03379                 assert(World);
03380                 geWorld_RemoveLight(World, Player->Light);
03381         }
03382                         
03383         if (Player->Poly)
03384         {
03385                 assert(World);
03386                 geWorld_RemovePoly(World, Player->Poly);
03387         }
03388 }
03389 
03390 //=====================================================================================
03391 //      Client_DestroyTempPlayer
03392 //=====================================================================================
03393 void Client_DestroyTempPlayer(Client_Client *Client, GPlayer *Player)
03394 {
03395         assert(Client_IsValid(Client) == GE_TRUE);
03396         assert(Player);
03397 
03398         assert(Player->Active);
03399 
03400         //if (!Fx_PlayerSetFxFlags(GameMgr_GetFxSystem(Client->GMgr), TEMP_PLAYER_TO_FXPLAYER(Client, Player), 0))
03401         //      GenVS_Error("[CLIENT] UpdatePlayers:  Could not set Fx_Player flags.\n");
03402 
03403         Client_DestroyPlayerWorldObjects(Client, Player);
03404 
03405         memset(Player, 0, sizeof(GPlayer));
03406 }
03407 
03408 //=====================================================================================
03409 //      Client_GetPlayer
03410 //=====================================================================================
03411 GPlayer *Client_GetPlayer(Client_Client *Client, int32 Index)
03412 {
03413         assert(Client_IsValid(Client) == GE_TRUE);
03414         assert(Index >= 0);
03415         assert(Index < NETMGR_MAX_PLAYERS);
03416 
03417         return &Client->Players[Index];
03418 }
03419 
03420 //=====================================================================================
03421 //      Client_DestroyPlayer
03422 //=====================================================================================
03423 void Client_DestroyPlayer(Client_Client *Client, GPlayer *Player)
03424 {
03425         assert(Client_IsValid(Client) == GE_TRUE);
03426         assert(Player);
03427 
03428         assert(Player->Active);
03429 
03430         if (!Fx_PlayerSetFxFlags(GameMgr_GetFxSystem(Client->GMgr), PLAYER_TO_FXPLAYER(Client, Player), 0))
03431                 GenVS_Error("[CLIENT] UpdatePlayers:  Could not set Fx_Player flags.\n");
03432 
03433         Client_DestroyPlayerWorldObjects(Client, Player);
03434 
03435         memset(Player, 0, sizeof(GPlayer));
03436 }
03437 
03438 
03439 //=====================================================================================
03440 //      Client_SetupGenVSI
03441 //=====================================================================================
03442 static void Client_SetupGenVSI(Client_Client *Client)
03443 {
03444         GenVSI  *VSI;
03445 
03446         assert(Client_IsValid(Client) == GE_TRUE);
03447 
03448         VSI = &Client->GenVSI;
03449 
03450         memset(VSI, 0, sizeof(GenVSI));
03451 
03452         VSI->Mode = MODE_SmartClient;
03453 
03454         VSI->UData = Client;
03455 
03456         VSI->GetTime = Client_GetTime;
03457 
03458         VSI->MovePlayerModel = Client_MovePlayerModel;
03459         
03460         VSI->GetWorld = Client_GetWorld;
03461         VSI->GetClientMove = Client_GetClientMove;
03462 
03463         VSI->ProcIndex = Client_ProcIndex;
03464 
03465         VSI->SpawnPlayer = Client_SpawnTempPlayer;
03466         VSI->DestroyPlayer = Client_DestroyTempPlayer;
03467 }

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