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