Game Development Community

NoCursor problems

by Chris B · in Torque Game Engine · 09/12/2004 (5:54 pm) · 14 replies

Hi!

I am developing a game (duh!) that has the following requirements:

1) The ability to use the mouse on the screen
2) The ability to bind xaxis and yaxis in script

After digging around through the engine code last night and editing maincc, guicanvas.cc and event.cc (i think its event.cc, the one with processaction, handleaction) I came up with a bit of a hack to get what I needed working.

My 'hack' involves the ProcessMouseMovement in main.cc passing an InputEvent struct (manually constructed using the MouseMoveEvent variables) to Action::HandleEvent();

Movement speed of the mouse (when passed to an xaxis or yaxis bind) is increased 10 fold, which I have compensated for in script. The cursor movement itself is fine.

Problem is that I am unsatisfied with the results.

I guess I am looking for some comments from the gurus on the best way to approach my requirements above.

Do I go with what I have done, or should I simply do noCursor = 1 in my GameTSCtrl and create a custom bind for xaxis and yaxis that will do what I need?

Is there a better way?

I hope my post is clear enough, and I greatly appreciate any input from the community.

Thanks

#1
09/12/2004 (9:43 pm)
I'm not sure I entirely follow what you're trying to do. Can you give me an example of what use this functionality is in your game? (Not trying to say you don't need it - just that there might be a more elegant way to get where you need to go than the approach you've tried.)
#2
09/12/2004 (9:45 pm)
Hi Ben,

I am using the advanced camera code by Thomas (Man of Ice) and I want to be able to (in 3rd person view) hold middle mouse down and trap the X and Y axis movement of the mouse to rotate the camera.

I cannot do this whilst I have the cursor displayed as it appears that the actionmaps are not called while you have cursor enabled :)
#3
09/13/2004 (8:11 am)
Ah, that's easy. The editor does that when you right click. I suggest looking at the editor and reproducing the functionality.
#4
11/07/2004 (4:49 pm)
I am trying to do the same functionality as seen in the editor where movement is mapped to the right mouse button. Can someone give me some suggestions that aren't as vague?

Thanks
#5
11/07/2004 (4:56 pm)
I ended up getting this working but I took two approaches to see which worked better.

I am at work now so the answers ARE going to be vague (sorry) :)

The first thing I did was try to figure out why you couldnt use xaxis/yaxis when you have noCursor disabled.
I ended up tracing this down to a fairly low level function that called ProcessInputEvent (not sure if this is correct, it has been awhile)

If the cursor wasnt enabled - it would also call a function such as ProcessMouseEvent, I tried calling this function regardless and with a few modifications got it working.. I scrapped this solution as I wasnt too confident in modifying the engine on that level at the time.

The way I ended up doing it was to actually take the code for the editor, in worldeditor.cc and ... i forget the name of the other file, its editsomething in engine/editor/ :/

I ported all of that code to GameTSCtrl:: and then started ripping out the bits I didnt need.

What I ended up with was functionality very similar to the editor where I could click and drag select an object/objects, move them to a point, use my right mouse button around etc - regardless of what noCursor is set to.

I am most likely going to redo this as the code from the editor does not support multiplayer and this is essential to what I need.

If your game is single player I would be happy to post my GameTSCtrl modifications as a resource - although I am not the best coder in the world and there is probably a much better/easier way to do it :)
#6
11/07/2004 (5:13 pm)
When you get a chance could you post your modifications?

Thanks Chris
#7
06/19/2006 (8:29 pm)
Quote:The editor does that when you right click. I suggest looking at the editor and reproducing the functionality.

I know that this is an old thread, but I figured that it isn't worth starting a new thread on it.

I'm having trouble finding both the TorqueScript and the engine code for this, can you point me to the files where this is done? I couldn't even find the mouse button1 and the x/yaxis being bound. So if somebody could point me to the TorqueScript and the engine code that would be great.

Thanks,
Justin
#8
06/21/2006 (2:08 am)
I am pretty much working on the same thing right now, and would like to build something that is less 'hacked' (Sorry if it offends anybody) then the changes that is recommended. What I am working on right now is:

a) Turn on the mouse cursor (I am in 3rd person overhead view )
b) Grab the x,y coordinates use it to rotate the character facing based on where the mouse pointer is.

I am partially succesful and have implemented it by turning the mouse cursor on and trapping the the x,y coordinates in getMoves(GameConnectionMoves.cc). The only problem now is the action map doesn't work anymore. I can show people the code if they want to see it, but it's probably going to change..

I am wondering if anybody at GG has a better approach than this and keeping the Game still multiplayer. I will be doing some additional research and will post my findings, but it would be helpful if anybody has any additional information to share first.
#9
06/21/2006 (5:36 am)
OK,

I haven't done a proper stress test on this right now but this is what I ended up doing. My approach was not to try to break anything. If this post is unclear (or it seems to be an acceptable solution) then I will go ahead and make a resource.

What I did was to:
a) Extend the GuiCanvas class to have a ghost cursor flag
b) Change processMouseMoveEvent to 'use' the mouse x,y coodinates feed into but return a false
c) Change renderFrame to draw mouse cursor if the ghost cursor flag is on
d) Extend a method that allows you to turn it on/off

I figure that this is the safest way to do things without breaking too many thing. The code is NOT optimized yet until I figure out if it has bugs or not.

In gui\core\guiCanvas.h add:

bool        cursorON;
   bool        mShowCursor;
   bool        mRenderFront;
   Point2F     cursorPt;
   Point2I     lastCursorPt;
   GuiCursor   *defaultCursor;
   GuiCursor   *lastCursor;
   bool        lastCursorON;

   bool				mGhostCursor; // Ghost cursor flag

and..
   /// Turns the cursor on or off.
   /// @param   onOff   True if the cursor should be on.
   virtual void setCursorON(bool onOff);

	 /// Turns the ghost cursor on or off - Terence
	 /// @param   onOff		True if the cursor should be on.
	 virtual void setGhostCursor(bool onOff);

Now in guiCanvas.cc
GuiCanvas::GuiCanvas()
{
...
   rLastFrameTime = 0.0f;
  mGhostCursor = false;

In bool GuiCanvas::processInputEvent(const InputEvent *event) locate
else if(event->deviceType == MouseDeviceType && cursorON)
and change it to:
else if(event->deviceType == MouseDeviceType)
	 {
		 if (cursorON)
		 {

Near the bottom of the method, after the cursorOn code:
}
			else
			if (mGhostCursor)
			{
				if(event->objType == SI_XAXIS || event->objType == SI_YAXIS)
				{
					Point2F pt(cursorPt.x, cursorPt.y);

					if (event->objType == SI_XAXIS)
					{
						pt.x += (event->fValue * mPixelsPerMickey);
            cursorPt.x = getMax(0, getMin((S32)pt.x, mBounds.extent.x - 1));
					}
					else
					{
						pt.y += (event->fValue * mPixelsPerMickey);
            cursorPt.y = getMax(0, getMin((S32)pt.y, mBounds.extent.y - 1));
					}
				}
				return false;
			}

In renderFrame:
if (cursorON && mouseCursor && mShowCursor)
      {
         Point2I pos((S32)cursorPt.x, (S32)cursorPt.y);
         Point2I spot = mouseCursor->getHotSpot();

         pos -= spot;
         mouseCursor->render(pos);
      }
			else
			if (mouseCursor && mGhostCursor)
			{
				// Terence
				// Can add code here that 'checks' for flag and
				// also draw cursor. Making sure we don't draw more
				// than one.
				Point2I pos((S32)cursorPt.x, (S32)cursorPt.y);
				Point2I spot = mouseCursor->getHotSpot();

				pos -= spot;
				mouseCursor->render(pos);
			}

and finally add

// Ghost cursor, expose to script - Terence
ConsoleMethod( GuiCanvas, setGhostCursor, void, 3 , 3, "(bool onOff)")
{
	Canvas->setGhostCursor(dAtob(argv[2]));
}

Code is terrible..heh..but gives you the general idea...Not sure if this is the best approach. It may break something else...if you want it in a resource...then yell and I will do it over the weekend...cleaned up and all.

Oh yeah and make sure you turn it on. Currently I turn it on in starter.fps\client\init.c. If there is a better place to do it let me know..

function initClient()
{
 .....
   // Terence turn on ghost cursor
   Canvas.setGhostCursor(true);
#10
07/31/2006 (9:46 pm)
I managed to reproduce the functionality of EditTSCtrl into GameTSCtrl, however, it seems that other invisible controls get on the way on some portions of the screen (I think its the editor controls), grabbing the rightmousedown event :(.

First change playGui.gui from
new GameTSCtrl(PlayGui) {
   profile = "GuiContentProfile";
   horizSizing = "right";
   vertSizing = "bottom";
   position = "0 0";
   extent = "640 480";
   minExtent = "8 8";
   visible = "1";
   helpTag = "0";
   noCursor = "1";

to

new GameTSCtrl(PlayGui) {
   profile = "GuiContentProfile";
   horizSizing = "right";
   vertSizing = "bottom";
   position = "0 0";
   extent = "640 480";
   minExtent = "8 8";
   visible = "1";
   helpTag = "0";
   noCursor = "[b]0[/b]";

change in customProfile.cs from
new GuiControlProfile (GuiDefaultProfile)
{
   tab = false;
   canKeyFocus = false;
   hasBitmapArray = false;
   mouseOverSelected = false;

to

new GuiControlProfile (GuiDefaultProfile)
{
   tab = false;
   canKeyFocus = [b]true[/b];
   hasBitmapArray = false;
   mouseOverSelected = false;


on guiControl.cc change:
void GuiControl::onRightMouseDown(const GuiEvent & event)
{
}

to

void GuiControl::onRightMouseDown(const GuiEvent & event)
{
	// Pass down the event
	GuiControl *parent = getParent();
	if(parent)
	{
		parent->onRightMouseDown(event);
	}
}

To make foreground controls pass down the mouse right down event to its parent (guiShapeNameHud grabs it otherwise).

Then add the following to gameTSCtrl.h after void onMouseMove(const GuiEvent &evt);


bool onInputEvent(const InputEvent & event);
   void onRightMouseDown(const GuiEvent & event);

add the following include at the top of gameTSCtrl.cc
#include "gui/core/guiCanvas.h"

then add to the bottom of gameTSCtrl.cc the following functions:

void GameTSCtrl::onRightMouseDown(const GuiEvent & event)
{
   if(mProfile->mCanKeyFocus)
   {
      Platform::setWindowLocked(true);
      Canvas->setCursorON(false);
      setFirstResponder();
   }
}

bool GameTSCtrl::onInputEvent(const InputEvent & event)
{
   if(event.deviceType == MouseDeviceType &&
      event.objInst == KEY_BUTTON1 && event.action == SI_BREAK)
   {
      Platform::setWindowLocked(false);
      Canvas->setCursorON(true);
   }
   return false;
}

Like I said, it works, but other invisible controls not parented by the GameTSCtrl get in the way, namely children of GuiEffectCanvas, so, if anyone gives it a try and finds out how to avoid it, let me know :).
#11
11/06/2006 (11:37 am)
I am at the same problem.

I cant get an ingame cursor to work right.

Is this working?
#12
11/07/2006 (5:22 am)
Wolfgang,

I have sent you the changes I made to get things working(Mostly what I listed above). Works for me.

Cheers,

Terence
#13
07/27/2007 (1:06 am)
@ Terence , just quickly copy your resource to my project and it did want I wanted so THANK YOU .

However, you might be forgetting to put this in ?

void GuiCanvas::setGhostCursor(bool _bGhostCursor)
{
	
	mGhostCursor = _bGhostCursor ;
}


Aun.
Torque-Motion
#14
07/27/2007 (10:59 am)
I made a resource on this that might help

www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=13034