How to Handle Green Key (Call Button) event in Symbian C++ - c++

I want to handle the Green Key Event in Symbian. I have handled Red Key(End Button) with the help of KAknUidValueEndKeyCloseEvent. Can you suggest me what is the name of the event of Green Key. Here is the necessary code.
void CMobileDialerAppUi::HandleWsEventL(const TWsEvent &aEvent, CCoeControl *aDestination)
{
switch (aEvent.Type())
{
case KAknUidValueEndKeyCloseEvent:
{
TUid KMyAppUid = { 0x20070DF6 };
TApaTaskList tasklist(CCoeEnv::Static()->WsSession());
TApaTask task = tasklist.FindApp(KMyAppUid);
if(task.Exists())
{
task.BringToForeground();
}
symbian_ua_endcall();
break;
}
default:
CAknAppUi::HandleWsEventL(aEvent, aDestination);
break;
}
}

on your container override method OfferKeyEventL
TKeyResponse CMobileDialerContainer::OfferKeyEventL(const TKeyEvent &aKeyEvent, TEventCode aType)
{
if (EStdKeyDevice0==aKeyEvent.iScanCode){
if (aType == EEventKeyUp) {
//a green key has press
return EKeyWasConsumed;
}
}
return EKeyWasConsumed;
}

Related

How to implement entry actions in the finite state machine?

Let's say I have been implementing a state machine in the C++ based on the switch statement i.e.
I have following piece of code
class StateMachine {
public:
enum class State {
State_A,
State_B,
State_C
};
enum class Event {
Event_Default,
Event_A,
Event_B,
Event_C
};
StateMachine();
void handleEvent(Event e);
private:
State state;
void doStateA();
void doStateB();
void doStateC();
};
StateMachine::StateMachine()
{
state = State::State_A;
}
void StateMachine::handleEvent(Event e)
{
switch (state)
{
case State::State_A:
doStateA(e);
break;
case State::State_B:
doStateB(e);
break;
case State::State_C:
doStateC(e);
break;
}
}
void StateMachine::doStateA(Event e)
{
// once upon entry into the state do some actions here
// the actions have to be done only once after state entry
switch(e) {
case Event::Event_Default:
break;
case Event::Event_A:
state = State::State_B;
break;
case Event::Event_B:
state = State::State_C;
break;
case StateMachine::Event::Event_C:
state = State::State_A;
break;
}
}
void StateMachine::doStateB(Event e)
{
// ...
}
void StateMachine::doStateC(Event e)
{
// ...
}
I have found that I need to have the ability to do some actions once upon entry into the states. Of cource I could do those entry actions before the state transitions in the doStateX() methods. But I see following disadvantage of this approach. The entry action of a given state isn't done in that state but in the state (or states) from which the transition occurs. This approach seems to me to be error prone. So I have been looking for a solution where the entry action of a given state is localized directly in that state. Does anybody have any idea?

c++ sfml apply only when button pressed

I have a probleme my character stay running when i release the LShift button
How can i reset the speed when the button is released ?
Actually i have this :
int speed(4);
int speedSprinte(20);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
keyCount++;
speed=speedSprinte;
std::cout<<speed<<std::endl;
}
i can add that but i think it possible to do that easier :
if(!sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
keyCount++;
speed=4;
std::cout<<speed<<std::endl;
}
Either use SFML events and listen to sf::Events::KeyReleased (https://www.sfml-dev.org/tutorials/2.5/window-events.php) or do it manually by storing the last state.
int speed(4);
int speedSprinte(20);
bool pressedLastTime{false};
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
keyCount++;
speed=speedSprinte;
std::cout<<speed<<std::endl;
pressedLastTime = true;
}
else
{
if (pressedLastTime)
{
speed = 4;
pressedLastTime = false;
}
}

C++ How do I Handle all possible Player Movement inputs?

I am trying to clean up movement code I followed from a video tutorial series that was never finished. My intent is for the character to only ever be able to move on X or Y at any given time (so no diagonal). The character has direction facing to keep in mind.
My issue is the player can still press any key they want, or accidently press two keys at the same time.
Ex. if you move Up and make a right turn, accidentally press Right before letting go of Up.
Or if you press Up, press and let go Right to make a slight movement right while continuing to press Up, the player should continue to move up after letting go of Right without having to re-press Up. etc.
Just to make sure all possible input cases are handled intuitively.
EDIT: This is the code so far and I'm getting weird errors I don't know what's wrong
#pragma once
#include "../game.h"
#include "ECS.h"
#include "Components.h"
#include <list>
using namespace std;
class KeyboardController : public Component
{
public:
TransformComponent *transform;
SpriteComponent *sprite;
std::list<SDL_Event> keyDownList;
SDL_Event lastDirection;
void updateKeyState()
{
if (Game::event.type == SDLK_ESCAPE) {
Game::isRunning = false;
}
else if (Game::event.type == SDL_KEYDOWN) {
keyDownList.push_back(Game::event.key.keysym.sym);
}
else if (Game::event.type == SDL_KEYUP) {
keyDownList.remove(Game::event.key.keysym.sym);
}
}
void init() override
{
transform = &entity->getComponent<TransformComponent>();
sprite = &entity->getComponent<SpriteComponent>();
}
void update() override
{
void updateKeyState();
void updateMovement();
}
};
Severity Code Description Project File Line Suppression State
Error (active) E0304 no instance of overloaded function "std::list<_Ty, _Alloc>::push_back [with _Ty=SDL_Event, _Alloc=std::allocator]" matches the argument list Sandbox C:\file_path\KeyboardController.h 31
Severity Code Description Project File Line Suppression State
Error (active) E0415 no suitable constructor exists to convert from "SDL_Keycode" to "SDL_Event" Sandbox C:\file_path\KeyboardController.h 34
You should basically clean up your code by separating the logic between key events and player movement. So your update() method could look like this:
void update() override
{
updateKeyState();
updateMovement();
}
Since you want the player to move only vertically or horizontally (never diagonally), you have to store the key press order in a data structure that can be easily accessed. I think you could use a doubly-linked list:
std::list<SDL_Event> keyDownList;
and we should also store the last key pressed in order to restore the idle animation of the player:
SDL_Event lastDirection;
The updateKeyState() method should add or remove the key to/from the linked list. We should also check if the player wants to leave the game by pressing ESC:
void updateKeyState() {
if (Game::event.type == SDLK_ESCAPE) {
Game::isRunning = false;
} else if (Game::event.type == SDL_KEYDOWN) {
keyDownList.push_back(Game::event.key.keysym.sym);
} else if (Game::event.type == SDL_KEYUP) {
keyDownList.remove(Game::event.key.keysym.sym);
}
}
The updatePlayerMovement() method is where the magic happens. We should basically check which key was pressed first and update the player position accordingly. We also save the down key in the lastDirection field in order to use it when no key is pressed.
void updateMovement() {
// if any key is down
if (keyDownList.size() > 0) {
const SDL_Event downKey = keyDownList.front();
switch (downKey) {
case SDLK_w:
transform->velocity.y = -1;
transform->velocity.x = 0;
sprite->Play("BackWalk");
lastDirection = downKey;
break;
case SDLK_a:
transform->velocity.x = -1;
transform->velocity.y = 0;
sprite->Play("SideWalk");
sprite->spriteFlip = SDL_FLIP_HORIZONTAL;
lastDirection = downKey;
break;
case SDLK_s:
transform->velocity.y = 1;
transform->velocity.x = 0;
sprite->Play("FrontWalk");
lastDirection = downKey;
break;
case SDLK_d:
transform->velocity.x = 1;
transform->velocity.y = 0;
sprite->Play("SideWalk");
sprite->spriteFlip = SDL_FLIP_NONE;
lastDirection = downKey;
break;
}
} else {
// no key is down, handle idle situations
transform->velocity.x= 0;
transform->velocity.y = 0;
switch (lastDirection) {
case SDLK_w:
sprite->Play("BackIdle");
break;
case SDLK_a:
sprite->Play("SideIdle");
break;
case SDLK_s:
sprite->Play("FrontIdle");
break;
case SDLK_d:
sprite->Play("SideIdle");
break;
}
}
}
Note: I haven't tested this code because I don't have the code and structures from your game. So you may have to edit a piece here and there to make it work for you.

OpenGL - Left mouse click keeps removing my grid

I have created a drawGrid() function that draws a squared grid along my X and Y axis, which works fine. I have then created a menu() function (called in the main()), that toggles the grid on and off, here's the code for that:
void menu(int item)
{
switch (item)
{
case MENU_SWITCH_OFF_GRID:
{
if (gridActive == true)
{
gridActive = true;
}
}
break;
case MENU_SWITCH_ON_GRID:
{
if (gridActive == true)
{
gridActive = false;
}
}
break;
default:
{ /* Nothing */ }
break;
}
glutPostRedisplay();
return;
}
}
The menu switch works fine, as I have created a global variable called gridActive without a true or false value so it doesn't reset each time, that way it can be accessed in my display() function like so:
if (gridActive != true)
{
drawGrid();
gridActive = true;
}
All of this works just fine.
What's my issue?
My issue is, whenever I click the left mouse button, my grid disappears, which I don't want. So I've made a mouse() function like this:
case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN)
{
exit(0); // this has been added to see if
// my program will exit!
}
break;
To test if my program exits when I click the left mouse, and it does.
So instead of using exit(0); what code can i put here so that my grid doesn't disappear when I click the left mouse button? Or is the issue beyond that?
UPDATE:
Here's the mouse function:
void mouse(int button, int state, int x, int y)
{
// these have simply been set-up for me to use
// in the future
switch (button)
{
case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN)
{
}
break;
case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN)
{
}
break;
default: break;
}
}
Based on your code:
if (gridActive != true)
{
drawGrid();
gridActive = true;
}
You only draw the grid when gridActive is false. However, after every time you draw it, you set gridActive=true which will then stop it from being drawn.
Without more of your code, it's impossible to tell exactly what's going on, but these lines may not be doing what you think they are, and that may be causing some issues.
This never does anything.
if (gridActive == true)
{
gridActive = true;
}
This:
if (gridActive == true)
{
gridActive = false;
}
is the same as:
gridActive = false;
In order to tell what's going on, though, we need to know what happens when you click your mouse button when the exit call isn't there, but you didn't post that code yet.
Also, i don't quite know what you mean by:
I have created a global variable called gridActive without a true or false value so it doesn't reset each time
but it sounds like you made an uninitialized global variable and expect that it has some specific meaning because it's uninitialized?

SDL is sending a wrong controller index

I'm creating a simple game and I'm using SDL2 for handling inputs from controllers. The issue is that SDL is not giving me the correct index for the controller which causes my game to crash.
/receive the controller index given by SDL
int cIdx = evt.cdevice.which;
switch (evt.type)
{
case SDL_CONTROLLERAXISMOTION:
{
//.........
break;
}
case SDL_CONTROLLERBUTTONUP:
{
InputButton sender = InputButton(evt.cbutton.button);
controllerStates[cIdx]->SetButtonState(sender, false);
break;
}
case SDL_CONTROLLERBUTTONDOWN:
{
if (evt.cbutton.button != SDL_CONTROLLER_BUTTON_INVALID)
{
InputButton sender = InputButton(evt.cbutton.button);
controllerStates[cIdx]->SetButtonState(sender, true);
}
break;
}
case SDL_CONTROLLERDEVICEADDED:
{
if (SDL_IsGameController(cIdx))
{
SDL_GameController * controller = SDL_GameControllerOpen(cIdx);
AddController(controller);
}
break;
}
case SDL_CONTROLLERDEVICEREMOVED:
{
RemoveController(controllers[(cIdx)]);
break;
}
}
This works just fine when the user add the controller for the first time, SDL is sending me 0 as index in the SDL_CONTROLLERDEVICEADDED event and also 0 for the other events.
The problem is that if the user tries disconnect and reconnect the controller SDL send 0 as index in SDL_CONTROLLERDEVICEADDED event and 1 for the other events which causes the game to crash.
I can also make simple check if the index to avoid the crash but it will be useless since all controller events will be ignored.
Any help will be appreciated.
Thanks
According to SDL documentation, the index used on SDL_GameControllerOpen is not the index that will identify the controller in future events. So you need to use the joystick id instead.
switch (evt.type)
{
case SDL_CONTROLLERAXISMOTION:
{
//...
break;
}
case SDL_CONTROLLERBUTTONUP:
{
//Get the joystick id from the controller index
//....
break;
}
case SDL_CONTROLLERBUTTONDOWN:
{
//Get the joystick id from the controller index
//....
break;
}
case SDL_CONTROLLERDEVICEADDED:
{
if (SDL_IsGameController(cIdx))
{
SDL_GameController * controller = SDL_GameControllerOpen(cIdx);
SDL_Joystick* j = SDL_GameControllerGetJoystick(controller);
SDL_JoystickID joyId = SDL_JoystickInstanceID(j);
//Save the joystick id to used in the future events
AddController(controller);
}
break;
}
case SDL_CONTROLLERDEVICEREMOVED:
{
//Get the joystick id from the controller index
break;
}
}