SDL_PollEvents - Part of the code that are executed without key being pressed. Situation not desired - c++

My program has to quit when I press ESC key. Even not pressing the key, my program exit automatically after some seconds of execution. No errors or notable exceptions found during the execution and the code seems to be correct.
void pollE(bool& _isRunning, build *actionBuild,finance *money,squareId* slotId,squareId map[][MAP_SLOTS_H]) {
while (SDL_PollEvent(&event)) {
// MOUSE
switch (event.button.button) {
case SDL_BUTTON_LEFT:
if (event.button.state == SDL_RELEASED) {
actionBuild->construct(ID_CASA, map);
}
if (event.button.state == SDL_PRESSED) {
}
break;
case SDL_BUTTON_RIGHT:
if (event.button.state == SDL_RELEASED) {
// test
debugPrintMap(map);
}
if (event.button.state == SDL_PRESSED) {
}
break;
}
// KEYBOARD
switch (event.key.keysym.sym) { // ---------------------------- HERE
case SDLK_ESCAPE: // ------------------------------------------ HERE
_isRunning = false; // ------------------- to stop mainLoop()
break;
case SDLK_SPACE:
break;
default:
break;
}
}
The function is called here:
void mainLoop() {
(...)
while (isRunning == true) {
dealWithEvents->pollE(isRunning,actionBuild,money,slotId,map);
preDraw();
draw();
afterDrawEffects();
draw();
(...)
}
(...)
}

Related

How to debug why Arduino is breaking a while loop?

I first added an infinite loop. Dugme is a variable for loop. But I couldn't break the loop. That’s why, when I enter the loop, I can’t exit.
void otoac()
{
long duration, distance;
while(dugme==1)
{
int distanceR = 0;
int distanceL = 0;
delay(40);
if(distance<=24)
{
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
distanceR = lookRight();
delay(200);
distanceL = lookLeft();
delay(200);
if(distanceR>=distanceL)
{
turnRight();
moveStop();
}
else
{
turnLeft();
moveStop();
}
}
else
{
moveForward();
}
distance = readPing();
}
}
I have an code that when I click on case:'X' it goes in automatic mode (application). I have here the code for when I click out of 'X' that's 'x' (little x) it needs to stop but it doesn't stop. This is the code for the 'x'.
void otokapa()
{
dugme=0
motor1.setSpeed(0);
motor2.run(RELEASE); //turn motor1 off
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}
Someone on YouTube only gave me this answer:
I added a while loop to the command, as well as a contradiction to the command, meaning, the action that the car will do when the triangle is not pressed, which is nothing.
More code:
void loop(){
if(Serial.available() > 0){
command = Serial.read();
Stop();
switch(command){
case 'F':
forward();
break;
case 'B':
back();
break;
case 'L':
left();
break;
case 'R':
right();
break;
case 'G':
onsol();
break;
case 'I':
onsag();
break;
case 'H':
arkasag();
break;
case 'J':
arkasol();
break;
case 'W':
onac();
break;
case 'w':
onkapa();
break;
case 'X':
otoac();
break;
case 'x':
otokapa();
break;
}
}
}
and dugme:
on top of all the code int dugme=1; and dugme is only in void otokapa and in otoac while(dugme==1)
Is this in essence what your problem looks like?
int dugme = 1; // one and only definition of this (ODR)
void otoac() {
long duration, distance;
while(dugme==1) {
}
}
void otokapa() {
dugme=0;
}
void loop(){
if(Serial.available() > 0){
command = Serial.read();
Stop();
switch(command){
case 'X':
otoac();
break;
case 'x':
otokapa();
break;
}
}
}
Possible errors violation of ODR.
if loop and otoac runs in the same thread you will never get to the serial again.

SDL Text Input returning white squares

I created an event class and wanted to get text with it. Unfortunately the text isn't reading correctly...
I've set it up so that all text that is gotten is output to the command line when a new key is input, but it obviously isn't working.
Here's my "EventManager" code for my update function:
void EventManager::update(){
while(SDL_PollEvent(&e)){
switch(e.type){
case SDL_QUIT:
running = false;
break;
case SDL_MOUSEBUTTONDOWN:
mousePressed = true;
break;
case SDL_KEYDOWN:
if(shouldCollectText && e.key.keysym.sym == SDLK_BACKSPACE && currentCollectedText.length() > 0){
currentCollectedText.pop_back();
}else if(shouldCollectText && e.key.keysym.sym != SDLK_BACKSPACE){
currentCollectedText += e.text.text; //The problem
std::cout << currentCollectedText << std::endl;
}
}
}
}
I followed the Lazy Foo tutorials, and I can't find the problem.
Some other things to note:
I start text input in my "main.cpp" class:
int main( int argc, char *argv[] ) {
Game *game = new Game();
game->init();
SDL_StartTextInput();
while(game->isRunning()){
game->handleEvents();
game->update();
game->render();
}
game->close();
SDL_StopTextInput();
return 0;
}
I create some of my variables in "EventManager.h":
bool shouldCollectText;
std::string currentCollectedText;
And define them in an "init()" function:
shouldCollectText = false;
currentCollectedText = "";
Your problem is that you are using the wrong event type. Take a second look at Lazy Foo's tutorial and here:
TextInputEvent
e.text.text is reserved for Text Input events and nothing else. Being SDL_Event an union of structures, overlaps may occur in the used memory. That is exactly what you see in the terminal output.
Remove the SDL_KEYDOWN event and try this instead:
case SDL_TEXTINPUT:
currentCollectedText += e.text.text;
break;
I'm not sure about std::cout << currentCollectedText << std::endl; though. It depends on when you want to get output of the text content.
If you want to use SDL_KEYDOWN you will have to access the keysym tables and maybe calculate to which letter they correspond and print those out. I would say, that approach is more complicated for what you want to achieve.
So in conclusion e.text.text will only work if e.type has the SDL_TEXTINPUT value as event. With all the other settings in your code that event should be triggered and may get the text you type in.
So your complete example could look like this:
void EventManager::update(){
while(SDL_PollEvent(&e)){
switch(e.type){
case SDL_QUIT:
running = false;
break;
case SDL_MOUSEBUTTONDOWN:
mousePressed = true;
break;
case SDL_TEXTINPUT:
if(shouldCollectText && currentCollectedText.length() > 0){
currentCollectedText.pop_back();
}else if(shouldCollectText) {
currentCollectedText += e.text.text; //The problem
std::cout << currentCollectedText << std::endl;
}
break;
default: break;
}
}
}

Code debugging error Arduino

I am facing two errors for the below program:
On serial monitor it is not printing IN main().
When enter lcd_call() function. If any key being pressed it goes to next case. As per program it should stay in same window but it is going back to case 1.
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println("In main");
lcd_call();
}
void lcd_call()
{
int menuOption=0;
int button;
do
{
switch(menuOption)
{
case 0:
Serial.println("set+date:");
Display_Date_Time();
timedBeep(shortBeep,1);
break;
case 1:
Serial.println("DISPLAY:");
lcdClear();
lcd.print("DISPLAY MENU");
timedBeep(shortBeep,1);
break;
case 2:
Serial.println("SET MENU:");
lcdClear();
lcd.print("SET MENU");
timedBeep(shortBeep,1);
break;
}
button=read_LCD_buttons();
if(button==btnRIGHT)
{
menuOption=menuOption+1;
if(menuOption>2)
{
menuOption=0;
}
}
else
{
menuOption;
}
}
while(menuOption<menuOptions);
}

SDL 2 Space keydown not detected but Space keyup works fine

Hey so I'm working on a project/2d game and I'm having some odd behavior from SDL which I'm sure is probably something I'm not understanding. The function ProcessKeys is called and works fine for all the key press downs except SDLK_SPACE and I cannot for the life of me figure out why.
What is even more bizarre is that the SDL_KEYUP switch of SDLK_SPACE works great. I tried using some debugging code to print out which key is being pressed and when you press space down nothing registers. Every other key on the keyboard registers in my debug statement at the top of the SDL_KEYDOWN case.
If anyone can see what is going on I would really appreciate it.
And if you need to see where its being called let me know.
SDLKeyboard::KeyState SDLKeyboard::ProcessKeys(SDL_Event * event)
{
switch(event->type)
{
/* Look for a keypress */
case SDL_KEYDOWN:
{
std::cout << "Key currently pressed" << event->key.keysym.sym << std::endl;
/* Check the SDLKey values and move change the coords */
switch(event->key.keysym.sym)
{
case SDLK_LEFT:
{ // rotate the ship left
c.setIsTurningLeft(true);
return this->keystate = LeftPressed;
// add code when user presses left
break;
}
case SDLK_RIGHT:
{
// rotate the ship right
c.setIsTurningRight(true);
return this->keystate = RightPressed;
// add code when user presses right
break;
}
case SDLK_UP:
{
// accleration
c.setIsAccelerating(true);
return this->keystate = UpPressed;
// add code when user presses up
break;
}
case SDLK_SPACE:
{
// shoot
c.setIsShooting(true);
std::cout << "keystate = " << this->keystate;
return this->keystate = SpacePressed;
// add code when user presses space
break;
}
default:
{
return this->keystate = NotPressed;
break;
}
}
break;
}
/* We must also use the SDL_KEYUP events to zero the x */
/* and y velocity variables. But we must also be */
/* careful not to zero the velocities when we shouldn't*/
case SDL_KEYUP:
{
std::cout << "Key currently pressed" << event->key.keysym.sym << std::endl;
switch(event->key.keysym.sym)
{
case SDLK_LEFT:
{ /* We check to make sure the ship is moving */
/* to the left. If it is then we zero the */
/* velocity. If the ship is moving to the */
/* right then the right key is still press */
/* so we don't touch the velocity */
c.setIsTurningLeft(false);
return this->keystate = LeftReleased;
// code to do things when left isn't pushed anymore but still moving left
break;
}
case SDLK_RIGHT:
{ // code to do things when right isn't pushed anymore but still moving right
c.setIsTurningRight(false);
return this->keystate = RightReleased;
break;
}
case SDLK_UP:
{ // code to do things when up isn't pushed anymore but still moving up
c.setIsAccelerating(false);
return this->keystate = UpReleased;
break;
}
case SDLK_SPACE:
{ // accleration
c.setIsShooting(false);
return this->keystate = SpaceReleased;
// add code when user presses up
break;
}
default:
break;
}
break;
}
default:
{
return this->keystate = NotPressed;
break;
}
}
}
EDIT:
Here is the example requested. The other thing that I've noticed is the latency in response isn't that great. Like if you press a key sometimes the console doesn't print the corresponding key. Probably has to do with the issue I'm having with the space as well.
void GUI::TakeInput(SDL_Event *e)
{
while (SDL_PollEvent(e))
OnEvent(e);
}
void SDLEvent::OnEvent(SDL_Event * event)
{
switch(event->type)
{
case SDL_KEYDOWN:
{
OnKeyDown(event->key.keysym.sym);
break;
}
case SDL_KEYUP:
{
OnKeyUp(event->key.keysym.sym);
break;
}
case SDL_MOUSEMOTION:
{
OnMouseMove(event->motion.x,event->motion.y);
break;
}
case SDL_MOUSEBUTTONDOWN:
{
OnMouseButtonDown(event->button.button, event->button.x,event->button.y);
break;
}
case SDL_MOUSEBUTTONUP:
{
OnMouseButtonUp(event->button.button, event->button.x,event->button.y);
break;
}
case SDL_QUIT: {
OnExit();
break;
}
case SDL_SYSWMEVENT: {
//Ignore
break;
}
case SDL_WINDOWEVENT_RESIZED: {
OnResize();
break;
}
case SDL_WINDOWEVENT_EXPOSED: {
OnExpose();
break;
}
default: {
OnUser(event->user.type,event->user.code,event->user.data1,event->user.data2);
break;
}
}
}
void GUI::Play()
{
Uint32 start_ticks = SDL_GetTicks();
TakeInput(this->setup->GetEvent());
this->keyboard->ProcessKeys(this->setup->GetEvent());
this->setup->RenderBegin();
this->ship->drawBackBuffer();
this->ship->renderSprite();
Uint32 end_ticks = SDL_GetTicks();
int sleep_delay = (1000 / 60) - (end_ticks-start_ticks);
if (sleep_delay > 0) {
SDL_Delay(sleep_delay);
}
}
If you are only writing event->key.keysym.sym on the console, you should know that the spacebar key produces an almost invisible character.
Try this instead:
std::cout << "<" << event->key.keysym.sym << ">"
So you can see whataver invisible character printed between angle brackets.

SDL_PollEvent not picking up all events

I'm currently playing around with SDL to make a game and I've run into a problem where SDL is not picking up some events. For exampling, I would be pressing 'w' to move forward and at the same time, I'm moving my mouse to look around. But let's say I then press 'a' or 'd', SDL will not pick these events or even when I release 'w', SDL will not pickup the KEYUP event. I first wrote this code in windows and it all worked fine, but after switching to ubuntu, it doesn't work as expected anymore. Here is my main loop where I poll for events:
while(Running)
{
while(SDL_PollEvent(&event))
Events(&event);
if( active ){
Loop();
Render();
}
}
This is the code within Events():
switch(Event->type)
{
case SDL_QUIT:
Running = false;
break;
case SDL_KEYDOWN:
switch(Event->key.keysym.sym)
{
case SDLK_ESCAPE:
Running = false;
break;
case SDLK_a:
keyStates['a'] = true;
break;
case SDLK_s:
keyStates['s'] = true;
break;
case SDLK_d:
keyStates['d'] = true;
break;
case SDLK_w:
keyStates['w'] = true;
break;
case SDLK_LSHIFT:
camera.setSpeed(2.0f);
break;
}
break;
case SDL_KEYUP:
switch(Event->key.keysym.sym)
{
case SDLK_a:
keyStates['a'] = false;
break;
case SDLK_s:
keyStates['s'] = false;
break;
case SDLK_d:
keyStates['d'] = false;
break;
case SDLK_w:
keyStates['w'] = false;
break;
case SDLK_LSHIFT:
camera.setSpeed(1.0f);
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
switch(Event->button.button)
{
case SDL_BUTTON_MIDDLE:
mouse.middle = true;
break;
}
break;
case SDL_MOUSEBUTTONUP:
switch(Event->button.button)
{
case SDL_BUTTON_MIDDLE:
mouse.middle = false;
break;
}
break;
case SDL_MOUSEMOTION:
if( moving ){
camera.lookat(float(Event->motion.x - winWidth/2),float(Event->motion.y - winHeight/2), MOUSE_SENSITIVITY, dt);
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
SDL_WarpMouse(winWidth/2, winHeight/2);
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
}
break;
}
keyStates['a'] = true;
There's SDL_GetKeyState for this. Use it instead of manually maintaining array.
Uint8 keys[SDLK_LAST];
Uint8* sdlKeys = SDL_GetKeyState(0);
memcpy(keys, sdlKeys, sizeof(keys));
.
bool keyPressed(SDLKey key){
return keys[key] == SDL_PRESSED;
}
Also check documentation.