SDL_FINGERDOWN gives wrong cursor position on MultiTouch,OSX - c++

Device: Macbook, OS X, multitouch, SDL2.
float posX = event.tfinger.x;
float posY = event.tfinger.y;
if ( event.type == SDL_FINGERDOWN ) std::cout << "posX = " << posX << ", posY = " << posY << "\n";
It returns me coordinates of my multitouch device. If I tap my multitouch at the left-top corner it returns me coordinates something like 0.1x0.1. Ok, right. But how to get coordinates of the cursor position in OS X?
I can get only coordinates of multitouch device but it doesn't mean that it's the coordinates of the cursor on the screen. I mean... I can tap my multitouch at the left-top corner but my cursor at this time will be at the right-bottom corner of the screen.

If I understand you correctly, you want to get both the point where you touch the device, and where the cursor on the screen is?
I'd recommend using the SDL_MOUSEMOTION event:
while (SDL_PollEvent(&e))
{
switch(e->type) {
case SDL_MOUSEMOTION:
mouseX = e.button.x;
mouseY = e.button.y;
break;
}
}
where the "mouseX" and "mouseY" variables will be the coordinates of the cursor on the screen within the SDL_Window.
If you want the global mouse coordinates, you can use SDL_GetGlobalMouseState:
int mouseX;
int mouseY;
SDL_GetGlobalMouseState(&mouseX, &mouseY);
which will get you the global (relative to the desktop) coordinates.
Currently there is a bug with SDL_GetMouseState where if you use SDL_SetWindowFullscreen and set it to borderless fullscreen (SDL_WINDOW_FULLSCREEN_DESKTOP) it gets the wrong coordinates, which is why I recommed use of the SDL_MOUSEMOTION event instead.
It's fine to use in any other instance (as far as I can tell).

Related

How do I capture(trap) a mouse in a window in c++?

I am writing a tile map editor in SFML and C++. I have been having all sorts of troubles with the mouse. I am using the built in SFML Mouse:: static functions and recently managed to get a custom cursor moving on the screen and pointing accurately to a tile by doing as follows:`
Sprite cursor;
bool focus = false;
RenderWindow window(VideoMode(512, 288), "Tilemap editor");
window.setFramerateLimit(60);
Texture cursorTexture;
if(!cursorTexture.loadFromFile("Graphics/Cursor.png")) {
std::cout << "Failed to load cursor texture\n";
return 0;
}
cursor.setTexture(cursorTexture);
Mouse::setPosition(mousePos);
While(window.isOpen()) {
window.setMouseCursorVisible(focus);
if(Mouse::getPosition().x != lastMousePos.x) {
mousePos.x = mousePos.x + (Mouse::getPosition().x - lastMousePos.x);
}
if(Mouse::getPosition().y != lastMousePos.y) {
mousePos.y = mousePos.y + (Mouse::getPosition().y - lastMousePos.y);
}
cursor.setPosition(mousePos.x, mousePos.y);
lastMousePos = Mouse::getPosition();
window.clear();
window.draw(cursor)
window.display()
}
The built-in Mouse functions only display relativity to the desktop or the window and as I am using this app in a small window in which my view moves, I can't use either. The solution above moves a cursor independent of the desktop and with the ability to move the cursor if and when I want to move my view.
The issue is that my mouse will move off the side of the app when I try to click items in the top left corner.
Is there a good cross-platform (I'm on Linux BTW) way to trap the mouse inside of the window unless I enter a keystroke (like a VM window)? Also, is there a better way to do cross-platform mouse support in general? SFML kinda sucks. (Code obviously needs to be in a main function and the namespace must be sf with SFML/Graphics.hpp included)
There is already a method for that.
void setMouseCursorGrabbed (bool grabbed)
// Grab or release the mouse cursor.
You can also use these methods to convert your screen coordinates to mouse coordinates and vice versa.
Vector2f mapPixelToCoords (const Vector2i &point) const
// Convert a point from target coordinates to world coordinates, using the current view.
Vector2f mapPixelToCoords (const Vector2i &point, const View &view) const
// Convert a point from target coordinates to world coordinates.
Vector2i mapCoordsToPixel (const Vector2f &point) const
// Convert a point from world coordinates to target coordinates, using the current view.
Vector2i mapCoordsToPixel (const Vector2f &point, const View &view) const
// Convert a point from world coordinates to target coordinates.
sf::RenderWindow Class Reference

C++ Ncurses , how to check what the current mouse position is

How Do I Check What The Mouse Position is when I move the mouse in Ncurses. I have tried searching but couldnt find any answer . I have seen the use of getmouse() , but getting the mouse co-ordinates from that function requires enabling an event first. I want to get the position of the mouse without clicking the mouse.
You get the cursor position by calling GetCursorPos.
POINT p;
if (GetCursorPos(&p))
{
//cursor position now in p.x and p.y
}
This returns the cursor position relative to screen coordinates. Call ScreenToClient to map to window coordinates.
if (ScreenToClient(hwnd, &p))
{
//p.x and p.y are now relative to hwnd's client area
}

Using glut to prevent the mouse from leaving the window

I'm using glut for a game right now and I'm trying to keep the mouse inside the window. This isn't a first person shooter so locking it in the center is no good. I already know about glutWarpPointer(int, int); and I've trying things that work (kinda).
I've tried having the mouse warp back to the nearest edge of the window when it leaves, this works, but for a split second you see the mouse outside of the window and teleport back in. I don't want that, I want it to seem like the mouse just hits the edge of the window and stops going any further in that direction, while keeping movement in any other available direction. Like you would expect it to work.
This is not exactly an answer to your question, but it is an answer to your problem!
Almost every game has its own cursors. They would hide the mouse, and draw the cursor manually where the mouse should be positioned.
If you get your own cursor image and do as I said, you can simply draw the curser at the edge of the screen, even though the mouse position reads out of boundaries. Then you can warp the mouse back in.
Tried to search and figure this out and couldn't find an answer, so I implemented it myself. Here is what worked for my first person camera case:
callback from glutPassiveMotion
CODE SAMPLE
void Game::passiveMouseMotion(int x, int y)
{
//of my code for doing the cam, yours is may be different, this is based on the example from https://learnopengl.com/Getting-started/Camera
if (firstMouse) {
lastX = x;
lastY = y;
firstMouse = false;
}
float xoffset = x - lastX;
float yoffset = lastY - y; // reversed since y-coordinates go from bottom to top
lastX = x;
lastY = y;
camera->ProcessMouseMovement(xoffset, yoffset);
glutPostRedisplay();
//this is the main thing that keeps it from leaving the screen
if ( x < 100 || x > win_w - 100 ) { //you can use values other than 100 for the screen edges if you like, kind of seems to depend on your mouse sensitivity for what ends up working best
lastX = win_w/2; //centers the last known position, this way there isn't an odd jump with your cam as it resets
lastY = win_h/2;
glutWarpPointer(win_w/2, win_h/2); //centers the cursor
} else if (y < 100 || y > win_h - 100) {
lastX = win_w/2;
lastY = win_h/2;
glutWarpPointer(win_w/2, win_h/2);
}
}
Hope this helps!

Trapping the mouse?

I'm using GLUT and developing a FPS game. I need a way to trap the mouse so that the camera continues to move because right now when the mouse position exceeds the monitor limit, there is no way to calculate change in X or change in Y. How can I 'trap' the mouse with GLUT?
Thanks
I'd recommend using a ready-made engine like OGRE 3D instead, but if you really want to reinvent the wheel, here's how...
In all cases I'm aware of, PC FPS games "trap" the pointer by registering a mouse motion callback, noting the relative motion, and then warping the pointer back to the center of the window.
Here's some code I wrote to add mouse input to a sample ping-pong table in an OpenGL with C++ course a year or two ago:
void resetPointer() {
glutWarpPointer(TABLE_X/2, TABLE_Y/2);
lastMousePos = TABLE_Y/2;
}
void mouseFunc(int sx, int sy) {
if (!started) { return; }
int vertMotion = lastMousePos - sy;
lastMousePos = sy;
player1.move(vertMotion);
// Keep the pointer from leaving the window.
if (fabs(TABLE_X/2 - sx) > 25 || fabs(TABLE_Y/2 - sy) > 25) {
resetPointer();
}
}
// This goes in with your "start new game" code if you want a menu
resetPointer();
glutSetCursor(GLUT_CURSOR_NONE);
glutPassiveMotionFunc(mouseFunc);
It only tracks vertical motion, but adding horizontal is trivial.

using event handler

is there a way to use mouse as an event handler in c/c++ im making a game on snakes and ladder (the famous board game) and trying to make it with basic borland c++ compiler working with a header file called graphics.h, which is very basic and gives output of 640 X 480 res, so I was wondering if there is a possiblity of using mouse as an event handler (about which i have no experiance)to have control over the palyer coins on the board.
I'm not sure which version of graphics.h you happen to have, but there are functions getmousey, getmousey, clearmouseclick and getmouseclick. See this for some documentation that may work for you.
It appeas that you can use registermousehandler and a call-back function to do some level of event-based programming. Here's a sample from the document I sent you.
// The click_handler will be called whenever the left mouse button is
// clicked. It checks copies the x,y coordinates of the click to
// see if the click was on a red pixel. If so, then the boolean
// variable red_clicked is set to true. Note that in general
// all handlers should be quick. If they need to do more than a little
// work, they should set a variable that will trigger the work going,
// and then return.
bool red_clicked = false;
void click_handler(int x, int y)
{
if (getpixel(x,y) == RED)
red_clicked = true;
}
// Call this function to draw an isosoles triangle with the given base and
// height. The triangle will be drawn just above the botton of the screen.
void triangle(int base, int height)
{
int maxx = getmaxx( );
int maxy = getmaxy( );
line(maxx/2 - base/2, maxy - 10, maxx/2 + base/2, maxy - 10);
line(maxx/2 - base/2, maxy - 10, maxx/2, maxy - 10 - height);
line(maxx/2 + base/2, maxy - 10, maxx/2, maxy - 10 - height);
}
void main(void)
{
int maxx, maxy; // Maximum x and y pixel coordinates
int divisor; // Divisor for the length of a triangle side
// Put the machine into graphics mode and get the maximum coordinates:
initwindow(450, 300);
maxx = getmaxx( );
maxy = getmaxy( );
// Register the function that handles a left mouse click
registermousehandler(WM_LBUTTONDOWN, click_handler);
// Draw a white circle with red inside and a radius of 50 pixels:
setfillstyle(SOLID_FILL, RED);
setcolor(WHITE);
fillellipse(maxx/2, maxy/2, 50, 50);
// Print a message and wait for a red pixel to be double clicked:
settextstyle(DEFAULT_FONT, HORIZ_DIR, 2);
outtextxy(20, 20, "Left click in RED to end.");
setcolor(BLUE);
red_clicked = false;
divisor = 2;
while (!red_clicked)
{
triangle(maxx/divisor, maxy/divisor);
delay(500);
divisor++;
}
cout << "The mouse was clicked at: ";
cout << "x=" << mousex( );
cout << " y=" << mousey( ) << endl;
// Switch back to text mode:
closegraph( );
}
You can use Mouse and Keyboard events using Win32 Programming (In Visual Studio).
Is it the requirement to use borland c++.
I think similar APIs are there in borland c++.
You can refer http://www.functionx.com/win32/index.htm for more information on event handling in Visual Studio using Win32 Programming.