Announcement

Collapse
No announcement yet.

Locking mouse position when hidden

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Locking mouse position when hidden

    I am working on a simple HUD/user interface system (inventory/loadout type stuff) in Flash/semi-Scaleform. I am only using open-source Flash tools so far (FlashDevelop with ActionScript 2.0) and I have not yet figured out fancy ways to use Scaleform components, so this may be more of a "pure" Flash UI. Hopefully there's no problem with that.

    Anyway, right now I have a UDKHUD subclass which spawns a GFxMoviePlayer subclass that is used to display either the normal HUD icons/crosshair/etc., or a loadout screen, essentially. The player can press a button to bring up the loadout screen. There is a mouse cursor that behaves normally and it is only visible when the loadout screen is displayed.

    My problem is that if the user moves the mouse to say, the left half of the screen, closes the loadout screen, and then spins around to the right ingame, the mouse will have moved to the right in the augment screen even though it (and the mouse cursor) were hidden. I would like the cursor to either stay in place, or else go back to the center of the screen each time the loadout screen is working.

    The cursor is a simple MovieClip, set with code like this:
    Code:
    mouseListener.onMouseMove = function()
    {
       Main.cursor1Clip._x = _root._xmouse;
       Main.cursor1Clip._y = _root._ymouse;
    }
    My understanding is that there is no way to actually set the Flash/Scaleform cursor position since that would be a big Flash vulnerability on the web etc. I cannot keep my own offset and try to draw the cursor at the center each time the loadout screen comes up, since I think the Flash/Scaleform _root._xmouse or _root._ymouse would run into the side of the screen and simply stop moving.

    Does anyone have any idea how this might be accomplished, or is it impossible? I am trying to use the new Flash/Scaleform technology since the older stuff is being/has been deprecated. I found a couple threads that have similar questions but apparently no solution so far.

    Thanks for reading! Any response is appreciated, even if it's just "that's basically impossible with Scaleform".

    *edit*

    I should also put in my own ideas for solutions:
    1. I have tried some of the various variable settings in the movie player and whatnot in an attempt to ignore mouse input while the movie is not displayed. I have not had success yet, however.
    2. Is it "proper" design to have the same flash movie and GfxMoviePlayer show both the HUD and inventory/loadout screens? Maybe the mouse cursor would be properly ignored if I actually created a new movie each time the screen needed to come up, or swapped out movies, instead of just showing different things with the same movie/movie player.

    #2
    the only thing I can think of right now is to save th elocation of the mousepointer when you hide it, and when you enable it again you set the mousepointer.x and y to the difference between the real mousecoordinates and the mousepointerGFX, I hav eno idea if this will work if the real mouse "escapes" the screen though, as it might be clamped to screen coordinates

    Comment


      #3
      Thanks for the quick reply! Right, my fear is that it would be clamped (I think that is my observation from testing so far). I think the most realistic option may be trying to make a second movieplayer subclass and switching between the HUD UI and the loadout movieplayer.

      I am kind of surprised more people have not run into this before, since it seems like this would affect anyone who uses scaleform HUD stuff and an optionally visible mouse cursor.

      Comment


        #4
        Well, even if I ONLY create the GFxMoviePlayer when I need to display the loadout screen, and delete it when it's hidden, the mouse cursor still moves in the background.

        In fact, it seems to pull directly from the Windows mouse cursor position, from before I even start the UDK. Maybe it'd work if I wasn't in windowed mode? I'm not sure, but I want to support windowed mode as well. I think one person suggested the possibility of using DllBind to try to use API calls to move the mouse, but that seems kind of dirty to me and I was hoping there was another way to do it.

        Once again, has anyone at all ever used a Scaleform UI that has a mouse cursor, but the mouse cursor only appears if you're in menus? And if so, how did you handle the situation I'm having? I honestly just don't see how it's possible unless DllBind is involved. :X

        Comment


          #5
          Latest attempt, using DLLBind. This gets me SO CLOSE to what I need. After a bunch of debugging to get the DLL calling stuff right (non-mangled symbols presumably, using a manual .def file, and manually running the 32-bit editor instead of the 64-bit editor), I can set system, and thus Flash/Scaleform, mouse position using DLLBind'd C++ code:

          Code:
             __declspec(dllexport) void SetMousePosition(int newX, int newY)
             {
                SetCursorPos(newX, newY);
             }
          Unfortunately, this uses screen coordinates, so for a windowed view I cannot center the mouse properly. I still want to use windowed view, but I would need some way of actually getting a HWND to the windowed play-in-editor or windowed UDK game window. Does anyone have any experiences with this, or other suggestions? Thanks for reading!

          Comment


            #6
            Here is yet another update. I was able to use this DLL code to set mouse coordinates:

            Code:
               // Sets the mouse cursor position.
               __declspec(dllexport) void SetMousePosition(int newX, int newY)
               {
                  POINT newPosition;
                  newPosition.x = newX;
                  newPosition.y = newY;
            
                  // Convert client coordinates to screen coordinates if needed.
                  HWND curWindow = GetActiveWindow();
                  if(NULL != curWindow)
                  {
                     ClientToScreen(curWindow, &newPosition);
                  }
            
                  SetCursorPos(newPosition.x, newPosition.y);
               }
            Even if the window is moved, the cursor still resets to an appropriate window-coordinates location when my loadout screen is opened, now, as long as I call SetMousePosition with an appropriate constant.

            Maybe this will help someone else some day.

            Comment


              #7
              tnx, i was looking some like that too

              Comment


                #8
                Originally posted by _h2o_ View Post
                tnx, i was looking some like that too
                You're welcome. Since you requested it via PM I figured I would post the full DLL code necessary to do this. It's very simple. I also had a silly math function so I could test returning a value from a DLL call.

                Code:
                #include "stdafx.h"
                #include <stdio.h>
                
                extern "C"
                {
                   // Sets the mouse cursor position.
                   __declspec(dllexport) void SetMousePosition(int newX, int newY)
                   {
                      POINT newPosition;
                      newPosition.x = newX;
                      newPosition.y = newY;
                
                      // Convert client coordinates to screen coordinates if needed.
                      HWND curWindow = GetActiveWindow();
                      if(NULL != curWindow)
                      {
                         ClientToScreen(curWindow, &newPosition);
                      }
                
                      SetCursorPos(newPosition.x, newPosition.y);
                   }
                
                   // Test function that performs integer addition and returns a sum.
                   __declspec(dllexport) int TestMath(int a, int b)
                   {
                      return a + b;
                   }
                }
                See http://udn.epicgames.com/Three/DLLBind.html for more information on doing this sort of thing, but bear in mind that it may take some experimentation to get the build and runtime environment set up properly. Big gotcha for me, by default the 64-bit editor runs, but I'm not sure if 64-bit DLL binds work. I think the game engine itself is only 32-bit? Anyway, you need to manually run "UDK.exe editor" from the Win32 directory instead of the Win64 directory to properly pick up your DLL (from the Binaries\Win32\UserCode directory).

                Comment


                  #9
                  Blizzard_Edge tnx again

                  Comment


                    #10
                    Great work. Added a link in the Getting Started forum post.

                    Comment


                      #11
                      With newer version of UDK you can do it much easier:

                      Code:
                      [CustomClass extends GfxMoviePlayer ]
                      function CaptureMouse(bool IsEnabled)
                      {
                      	local Vector2D screensize;
                      	
                      	GetGameViewportClient().GetViewportSize(screensize);
                      	GetGameViewportClient().SetMouse(int(screensize.X / 2), int(screensize.Y / 2));
                      	bIgnoreMouseInput = !IsEnabled;
                      	bCaptureMouseInput = IsEnabled;
                      }
                      GetGameViewportClient().SetMouse works the same as this custom dll on the top.

                      Seems this is wrong thread for placing bugs, but this is important information.

                      Bug:
                      Scaleform does not update actual mouse location before any user mouse movement.
                      This bug is relevant to any solution to set mouse position (dllbind or GetGameViewportClient().SetMouse).
                      Steps to reproduce:
                      1) GfxMoviePlayer captures a mouse.
                      2) User starts to move mouse.
                      3) Cursor appears in a middle of the viewport.
                      4) Cursor starts to follow mouse.
                      5) User hovers cursor over CLIK button.
                      6) CLIK button changes state to "hover".
                      7) User somehow fires CaptureMouse(false) (via exec function for example).
                      8) Cursor stays in place. CLIK button is in "hover" state and recieves mouseClick events.
                      9) User fires CaptureMouse(true).
                      10) Nothing happens.
                      11) User starts to move mouse.
                      12) Cursor appears in the middle of the screen (actual mouse position is there now) and starts to follow mouse.

                      Comment

                      Working...
                      X