home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / input / mouse.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-08-26  |  30.7 KB  |  1,490 lines

  1. /***************************************************************************
  2.  * mouse.cpp  -  mouse handling class
  3.  *
  4.  * Copyright (C) 2003 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../core/globals.h"
  17. #include "../core/main.h"
  18. #include "../input/mouse.h"
  19. #include "../input/keyboard.h"
  20. #include "../core/game_core.h"
  21. #include "../level/level_editor.h"
  22. #include "../overworld/world_editor.h"
  23. #include "../overworld/overworld.h"
  24. #include "../overworld/world_player.h"
  25. #include "../gui/menu.h"
  26. #include "../core/camera.h"
  27. #include "../level/level.h"
  28. #include "../player/player.h"
  29. #include "../user/preferences.h"
  30. #include "../core/framerate.h"
  31. #include "../objects/goldpiece.h"
  32. #include "../objects/levelexit.h"
  33. #include "../objects/bonusbox.h"
  34. #include "../enemies/furball.h"
  35. #include "../video/font.h"
  36. #include "../video/renderer.h"
  37. #include "../video/gl_surface.h"
  38. #include "../core/sprite_manager.h"
  39. #include "../core/i18n.h"
  40.  
  41. /* *** *** *** *** *** cSelectedObject *** *** *** *** *** *** *** *** *** *** *** *** */
  42.  
  43. cSelectedObject :: cSelectedObject( void )
  44. {
  45.     obj = NULL;
  46.  
  47.     mouse_h = 0;
  48.     mouse_w = 0;
  49.  
  50.     user = 0;
  51. }
  52.  
  53. cSelectedObject :: ~cSelectedObject( void )
  54. {
  55.  
  56. }
  57.  
  58. /* *** *** *** *** *** cCopyObject *** *** *** *** *** *** *** *** *** *** *** *** */
  59.  
  60. cCopyObject :: cCopyObject( void )
  61. {
  62.     obj = NULL;
  63. }
  64.  
  65. cCopyObject :: ~cCopyObject( void )
  66. {
  67.     if( obj )
  68.     {
  69.         delete obj;
  70.     }
  71. }
  72.  
  73. /* *** *** *** *** *** cMouseCursor *** *** *** *** *** *** *** *** *** *** *** *** */
  74.  
  75. cMouseCursor :: cMouseCursor( void )
  76. : cMovingSprite()
  77. {
  78.     type = TYPE_MOUSECURSOR;
  79.  
  80.     clickcounter = 0;
  81.  
  82.     mode_selection = 0;
  83.     selection_rect = GL_rect( 0, 0, 0, 0 );
  84.  
  85.     mouse_object = new cSelectedObject();
  86.     active_object = NULL;
  87.  
  88.     mode_fastcopy = 0;
  89.     mover_mode = 0;
  90.     click_temp = NULL;
  91.  
  92.     Reset_Keys();
  93.  
  94.     SDL_GetMouseState( &x, &y );
  95.     // scale to the virtual game size
  96.     x = static_cast<int>( static_cast<float>(x) * global_downscalex );
  97.     y = static_cast<int>( static_cast<float>(y) * global_downscaley );
  98. }
  99.  
  100. cMouseCursor :: ~cMouseCursor( void )
  101. {
  102.     Clear_Copy_Objects();
  103.     Clear_Selected_Objects();
  104.     delete mouse_object;
  105. }
  106.  
  107. void cMouseCursor :: Reset( bool clear_copy_buffer /* = 1 */ )
  108. {
  109.     // only clear copy buffer if requested
  110.     if( clear_copy_buffer )
  111.     {
  112.         Clear_Copy_Objects();
  113.     }
  114.     Clear_Selected_Objects();
  115.     Clear_Mouse_Object();
  116.     Clear_Active_Object();
  117.  
  118.     // change to default cursor
  119.     if( mover_mode )
  120.     {
  121.         CEGUI::MouseCursor::getSingleton().setImage( "TaharezLook", "MouseArrow" );
  122.     }
  123.  
  124.     mover_mode = 0;
  125.     mode_selection = 0;
  126.     mode_fastcopy = 0;
  127.  
  128.     Collisions_Clear();
  129.  
  130.     // show mouse
  131.     if( editor_enabled )
  132.     {
  133.         visible = 1;
  134.     }
  135. }
  136.  
  137. void cMouseCursor :: Reset_Keys( void )
  138. {
  139.     left = 0;
  140.     right = 0;
  141.     middle = 0;
  142. }
  143.  
  144. bool cMouseCursor :: Handle_Event( SDL_Event *ev )
  145. {
  146.     switch( ev->type )
  147.     {
  148.         case SDL_MOUSEMOTION:
  149.         {
  150.             pGuiSystem->injectMousePosition( static_cast<float>(ev->motion.x), static_cast<float>(ev->motion.y) );
  151.             Update_Position();
  152.             break;
  153.         }
  154.         case SDL_MOUSEBUTTONUP:
  155.         {
  156.             if( Handle_Mouse_Up( ev->button.button ) )
  157.             {
  158.                 // processed
  159.                 return 1;
  160.             }
  161.  
  162.             break;
  163.         }
  164.         case SDL_MOUSEBUTTONDOWN:
  165.         {
  166.             if( Handle_Mouse_Down( ev->button.button ) )
  167.             {
  168.                 // processed
  169.                 return 1;
  170.             }
  171.  
  172.             break;
  173.         }
  174.         default:
  175.         {
  176.             break;
  177.         }
  178.     }
  179.  
  180.     return 0;
  181. }
  182.  
  183. bool cMouseCursor :: Handle_Mouse_Down( Uint8 button )
  184. {
  185.     switch( button )
  186.     {
  187.         // mouse buttons
  188.         case SDL_BUTTON_LEFT:
  189.         {
  190.             if( CEGUI::System::getSingleton().injectMouseButtonDown( CEGUI::LeftButton ) )
  191.             {
  192.                 return 1;
  193.             }
  194.             left = 1;
  195.             break;
  196.         }
  197.         case SDL_BUTTON_MIDDLE:
  198.         {
  199.             if( CEGUI::System::getSingleton().injectMouseButtonDown( CEGUI::MiddleButton ) )
  200.             {
  201.                 return 1;
  202.             }
  203.             middle = 1;
  204.             break;
  205.         }
  206.         case SDL_BUTTON_RIGHT:
  207.         {
  208.             if( CEGUI::System::getSingleton().injectMouseButtonDown( CEGUI::RightButton ) )
  209.             {
  210.                 return 1;
  211.             }
  212.             right = 1;
  213.             break;
  214.         }
  215.         // mouse wheel
  216.         case SDL_BUTTON_WHEELDOWN:
  217.         {
  218.             if( CEGUI::System::getSingleton().injectMouseWheelChange( -1 ) )
  219.             {
  220.                 return 1;
  221.             }
  222.             break;
  223.         }
  224.         case SDL_BUTTON_WHEELUP:
  225.         {
  226.             if( CEGUI::System::getSingleton().injectMouseWheelChange( +1 ) )
  227.             {
  228.                 return 1;
  229.             }
  230.             break;
  231.         }
  232.         default:
  233.         {
  234.             break;
  235.         }
  236.     }
  237.  
  238.     // handle button in the current mode
  239.     if( Game_Mode == MODE_LEVEL )
  240.     {
  241.         // processed by the level
  242.         if( pActive_Level->Mouse_Down( button ) )
  243.         {
  244.             return 1;
  245.         }
  246.     }
  247.     else if( Game_Mode == MODE_OVERWORLD )
  248.     {
  249.         // processed by the overworld
  250.         if( pActive_Overworld->Mouse_Down( button ) )
  251.         {
  252.             return 1;
  253.         }
  254.     }
  255.     else if( Game_Mode == MODE_MENU )
  256.     {
  257.         // processed by the menu
  258.         if( pMenuCore->Mouse_Down( button ) )
  259.         {
  260.             return 1;
  261.         }
  262.     }
  263.  
  264.     return 0;
  265. }
  266.  
  267. bool cMouseCursor :: Handle_Mouse_Up( Uint8 button )
  268. {
  269.     switch ( button )
  270.     {
  271.         case SDL_BUTTON_LEFT:
  272.         {
  273.             left = 0;
  274.             if( CEGUI::System::getSingleton().injectMouseButtonUp( CEGUI::LeftButton ) )
  275.             {
  276.                 return 1;
  277.             }
  278.         }
  279.         break;
  280.         case SDL_BUTTON_MIDDLE:
  281.         {
  282.             middle = 0;
  283.             if( CEGUI::System::getSingleton().injectMouseButtonUp( CEGUI::MiddleButton ) )
  284.             {
  285.                 return 1;
  286.             }
  287.         }
  288.         break;
  289.         case SDL_BUTTON_RIGHT:
  290.         {
  291.             right = 0;
  292.             if( CEGUI::System::getSingleton().injectMouseButtonUp( CEGUI::RightButton ) )
  293.             {
  294.                 return 1;
  295.             }
  296.         }
  297.         break;
  298.         default:
  299.         {
  300.             break;
  301.         }
  302.     }
  303.  
  304.     // handle button in the current mode
  305.     if( Game_Mode == MODE_LEVEL )
  306.     {
  307.         // processed by the level
  308.         if( pActive_Level->Mouse_Up( button ) )
  309.         {
  310.             return 1;
  311.         }
  312.     }
  313.     else if( Game_Mode == MODE_OVERWORLD )
  314.     {
  315.         // processed by the overworld
  316.         if( pActive_Overworld->Mouse_Up( button ) )
  317.         {
  318.             return 1;
  319.         }
  320.     }
  321.     else if( Game_Mode == MODE_MENU )
  322.     {
  323.         // processed by the menu
  324.         if( pMenuCore->Mouse_Up( button ) )
  325.         {
  326.             return 1;
  327.         }
  328.     }
  329.  
  330.     return 0;
  331. }
  332.  
  333. bool cMouseCursor :: Collsion_Check( GL_rect *crect )
  334. {
  335.     if( !crect )
  336.     {
  337.         return 0;
  338.     }
  339.  
  340.     if( x > crect->x + crect->w )
  341.     {
  342.         return 0;
  343.     }
  344.     if( x < crect->x )
  345.     {
  346.         return 0;
  347.     }
  348.     if( y > crect->y + crect->h )
  349.     {
  350.         return 0;
  351.     }
  352.     if( y < crect->y )
  353.     {
  354.         return 0;
  355.     }
  356.  
  357.     return 1;
  358. }
  359.  
  360. bool cMouseCursor :: Editor_Collsion_Check( float px /* = 0 */, float py /* = 0 */ )
  361. {
  362.     Collisions_Clear();
  363.  
  364.     if( mover_mode )
  365.     {
  366.         return 0;
  367.     }
  368.  
  369.     // Get CEGUI Window containing the mouse
  370.     CEGUI::Window *mouse_window = pGuiSystem->getWindowContainingMouse();
  371.  
  372.     // if mouse is over a blocking CEGUI window
  373.     if( mouse_window && !mouse_window->isMousePassThroughEnabled() )
  374.     {
  375.         return 0;
  376.     }
  377.  
  378.     // mouse rect
  379.     GL_rect mouse_rect;
  380.  
  381.     // use given posx
  382.     if( px != 0 )
  383.     {
  384.         mouse_rect.x = px;
  385.     }
  386.     else
  387.     {
  388.         mouse_rect.x = posx;
  389.     }
  390.  
  391.     // use given posy
  392.     if( py != 0 )
  393.     {
  394.         mouse_rect.y = py;
  395.     }
  396.     else
  397.     {
  398.         mouse_rect.y = posy;
  399.     }
  400.  
  401.     mouse_rect.w = 1;
  402.     mouse_rect.h = 1;
  403.  
  404.     if( Get_Collision( &mouse_rect ) )
  405.     {
  406.         return 1;
  407.     }
  408.  
  409.     // no collisions
  410.     return 0;
  411. }
  412.  
  413. bool cMouseCursor :: Get_Collision( GL_rect *mouse_rect )
  414. {
  415.     SpriteList sprite_objects;
  416.     pActive_Sprite_Manager->Get_Objects_sorted( sprite_objects, 1, 1 );
  417.  
  418.     // check objects
  419.     for( SpriteList::reverse_iterator itr = sprite_objects.rbegin(), itr_end = sprite_objects.rend(); itr != itr_end; ++itr )
  420.     {
  421.         cSprite *obj = (*itr);
  422.  
  423.         // don't check spawned objects
  424.         if( obj->spawned )
  425.         {
  426.             continue;
  427.         }
  428.  
  429.         if( Col_Box( mouse_rect, &obj->start_rect ) )
  430.         {
  431.             if( obj->type == TYPE_PLAYER )
  432.             {
  433.                 Collision_Add( this, pActive_Player, 0, CO_PLAYER );
  434.             }
  435.             else
  436.             {
  437.                 Collision_Add( this, obj, pActive_Sprite_Manager->Get_Array_Num( obj ), Get_Collision_Type( obj->sprite_array ) );
  438.             }
  439.  
  440.             return 1;
  441.         }
  442.     }
  443.  
  444.     return 0;
  445. }
  446.  
  447. void cMouseCursor :: Update( void )
  448. {
  449.     // only if editor is enabled
  450.     if( !editor_enabled )
  451.     {
  452.         return;
  453.     }
  454.  
  455.     Update_Doubleclick();
  456. }
  457.  
  458. void cMouseCursor :: Draw( void )
  459. {
  460.     // only if editor is enabled
  461.     if( !editor_enabled )
  462.     {
  463.         return;
  464.     }
  465.  
  466.     Update_Selection();
  467.  
  468.     // if in Level or Overworld
  469.     if( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD )
  470.     {
  471.         // draw if not in mover mode
  472.         if( !mover_mode )
  473.         {
  474.             Draw_Object_Rects();
  475.         }
  476.     }
  477. }
  478.  
  479. void cMouseCursor :: Render( void )
  480. {
  481.     if( !visible )
  482.     {
  483.         return;
  484.     }
  485.  
  486.     // Render CEGUI Mouse
  487.     pGuiRenderer->setQueueingEnabled( 0 );
  488.     CEGUI::MouseCursor *mouse = CEGUI::MouseCursor::getSingletonPtr();
  489.     mouse->setVisible( 1 );
  490.     mouse->draw();
  491.     mouse->setVisible( 0 );
  492. }
  493.  
  494. void cMouseCursor :: Update_Position( void )
  495. {
  496.     if( !mover_mode )
  497.     {
  498.         SDL_GetMouseState( &x, &y );
  499.         // scale to the virtual game size
  500.         x = static_cast<int>( static_cast<float>(x) * global_downscalex );
  501.         y = static_cast<int>( static_cast<float>(y) * global_downscaley );
  502.     }
  503.  
  504.     if( editor_enabled )
  505.     {
  506.         if( !mover_mode )
  507.         {
  508.             Set_Pos( x + pActive_Camera->x, y + pActive_Camera->y, 1 );
  509.         }
  510.  
  511.         Update_Mouse_Object();
  512.         Update_Selected_Objects();
  513.     }
  514.     else
  515.     {
  516.         Set_Pos( static_cast<float>(x), static_cast<float>(y), 1 );
  517.     }
  518. }
  519.  
  520. void cMouseCursor :: Update_Doubleclick( void )
  521. {
  522.     if( clickcounter )
  523.     {
  524.         clickcounter -= pFramerate->speedfactor;
  525.  
  526.         if( clickcounter < 0 )
  527.         {
  528.             clickcounter = 0;
  529.         }
  530.     }
  531. }
  532.  
  533. void cMouseCursor :: Click( void )
  534. {
  535.     Editor_Collsion_Check();
  536.  
  537.     if( mover_mode )
  538.     {
  539.         return;
  540.     }
  541.  
  542.     // no colliding sprite
  543.     if( !mouse_object->obj )
  544.     {
  545.         cObjectCollision *col = Collision_Get_first();
  546.  
  547.         // collision with an object
  548.         if( col )
  549.         {
  550.             cSprite *col_obj = NULL;
  551.  
  552.             // player
  553.             if( col->type == CO_PLAYER )
  554.             {
  555.                 col_obj = static_cast<cSprite *>(pActive_Player);
  556.             }
  557.             // object manager object
  558.             else
  559.             {
  560.                 col_obj = pActive_Sprite_Manager->Get_Pointer( col->number );
  561.             }
  562.  
  563.             // if shift is pressed add object to the mouse objects
  564.             if( pKeyboard->keys[SDLK_RSHIFT] || pKeyboard->keys[SDLK_LSHIFT] )
  565.             {
  566.                 // add object
  567.                 if( !Add_Selected_Object( col_obj, 1 ) )
  568.                 {
  569.                     // if already added remove it
  570.                     Remove_Selected_Object( col_obj );
  571.                 }
  572.             }
  573.         }
  574.  
  575.         Start_Selection();
  576.         clickcounter = 0;
  577.         return;
  578.     }
  579.  
  580.     if( clickcounter > 0 )
  581.     {
  582.         // if last clicked object was the same
  583.         if( click_temp == mouse_object->obj )
  584.         {
  585.             Double_Click();
  586.         }
  587.         else
  588.         {
  589.             clickcounter = 0;
  590.         }
  591.     }
  592.     else
  593.     {
  594.         // double click counter
  595.         clickcounter = speedfactor_fps * 0.3f;
  596.         // save last clicked object
  597.         click_temp = mouse_object->obj;
  598.     }
  599. }
  600.  
  601. void cMouseCursor :: Double_Click( bool activate /* = 1 */ )
  602. {
  603.     Clear_Active_Object();
  604.  
  605.     // add new
  606.     if( activate )
  607.     {
  608.         Set_Active_Object( mouse_object->obj );
  609.     }
  610.  
  611.     clickcounter = 0;
  612. }
  613.  
  614. void cMouseCursor :: Set_Mouse_Object( cSprite *sprite )
  615. {
  616.     // return if mouse object is the same or in mouse selection mode
  617.     if( mouse_object->obj == sprite || ( sprite && ( pKeyboard->keys[SDLK_RSHIFT] || pKeyboard->keys[SDLK_LSHIFT] || mode_selection ) ) )
  618.     {
  619.         return;
  620.     }
  621.  
  622.     // remove old mouse_object from selected objects
  623.     if( mouse_object->obj )
  624.     {
  625.         Remove_Selected_Object( mouse_object->obj, 1 );
  626.     }
  627.  
  628.     // set new mouse object
  629.     mouse_object->obj = sprite;
  630.     // add new mouse object to selected objects
  631.     Add_Selected_Object( sprite );
  632. }
  633.  
  634. void cMouseCursor :: Update_Mouse_Object( void )
  635. {
  636.     if( ( !editor_enabled ) || !mouse_object->obj || ( mover_mode && ( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD ) ) )
  637.     {
  638.         return;
  639.     }
  640.  
  641.     // left mouse is pressed and no shift
  642.     if( left )
  643.     {
  644.         // set new position
  645.         mouse_object->obj->Set_Pos( static_cast<float>( static_cast<int>(posx) - mouse_object->mouse_w ), static_cast<float>( static_cast<int>(posy) - mouse_object->mouse_h ), 1 );
  646.  
  647.         // update object settings position
  648.         if( active_object && active_object == mouse_object->obj )
  649.         {
  650.             active_object->Editor_Position_Update();
  651.         }
  652.     }
  653.     // left mouse is not pressed
  654.     else
  655.     {
  656.         // update mouse object positioning mouse width and height
  657.         mouse_object->mouse_w = static_cast<int>(posx) - static_cast<int>(mouse_object->obj->startposx);
  658.         mouse_object->mouse_h = static_cast<int>(posy) - static_cast<int>(mouse_object->obj->startposy);
  659.     }
  660. }
  661.  
  662. void cMouseCursor :: Clear_Mouse_Object( void )
  663. {
  664.     Set_Mouse_Object( NULL );
  665. }
  666.  
  667. void cMouseCursor :: Add_Copy_Object( cSprite *sprite )
  668. {
  669.     if( !sprite )
  670.     {
  671.         return;
  672.     }
  673.  
  674.     // check if not already added
  675.     for( CopyObjectList::iterator itr = copy_objects.begin(), itr_end = copy_objects.end(); itr != itr_end; ++itr )
  676.     {
  677.         if( (*itr)->obj == sprite )
  678.         {
  679.             return;
  680.         }
  681.     }
  682.  
  683.     cSprite *copy = sprite->Copy();
  684.  
  685.     // can't be copied
  686.     if( !copy )
  687.     {
  688.         return;
  689.     }
  690.  
  691.     // insert object
  692.     cCopyObject *copy_object = new cCopyObject();
  693.     copy_object->obj = copy;
  694.     copy_objects.push_back( copy_object );
  695. }
  696.  
  697. void cMouseCursor :: Add_Copy_Objects( SpriteList spritelist )
  698. {
  699.     if( !spritelist.size() )
  700.     {
  701.         return;
  702.     }
  703.  
  704.     // inserts all objects
  705.     for( SpriteList::iterator itr = spritelist.begin(), itr_end = spritelist.end(); itr != itr_end; ++itr )
  706.     {
  707.         cSprite *obj = (*itr);
  708.  
  709.         Add_Copy_Object( obj );
  710.     }
  711. }
  712.  
  713. bool cMouseCursor :: Remove_Copy_Object( cSprite *sprite )
  714. {
  715.     if( !sprite )
  716.     {
  717.         return 0;
  718.     }
  719.  
  720.     for( CopyObjectList::iterator itr = copy_objects.begin(), itr_end = copy_objects.end(); itr != itr_end; ++itr )
  721.     {
  722.         cCopyObject *copy_obj = (*itr);
  723.  
  724.         if( copy_obj->obj == sprite )
  725.         {
  726.             copy_objects.erase( itr );
  727.             delete copy_obj;
  728.             
  729.             return 1;
  730.         }
  731.     }
  732.  
  733.     return 0;
  734. }
  735.  
  736. void cMouseCursor :: Clear_Copy_Objects( void )
  737. {
  738.     for( CopyObjectList::iterator itr = copy_objects.begin(), itr_end = copy_objects.end(); itr != itr_end; ++itr )
  739.     {
  740.         delete *itr;
  741.     }
  742.  
  743.     copy_objects.clear();
  744. }
  745.  
  746. GL_Vector cMouseCursor :: Get_Copy_Object_Base( float px, float py )
  747. {
  748.     GL_Vector vec = GL_Vector();
  749.  
  750.     if( !copy_objects.size() )
  751.     {
  752.         return vec;
  753.     }
  754.  
  755.     // set a base
  756.     float base_x = copy_objects[0]->obj->posx;
  757.     float base_y = copy_objects[0]->obj->posy;
  758.  
  759.     for( CopyObjectList::iterator itr = copy_objects.begin(), itr_end = copy_objects.end(); itr != itr_end; ++itr )
  760.     {
  761.         cCopyObject *copy_obj = (*itr);
  762.  
  763.         // if more in top or left
  764.         if( copy_obj->obj->posx < base_x || copy_obj->obj->posy < base_y )
  765.         {
  766.             base_x = copy_obj->obj->posx;
  767.             base_y = copy_obj->obj->posy;
  768.         }
  769.     }
  770.  
  771.     vec.x = px - base_x;
  772.     vec.y = py - base_y;
  773.  
  774.     return vec;
  775. }
  776.  
  777. void cMouseCursor :: Paste_Copy_Objects( float px, float py )
  778. {
  779.     if( !copy_objects.size() )
  780.     {
  781.         return;
  782.     }
  783.  
  784.     SpriteList new_objects;
  785.  
  786.     for( CopyObjectList::iterator itr = copy_objects.begin(), itr_end = copy_objects.end(); itr != itr_end; ++itr )
  787.     {
  788.         cCopyObject *copy_obj = (*itr);
  789.  
  790.         // set base vector
  791.         GL_Vector base_vec = Get_Copy_Object_Base( copy_obj->obj->posx, copy_obj->obj->posy );
  792.  
  793.         // copy
  794.         cSprite* new_object = Copy( copy_obj->obj, px + base_vec.x, py + base_vec.y );
  795.  
  796.         if( new_object )
  797.         {
  798.             new_objects.push_back( new_object );
  799.         }
  800.     }
  801.  
  802.     if( copy_objects.size() )
  803.     {
  804.         mouse_object->mouse_h = static_cast<int>( copy_objects[0]->obj->col_rect.h / 2 );
  805.         mouse_object->mouse_w = static_cast<int>( copy_objects[0]->obj->col_rect.w / 2 );
  806.     }
  807.  
  808.     // pasted objects are selected
  809.     Clear_Selected_Objects();
  810.     Add_Selected_Objects( new_objects, 1 );
  811. }
  812.  
  813. bool cMouseCursor :: Add_Selected_Object( cSprite *sprite, bool from_user /* = 0 */ )
  814. {
  815.     if( !sprite )
  816.     {
  817.         return 0;
  818.     }
  819.  
  820.     // check if not already added
  821.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  822.     {
  823.         cSelectedObject *sel_obj = (*itr);
  824.  
  825.         if( sel_obj->obj == sprite )
  826.         {
  827.             // overwrite user if given
  828.             if( from_user && !sel_obj->user )
  829.             {
  830.                 sel_obj->user = 1;
  831.                 return 1;
  832.             }
  833.  
  834.             return 0;
  835.         }
  836.     }
  837.  
  838.     // insert object
  839.     cSelectedObject *selected_object = new cSelectedObject();
  840.     selected_object->obj = sprite;
  841.     selected_object->user = from_user;
  842.     selected_objects.push_back( selected_object );
  843.  
  844.     return 1;
  845. }
  846.  
  847. void cMouseCursor :: Add_Selected_Objects( SpriteList spritelist, bool from_user /* = 0 */ )
  848. {
  849.     if( !spritelist.size() )
  850.     {
  851.         return;
  852.     }
  853.  
  854.     // inserts all objects
  855.     for( SpriteList::iterator itr = spritelist.begin(), itr_end = spritelist.end(); itr != itr_end; ++itr )
  856.     {
  857.         cSprite *obj = (*itr);
  858.  
  859.         Add_Selected_Object( obj, from_user );
  860.     }
  861. }
  862.  
  863. bool cMouseCursor :: Remove_Selected_Object( cSprite *sprite, bool no_user /* = 0 */ )
  864. {
  865.     if( !sprite )
  866.     {
  867.         return 0;
  868.     }
  869.  
  870.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  871.     {
  872.         cSelectedObject *sel_obj = (*itr);
  873.  
  874.         if( sel_obj->obj == sprite )
  875.         {
  876.             // don't delete user added selected object
  877.             if( no_user && sel_obj->user )
  878.             {
  879.                 return 0;
  880.             }
  881.  
  882.             selected_objects.erase( itr );
  883.             delete sel_obj;
  884.             
  885.             return 1;
  886.         }
  887.     }
  888.  
  889.     return 0;
  890. }
  891.  
  892. SpriteList cMouseCursor :: Get_Selected_Objects( void )
  893. {
  894.     SpriteList spritelist;
  895.  
  896.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  897.     {
  898.         cSelectedObject *object = (*itr);
  899.  
  900.         spritelist.push_back( object->obj );
  901.     }
  902.  
  903.     return spritelist;
  904. }
  905.  
  906. void cMouseCursor :: Clear_Selected_Objects( void )
  907. {
  908.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  909.     {
  910.         delete *itr;
  911.     }
  912.  
  913.     selected_objects.clear();
  914. }
  915.  
  916. void cMouseCursor :: Update_Selected_Objects( void )
  917. {
  918.     if( !editor_enabled || ( mover_mode && ( Game_Mode == MODE_LEVEL || Game_Mode == MODE_OVERWORLD ) ) )
  919.     {
  920.         return;
  921.     }
  922.  
  923.     // update selected objects positioning mouse width and height
  924.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  925.     {
  926.         cSelectedObject *sel_obj = (*itr);
  927.  
  928.         if( !left || mode_selection )
  929.         {
  930.             sel_obj->mouse_w = static_cast<int>(posx) - static_cast<int>(sel_obj->obj->startposx);
  931.             sel_obj->mouse_h = static_cast<int>(posy) - static_cast<int>(sel_obj->obj->startposy);
  932.         }
  933.     }
  934.  
  935.     // if a user selected object is not active
  936.     if( !Is_Selected_Object( mouse_object->obj, 1 ) )
  937.     {
  938.         return;
  939.     }
  940.  
  941.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  942.     {
  943.         cSelectedObject *sel_obj = (*itr);
  944.  
  945.         // left mouse is pressed
  946.         if( left )
  947.         {
  948.             // set new position
  949.             sel_obj->obj->Set_Pos( static_cast<float>(static_cast<int>(posx) - sel_obj->mouse_w), static_cast<float>(static_cast<int>(posy) - sel_obj->mouse_h), 1 );
  950.  
  951.             // update object settings position
  952.             if( active_object && active_object == sel_obj->obj )
  953.             {
  954.                 active_object->Editor_Position_Update();
  955.             }
  956.         }
  957.     }
  958. }
  959.  
  960. bool cMouseCursor :: Is_Selected_Object( cSprite *sprite, bool only_user /* = 0 */ )
  961. {
  962.     if( !sprite )
  963.     {
  964.         return 0;
  965.     }
  966.  
  967.     for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  968.     {
  969.         cSelectedObject *sel_obj = (*itr);
  970.  
  971.         if( sel_obj->obj == sprite )
  972.         {
  973.             // if only user objects
  974.             if( only_user && !sel_obj->user )
  975.             {
  976.                 continue;
  977.             }
  978.  
  979.             // found
  980.             return 1;
  981.         }
  982.     }
  983.  
  984.     return 0;
  985. }
  986.  
  987. void cMouseCursor :: Delete_Selected_Objects( void )
  988. {
  989.     for( int i = selected_objects.size() - 1; i >= 0; i-- )
  990.     {
  991.         Delete( selected_objects[i]->obj );
  992.     }
  993.  
  994.     Clear_Selected_Objects();
  995. }
  996.  
  997. unsigned int cMouseCursor :: Get_Selected_Object_Size( void )
  998. {
  999.     return selected_objects.size();
  1000. }
  1001.  
  1002. void cMouseCursor :: Set_Active_Object( cSprite *sprite )
  1003. {
  1004.     // clear existing
  1005.     Clear_Active_Object();
  1006.  
  1007.     if( sprite )
  1008.     {
  1009.         active_object = sprite;
  1010.         active_object->Editor_Activate();
  1011.     }
  1012. }
  1013.  
  1014. void cMouseCursor :: Clear_Active_Object( void )
  1015. {
  1016.     if( active_object )
  1017.     {
  1018.         active_object->Editor_Deactivate();
  1019.         active_object = NULL;
  1020.     }
  1021. }
  1022.  
  1023. cSprite *cMouseCursor :: Copy( cSprite *ncopy_object, float px, float py )
  1024. {
  1025.     if( !ncopy_object )
  1026.     {
  1027.         return NULL;
  1028.     }
  1029.  
  1030.     if( !editor_enabled )
  1031.     {
  1032.         printf( "Warning : No editor enabled for copy object: %s\n", ncopy_object->name.c_str() );
  1033.         return NULL;
  1034.     }
  1035.  
  1036.     cSprite *new_sprite = ncopy_object->Copy();
  1037.  
  1038.     if( !new_sprite )
  1039.     {
  1040.         printf( "Warning : Mouse object copying failed\n" );
  1041.         return NULL;
  1042.     }
  1043.  
  1044.     new_sprite->Set_Pos( px, py, 1 );
  1045.  
  1046.     if( new_sprite->sprite_array == ARRAY_MASSIVE || new_sprite->sprite_array == ARRAY_PASSIVE || new_sprite->sprite_array == ARRAY_FRONT_PASSIVE || new_sprite->sprite_array == ARRAY_ACTIVE || new_sprite->sprite_array == ARRAY_ENEMY || new_sprite->sprite_array == ARRAY_ANIM )
  1047.     {
  1048.         pActive_Sprite_Manager->Add( new_sprite );
  1049.     }
  1050.     else
  1051.     {
  1052.         printf( "Warning : cMouseCursor :: Copy object unknown array : %d\n", new_sprite->sprite_array );
  1053.         delete new_sprite;
  1054.         return NULL;
  1055.     }
  1056.  
  1057.     return new_sprite;
  1058. }
  1059.  
  1060. void cMouseCursor :: Delete( cSprite *sprite )
  1061. {
  1062.     if( !sprite )
  1063.     {
  1064.         return;
  1065.     }
  1066.  
  1067.     if( sprite->sprite_array == ARRAY_PASSIVE || sprite->sprite_array == ARRAY_FRONT_PASSIVE || sprite->sprite_array == ARRAY_MASSIVE || sprite->sprite_array == ARRAY_ACTIVE || sprite->sprite_array == ARRAY_ENEMY || sprite->sprite_array == ARRAY_ANIM )
  1068.     {
  1069.         // deactivate active object
  1070.         if( active_object == sprite )
  1071.         {
  1072.             Double_Click( 0 );
  1073.         }
  1074.  
  1075.         // remove if current player active item object
  1076.         if( pPlayer->active_object == sprite )
  1077.         {
  1078.             pPlayer->active_object = NULL;
  1079.         }
  1080.  
  1081.         // remove selected object
  1082.         Remove_Selected_Object( sprite );
  1083.         // remove copy object
  1084.         Remove_Copy_Object( sprite );
  1085.  
  1086.         // delete object
  1087.         if( editor_enabled )
  1088.         {
  1089.             // if overworld line point
  1090.             if( sprite->type == TYPE_OW_LINE_START || sprite->type == TYPE_OW_LINE_END )
  1091.             {
  1092.                 cLayer_Line *line = static_cast<cLayer_Line *>(static_cast<cLayer_Line_Point *>(sprite)->line);
  1093.  
  1094.                 // delete line
  1095.                 pActive_Overworld->pLayer->Delete( line );
  1096.             }
  1097.             else
  1098.             {
  1099.                 sprite->Destroy();
  1100.             }
  1101.         }
  1102.  
  1103.         sprite = NULL;
  1104.     }
  1105. }
  1106.  
  1107. void cMouseCursor :: Draw_Object_Rects( void )
  1108. {
  1109.     // draw mouse object
  1110.     GL_rect hover_rect;
  1111.  
  1112.     if( !left && mouse_object->obj )
  1113.     {
  1114.         hover_rect.x = mouse_object->obj->startposx - pActive_Camera->x;
  1115.         hover_rect.y = mouse_object->obj->startposy - pActive_Camera->y;
  1116.         hover_rect.w = mouse_object->obj->start_rect.w;
  1117.         hover_rect.h = mouse_object->obj->start_rect.h;
  1118.  
  1119.         // create request
  1120.         cRectRequest *request = new cRectRequest();
  1121.  
  1122.         if( mode_fastcopy )
  1123.         {
  1124.             pVideo->Draw_Rect( &hover_rect, 0.6f, &green, request );
  1125.         }
  1126.         else
  1127.         {
  1128.             pVideo->Draw_Rect( &hover_rect, 0.6f, &blue, request );
  1129.         }
  1130.  
  1131.         // not filled
  1132.         request->filled = 0;
  1133.  
  1134.         // add request
  1135.         pRenderer->Add( request );
  1136.     }
  1137.  
  1138.  
  1139.     // draw selected objects if not left mouse is pressed, shift selection or mouse selection
  1140.     if( !left || ( pKeyboard->keys[SDLK_RSHIFT] || pKeyboard->keys[SDLK_LSHIFT] ) || mode_selection )
  1141.     {
  1142.         Color obj_color = white;
  1143.  
  1144.         for( SelectedObjectList::iterator itr = selected_objects.begin(), itr_end = selected_objects.end(); itr != itr_end; ++itr )
  1145.         {
  1146.             cSprite *object = (*itr)->obj;
  1147.  
  1148.             // check if visible on screen
  1149.             if( !object->Is_Visible_on_Screen() )
  1150.             {
  1151.                 continue;
  1152.             }
  1153.  
  1154.             hover_rect.x = object->startposx - pActive_Camera->x;
  1155.             hover_rect.y = object->startposy - pActive_Camera->y;
  1156.             hover_rect.w = object->start_rect.w;
  1157.             hover_rect.h = object->start_rect.h;
  1158.  
  1159.             // object color
  1160.             obj_color = Get_Massive_Type_Color( object->massivetype );
  1161.  
  1162.             // create request
  1163.             cRectRequest *rect_request = new cRectRequest();
  1164.             pVideo->Draw_Rect( &hover_rect, 0.5f, &obj_color, rect_request );
  1165.  
  1166.             // not filled
  1167.             rect_request->filled = 0;
  1168.  
  1169.             // add request
  1170.             pRenderer->Add( rect_request );
  1171.         }
  1172.     }
  1173. }
  1174.  
  1175. void cMouseCursor :: Start_Selection( void )
  1176. {
  1177.     Clear_Mouse_Object();
  1178.     mode_selection = 1;
  1179.     selection_rect.x = x + pActive_Camera->x;
  1180.     selection_rect.y = y + pActive_Camera->y;
  1181. }
  1182.  
  1183. void cMouseCursor :: End_Selection( void )
  1184. {
  1185.     mode_selection = 0;
  1186.  
  1187.     Update_Position();
  1188. }
  1189.  
  1190. void cMouseCursor :: Update_Selection( void )
  1191. {
  1192.     if( !mode_selection )
  1193.     {
  1194.         return;
  1195.     }
  1196.  
  1197.     selection_rect.w = x - selection_rect.x + pActive_Camera->x;
  1198.     selection_rect.h = y - selection_rect.y + pActive_Camera->y;
  1199.  
  1200.     // create collision checking rect
  1201.     GL_rect rect = GL_rect( selection_rect.x, selection_rect.y, 0, 0 );
  1202.  
  1203.     // negative to positive
  1204.     if( selection_rect.w < 0 )
  1205.     {
  1206.         rect.x = selection_rect.x + selection_rect.w;
  1207.         rect.w = -selection_rect.w;
  1208.     }
  1209.     // positive
  1210.     else
  1211.     {
  1212.         rect.w = selection_rect.w;
  1213.     }
  1214.  
  1215.     // negative to positive
  1216.     if( selection_rect.h < 0 )
  1217.     {
  1218.         rect.y = selection_rect.y + selection_rect.h;
  1219.         rect.h = -selection_rect.h;
  1220.     }
  1221.     // positive
  1222.     else
  1223.     {
  1224.         rect.h = selection_rect.h;
  1225.     }
  1226.  
  1227.     // if rect is below minimum
  1228.     if( rect.w < 2 && rect.h < 2 )
  1229.     {
  1230.         return;
  1231.     }
  1232.  
  1233.     // only clear if not shift is pressed
  1234.     if( !( pKeyboard->keys[SDLK_RSHIFT] || pKeyboard->keys[SDLK_LSHIFT] ) )
  1235.     {
  1236.         Clear_Selected_Objects();
  1237.     }
  1238.  
  1239.     // add selected objects
  1240.     for( SpriteList::iterator itr = pActive_Sprite_Manager->objects.begin(), itr_end = pActive_Sprite_Manager->objects.end(); itr != itr_end; ++itr )
  1241.     {
  1242.         cSprite *object = (*itr);
  1243.  
  1244.         if( !object->spawned && Col_Box( &rect, &object->rect ) )
  1245.         {
  1246.             Add_Selected_Object( object, 1 );
  1247.         }
  1248.     }
  1249.  
  1250.     if( Col_Box( &rect, &pActive_Player->rect ) )
  1251.     {
  1252.         Add_Selected_Object( pActive_Player, 1 );
  1253.     }
  1254.  
  1255.     // ## inner rect
  1256.     cRectRequest *rect_request = new cRectRequest();
  1257.     pVideo->Draw_Rect( selection_rect.x - pActive_Camera->x + 0.5f, selection_rect.y - pActive_Camera->y + 0.5f, selection_rect.w, selection_rect.h, 0.509f, &white, rect_request );
  1258.  
  1259.     // not filled
  1260.     rect_request->filled = 0;
  1261.     // color
  1262.     rect_request->color.alpha = 128;
  1263.  
  1264.     // add request
  1265.     pRenderer->Add( rect_request );
  1266.  
  1267.     // ## outer rect
  1268.     // create request
  1269.     rect_request = new cRectRequest();
  1270.     pVideo->Draw_Rect( selection_rect.x - pActive_Camera->x, selection_rect.y - pActive_Camera->y, selection_rect.w, selection_rect.h, 0.51f, &lightblue, rect_request );
  1271.  
  1272.     // not filled
  1273.     rect_request->filled = 0;
  1274.  
  1275.     // add request
  1276.     pRenderer->Add( rect_request );
  1277. }
  1278.  
  1279. void cMouseCursor :: Toggle_Mover_Mode( void )
  1280. {
  1281.     mover_mode = !mover_mode;
  1282.  
  1283.     if( mover_mode )
  1284.     {
  1285.         CEGUI::MouseCursor::getSingleton().setImage( "TaharezLook", "MouseMoveCursor" );
  1286.     }
  1287.     else
  1288.     {
  1289.         CEGUI::MouseCursor::getSingleton().setImage( "TaharezLook", "MouseArrow" );
  1290.     }
  1291. }
  1292.  
  1293. void cMouseCursor :: Mover_Update( Sint16 move_x, Sint16 move_y )
  1294. {
  1295.     if( !mover_mode )
  1296.     {
  1297.         return;
  1298.     }
  1299.  
  1300.     // mouse moves the camera
  1301.     pActive_Camera->Move( move_x, move_y );
  1302.     // keep mouse at it's position
  1303.     SDL_WarpMouse( static_cast<Uint16>(x * global_upscalex), static_cast<Uint16>(y * global_upscaley) );
  1304.  
  1305.     SDL_Event inEvent;
  1306.     SDL_PeepEvents( &inEvent, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK );
  1307.  
  1308.     while( SDL_PollEvent( &inEvent ) )
  1309.     {
  1310.         switch( inEvent.type )
  1311.         {
  1312.             case SDL_MOUSEBUTTONDOWN:
  1313.             {
  1314.                 if( inEvent.button.button == 2 )
  1315.                 {
  1316.                     mover_mode = 0;
  1317.                 }
  1318.                 break;
  1319.             }
  1320.             case SDL_KEYDOWN:
  1321.             {
  1322.                 mover_mode = 0;
  1323.                 pKeyboard->Key_Down( inEvent.key.keysym.sym );
  1324.                 break;
  1325.             }
  1326.             case SDL_QUIT:
  1327.             {
  1328.                 game_exit = 1;
  1329.                 break;
  1330.             }
  1331.         }
  1332.     }
  1333. }
  1334.  
  1335. void cMouseCursor :: Editor_Update( void )
  1336. {
  1337.     if( !editor_enabled )
  1338.     {
  1339.         return;
  1340.     }
  1341.  
  1342.     bool is_col = Editor_Collsion_Check();
  1343.     cObjectCollision *col = Collision_Get_first();
  1344.  
  1345.     // valid object
  1346.     if( is_col && col )
  1347.     {
  1348.         // get colliding object
  1349.         cSprite *obj = NULL;
  1350.  
  1351.         // player
  1352.         if( col->type == CO_PLAYER )
  1353.         {
  1354.             obj = static_cast<cSprite *>(pActive_Player);
  1355.         }
  1356.         // object manager object
  1357.         else
  1358.         {
  1359.             obj = pActive_Sprite_Manager->Get_Pointer( col->number );
  1360.         }
  1361.  
  1362.         // mouse object type string
  1363.         string type_name;
  1364.  
  1365.         // set object data
  1366.         if( obj )
  1367.         {
  1368.             type_name = obj->name;
  1369.  
  1370.             if( !left || !mouse_object->obj )
  1371.             {
  1372.                 Set_Mouse_Object( obj );
  1373.             }
  1374.         }
  1375.  
  1376.         // ## Set Massivetype Text
  1377.         if( col->type == CO_MASSIVE )
  1378.         {
  1379.             if( obj->massivetype == MASS_HALFMASSIVE )
  1380.             {
  1381.                 type_name.insert( 0, _("Halfmassive - ") );
  1382.             }
  1383.             else
  1384.             {
  1385.                 type_name.insert( 0, _("Massive - ") );
  1386.             }
  1387.         }
  1388.         else if( col->type == CO_PASSIVE )
  1389.         {
  1390.             if( obj->type == TYPE_OW_LINE_START || obj->type == TYPE_OW_LINE_END || obj->type == TYPE_OW_WAYPOINT )
  1391.             {
  1392.                 // ignore
  1393.             }
  1394.             else if( obj->sprite_array == ARRAY_PASSIVE )
  1395.             {
  1396.                 type_name.insert( 0, _("Passive - ") );
  1397.             }
  1398.             else
  1399.             {
  1400.                 type_name.insert( 0, _("Front Passive - ") );
  1401.             }
  1402.         }
  1403.         else if( col->type == CO_ACTIVE )
  1404.         {
  1405.             if( obj->type == TYPE_HALFMASSIVE )
  1406.             {
  1407.                 type_name.insert( 0, _("Halfmassive - ") );
  1408.             }
  1409.             else if( obj->type == TYPE_CLIMBABLE )
  1410.             {
  1411.                 type_name.insert( 0, _("Climbable - ") );
  1412.             }
  1413.         }
  1414.  
  1415.  
  1416.         // if valid object draw position text
  1417.         if( col->type != CO_NOTHING && mouse_object->obj )
  1418.         {
  1419.             // position text
  1420.             string info = "X : " + int_to_string( static_cast<int>(mouse_object->obj->startposx) ) + "  Y : " + int_to_string( static_cast<int>(mouse_object->obj->startposy) );
  1421.  
  1422.             // if in debug mode draw editor Z position
  1423.             if( game_debug )
  1424.             {
  1425.                 info.insert( info.length(), "  Z : " + float_to_string( mouse_object->obj->posz, 6 ) );
  1426.  
  1427.                 // if also got editor z position
  1428.                 if( obj->editor_posz != 0 )
  1429.                 {
  1430.                     info.insert( info.length(), _("  Editor Z : ") + float_to_string( mouse_object->obj->editor_posz, 6 ) );
  1431.                 }
  1432.             }
  1433.  
  1434.             GL_Surface *position_info = pFont->Render_Text( pFont->font_small, info, white );
  1435.  
  1436.             // create request
  1437.             cSurfaceRequest *request = new cSurfaceRequest();
  1438.             position_info->Blit( static_cast<float>( x + 20 ), static_cast<float>( y + 35 ), 0.52f, request );
  1439.             request->delete_texture = 1;
  1440.  
  1441.             // shadow
  1442.             request->shadow_pos = 1;
  1443.             request->shadow_color = black;
  1444.  
  1445.             // add request
  1446.             pRenderer->Add( request );
  1447.  
  1448.             position_info->auto_del_img = 0;
  1449.             delete position_info;
  1450.         }
  1451.  
  1452.         if( debugdisplay->counter <= 0 )
  1453.         {
  1454.             debugdisplay->Set_Text( type_name, 1 );
  1455.         }
  1456.     }
  1457.     else
  1458.     {
  1459.         if( !left )
  1460.         {
  1461.             Clear_Mouse_Object();
  1462.  
  1463.             if( !col )
  1464.             {
  1465.                 mouse_object->mouse_w = 0;
  1466.                 mouse_object->mouse_h = 0;
  1467.             }
  1468.         }
  1469.         else
  1470.         {
  1471.             // no mouse object
  1472.             if( !mouse_object->obj )
  1473.             {
  1474.                 // clear active object
  1475.                 Double_Click( 0 );
  1476.  
  1477.                 // clear selected objects if no shift is pressed
  1478.                 if( !( pKeyboard->keys[SDLK_RSHIFT] || pKeyboard->keys[SDLK_LSHIFT] ) )
  1479.                 {
  1480.                     Clear_Selected_Objects();
  1481.                 }
  1482.             }
  1483.         }
  1484.     }
  1485. }
  1486.  
  1487. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  1488.  
  1489. cMouseCursor *pMouseCursor = NULL;
  1490.