SDL_GetKeyName but for mouse and joystick input - c

I want to make a game where any action can be bound to any input, be it from a keyboard, mouse, controller. Think of scrollwheel bound to jump.
To do this I must be able to present the current bindings in a human readable fashion to the user in a UI, such as "Jump: spacebar" and "shoot: left mouse button".
Currently, in my input routine, I am converting a SDL_KeyboardEvent to a human readable string with SDL_GetKeyName(event.key.keysym.sym).
I'm looking for a way to convert the following events into human readable text:
SDL_JoyAxisEvent
SDL_JoyBallEvent
SDL_JoyButtonEvent
SDL_JoyDeviceEvent
SDL_JoyHatEvent
SDL_MouseButtonEvent
SDL_MouseMotionEvent
SDL_MouseWheelEvent
I would expect the function to output something like "scrollup" or "X button" or "move up" or "left mouse button" or "select button". Currently I am manually implementing this, but it just seems so cumbersome. I've already looked at the docs but I couldn't find anything.
Sidenote: the documentation does not reveal whether a string from SDL_GetKeyName needs to be freed or not. I'm currently not freeing it.
My code currently:
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = 1;
break;
case SDL_KEYDOWN:{
const char* a = SDL_GetKeyName(event.key.keysym.sym);
printf("Pressed down: %s\n", a);
break;
}
case SDL_KEYUP:{
const char* a = SDL_GetKeyName(event.key.keysym.sym);
printf("Released: %s\n", a);
break;
}
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
{
switch (event.button.button)
{
case SDL_BUTTON_LEFT:{
printf("LMB");
break;
}
case SDL_BUTTON_RIGHT:{
printf("RMB");
break;
}
case SDL_BUTTON_MIDDLE:{
printf("MMB");
break;
}
case SDL_BUTTON_X1:{
printf("X1");
break;
}
case SDL_BUTTON_X2:{
printf("X2");
break;
}
}
if (event.type == SDL_MOUSEBUTTONDOWN){
printf(" was clicked!\n");
} else {
printf(" was released!\n");
}
break;
}
case SDL_MOUSEMOTION:{
printf("Mouse moved to (%d, %d)\n", event.motion.x, event.motion.y);
break;
}
case SDL_MOUSEWHEEL:{
printf("Scrolled ");
if(event.wheel.y > 0){
printf("up\n");
}else if(event.wheel.y < 0){
printf("down\n");
}
if(event.wheel.x > 0){
printf("right\n");
}else if(event.wheel.x < 0){
printf("left\n");
}
break;
}
default:{
printf("Unsupported input method\n");
}
}

Related

KEY_ENTER doesnt work on Sensehat joystick input for a case statement

im trying to check for the event input on a sensehat for raspberry
I already checked the eventtype with evtest und it says KEY_ENTER when I press the Joystick
void MovePlayer(unsigned int code)
{
int i;
switch (code) {
case '\r': case '\n': case KEY_ENTER:
printf("works");
i = CheckPoint();
printf("works");
if (i=0){
zaehler++;
printf("success");
}
else
//looselife or game
printf("error");
break;
case KEY_UP:
player.x--;
if (player.x<0)
player.x=7;
break;
case KEY_RIGHT:
player.y++;
if (player.y>7)
player.y=0;
break;
case KEY_DOWN:
player.x ++;
if (player.x>7)
player.x=0;
break;
case KEY_LEFT:
player.y--;
if (player.y<0)
player.y=7;
break;
}
}
This is what the code looks like all the other keys work just fine
i already tried out something i found in here but this was mainly for enterkey on keyboard

How do I check the value of an enum in C?

I'm reading through a library and found an enumeration that looks like this:
typedef enum
{
IS_SYNCED = 0; //Determines if device is in/out of sync
IS_VALID_REF = 1; //Determines if device reference is valid
} EVENT;
I'm wondering how the to check what the value of IS_SYNCED would be?
You can compare enum values with ==.
EVENT e = IS_SYNCED;
if(e == IS_SYNCED)
printf("Is synced event\n");
else if(e == IS_VALID_REF)
printf("Is valid ref event\n");
else
printf("Unknown event\n");
prints:
Is synced event
You can also use switch:
EVENT e = IS_SYNCED;
switch(e) {
case IS_SYNCED:
printf("Is synced event\n");
break;
case IS_VALID_REF:
printf("Is valid ref event\n");
break;
default:
printf("Unknown event\n");
break;
}

Incorrect coding with respect to logic written

The program needs to execute until 'q' is pressed. But the below code what I wrote it is only executing whichever case is first and then stops executing further cases. Ex: case 1.if my input is p, q, then only p case is executed, not the q.
case 2.if my input is g, q, then only g case is executed, not the q.
int main()
{
int i,n,cnt;
char value[10]={0,0,0,0,0,0,0,0,0,0};
int index; float values,Max;
int *val;
bool quit=false;
float num[10]={1.500, 2.200, 7.300, 9.200, 7.400, 7.500, -8.000, 1.500, 12.000, 0.000};
for(i=0;i<20;i++)
{
scanf("%c",&value[i]);
if(value[i]=='r')
{
scanf("%d", &index);
scanf(", %3f",&values);
}
if((value[i] =='p')|(value[i] =='q')|(value[i] =='r')|(value[i] =='g')|(value[i] =='s'))
{
cnt++;
}
}
for(i=0;i<cnt;i++)
{
while(!quit)
{
switch(value[i])
{
//printf("Command (p/g/r/s/q):");
case 'p':
{
printf("Command (p/g/r/s/q):");
printValues(&num,10);
return;
}
case 'g':
{
printf("Command (p/g/r/s/q):");
Max= largestElement(&num,10);
printf("Max=%0.3f",Max);
return;
}
case 'r':
{
printf("Command (p/g/r/s/q):");
replaceElement(&num,index,values);
printValues(&num,10);
return;
}
case 's':
{
printf("Command (p/g/r/s/q):");
sortOnValue(&num,10);
printValues(&num,10);
return;
}
case'q':
{
printf("Command (p/g/r/s/q):");
quit= true;
break;
}
default:
{
printf("help");
return;
}
}
}
}
return 0;
}
Within most of your case blocks you probably want break rather than return to exit the switch. At the moment you are returning frommain() and consequently exiting the program. break transfers control to the end of the switch and your program can then continue.
The case 'q' block would then have a return to exit the program.
Few problems here.
for(i=0;i<20;i++) you are accessing out of bound so your loop should be
for(i=0;i<10;i++).
You need to add ' ' in the format string to consume new line character (\n).
`scanf(" %c",&value[i]);`
You are using | operator instead of || hence your if should be.
if((value[i] =='p')||(value[i] =='q')||(value[i] =='r')||(value[i] =='g')||(value[i] =='s'))
{
cnt++;
}
You are using return instead of break in your switch case.
change this
case 'p':
{
printf("Command (p/g/r/s/q):");
printValues(&num,10);
return;
}
to
case 'p':
{
printf("Command (p/g/r/s/q):");
printValues(&num,10);
break;
}
Your while(!quit) inside the for loop is not useful and will lead to infinate loop when used break statement inside switch case. Hence remove the while(!quit) and change your for loop as below.
for(i=0;i<cnt&&!quit;i++)
side note:: It is high time for you
learn-how-to-debug-small-programs

strcmp with conditional statement

Assuming buf will be either WIN LOSE or DRAW, (I have tested this to be the case), some of the if statements are not running at all. Only the first statement where buf is equal to WIN, the switch inside of the if statement will be reached. For the other two cases, where buf equals LOSE, or DRAW, the program does not enter the if statements, nor run the switch cases, and a segmentation fault happens. I can't seem to find the error. I am not good at comparing strings in C, if someone could please correct my mistake that would be great. Thank you.
A chunk of code from the program
const char* opp[1];
printf("passed declarer comp\n");
if(strcmp(buf, "WIN")==0) {
printf("Entered win statement\n");
switch(choice) {
case 1: opp[0]="Rock"; break;
case 2: opp[0]="Paper"; break;
case 3: opp[0]="Scissors"; break;
}
}
if(strcmp(buf, "LOSE")==0) {
printf("Entered lose statement\n");
switch(choice) {
case 1: opp[0]="Scissors"; break;
case 2: opp[0]="Rock"; break;
case 3: opp[0]="Paper"; break;
}
}
if(strcmp(buf, "DRAW")==0) {
printf("Entered draw statement\n");
opp[0] = playerChose[0];
}
printf("passed logic\n");
printf("%s\n", buf);
printf("%s\n",opp[0]);
printf("The other player chose %s, you %s\n", opp[0], buf);

How can I repeat scanf in a switch-case scenario if some invalid input has been given?

I have the following code, where I expect the user to give eiher 's' or 'f' (case insensitive) as input:
/* ... snip ... */
char acc_type;
printf("\n\nENTER HERE\t : ");
scanf("%c",&acc_type);
switch (acc_type)
{
case 's':
case 'S':
printf("\n SAVING ACCOUNT");
break;
case 'f':
case 'F':
printf("\n FIXED ACCOUNT");
break;
default:
printf("\n INVALID INPUT!!! TRY AGAIN");
}
/* ... snip ... */
However, the default action doesn't allow me to repeat the whole switch statement. How can I ask for input in his scenario again if the input wasn't valid?
You need a loop, essentially (in pseudo-code):
good_input = 0;
while(good_input == 0) {
... prompt for input ...
if (input == good) {
good_input = 1;
}
}
Until something valid is entered, good_input stays 0 and the while() loop continues to prompt for input. Once something good is entered, that flag changes and the code continues on to the next section.
Put the part you want to repeat in a loop, like this:
bool inputOK = false;
do {
printf("\n\nType S to SAVING ACCOUNT");
printf("\nType F to FIX ACCOUNT");
printf("\n\nENTER HERE\t : ");
scanf("%c",&acc_type);
switch (acc_type)
{
case 's':
case 'S':
printf("\n SAVING ACCOUNT");
inputOK = true;
break;
case 'f':
case 'F':
printf("\n FIXED ACCOUNT");
inputOK = true;
break;
default:
printf("\n INVALID INPUT!!! TRY AGAIN");
break; // Note: it's wise to use break in EVERY case
}
} while (inputOK == false);

Resources