00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llappviewer.h"
00035 #include "llviewerkeyboard.h"
00036 #include "llmath.h"
00037 #include "llagent.h"
00038 #include "llchatbar.h"
00039 #include "llviewercontrol.h"
00040 #include "llfocusmgr.h"
00041 #include "llmorphview.h"
00042 #include "llmoveview.h"
00043 #include "lltoolfocus.h"
00044 #include "llviewerwindow.h"
00045 #include "llvoavatar.h"
00046
00047
00048
00049
00050
00051 const F32 FLY_TIME = 0.5f;
00052 const F32 FLY_FRAMES = 4;
00053
00054 const F32 NUDGE_TIME = 0.25f;
00055 const S32 NUDGE_FRAMES = 2;
00056 const F32 ORBIT_NUDGE_RATE = 0.05f;
00057 const F32 YAW_NUDGE_RATE = 0.05f;
00058
00059 LLViewerKeyboard gViewerKeyboard;
00060
00061 void agent_jump( EKeystate s )
00062 {
00063 if( KEYSTATE_UP == s ) return;
00064 F32 time = gKeyboard->getCurKeyElapsedTime();
00065 S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount());
00066
00067 if( time < FLY_TIME
00068 || frame_count <= FLY_FRAMES
00069 || gAgent.upGrabbed()
00070 || !gSavedSettings.getBOOL("AutomaticFly"))
00071 {
00072 gAgent.moveUp(1);
00073 }
00074 else
00075 {
00076 gAgent.setFlying(TRUE);
00077 gAgent.moveUp(1);
00078 }
00079 }
00080
00081 void agent_push_down( EKeystate s )
00082 {
00083 if( KEYSTATE_UP == s ) return;
00084 gAgent.moveUp(-1);
00085 }
00086
00087 static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
00088 {
00089 if (KEYSTATE_UP == s)
00090 {
00091 if (gAgent.mDoubleTapRunMode == mode &&
00092 gAgent.getRunning() &&
00093 !gAgent.getAlwaysRun())
00094 {
00095
00096 gAgent.clearRunning();
00097 gAgent.sendWalkRun(gAgent.getRunning());
00098 }
00099 }
00100 else if (gAllowTapTapHoldRun &&
00101 KEYSTATE_DOWN == s &&
00102 !gAgent.getRunning())
00103 {
00104 if (gAgent.mDoubleTapRunMode == mode &&
00105 gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME)
00106 {
00107
00108
00109 gAgent.setRunning();
00110 gAgent.sendWalkRun(gAgent.getRunning());
00111 }
00112
00113
00114 gAgent.mDoubleTapRunTimer.reset();
00115 gAgent.mDoubleTapRunMode = mode;
00116 }
00117 }
00118
00119 static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
00120 {
00121 agent_handle_doubletap_run(s, mode);
00122 if (KEYSTATE_UP == s) return;
00123
00124 F32 time = gKeyboard->getCurKeyElapsedTime();
00125 S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount());
00126
00127 if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
00128 {
00129 gAgent.moveAtNudge(direction);
00130 }
00131 else
00132 {
00133 gAgent.moveAt(direction);
00134 }
00135 }
00136
00137 void agent_push_forward( EKeystate s )
00138 {
00139 agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD);
00140 }
00141
00142
00143 void agent_push_backward( EKeystate s )
00144 {
00145 agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
00146 }
00147
00148 static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
00149 {
00150 agent_handle_doubletap_run(s, mode);
00151 if( KEYSTATE_UP == s ) return;
00152 F32 time = gKeyboard->getCurKeyElapsedTime();
00153 S32 frame_count = llround(gKeyboard->getCurKeyElapsedFrameCount());
00154
00155 if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
00156 {
00157 gAgent.moveLeftNudge(direction);
00158 }
00159 else
00160 {
00161 gAgent.moveLeft(direction);
00162 }
00163 }
00164
00165
00166 void agent_slide_left( EKeystate s )
00167 {
00168 agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT);
00169 }
00170
00171
00172 void agent_slide_right( EKeystate s )
00173 {
00174 agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT);
00175 }
00176
00177 void agent_turn_left( EKeystate s )
00178 {
00179 if (LLToolCamera::getInstance()->mouseSteerMode())
00180 {
00181 agent_slide_left(s);
00182 }
00183 else
00184 {
00185 if (KEYSTATE_UP == s) return;
00186 F32 time = gKeyboard->getCurKeyElapsedTime();
00187 gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
00188 }
00189 }
00190
00191
00192 void agent_turn_right( EKeystate s )
00193 {
00194 if (LLToolCamera::getInstance()->mouseSteerMode())
00195 {
00196 agent_slide_right(s);
00197 }
00198 else
00199 {
00200 if (KEYSTATE_UP == s) return;
00201 F32 time = gKeyboard->getCurKeyElapsedTime();
00202 gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
00203 }
00204 }
00205
00206 void agent_look_up( EKeystate s )
00207 {
00208 if( KEYSTATE_UP == s ) return;
00209 gAgent.movePitch(-1);
00210
00211 }
00212
00213
00214 void agent_look_down( EKeystate s )
00215 {
00216 if( KEYSTATE_UP == s ) return;
00217 gAgent.movePitch(1);
00218
00219 }
00220
00221 void agent_toggle_fly( EKeystate s )
00222 {
00223
00224 if (KEYSTATE_DOWN == s )
00225 {
00226 gAgent.toggleFlying();
00227 }
00228 }
00229
00230 F32 get_orbit_rate()
00231 {
00232 F32 time = gKeyboard->getCurKeyElapsedTime();
00233 if( time < NUDGE_TIME )
00234 {
00235 F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
00236
00237 return rate;
00238 }
00239 else
00240 {
00241 return 1;
00242 }
00243 }
00244
00245 void camera_spin_around_ccw( EKeystate s )
00246 {
00247 if( KEYSTATE_UP == s ) return;
00248 gAgent.unlockView();
00249 gAgent.setOrbitLeftKey( get_orbit_rate() );
00250 }
00251
00252
00253 void camera_spin_around_cw( EKeystate s )
00254 {
00255 if( KEYSTATE_UP == s ) return;
00256 gAgent.unlockView();
00257 gAgent.setOrbitRightKey( get_orbit_rate() );
00258 }
00259
00260 void camera_spin_around_ccw_sitting( EKeystate s )
00261 {
00262 if( KEYSTATE_UP == s ) return;
00263 if (gAgent.rotateGrabbed() || gAgent.sitCameraEnabled())
00264 {
00265
00266 agent_turn_right(s);
00267 }
00268 else
00269 {
00270
00271 gAgent.setOrbitLeftKey( get_orbit_rate() );
00272 }
00273 }
00274
00275
00276 void camera_spin_around_cw_sitting( EKeystate s )
00277 {
00278 if( KEYSTATE_UP == s ) return;
00279 if (gAgent.rotateGrabbed() || gAgent.sitCameraEnabled())
00280 {
00281
00282 agent_turn_left(s);
00283 }
00284 else
00285 {
00286
00287 gAgent.setOrbitRightKey( get_orbit_rate() );
00288 }
00289 }
00290
00291
00292 void camera_spin_over( EKeystate s )
00293 {
00294 if( KEYSTATE_UP == s ) return;
00295 gAgent.unlockView();
00296 gAgent.setOrbitUpKey( get_orbit_rate() );
00297 }
00298
00299
00300 void camera_spin_under( EKeystate s )
00301 {
00302 if( KEYSTATE_UP == s ) return;
00303 gAgent.unlockView();
00304 gAgent.setOrbitDownKey( get_orbit_rate() );
00305 }
00306
00307 void camera_spin_over_sitting( EKeystate s )
00308 {
00309 if( KEYSTATE_UP == s ) return;
00310 if (gAgent.upGrabbed() || gAgent.sitCameraEnabled())
00311 {
00312
00313 agent_jump(s);
00314 }
00315 else
00316 {
00317
00318 gAgent.setOrbitUpKey( get_orbit_rate() );
00319 }
00320 }
00321
00322
00323 void camera_spin_under_sitting( EKeystate s )
00324 {
00325 if( KEYSTATE_UP == s ) return;
00326 if (gAgent.downGrabbed() || gAgent.sitCameraEnabled())
00327 {
00328
00329 agent_push_down(s);
00330 }
00331 else
00332 {
00333
00334 gAgent.setOrbitDownKey( get_orbit_rate() );
00335 }
00336 }
00337
00338 void camera_move_forward( EKeystate s )
00339 {
00340 if( KEYSTATE_UP == s ) return;
00341 gAgent.unlockView();
00342 gAgent.setOrbitInKey( get_orbit_rate() );
00343 }
00344
00345
00346 void camera_move_backward( EKeystate s )
00347 {
00348 if( KEYSTATE_UP == s ) return;
00349 gAgent.unlockView();
00350 gAgent.setOrbitOutKey( get_orbit_rate() );
00351 }
00352
00353 void camera_move_forward_sitting( EKeystate s )
00354 {
00355 if( KEYSTATE_UP == s ) return;
00356 if (gAgent.forwardGrabbed() || gAgent.sitCameraEnabled())
00357 {
00358 agent_push_forward(s);
00359 }
00360 else
00361 {
00362 gAgent.setOrbitInKey( get_orbit_rate() );
00363 }
00364 }
00365
00366
00367 void camera_move_backward_sitting( EKeystate s )
00368 {
00369 if( KEYSTATE_UP == s ) return;
00370
00371 if (gAgent.backwardGrabbed() || gAgent.sitCameraEnabled())
00372 {
00373 agent_push_backward(s);
00374 }
00375 else
00376 {
00377 gAgent.setOrbitOutKey( get_orbit_rate() );
00378 }
00379 }
00380
00381 void camera_pan_up( EKeystate s )
00382 {
00383 if( KEYSTATE_UP == s ) return;
00384 gAgent.unlockView();
00385 gAgent.setPanUpKey( get_orbit_rate() );
00386 }
00387
00388 void camera_pan_down( EKeystate s )
00389 {
00390 if( KEYSTATE_UP == s ) return;
00391 gAgent.unlockView();
00392 gAgent.setPanDownKey( get_orbit_rate() );
00393 }
00394
00395 void camera_pan_left( EKeystate s )
00396 {
00397 if( KEYSTATE_UP == s ) return;
00398 gAgent.unlockView();
00399 gAgent.setPanLeftKey( get_orbit_rate() );
00400 }
00401
00402 void camera_pan_right( EKeystate s )
00403 {
00404 if( KEYSTATE_UP == s ) return;
00405 gAgent.unlockView();
00406 gAgent.setPanRightKey( get_orbit_rate() );
00407 }
00408
00409 void camera_pan_in( EKeystate s )
00410 {
00411 if( KEYSTATE_UP == s ) return;
00412 gAgent.unlockView();
00413 gAgent.setPanInKey( get_orbit_rate() );
00414 }
00415
00416 void camera_pan_out( EKeystate s )
00417 {
00418 if( KEYSTATE_UP == s ) return;
00419 gAgent.unlockView();
00420 gAgent.setPanOutKey( get_orbit_rate() );
00421 }
00422
00423 void camera_move_forward_fast( EKeystate s )
00424 {
00425 if( KEYSTATE_UP == s ) return;
00426 gAgent.unlockView();
00427 gAgent.setOrbitInKey(2.5f);
00428 }
00429
00430 void camera_move_backward_fast( EKeystate s )
00431 {
00432 if( KEYSTATE_UP == s ) return;
00433 gAgent.unlockView();
00434 gAgent.setOrbitOutKey(2.5f);
00435 }
00436
00437
00438 void edit_avatar_spin_ccw( EKeystate s )
00439 {
00440 if( KEYSTATE_UP == s ) return;
00441 gMorphView->setCameraDrivenByKeys( TRUE );
00442 gAgent.setOrbitLeftKey( get_orbit_rate() );
00443
00444 }
00445
00446
00447 void edit_avatar_spin_cw( EKeystate s )
00448 {
00449 if( KEYSTATE_UP == s ) return;
00450 gMorphView->setCameraDrivenByKeys( TRUE );
00451 gAgent.setOrbitRightKey( get_orbit_rate() );
00452
00453 }
00454
00455 void edit_avatar_spin_over( EKeystate s )
00456 {
00457 if( KEYSTATE_UP == s ) return;
00458 gMorphView->setCameraDrivenByKeys( TRUE );
00459 gAgent.setOrbitUpKey( get_orbit_rate() );
00460
00461 }
00462
00463
00464 void edit_avatar_spin_under( EKeystate s )
00465 {
00466 if( KEYSTATE_UP == s ) return;
00467 gMorphView->setCameraDrivenByKeys( TRUE );
00468 gAgent.setOrbitDownKey( get_orbit_rate() );
00469
00470 }
00471
00472 void edit_avatar_move_forward( EKeystate s )
00473 {
00474 if( KEYSTATE_UP == s ) return;
00475 gMorphView->setCameraDrivenByKeys( TRUE );
00476 gAgent.setOrbitInKey( get_orbit_rate() );
00477
00478 }
00479
00480
00481 void edit_avatar_move_backward( EKeystate s )
00482 {
00483 if( KEYSTATE_UP == s ) return;
00484 gMorphView->setCameraDrivenByKeys( TRUE );
00485 gAgent.setOrbitOutKey( get_orbit_rate() );
00486
00487 }
00488
00489 void stop_moving( EKeystate s )
00490 {
00491 if( KEYSTATE_UP == s ) return;
00492
00493 gAgent.setControlFlags(AGENT_CONTROL_STOP);
00494
00495
00496 gAgent.stopAutoPilot();
00497 }
00498
00499 void start_chat( EKeystate s )
00500 {
00501
00502 gChatBar->startChat(NULL);
00503 }
00504
00505 void start_gesture( EKeystate s )
00506 {
00507 if (KEYSTATE_UP == s &&
00508 !(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))
00509 {
00510 if (gChatBar->getCurrentChat().empty())
00511 {
00512
00513 gChatBar->startChat("/");
00514 }
00515 else
00516 {
00517
00518 gChatBar->startChat(NULL);
00519 }
00520 }
00521 }
00522
00523 void bind_keyboard_functions()
00524 {
00525 gViewerKeyboard.bindNamedFunction("jump", agent_jump);
00526 gViewerKeyboard.bindNamedFunction("push_down", agent_push_down);
00527 gViewerKeyboard.bindNamedFunction("push_forward", agent_push_forward);
00528 gViewerKeyboard.bindNamedFunction("push_backward", agent_push_backward);
00529 gViewerKeyboard.bindNamedFunction("look_up", agent_look_up);
00530 gViewerKeyboard.bindNamedFunction("look_down", agent_look_down);
00531 gViewerKeyboard.bindNamedFunction("toggle_fly", agent_toggle_fly);
00532 gViewerKeyboard.bindNamedFunction("turn_left", agent_turn_left);
00533 gViewerKeyboard.bindNamedFunction("turn_right", agent_turn_right);
00534 gViewerKeyboard.bindNamedFunction("slide_left", agent_slide_left);
00535 gViewerKeyboard.bindNamedFunction("slide_right", agent_slide_right);
00536 gViewerKeyboard.bindNamedFunction("spin_around_ccw", camera_spin_around_ccw);
00537 gViewerKeyboard.bindNamedFunction("spin_around_cw", camera_spin_around_cw);
00538 gViewerKeyboard.bindNamedFunction("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
00539 gViewerKeyboard.bindNamedFunction("spin_around_cw_sitting", camera_spin_around_cw_sitting);
00540 gViewerKeyboard.bindNamedFunction("spin_over", camera_spin_over);
00541 gViewerKeyboard.bindNamedFunction("spin_under", camera_spin_under);
00542 gViewerKeyboard.bindNamedFunction("spin_over_sitting", camera_spin_over_sitting);
00543 gViewerKeyboard.bindNamedFunction("spin_under_sitting", camera_spin_under_sitting);
00544 gViewerKeyboard.bindNamedFunction("move_forward", camera_move_forward);
00545 gViewerKeyboard.bindNamedFunction("move_backward", camera_move_backward);
00546 gViewerKeyboard.bindNamedFunction("move_forward_sitting", camera_move_forward_sitting);
00547 gViewerKeyboard.bindNamedFunction("move_backward_sitting", camera_move_backward_sitting);
00548 gViewerKeyboard.bindNamedFunction("pan_up", camera_pan_up);
00549 gViewerKeyboard.bindNamedFunction("pan_down", camera_pan_down);
00550 gViewerKeyboard.bindNamedFunction("pan_left", camera_pan_left);
00551 gViewerKeyboard.bindNamedFunction("pan_right", camera_pan_right);
00552 gViewerKeyboard.bindNamedFunction("pan_in", camera_pan_in);
00553 gViewerKeyboard.bindNamedFunction("pan_out", camera_pan_out);
00554 gViewerKeyboard.bindNamedFunction("move_forward_fast", camera_move_forward_fast);
00555 gViewerKeyboard.bindNamedFunction("move_backward_fast", camera_move_backward_fast);
00556 gViewerKeyboard.bindNamedFunction("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
00557 gViewerKeyboard.bindNamedFunction("edit_avatar_spin_cw", edit_avatar_spin_cw);
00558 gViewerKeyboard.bindNamedFunction("edit_avatar_spin_over", edit_avatar_spin_over);
00559 gViewerKeyboard.bindNamedFunction("edit_avatar_spin_under", edit_avatar_spin_under);
00560 gViewerKeyboard.bindNamedFunction("edit_avatar_move_forward", edit_avatar_move_forward);
00561 gViewerKeyboard.bindNamedFunction("edit_avatar_move_backward", edit_avatar_move_backward);
00562 gViewerKeyboard.bindNamedFunction("stop_moving", stop_moving);
00563 gViewerKeyboard.bindNamedFunction("start_chat", start_chat);
00564 gViewerKeyboard.bindNamedFunction("start_gesture", start_gesture);
00565 }
00566
00567 LLViewerKeyboard::LLViewerKeyboard()
00568 {
00569 for (S32 i = 0; i < MODE_COUNT; i++)
00570 {
00571 mBindingCount[i] = 0;
00572 }
00573
00574 for (S32 i = 0; i < KEY_COUNT; i++)
00575 {
00576 mKeyHandledByUI[i] = FALSE;
00577 }
00578
00579 for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++)
00580 {
00581 mKeysSkippedByUI.insert(k);
00582 }
00583 }
00584
00585
00586 void LLViewerKeyboard::bindNamedFunction(const char *name, LLKeyFunc func)
00587 {
00588 S32 i = mNamedFunctionCount;
00589 mNamedFunctions[i].mName = name;
00590 mNamedFunctions[i].mFunction = func;
00591 mNamedFunctionCount++;
00592 }
00593
00594
00595 BOOL LLViewerKeyboard::modeFromString(const char *string, S32 *mode)
00596 {
00597 if (!strcmp(string, "FIRST_PERSON"))
00598 {
00599 *mode = MODE_FIRST_PERSON;
00600 return TRUE;
00601 }
00602 else if (!strcmp(string, "THIRD_PERSON"))
00603 {
00604 *mode = MODE_THIRD_PERSON;
00605 return TRUE;
00606 }
00607 else if (!strcmp(string, "EDIT"))
00608 {
00609 *mode = MODE_EDIT;
00610 return TRUE;
00611 }
00612 else if (!strcmp(string, "EDIT_AVATAR"))
00613 {
00614 *mode = MODE_EDIT_AVATAR;
00615 return TRUE;
00616 }
00617 else if (!strcmp(string, "SITTING"))
00618 {
00619 *mode = MODE_SITTING;
00620 return TRUE;
00621 }
00622 else
00623 {
00624 *mode = MODE_THIRD_PERSON;
00625 return FALSE;
00626 }
00627 }
00628
00629 BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated)
00630 {
00631
00632 EKeyboardMode mode = gViewerKeyboard.getMode();
00633 U32 keyidx = (translated_mask<<16) | translated_key;
00634 key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx);
00635 if (iter != mRemapKeys[mode].end())
00636 {
00637 translated_key = (iter->second) & 0xff;
00638 translated_mask = (iter->second)>>16;
00639 }
00640
00641
00642 BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12);
00643 if (!repeatable_key && repeated)
00644 {
00645 return FALSE;
00646 }
00647
00648 lldebugst(LLERR_USER_INPUT) << "keydown -" << translated_key << "-" << llendl;
00649
00650 if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end())
00651 {
00652 mKeyHandledByUI[translated_key] = FALSE;
00653 }
00654 else
00655 {
00656
00657
00658 mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
00659 }
00660 return mKeyHandledByUI[translated_key];
00661 }
00662
00663
00664
00665 BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const char *function_name)
00666 {
00667 S32 i,index;
00668 void (*function)(EKeystate keystate) = NULL;
00669 const char *name = NULL;
00670
00671
00672 if (function_name[0] == 'F')
00673 {
00674 int c1 = function_name[1] - '0';
00675 int c2 = function_name[2] ? function_name[2] - '0' : -1;
00676 if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9)
00677 {
00678 int idx = c1;
00679 if (c2 >= 0)
00680 idx = idx*10 + c2;
00681 if (idx >=2 && idx <= 12)
00682 {
00683 U32 keyidx = ((mask<<16)|key);
00684 (mRemapKeys[mode])[keyidx] = ((0<<16)|KEY_F1+(idx-1));
00685 return TRUE;
00686 }
00687 }
00688 }
00689
00690
00691 for (i = 0; i < mNamedFunctionCount; i++)
00692 {
00693 if (!strcmp(function_name, mNamedFunctions[i].mName))
00694 {
00695 function = mNamedFunctions[i].mFunction;
00696 name = mNamedFunctions[i].mName;
00697 }
00698 }
00699
00700 if (!function)
00701 {
00702 llerrs << "Can't bind key to function " << function_name << ", no function with this name found" << llendl;
00703 return FALSE;
00704 }
00705
00706
00707 for (index = 0; index < mBindingCount[mode]; index++)
00708 {
00709 if (key == mBindings[mode][index].mKey && mask == mBindings[mode][index].mMask)
00710 break;
00711 }
00712
00713 if (index >= MAX_KEY_BINDINGS)
00714 {
00715 llerrs << "LLKeyboard::bindKey() - too many keys for mode " << mode << llendl;
00716 return FALSE;
00717 }
00718
00719 if (mode >= MODE_COUNT)
00720 {
00721 llerror("LLKeyboard::bindKey() - unknown mode passed", mode);
00722 return FALSE;
00723 }
00724
00725 mBindings[mode][index].mKey = key;
00726 mBindings[mode][index].mMask = mask;
00727
00728 mBindings[mode][index].mFunction = function;
00729
00730 if (index == mBindingCount[mode])
00731 mBindingCount[mode]++;
00732
00733
00734
00735 return TRUE;
00736 }
00737
00738
00739 S32 LLViewerKeyboard::loadBindings(const char *filename)
00740 {
00741 LLFILE *fp;
00742 const S32 BUFFER_SIZE = 2048;
00743 char buffer[BUFFER_SIZE];
00744
00745 char mode_string[MAX_STRING];
00746 char key_string[MAX_STRING];
00747 char mask_string[MAX_STRING];
00748 char function_string[MAX_STRING];
00749 S32 mode = MODE_THIRD_PERSON;
00750 KEY key = 0;
00751 MASK mask = 0;
00752 S32 tokens_read;
00753 S32 binding_count = 0;
00754 S32 line_count = 0;
00755
00756 if(!filename)
00757 {
00758 llerrs << " No filename specified" << llendl;
00759 return 0;
00760 }
00761
00762 fp = LLFile::fopen(filename, "r");
00763
00764 if (!fp)
00765 {
00766 return 0;
00767 }
00768
00769
00770 while (!feof(fp))
00771 {
00772 line_count++;
00773 if (!fgets(buffer, BUFFER_SIZE, fp))
00774 break;
00775
00776
00777 if (buffer[0] == '#' || buffer[0] == '\n') continue;
00778
00779
00780 tokens_read = sscanf(
00781 buffer,
00782 "%254s %254s %254s %254s",
00783 mode_string,
00784 key_string,
00785 mask_string,
00786 function_string);
00787
00788 if (tokens_read == EOF)
00789 {
00790 llinfos << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << llendl;
00791 fclose(fp);
00792 return 0;
00793 }
00794 else if (tokens_read < 4)
00795 {
00796 llinfos << "Can't read line " << line_count << " of key binding file " << filename << llendl;
00797 continue;
00798 }
00799
00800
00801 if (!modeFromString(mode_string, &mode))
00802 {
00803 llinfos << "Unknown mode on line " << line_count << " of key binding file " << filename << llendl;
00804 llinfos << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << llendl;
00805 continue;
00806 }
00807
00808
00809 if (!LLKeyboard::keyFromString(key_string, &key))
00810 {
00811 llinfos << "Can't interpret key on line " << line_count << " of key binding file " << filename << llendl;
00812 continue;
00813 }
00814
00815
00816 if (!LLKeyboard::maskFromString(mask_string, &mask))
00817 {
00818 llinfos << "Can't interpret mask on line " << line_count << " of key binding file " << filename << llendl;
00819 continue;
00820 }
00821
00822
00823 if (bindKey(mode, key, mask, function_string))
00824 {
00825 binding_count++;
00826 }
00827 }
00828
00829 fclose(fp);
00830
00831 return binding_count;
00832 }
00833
00834
00835 EKeyboardMode LLViewerKeyboard::getMode()
00836 {
00837 if ( gAgent.cameraMouselook() )
00838 {
00839 return MODE_FIRST_PERSON;
00840 }
00841 else if ( gMorphView && gMorphView->getVisible())
00842 {
00843 return MODE_EDIT_AVATAR;
00844 }
00845 else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting)
00846 {
00847 return MODE_SITTING;
00848 }
00849 else
00850 {
00851 return MODE_THIRD_PERSON;
00852 }
00853 }
00854
00855
00856
00857 void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
00858 {
00859 S32 mode = getMode();
00860
00861 MASK mask = gKeyboard->currentMask(FALSE);
00862
00863 LLKeyBinding* binding = mBindings[mode];
00864 S32 binding_count = mBindingCount[mode];
00865
00866
00867 if (mKeyHandledByUI[key])
00868 {
00869 return;
00870 }
00871
00872
00873 BOOL repeat = gKeyboard->getKeyRepeated(key);
00874
00875 for (S32 i = 0; i < binding_count; i++)
00876 {
00877
00878 if (binding[i].mKey == key)
00879 {
00880
00881 if (binding[i].mMask == mask)
00882 {
00883 if (key_down && !repeat)
00884 {
00885
00886 (*binding[i].mFunction)( KEYSTATE_DOWN );
00887 }
00888 else if (key_up)
00889 {
00890
00891 (*binding[i].mFunction)( KEYSTATE_UP );
00892 }
00893 else if (key_level)
00894 {
00895
00896
00897 (*binding[i].mFunction)( KEYSTATE_LEVEL );
00898 }
00899 }
00900 }
00901 }
00902 }