How would I get the position of the mouse in c++ SDL2? I found this wiki however I'm not really sure what it means and how would I get the x and y in int form?
https://wiki.libsdl.org/SDL_GetMouseState
Call the function described at the link you found; with pointers to the two int variables which you want to receive the coordinates.
Simplified, the function works like this one:
void SetXto5(int* x)
{*x = 5;}
i.e. the variable which your parameter points to will receive a value.
(This skips the check for NULL pointer, which is implied in the documentation.)
This does of course require the SDL environment to be correctly set up and initialised. I assume from your comments that you do not ask about that background part.
Related
The UI system in my program currently works by assigning function pointers of the type void(*)() to trigger elements (quads on the screen, keys on the keyboard) with a specifiable call condition which will be compared to the actual condition of the key (using GLFW), mouse button or cursor every frame to determine whether the callback function should be called.
A condition for a key could be KeyCondition(PRESS, LEFT_SHIFT) which would call the callback bound to the key if the key was pressed while left shift is being held down.
My problem is that I can only assign these buttons functions of the type void(*)(), which disables me to pass arguments to a button callback.
If for example I wanted to make a button light up when the cursor hovers over it, I would have to create a designated function void highlightButtonA() which sets the color of button A to a higher value internally, while I would of course much rather be able to set the callback to something like void offsetColor(unsigned int buttonIndex, float r, float g, float b, float a) and pass individual parameters to each callback.
Is there any way to do this? Is there some function pointer which can point to a function of any shape and will store parameters somehow? How much should I worry about the performance of these solutions? My program has to be able to handle multiple key/button presses per second and still be stable, as it is a fast-paced shooter game.
You can use non-capturing lambdas that decay to function pointers, something like this:
button.OnMouseHover([]{ offsetColour(buttonIndex, r, g, b, a); });
just remember that buttonIndex and other args to offsetColour should be literals as the lambda cannot capture variables from the enclosing scope.
I am having a strange problem with Gtkmm entries in C++.
I defined a Gtk::Entry here called inputEntry. I have a function called csf.
Where I declare the entry in main:
// Create input entry
Gtk::Entry inputEntry;
inputEntry.set_editable(TRUE);
inputEntry.set_text("3.55");
inputEntry.signal_activate().connect(sigc::bind<float>(sigc::ptr_fun(&csf), atof(inputEntry.get_text().c_str())));
I later attach this entry to a grid, then add that grid to the main window, then show all the widgets on the grid, then the grid itself.
Where I declare CSF (there is a prototype at the beginning of the code):
void csf(float sa)
{
printf("%f \n", sa);
}
However, strangely, when I run the program, no matter what I type into the Gtk::Entry, the terminal always shows 3.55 when I submit. I tried changing the set_text to "1.11", and it always showed 1.11 when I submitted. I even tried putting a second set_text to "1.11", and it would always show 1.11, then, I tried with no set_text at all, and it would always show 0. The value of the entry, regardless of what I type in, be it 300000 or 0.1, always show print the initial value and only the initial value of the Gtk::Entry. What is wrong?
Note: I have done this in Python before, pretty much the same way, and it worked. I want to try doing it in C++. Maybe it is because I didn't implement something?
It's C++ question, not a gtk one.
In line:
inputEntry.signal_activate().connect(sigc::bind<float>(sigc::ptr_fun(&csf), atof(inputEntry.get_text().c_str())));
You are calling function csf with a double created from string "3.55". In order to get what you want:
inputEntry.signal_activate().connect(sigc::bind<Gtk::Entry*>(sigc::ptr_fun(&csf), &inputEntry));
(...)
void csf(Gtk::Entry* entry)
{
std::cout<<atof(entry.get_text().c_str())<<" "<<std::endl;
}
Change of entry's text to double must occur after the activation. In your solution it was at signal connection.
I am creating a game in c++ using the SDL library.
To keep everything readable and orderly, I make a dll from the actual game program, the menu's program and have only the main program as an executable. In the main program I create a struct that holds all screen information, such as standard colors, the width and height of the screen, fonts and the renderer, window and surface object of the screen. In the main program I initialise one instance of this struct. A pointer to this instance is passed as a parameter to the functions and objects in the dll's.
The colors are defined in a std::map<char*, int>.
To access the colors, one could use something like this:
struct screen{
std::map<char*, Uint32> colors;
}
screen display;
std::pair<char*, Uint32> color;
color.first = "green";
color.second = 0x00FF00;
display.colors.insert(color);
int x = display.colors["green"] //for example
Reading the values in the main executable works fine, but having the screen object passed as a pointer to a function inside a dll, it returns a NULL. As a pointer, I read the value like this:
void function(screen* display){
Uint32 x = display->colors["green"];
}
When doing the following:
std::map<char*, int>::iterator i = display->colors.begin();
while(i->first != "green"){
i++
}
int x = i->second;
There seems to be no problem.
But I want to be able to use the first method in the dll's, since the second method is much less efficient.
Why doesn't the first method work in dll's? and how do I get it to work in the dll's? I use visual studio 2012.
The pointer issue I told you about is probably the reason for your problem. In the executable the string literal "green" has one address, and in the DLL the string-literal "green" has a totally different address. Yes the strings will be equal if you compare them, but the pointers themselves will not be the same, leading to your problem.
The answer is simply to use std::string as the key.
You should question yourself what "green" as a char* points to. Without using the DLL, being just one compilation unit gives "green" a single address which will be reused during the program. So, the pointer is the same when getting and retrieving from the map.
When you compile the DLL, the "green" pointer is a different pointer than the "green" pointer from the main executable, so you cannot retrieve it from the map.
I am trying for a longer while now to create a mechanism that would create text labels next to my points on a plot with the coordinates. From the documentation, I have read that I need to use QCPItemTracer for that. No matter how i try, I cannot display any additional items on my plot using this object. In the QCustomPlot examples, there is one program that user QCPItemTracer, but when i run it, I also dont see any additional objects. I am trying to run the example code from bellow:
QCPItemTracer *phaseTracer = new QCPItemTracer(customPlot);
customPlot->addItem(phaseTracer);
phaseTracer->setGraph(customPlot->graph(DATA_PLOT));
phaseTracer->setGraphKey(7);
phaseTracer->setInterpolating(true);
phaseTracer->setStyle(QCPItemTracer::tsCircle);
phaseTracer->setPen(QPen(Qt::red));
phaseTracer->setBrush(Qt::red);
phaseTracer->setSize(7);
From my understanding this was supposed to add red circles on my plot points. It does not. I Would really aprichiate any help in this matter, some example code maybe. I am struggling with this for a really long time.
I have managed to get the labels working:
returnCodes_t PlotData::insertPointLabel(const int& index, const double& x, const double& y)
{
QCPItemText *textLabel = new QCPItemText(m_parentPlot);
m_parentPlot->addItem(textLabel);
textLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignHCenter);
textLabel->position->setType(QCPItemPosition::ptPlotCoords);
textLabel->position->setCoords(x, y); // place position at center/top of axis rect
textLabel->setText(QString("x%1 y%2").arg(x).arg(y));
textLabel->setVisible(labelsVisible);
m_pointLabels.insert(index, textLabel);
return return_success;
}
This is an SDL problem, however I have the strong feeling that the problem I came across is not related to SDL, but more to C++ / pointers in general.
To make a long story short, this code doesn't work (edited to show what I really did):
player->picture = IMG_Load("player");
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I see nothing on the screen. However, when I do it like this, it works:
SDL_Surface* picture = IMG_Load("player.png");
player->picture = picture;
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I can see the little guy just fine.
The real problem is that I cannot instantiate Player::picture directly. Even when I try
picture = IMG_Load("player.png")
in player.cpp, I end up with a nullpointer.
I am so stupid. Turns out like I forgot the file extension ".png" every time I tried to store the surface in Player::picture, and conveniently remembered to add it every time I stired it in an SDL_Surface declared in main.cpp.
I had the feeling I was overlooking something really simple here, but this is just embarassing. What's a fitting punishment for this?
What data type is player->picture? What type does IMG_Load return? It's really hard to come up with a scenario where saving an expression in a temporary variable changes the result, unless a type conversion is involved.
And I wouldn't call this pointer instantiation. You're instantiating an instance of some picture type and storing a pointer to it.
This is why you should always check to see what IMG_Load() returns...
SDL_Surface* picture = IMG_Load("player.png");
if (picture == NULL) {
// there was obviously some sort of error.
// what does SDL_GetError() say?
}
Some SDL functions return -1 if there is an error. Just check the documentation and make sure you're checking your function returns. These steps make debugging a lot easier.