00001 //=============================================================================
00002 // Console: A player console, associated with a viewport.
00003 // This is a built-in Unreal class and it shouldn't be modified.
00004 //=============================================================================
00005 class Console extends Object
00006 native
00007 noexport
00008 transient;
00009
00010 // Imports.
00011 #exec Texture Import NAME=ConsoleBack File=Textures\Console.pcx
00012 #exec Texture Import File=Textures\Border.pcx
00013
00014 // Internal.
00015 var private const int vtblOut;
00016
00017 // Constants.
00018 const MaxBorder=6;
00019 const MaxLines=64;
00020 const MaxHistory=16;
00021 const TextMsgSize=128;
00022
00023 // Variables.
00024 var viewport Viewport;
00025 var int HistoryTop, HistoryBot, HistoryCur;
00026 var string TypedStr, History[16];
00027 var int Scrollback, NumLines, TopLine, TextLines;
00028 var float MsgTime, MsgTickTime;
00029 var string MsgText[64];
00030 var name MsgType[64];
00031 var PlayerReplicationInfo MsgPlayer[64];
00032 var float MsgTick[64];
00033 var int BorderSize;
00034 var int ConsoleLines, BorderLines, BorderPixels;
00035 var float ConsolePos, ConsoleDest;
00036 var float FrameX, FrameY;
00037 var texture ConBackground, Border;
00038 var bool bNoStuff, bTyping;
00039 var bool bNoDrawWorld;
00040
00041 // Timedemo
00042 var bool bTimeDemo;
00043 var bool bStartTimeDemo;
00044 var bool bRestartTimeDemo;
00045 var bool bSaveTimeDemoToFile;
00046 var float StartTime;
00047 var float ExtraTime;
00048 var float LastFrameTime;
00049 var float LastSecondStartTime;
00050 var int FrameCount;
00051 var int LastSecondFrameCount;
00052 var float MinFPS;
00053 var float MaxFPS;
00054 var float LastSecFPS;
00055 var Font TimeDemoFont;
00056
00057 var localized string LoadingMessage;
00058 var localized string SavingMessage;
00059 var localized string ConnectingMessage;
00060 var localized string PausedMessage;
00061 var localized string PrecachingMessage;
00062
00063 var localized string FrameRateText;
00064 var localized string AvgText;
00065 var localized string LastSecText;
00066 var localized string MinText;
00067 var localized string MaxText;
00068 var localized string fpsText;
00069 var localized string SecondsText;
00070 var localized string FramesText;
00071
00072 //-----------------------------------------------------------------------------
00073 // Input.
00074
00075 // Input system states.
00076 enum EInputAction
00077 {
00078 IST_None, // Not performing special input processing.
00079 IST_Press, // Handling a keypress or button press.
00080 IST_Hold, // Handling holding a key or button.
00081 IST_Release, // Handling a key or button release.
00082 IST_Axis, // Handling analog axis movement.
00083 };
00084
00085 // Input keys.
00086 enum EInputKey
00087 {
00088 /*00*/ IK_None ,IK_LeftMouse ,IK_RightMouse ,IK_Cancel ,
00089 /*04*/ IK_MiddleMouse ,IK_Unknown05 ,IK_Unknown06 ,IK_Unknown07 ,
00090 /*08*/ IK_Backspace ,IK_Tab ,IK_Unknown0A ,IK_Unknown0B ,
00091 /*0C*/ IK_Unknown0C ,IK_Enter ,IK_Unknown0E ,IK_Unknown0F ,
00092 /*10*/ IK_Shift ,IK_Ctrl ,IK_Alt ,IK_Pause ,
00093 /*14*/ IK_CapsLock ,IK_Unknown15 ,IK_Unknown16 ,IK_Unknown17 ,
00094 /*18*/ IK_Unknown18 ,IK_Unknown19 ,IK_Unknown1A ,IK_Escape ,
00095 /*1C*/ IK_Unknown1C ,IK_Unknown1D ,IK_Unknown1E ,IK_Unknown1F ,
00096 /*20*/ IK_Space ,IK_PageUp ,IK_PageDown ,IK_End ,
00097 /*24*/ IK_Home ,IK_Left ,IK_Up ,IK_Right ,
00098 /*28*/ IK_Down ,IK_Select ,IK_Print ,IK_Execute ,
00099 /*2C*/ IK_PrintScrn ,IK_Insert ,IK_Delete ,IK_Help ,
00100 /*30*/ IK_0 ,IK_1 ,IK_2 ,IK_3 ,
00101 /*34*/ IK_4 ,IK_5 ,IK_6 ,IK_7 ,
00102 /*38*/ IK_8 ,IK_9 ,IK_Unknown3A ,IK_Unknown3B ,
00103 /*3C*/ IK_Unknown3C ,IK_Unknown3D ,IK_Unknown3E ,IK_Unknown3F ,
00104 /*40*/ IK_Unknown40 ,IK_A ,IK_B ,IK_C ,
00105 /*44*/ IK_D ,IK_E ,IK_F ,IK_G ,
00106 /*48*/ IK_H ,IK_I ,IK_J ,IK_K ,
00107 /*4C*/ IK_L ,IK_M ,IK_N ,IK_O ,
00108 /*50*/ IK_P ,IK_Q ,IK_R ,IK_S ,
00109 /*54*/ IK_T ,IK_U ,IK_V ,IK_W ,
00110 /*58*/ IK_X ,IK_Y ,IK_Z ,IK_Unknown5B ,
00111 /*5C*/ IK_Unknown5C ,IK_Unknown5D ,IK_Unknown5E ,IK_Unknown5F ,
00112 /*60*/ IK_NumPad0 ,IK_NumPad1 ,IK_NumPad2 ,IK_NumPad3 ,
00113 /*64*/ IK_NumPad4 ,IK_NumPad5 ,IK_NumPad6 ,IK_NumPad7 ,
00114 /*68*/ IK_NumPad8 ,IK_NumPad9 ,IK_GreyStar ,IK_GreyPlus ,
00115 /*6C*/ IK_Separator ,IK_GreyMinus ,IK_NumPadPeriod,IK_GreySlash ,
00116 /*70*/ IK_F1 ,IK_F2 ,IK_F3 ,IK_F4 ,
00117 /*74*/ IK_F5 ,IK_F6 ,IK_F7 ,IK_F8 ,
00118 /*78*/ IK_F9 ,IK_F10 ,IK_F11 ,IK_F12 ,
00119 /*7C*/ IK_F13 ,IK_F14 ,IK_F15 ,IK_F16 ,
00120 /*80*/ IK_F17 ,IK_F18 ,IK_F19 ,IK_F20 ,
00121 /*84*/ IK_F21 ,IK_F22 ,IK_F23 ,IK_F24 ,
00122 /*88*/ IK_Unknown88 ,IK_Unknown89 ,IK_Unknown8A ,IK_Unknown8B ,
00123 /*8C*/ IK_Unknown8C ,IK_Unknown8D ,IK_Unknown8E ,IK_Unknown8F ,
00124 /*90*/ IK_NumLock ,IK_ScrollLock ,IK_Unknown92 ,IK_Unknown93 ,
00125 /*94*/ IK_Unknown94 ,IK_Unknown95 ,IK_Unknown96 ,IK_Unknown97 ,
00126 /*98*/ IK_Unknown98 ,IK_Unknown99 ,IK_Unknown9A ,IK_Unknown9B ,
00127 /*9C*/ IK_Unknown9C ,IK_Unknown9D ,IK_Unknown9E ,IK_Unknown9F ,
00128 /*A0*/ IK_LShift ,IK_RShift ,IK_LControl ,IK_RControl ,
00129 /*A4*/ IK_UnknownA4 ,IK_UnknownA5 ,IK_UnknownA6 ,IK_UnknownA7 ,
00130 /*A8*/ IK_UnknownA8 ,IK_UnknownA9 ,IK_UnknownAA ,IK_UnknownAB ,
00131 /*AC*/ IK_UnknownAC ,IK_UnknownAD ,IK_UnknownAE ,IK_UnknownAF ,
00132 /*B0*/ IK_UnknownB0 ,IK_UnknownB1 ,IK_UnknownB2 ,IK_UnknownB3 ,
00133 /*B4*/ IK_UnknownB4 ,IK_UnknownB5 ,IK_UnknownB6 ,IK_UnknownB7 ,
00134 /*B8*/ IK_UnknownB8 ,IK_UnknownB9 ,IK_Semicolon ,IK_Equals ,
00135 /*BC*/ IK_Comma ,IK_Minus ,IK_Period ,IK_Slash ,
00136 /*C0*/ IK_Tilde ,IK_UnknownC1 ,IK_UnknownC2 ,IK_UnknownC3 ,
00137 /*C4*/ IK_UnknownC4 ,IK_UnknownC5 ,IK_UnknownC6 ,IK_UnknownC7 ,
00138 /*C8*/ IK_Joy1 ,IK_Joy2 ,IK_Joy3 ,IK_Joy4 ,
00139 /*CC*/ IK_Joy5 ,IK_Joy6 ,IK_Joy7 ,IK_Joy8 ,
00140 /*D0*/ IK_Joy9 ,IK_Joy10 ,IK_Joy11 ,IK_Joy12 ,
00141 /*D4*/ IK_Joy13 ,IK_Joy14 ,IK_Joy15 ,IK_Joy16 ,
00142 /*D8*/ IK_UnknownD8 ,IK_UnknownD9 ,IK_UnknownDA ,IK_LeftBracket ,
00143 /*DC*/ IK_Backslash ,IK_RightBracket,IK_SingleQuote ,IK_UnknownDF ,
00144 /*E0*/ IK_JoyX ,IK_JoyY ,IK_JoyZ ,IK_JoyR ,
00145 /*E4*/ IK_MouseX ,IK_MouseY ,IK_MouseZ ,IK_MouseW ,
00146 /*E8*/ IK_JoyU ,IK_JoyV ,IK_UnknownEA ,IK_UnknownEB ,
00147 /*EC*/ IK_MouseWheelUp ,IK_MouseWheelDown,IK_Unknown10E,UK_Unknown10F ,
00148 /*F0*/ IK_UnknownF0 ,IK_UnknownF1 ,IK_UnknownF2 ,IK_UnknownF3 ,
00149 /*F4*/ IK_UnknownF4 ,IK_UnknownF5 ,IK_Attn ,IK_CrSel ,
00150 /*F8*/ IK_ExSel ,IK_ErEof ,IK_Play ,IK_Zoom ,
00151 /*FC*/ IK_NoName ,IK_PA1 ,IK_OEMClear
00152 };
00153
00154 //-----------------------------------------------------------------------------
00155 // natives.
00156
00157 // Execute a command on this console.
00158 native function bool ConsoleCommand( coerce string S );
00159 native function SaveTimeDemo( string S );
00160
00161 //-----------------------------------------------------------------------------
00162 // Exec functions accessible from the console and key bindings.
00163
00164 // Begin typing a command on the console.
00165 exec function Type()
00166 {
00167 TypedStr="";
00168 GotoState( 'Typing' );
00169 }
00170
00171 exec function Talk()
00172 {
00173 TypedStr="Say ";
00174 bNoStuff = true;
00175 GotoState( 'Typing' );
00176 }
00177
00178 exec function TeamTalk()
00179 {
00180 TypedStr="TeamSay ";
00181 bNoStuff = true;
00182 GotoState( 'Typing' );
00183 }
00184
00185 // Size the view up.
00186 exec function ViewUp()
00187 {
00188 BorderSize = Clamp( BorderSize-1, 0, MaxBorder );
00189 }
00190
00191 // Size the view down.
00192 exec function ViewDown()
00193 {
00194 BorderSize = Clamp( BorderSize+1, 0, MaxBorder );
00195 }
00196
00197 //-----------------------------------------------------------------------------
00198 // Member Access Functions.
00199
00200 function string GetMsgText( int Index )
00201 {
00202 return MsgText[Index];
00203 }
00204 function SetMsgText( int Index, string NewMsgText )
00205 {
00206 MsgText[Index] = NewMsgText;
00207 }
00208
00209 function name GetMsgType(int Index)
00210 {
00211 return MsgType[Index];
00212 }
00213 function SetMsgType(int Index, name NewMsgType)
00214 {
00215 MsgType[Index] = NewMsgType;
00216 }
00217
00218 function PlayerReplicationInfo GetMsgPlayer(int Index)
00219 {
00220 return MsgPlayer[Index];
00221 }
00222 function SetMsgPlayer(int Index, PlayerReplicationInfo NewMsgPlayer)
00223 {
00224 MsgPlayer[Index] = NewMsgPlayer;
00225 }
00226
00227 function float GetMsgTick(int Index)
00228 {
00229 return MsgTick[Index];
00230 }
00231 function SetMsgTick(int Index, int NewMsgTick)
00232 {
00233 MsgTick[Index] = NewMsgTick;
00234 }
00235
00236 //-----------------------------------------------------------------------------
00237 // Functions.
00238
00239 // Clear messages.
00240 function ClearMessages()
00241 {
00242 local int i;
00243
00244 for (i=0; i<MaxLines; i++)
00245 {
00246 MsgText[i] = "";
00247 MsgType[i] = '';
00248 MsgPlayer[i] = None;
00249 MsgTick[i] = 0.0;
00250 }
00251 MsgTime = 0.0;
00252 }
00253
00254 // Write to console.
00255 event Message( PlayerReplicationInfo PRI, coerce string Msg, name N )
00256 {
00257 if( Msg!="" )
00258 {
00259 if ( Viewport.Actor != None && Viewport.Actor.myHUD != None )
00260 Viewport.Actor.myHUD.Message(PRI, Msg, N);
00261
00262 TopLine = (TopLine+1) % MaxLines;
00263 NumLines = Min(NumLines+1,MaxLines-1);
00264 MsgType[TopLine] = N;
00265 MsgTime = 6.0;
00266 TextLines++;
00267 MsgText[TopLine] = Msg;
00268 MsgPlayer[TopLine] = PRI;
00269 MsgTick[TopLine] = MsgTickTime + MsgTime;
00270 }
00271 }
00272
00273 event AddString( coerce string Msg )
00274 {
00275 if( Msg!="" )
00276 {
00277 TopLine = (TopLine+1) % MaxLines;
00278 NumLines = Min(NumLines+1,MaxLines-1);
00279 MsgType[TopLine] = 'Event';
00280 MsgTime = 6.0;
00281 TextLines++;
00282 MsgText[TopLine] = Msg;
00283 MsgPlayer[TopLine] = None;
00284 MsgTick[TopLine] = MsgTickTime + MsgTime;
00285 }
00286 }
00287
00288 // Called by the engine when a single key is typed.
00289 event bool KeyType( EInputKey Key );
00290
00291 // Called by the engine when a key, mouse, or joystick button is pressed
00292 // or released, or any analog axis movement is processed.
00293 event bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta )
00294 {
00295 // Ask the HUD to deal with the key event (hook for mod authors).
00296 if (Viewport.Actor.myHUD != None)
00297 {
00298 if (Viewport.Actor.myHUD.ProcessKeyEvent( Key, Action, Delta ))
00299 return true;
00300 }
00301
00302 if( Action!=IST_Press )
00303 {
00304 return false;
00305 }
00306 else if( Key==IK_Tilde )
00307 {
00308 if( ConsoleDest==0.0 )
00309 {
00310 ConsoleDest=0.6;
00311 GotoState('Typing');
00312 }
00313 else GotoState('');
00314 return true;
00315 }
00316 else return false;
00317 }
00318
00319 // Called each rendering iteration to update any time-based display.
00320 event Tick( float Delta )
00321 {
00322 local int I;
00323
00324 MsgTickTime += Delta;
00325
00326 // Slide console up or down.
00327 if( ConsolePos < ConsoleDest )
00328 ConsolePos = FMin(ConsolePos+Delta,ConsoleDest);
00329 else if( ConsolePos > ConsoleDest )
00330 ConsolePos = FMax(ConsolePos-Delta,ConsoleDest);
00331
00332 // Update status message.
00333 if( ((MsgTime-=Delta) <= 0.0) && (TextLines > 0) )
00334 TextLines--;
00335 }
00336
00337 // Called before rendering the world view.
00338 event PreRender( canvas C );
00339
00340 // Called when video settings change (resolution, driver, color depth).
00341 event VideoChange();
00342
00343 event NotifyLevelChange()
00344 {
00345 bRestartTimeDemo = True;
00346 ClearMessages();
00347 }
00348
00349 event ConnectFailure( string FailCode, string URL );
00350
00351 function DrawLevelAction( canvas C )
00352 {
00353 local string BigMessage;
00354 if ( (Viewport.Actor.Level.Pauser != "") && (Viewport.Actor.Level.LevelAction == LEVACT_None) )
00355 {
00356 C.Font = C.MedFont;
00357 BigMessage = PausedMessage; // Add pauser name?
00358 PrintActionMessage(C, BigMessage);
00359 return;
00360 }
00361 if ( (Viewport.Actor.Level.LevelAction == LEVACT_None)
00362 || Viewport.Actor.bShowMenu )
00363 {
00364 BigMessage = "";
00365 return;
00366 }
00367 else if ( Viewport.Actor.Level.LevelAction == LEVACT_Loading )
00368 BigMessage = LoadingMessage;
00369 else if ( Viewport.Actor.Level.LevelAction == LEVACT_Saving )
00370 BigMessage = SavingMessage;
00371 else if ( Viewport.Actor.Level.LevelAction == LEVACT_Connecting )
00372 BigMessage = ConnectingMessage;
00373 else if ( Viewport.Actor.Level.LevelAction == LEVACT_Precaching )
00374 BigMessage = PrecachingMessage;
00375
00376 if ( BigMessage != "" )
00377 {
00378 C.Style = 1;
00379 C.Font = C.LargeFont;
00380 PrintActionMessage(C, BigMessage);
00381 }
00382 }
00383
00384 function PrintActionMessage( Canvas C, string BigMessage )
00385 {
00386 local float XL, YL;
00387
00388 C.bCenter = false;
00389 C.StrLen( BigMessage, XL, YL );
00390 C.SetPos(FrameX/2 - XL/2, FrameY/2 - YL/2);
00391 C.SetColor(200, 0, 0);
00392 C.DrawText( BigMessage, false );
00393 C.SetColor(255, 255, 255);
00394
00395 }
00396
00397 // Add localization to hardcoded strings!!
00398 // Called after rendering the world view.
00399 event PostRender( canvas C )
00400 {
00401 local int YStart, YEnd, Y, I, J, Line, iLine;
00402
00403 C.SetColor(255,255,255);
00404
00405 if(bNoDrawWorld)
00406 {
00407 C.SetPos(0,0);
00408 C.DrawPattern( Texture'Border', C.ClipX, C.ClipY, 1.0 );
00409 }
00410
00411 if( bTimeDemo )
00412 {
00413 TimeDemoCalc();
00414 TimeDemoRender( C );
00415 }
00416
00417 // call overridable "level action" rendering code to draw the "big message"
00418 DrawLevelAction( C );
00419
00420 // If the console has changed since the previous frame, draw it.
00421 if ( ConsoleLines > 0 )
00422 {
00423 C.SetOrigin(0.0, ConsoleLines - FrameY*0.6);
00424 C.SetPos(0.0, 0.0);
00425 C.DrawTile( ConBackground, FrameX, FrameY*0.6, C.CurX, C.CurY, FrameX, FrameY );
00426 }
00427
00428 // Draw border.
00429 if ( BorderLines > 0 || BorderPixels > 0 )
00430 {
00431 YStart = BorderLines + ConsoleLines;
00432 YEnd = FrameY - BorderLines;
00433 if ( BorderLines > 0 )
00434 {
00435 C.SetOrigin(0.0, 0.0);
00436 C.SetPos(0.0, 0.0);
00437 C.DrawPattern( Border, FrameX, BorderLines, 1.0 );
00438 C.SetPos(0.0, YEnd);
00439 C.DrawPattern( Border, FrameX, BorderLines, 1.0 );
00440 }
00441 if ( BorderPixels > 0 )
00442 {
00443 C.SetOrigin(0.0, 0.0);
00444 C.SetPos(0.0, YStart);
00445 C.DrawPattern( Border, BorderPixels, YEnd - YStart, 1.0 );
00446 C.SetPos( FrameX - BorderPixels, YStart );
00447 C.DrawPattern( Border, BorderPixels, YEnd - YStart, 1.0 );
00448 }
00449 }
00450
00451 // Draw console text.
00452 C.SetOrigin(0.0, 0.0);
00453 if ( ConsoleLines > 0 )
00454 DrawConsoleView( C );
00455 else
00456 DrawSingleView( C );
00457 }
00458
00459 simulated function DrawConsoleView( Canvas C )
00460 {
00461 local int Y, I, Line;
00462 local float XL, YL;
00463
00464 // Console is visible; display console view.
00465 Y = ConsoleLines - 1;
00466 MsgText[(TopLine + 1 + MaxLines) % MaxLines] = "(>"@TypedStr;
00467 for ( I = Scrollback; I < (NumLines + 1); I++ )
00468 {
00469 // Display all text in the buffer.
00470 Line = (TopLine + MaxLines*2 - (I-1)) % MaxLines;
00471
00472 C.Font = C.MedFont;
00473
00474 if (( MsgType[Line] == 'Say' ) || ( MsgType[Line] == 'TeamSay' ))
00475 C.StrLen( MsgPlayer[Line].PlayerName$":"@MsgText[Line], XL, YL );
00476 else
00477 C.StrLen( MsgText[Line], XL, YL );
00478
00479 // Half-space blank lines.
00480 if ( YL == 0 )
00481 YL = 5;
00482
00483 Y -= YL;
00484 if ( (Y + YL) < 0 )
00485 break;
00486 C.SetPos(4, Y);
00487 C.Font = C.MedFont;
00488
00489 if (( MsgType[Line] == 'Say' ) || ( MsgType[Line] == 'TeamSay' ))
00490 C.DrawText( MsgPlayer[Line].PlayerName$":"@MsgText[Line], false );
00491 else
00492 C.DrawText( MsgText[Line], false );
00493 }
00494 }
00495
00496 simulated function DrawSingleView( Canvas C )
00497 {
00498 local string TypingPrompt;
00499 local int I, J;
00500 local float XL, YL;
00501 local string ShortMessages[4];
00502 local int ExtraSpace;
00503
00504 // Console is hidden; display single-line view.
00505
00506 C.SetOrigin(0.0, 0.0);
00507
00508 // If the HUD doesn't deal with messages, use the default behavior
00509 if (!Viewport.Actor.bShowMenu)
00510 {
00511 if ( bTyping )
00512 {
00513 TypingPrompt = "(>"@TypedStr$"_";
00514 C.Font = C.MedFont;
00515 C.StrLen( TypingPrompt, XL, YL );
00516 C.SetPos( 2, FrameY - ConsoleLines - YL - 1 );
00517 C.DrawText( TypingPrompt, false );
00518 }
00519 }
00520
00521 // Ask the HUD to deal with messages.
00522 if ( Viewport.Actor.myHUD != None
00523 && Viewport.Actor.myHUD.DisplayMessages(C) )
00524 return;
00525
00526 if ( TextLines > 0 && (!Viewport.Actor.bShowMenu || Viewport.Actor.bShowScores) )
00527 {
00528 J = TopLine;
00529 I = 0;
00530 while ((I < 4) && (J >= 0))
00531 {
00532 if ((MsgText[J] != "") && (MsgTick[J] > 0.0) && (MsgTick[J] > MsgTickTime) )
00533 {
00534 if (MsgType[J] == 'Say')
00535 ShortMessages[I] = MsgPlayer[J]$":"@MsgText[J];
00536 else
00537 ShortMessages[I] = MsgText[J];
00538 I++;
00539 }
00540 J--;
00541 }
00542
00543 J = 0;
00544 C.Font = C.MedFont;
00545 for ( I = 0; I < 4; I++ )
00546 {
00547 if (ShortMessages[3 - I] != "")
00548 {
00549 C.SetPos(4, 2 + (10 * J) + (10 * ExtraSpace));
00550 C.StrLen( ShortMessages[3 - I], XL, YL );
00551 C.DrawText( ShortMessages[3 - I], false );
00552 if ( YL == 18.0 )
00553 ExtraSpace++;
00554 J++;
00555 }
00556 }
00557 }
00558 }
00559
00560 //-----------------------------------------------------------------------------
00561 // State used while typing a command on the console.
00562
00563 state Typing
00564 {
00565 exec function Type()
00566 {
00567 TypedStr="";
00568 gotoState( '' );
00569 }
00570 function bool KeyType( EInputKey Key )
00571 {
00572 if ( bNoStuff )
00573 {
00574 bNoStuff = false;
00575 return true;
00576 }
00577 if( Key>=0x20 && Key<0x100 && Key!=Asc("~") && Key!=Asc("`") )
00578 {
00579 TypedStr = TypedStr $ Chr(Key);
00580 Scrollback=0;
00581 return true;
00582 }
00583 }
00584 function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta )
00585 {
00586 local string Temp;
00587
00588 bNoStuff = false;
00589 if( Key==IK_Escape )
00590 {
00591 if( Scrollback!=0 )
00592 {
00593 Scrollback=0;
00594 }
00595 else if( TypedStr!="" )
00596 {
00597 TypedStr="";
00598 }
00599 else
00600 {
00601 ConsoleDest=0.0;
00602 GotoState( '' );
00603 }
00604 Scrollback=0;
00605 }
00606 else if( global.KeyEvent( Key, Action, Delta ) )
00607 {
00608 return true;
00609 }
00610 else if( Action != IST_Press )
00611 {
00612 return false;
00613 }
00614 else if( Key==IK_Enter )
00615 {
00616 if( Scrollback!=0 )
00617 {
00618 Scrollback=0;
00619 }
00620 else
00621 {
00622 if( TypedStr!="" )
00623 {
00624 // Print to console.
00625 if( ConsoleLines!=0 )
00626 Message( None, "(>" @ TypedStr, 'Console' );
00627
00628 // Update history buffer.
00629 History[HistoryCur++ % MaxHistory] = TypedStr;
00630 if( HistoryCur > HistoryBot )
00631 HistoryBot++;
00632 if( HistoryCur - HistoryTop >= MaxHistory )
00633 HistoryTop = HistoryCur - MaxHistory + 1;
00634
00635 // Make a local copy of the string.
00636 Temp=TypedStr;
00637 TypedStr="";
00638 if( !ConsoleCommand( Temp ) )
00639 Message( None, Localize("Errors","Exec","Core"), 'Console' );
00640 Message( None, "", 'Console' );
00641 }
00642 if( ConsoleDest==0.0 )
00643 GotoState('');
00644 Scrollback=0;
00645 }
00646 }
00647 else if( Key==IK_Up )
00648 {
00649 if( HistoryCur > HistoryTop )
00650 {
00651 History[HistoryCur % MaxHistory] = TypedStr;
00652 TypedStr = History[--HistoryCur % MaxHistory];
00653 }
00654 Scrollback=0;
00655 }
00656 else if( Key==IK_Down )
00657 {
00658 History[HistoryCur % MaxHistory] = TypedStr;
00659 if( HistoryCur < HistoryBot )
00660 TypedStr = History[++HistoryCur % MaxHistory];
00661 else
00662 TypedStr="";
00663 Scrollback=0;
00664 }
00665 else if( Key==IK_PageUp )
00666 {
00667 if( ++Scrollback >= MaxLines )
00668 Scrollback = MaxLines-1;
00669 }
00670 else if( Key==IK_PageDown )
00671 {
00672 if( --Scrollback < 0 )
00673 Scrollback = 0;
00674 }
00675 else if( Key==IK_Backspace || Key==IK_Left )
00676 {
00677 if( Len(TypedStr)>0 )
00678 TypedStr = Left(TypedStr,Len(TypedStr)-1);
00679 Scrollback = 0;
00680 }
00681 return true;
00682 }
00683 function BeginState()
00684 {
00685 bTyping = true;
00686 Viewport.Actor.Typing(bTyping);
00687 }
00688 function EndState()
00689 {
00690 bTyping = false;
00691 Viewport.Actor.Typing(bTyping);
00692 //log("Console leaving Typing");
00693 ConsoleDest=0.0;
00694 }
00695 }
00696
00697 //-----------------------------------------------------------------------------
00698 // State used while in a menu.
00699
00700 state Menuing
00701 {
00702 function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta )
00703 {
00704 if ( Action != IST_Press )
00705 return false;
00706 if ( Viewport.Actor.myHUD == None || Viewport.Actor.myHUD.MainMenu == None )
00707 return false;
00708
00709 Viewport.Actor.myHUD.MainMenu.MenuProcessInput(Key, Action);
00710 Scrollback=0;
00711 return true;
00712 }
00713 function BeginState()
00714 {
00715 //log("Console entering Menuing");
00716 }
00717 function EndState()
00718 {
00719 //log("Console leaving Menuing");
00720 }
00721 }
00722
00723 state EndMenuing
00724 {
00725 // pass all key events, not just presses
00726 function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta )
00727 {
00728 if ( Viewport.Actor.myHUD == None || Viewport.Actor.myHUD.MainMenu == None )
00729 return false;
00730
00731 Viewport.Actor.myHUD.MainMenu.MenuProcessInput(Key, Action);
00732 Scrollback=0;
00733 return true;
00734 }
00735 }
00736
00737 //-----------------------------------------------------------------------------
00738 // State used while typing in a menu.
00739
00740 state MenuTyping
00741 {
00742 function bool KeyType( EInputKey Key )
00743 {
00744 if( Key>=0x20 && Key<0x100 && Key!=Asc("~") && Key!=Asc("`") && Key!=Asc(" ") )
00745 {
00746 TypedStr = TypedStr $ Chr(Key);
00747 Scrollback=0;
00748 if ( (Viewport.Actor.myHUD != None) && (Viewport.Actor.myHUD.MainMenu != None) )
00749 Viewport.Actor.myHUD.MainMenu.ProcessMenuUpdate( TypedStr );
00750 return true;
00751 }
00752 }
00753 function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta )
00754 {
00755 local Menu PlayerMenu;
00756
00757 if( Action != IST_Press )
00758 return false;
00759
00760 if( Viewport.Actor.myHUD==None || Viewport.Actor.myHUD.MainMenu==None )
00761 return false;
00762
00763 PlayerMenu = Viewport.Actor.myHUD.MainMenu;
00764
00765 if( Key==IK_Escape )
00766 {
00767 if( Scrollback!=0 )
00768 Scrollback = 0;
00769 else if( TypedStr!="" )
00770 TypedStr="";
00771 else
00772 GotoState( 'Menuing' );
00773 PlayerMenu.ProcessMenuEscape();
00774 Scrollback=0;
00775 }
00776 else if( Key==IK_Enter )
00777 {
00778 if( Scrollback!=0 )
00779 Scrollback = 0;
00780 else
00781 {
00782 if( TypedStr!="" )
00783 PlayerMenu.ProcessMenuInput( TypedStr );
00784 TypedStr="";
00785 GotoState( 'Menuing' );
00786 Scrollback = 0;
00787 }
00788 }
00789 else if( Key==IK_Backspace || Key==IK_Left )
00790 {
00791 if( Len(TypedStr)>0 )
00792 TypedStr = Left(TypedStr,Len(TypedStr)-1);
00793 Scrollback = 0;
00794 PlayerMenu.ProcessMenuUpdate( TypedStr );
00795 }
00796 return true;
00797 }
00798 function BeginState()
00799 {
00800 log("Console entering MenuTyping");
00801 }
00802 function EndState()
00803 {
00804 log("Console leaving MenuTyping");
00805 }
00806 }
00807
00808 //-----------------------------------------------------------------------------
00809 // State used while expecting single key input in a menu.
00810
00811 state KeyMenuing
00812 {
00813 function bool KeyType( EInputKey Key )
00814 {
00815 ConsoleDest=0.0;
00816 if( Viewport.Actor.myHUD!=None && Viewport.Actor.myHUD.MainMenu!=None )
00817 Viewport.Actor.myHUD.MainMenu.ProcessMenuKey( Key, Chr(Key) );
00818 Scrollback=0;
00819 GotoState( 'Menuing' );
00820 }
00821 function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta )
00822 {
00823 if( Action==IST_Press )
00824 {
00825 ConsoleDest=0.0;
00826 if( Viewport.Actor.myHUD!=None && Viewport.Actor.myHUD.MainMenu!=None )
00827 Viewport.Actor.myHUD.MainMenu.ProcessMenuKey( Key, mid(string(GetEnum(enum'EInputKey',Key)),3) );
00828 Scrollback=0;
00829 GotoState( 'Menuing' );
00830 return true;
00831 }
00832 }
00833 function BeginState()
00834 {
00835 //log( "Console entering KeyMenuing" );
00836 }
00837 function EndState()
00838 {
00839 //log( "Console leaving KeyMenuing" );
00840 }
00841 }
00842
00843 //-----------------------------------------------------------------------------
00844 // Timedemo functions
00845
00846 exec function TimeDemo(bool bEnabled, optional bool bSaveToFile)
00847 {
00848 bSaveTimeDemoToFile = bSaveToFile;
00849 if(bEnabled)
00850 StartTimeDemo();
00851 else
00852 StopTimeDemo();
00853 }
00854
00855 function StartTimeDemo()
00856 {
00857 if(bTimeDemo)
00858 return;
00859 bTimeDemo = True;
00860 bStartTimeDemo = True;
00861 }
00862
00863 function StopTimeDemo()
00864 {
00865 if(!bTimeDemo)
00866 return;
00867 bTimeDemo = False;
00868 PrintTimeDemoResult();
00869 }
00870
00871 function PrintTimeDemoResult()
00872 {
00873 local LevelInfo Entry;
00874 local float Avg;
00875 local float Delta;
00876 local string AvgString;
00877 local string Temp;
00878
00879 Entry = Viewport.Actor.GetEntryLevel();
00880
00881 Delta = Entry.TimeSeconds - StartTime - ExtraTime;
00882 if(Delta <= 0)
00883 Avg = 0;
00884 else
00885 Avg = FrameCount / Delta;
00886
00887 AvgString = string(FrameCount)@FramesText@FormatFloat(delta)@SecondsText@MinText@FormatFloat(MinFPS)@MaxText@FormatFloat(MaxFPS)@AvgText@FormatFloat(Avg)@fpsText$".";
00888 Viewport.Actor.ClientMessage(AvgString);
00889 Log(AvgString);
00890 if(bSaveTimeDemoToFile)
00891 {
00892 Temp =
00893 FormatFloat(Avg) $ " Rune "$ Viewport.Actor.Level.EngineVersion $ Chr(13) $ Chr(10) $
00894 FormatFloat(MinFPS) $ " Min"$ Chr(13) $ Chr(10) $
00895 FormatFloat(MaxFPS) $ " Max"$ Chr(13) $ Chr(10);
00896
00897 SaveTimeDemo(Temp);
00898 }
00899 }
00900
00901 function TimeDemoCalc()
00902 {
00903 local LevelInfo Entry;
00904 local float Delta;
00905 Entry = Viewport.Actor.GetEntryLevel();
00906
00907 if( bRestartTimeDemo )
00908 {
00909 StopTimeDemo();
00910 StartTimeDemo();
00911 bRestartTimeDemo = False;
00912 }
00913
00914 if( bStartTimeDemo )
00915 {
00916 bStartTimeDemo = False;
00917 StartTime = Entry.TimeSeconds;
00918 ExtraTime = 0;
00919 LastFrameTime = StartTime;
00920 LastSecondStartTime = StartTime;
00921 FrameCount = 0;
00922 LastSecondFrameCount = 0;
00923 MinFPS = 0;
00924 MaxFPS = 0;
00925 LastSecFPS = 0;
00926 return;
00927 }
00928
00929 Delta = Entry.TimeSeconds - LastFrameTime;
00930
00931 // If delta time is more than a half of a second, ignore frame entirely (precaching, loading etc)
00932 if( Delta > 0.5 )
00933 {
00934 ExtraTime += Delta;
00935 LastSecondStartTime = Entry.TimeSeconds;
00936 LastSecondFrameCount = 0;
00937 LastFrameTime = Entry.TimeSeconds;
00938 return;
00939 }
00940
00941 FrameCount++;
00942 LastSecondFrameCount++;
00943
00944 if( Entry.TimeSeconds - LastSecondStartTime > 1)
00945 {
00946 LastSecFPS = LastSecondFrameCount / (Entry.TimeSeconds - LastSecondStartTime);
00947 if( MinFPS == 0 || LastSecFPS < MinFPS )
00948 MinFPS = LastSecFPS;
00949 if( LastSecFPS > MaxFPS )
00950 MaxFPS = LastSecFPS;
00951 LastSecondFrameCount = 0;
00952 LastSecondStartTime = Entry.TimeSeconds;
00953 }
00954
00955 LastFrameTime = Entry.TimeSeconds;
00956 }
00957
00958 function TimeDemoRender( Canvas C )
00959 {
00960 local string AText, LText;
00961 local float W, H;
00962
00963 C.Font = TimeDemoFont;
00964 C.DrawColor.R = 255;
00965 C.DrawColor.G = 255;
00966 C.DrawColor.B = 255;
00967
00968 AText = AvgText @ FormatFloat(FrameCount / (Viewport.Actor.GetEntryLevel().TimeSeconds - StartTime - ExtraTime));
00969 LText = LastSecText @ FormatFloat(LastSecFPS);
00970
00971 C.TextSize(AText, W, H);
00972 C.SetPos(C.ClipX - W, 0.3*C.ClipY);
00973 C.DrawText(AText);
00974 C.TextSize(LText, W, H);
00975 C.SetPos(C.ClipX - W, 0.3*C.ClipY+H);
00976 C.DrawText(LText);
00977 }
00978
00979 final function string FormatFloat( float f)
00980 {
00981 local string s;
00982 local int i;
00983 s = string(f);
00984 i = InStr(s, ".");
00985 if(i != -1)
00986 s = Left(s, i+3);
00987 return s;
00988 }
00989
00990 defaultproperties
00991 {
00992 ConBackground=Texture'Engine.ConsoleBack'
00993 Border=Texture'Engine.Border'
00994 TimeDemoFont=Font'Engine.SmallFont'
00995 LoadingMessage="LOADING"
00996 SavingMessage="SAVING"
00997 ConnectingMessage="CONNECTING"
00998 PausedMessage="PAUSED"
00999 PrecachingMessage="PRECACHING"
01000 FrameRateText="Frame Rate"
01001 AvgText="Avg"
01002 LastSecText="Last Sec"
01003 MinText="Min"
01004 MaxText="Max"
01005 fpsText="fps"
01006 SecondsText="seconds."
01007 FramesText="frames rendered in"
01008 }
|