llviewerkeyboard.cpp

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

Generated on Thu Jul 1 06:09:29 2010 for Second Life Viewer by  doxygen 1.4.7