Escape delay with a button in a game - c

I have a problem with a piece of code for a game. I would like to know, how to break the time delay if I press the button.
List of files
At the end, the game writes your end score on the LCD for 10 seconds. And goes back to the wait for start. I want to keep that as it is - the only thing that I want to include is that if I press the button within those 10 seconds I want it to go immediately back to the wait for start.
Function code is here
void DrawGameScore()
{ //&RFONT_8X12 &RFONT_16X26
//char key;
//key = KBD_GetKey();
char txt[10];
UG_FontSelect(&RFONT_16X26);
UG_SetForecolor(C_WHITE);
switch (level){
case 1:
UG_PutString(60,130,"Peasant Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 2:
UG_PutString(60,130,"Knight Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 3:
UG_PutString(60,130,"Queen Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 4:
UG_PutString(60,130,"King Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 5:
UG_PutString(60,130,"God Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
}
//UG_PutString(60,130,"Final Score:");
//sprintf(txt,"%d",score);
//UG_PutString(120,160,txt);
//_delay_ms(1000);
}
When the game is over this function draws your score based on your level. In this next function i am calling drawgamescore function, which is in dsip_end_score makro.
int EndOfGame()
{
char key;
//static int state;
int result = 1;
key = KBD_GetKey();
display_msg = DSIP_END_SCORE;
if (key == BTN_OK){
//display_msg = DISP_REFRESH_ALL;
//display_msg = DSIP_END_SCORE;
return result;
}
return result;
}
Here is the main game function
void Game()
{
static int state;
int result;
switch (state)
{
case 1: //waiting for the game start
result = WaitForStart();
if (result == 1) state++;
break;
case 2: //Play the game
result = PlayTheGame();
if (result == 1) state++;
break;
case 3: //Display the score
result = EndOfGame();
if (result == 1) state=0;
break;
default: //0 or unknown value: reset the game
state = 1;
break;
}
}
Thanks.
I tried
int EndOfGame()
{
char key;
static int state;
int result = 1;
key = KBD_GetKey();
display_msg = DSIP_END_SCORE;
if (key == BTN_OK){
//display_msg = DISP_REFRESH_ALL;
//display_msg = DSIP_END_SCORE;
return result;
}
return result;
}
/*
display_msg = DSIP_END_SCORE;
if (key != 0){
switch (key)
{
case BTN_OK:
return result;
break;
}
}
*/
/*
switch (state)
{
case 0:
display_msg = DSIP_END_SCORE;
state++;
break;
case 1:
key = KBD_GetKey();
if (key != 0){
switch (key)
{
case BTN_OK:
return result;
break;
}
break;
}
}
return result;
*/
//display_msg = DISP_REFRESH_ALL;
//display_msg = DSIP_END_SCORE;
//return result;
/*
char key;
int result=0;
//static int state;
key = KBD_GetKey();
if (KBD_isKeyStatePressed(BTN_OK))
{
display_msg = DSIP_END_SCORE;
result = 1;
} else {
result = 1;
}
//return result;
*/
/*
switch (state){
case 0:
KBD_flush(); //empty buffer
//display_msg = DISP_REFRESH_ALL;
display_msg = DSIP_END_SCORE;
return result;
state++;
break;
case 1:
key = KBD_GetKey(); //kbd read dela background services
if (key == BTN_OK){
//display_msg = DISP_REFRESH_ALL;
display_msg = DSIP_END_SCORE;
return result;
break;
}
break;
}
return result;
*/
/*
key = KBD_GetKey();
if (key == BTN_OK) {
//display_msg = DISP_REFRESH_ALL;
return result;
}else{
display_msg = DISP_REFRESH_ALL;
display_msg = DSIP_END_SCORE;
//TODO: write the program
return result;
}*/

I found a solution!
Here is the code if anyone is interested.
int EndOfGame()
{
int result = 0;
char key;
static uint32_t timeStamp;
static int state = 0;
display_msg = DISP_REFRESH_ALL;
switch (state)
{
case 0: //Show end score
display_msg = DSIP_END_SCORE;
timeStamp = GetSysTick();
state++;
break;
case 1: //read keys after 2 seconds
if (Has_X_MillisecondsPassed(2000, &timeStamp)
{
state++;
KBD_flush();
break;
}
break;
case 2:
key = KBD_GetKey();
if (key != 0)
{
switch (key)
{
case BTN_OK:
state = 0;
result = 1;
break;
}
}
//finish after 10 seconds
if (Has_X_MillisecondsPassed(10000, &timeStamp))
{
result = 1;
state = 0;
break;
}
break;
}
return result;
}
If you want to know about the
Has_X_millisecondsPassed();
function you are welcome to see it in systime.c in the File list hyperlink in the question above. For the reference i'm using AtMega328pb microcontroller.

Related

C error C2660: 'Menu' : function does not take 3 arguments

I am new to programming and do not understand this error.
I have the same arguments in the Menu () function and when I call the same function in the menu_principal () function.
In function menu_principal(), I want execute the switch-case statement by the function Menu() with 'option' variable.
Can you help please?
int main()
{
void menu_principal();
return 0;
}
void menu_principal()
{
bool stop = true;
int option;
const char *title = "MENU PRINCIPAL";
const char *options_menu[] = { "ARTIGOS", "CLIENTES", "ORCAMENTOS", "SAIR" };
int n_options = 4;
do
{
option = Menu(title, options_menu, n_options);
switch (option)
{
case 1:
Menu_Item();
break;
case 2:
Menu_Client();
break;
case 3:
Menu_Billing();
break;
case 4:
stop = false;
break;
}
} while (stop);
}
int Menu(const char *title1, const char *options_menu1[], int n_options1)
{
int OptionSelected= 1;
int key;
bool stop = true;
do
{
system("cls");
gotoxy(5, 3 + OptionSelected); printf(">>");
gotoxy(15, 2); printf("%s", title1);
for (int i = 0; i < n_options1; i++)
{
gotoxy(10, 4 + i);
printf("%s ", options_menu1[i]);
}
do
{
key = _getch();
} while (key != KEY_UP && key != KEY_DOWN && key != KEY_ENTER );
switch (key)
{
case KEY_UP:
OptionSelected--;
if (OptionSelected < 1)
{
OptionSelected = n_options1;
}
break;
case KEY_DOWN:
OptionSelected--;
if (OptionSelected > n_options1)
{
OptionSelected = 1;
}
break;
case KEY_ENTER:
stop = false;
break;
}
} while (stop);
return OptionSelected;
}
The compiler reads your program top to bottom, so it sees:
option = Menu(title, options_menu, n_options);
On this line, you call a previously unknown function, Menu.
Because the function is unknown, the compiler assumes it will be int Menu(void). (takes no parameters, returns an int).
That assumption is obviously different from how Menu eventually gets declared.
To fix this, declare the function properly near the top of your file:
int Menu(const char *title1, const char *options_menu1[], int n_options1);
Then, when the compiler encounters your function-call, it will not assume a declaration, it will use the declaration you already provided (takes 3 parameters, and returns an int)

Comments(/*...*/) longer than one line

I am supposed to count the /*...*/ comments in a file and I was wondering if this code is right or am I missing something out?
My Code
void commentsLongerThanOneLine(FILE* inputStream, FILE* outputStream) {
int count = 0, c, state = 1;
while ((c = fgetc(inputStream) != EOF)) {
switch (state) {
case 1: switch (c) {
case '/': state = 2; break;
}
break;
case 2: switch (c) {
case '/': state = 3; break;
case '*': state = 4; break;
default: state = 1;
}
break;
case 3: switch (c) {
case '\n': state = 1; break;
default: state = 4; count++;
}
break;
case 4:switch (c) {
case'*': if (c == '\n') count++; break;
default: state = 4; if (c == '\n') count++;
}
}
}
fprintf(outputStream, "Comments longer than one line: %d\n", count);
}

Using classes to get and set data buffers with arduino in C

I am having a problem storing data it seems in some buffers that I have made. Here is how the code looks:
Here are the definitions for each function:
WriteKeyBrdNum:
char Write_Keyboard::WriteKeybrdNum(TSPoint pos, Data_Buffers dB, int selection, int count)
{
char data;
switch (selection)
{
case EXERCISE:
{
if (pos.y > GRABCHARSIZE * 9) //0
{
//dspWord[count] = '0';
dB.SetDataBufferChar('0', selection, count);
data = dB.GetDataBufferChar(selection, count);
}
else if (pos.y > GRABCHARSIZE * 8) //1
{
//dspWord[count] = '1';
dB.SetDataBufferChar('1', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '1';
}
else if (pos.y > GRABCHARSIZE * 7) //2
{
//dspWord[count] = '2';
dB.SetDataBufferChar('2', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '2';
}
else if (pos.y > GRABCHARSIZE * 6) //3
{
//dspWord[count] = '3';
dB.SetDataBufferChar('3', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '3';
}
else if (pos.y > GRABCHARSIZE * 5) //4
{
//dspWord[count] = '4';
dB.SetDataBufferChar('4', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '4';
}
else if (pos.y > GRABCHARSIZE * 4) //5
{
//dspWord[count] = '5';
dB.SetDataBufferChar('5', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '5';
}
else if (pos.y > GRABCHARSIZE * 3) //6
{
//dspWord[count] = '6';
dB.SetDataBufferChar('6', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '6';
}
else if (pos.y > GRABCHARSIZE * 2) //7
{
//dspWord[count] = '7';
dB.SetDataBufferChar('7', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '7';
}
else if (pos.y > GRABCHARSIZE) //8
{
//dspWord[count] = '8';
dB.SetDataBufferChar('8', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '8';
}
else if (pos.y > 0) //9
{
//dspWord[count] = '9';
dB.SetDataBufferChar('9', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '9';
}
return data;
break;
}
GetDataBufferChar:
char Data_Buffers::GetDataBufferChar(int bufferSelect, int count)
{
char letter;
switch (bufferSelect)
{
case EXERCISE:
{
letter = dspWord[count];
break;
}
case SETS:
{
letter = setsNum[count];
break;
}
case REPS:
{
letter = repsNum[count];
break;
}
case WEIGHT:
{
letter = weightNum[count];
break;
}
default:
{
letter = '\0';
break;
}
}
return letter;
}
SetDataBufferChar:
void Data_Buffers::SetDataBufferChar(char data, int bufferSelect, int count)
{
switch (bufferSelect)
{
case EXERCISE:
{
dspWord[count] = data;
break;
}
case SETS:
{
setsNum[count] = data;
break;
}
case REPS:
{
repsNum[count] = data;
break;
}
case WEIGHT:
{
weightNum[count] = data;
break;
}
default:
break;
}
}
DrawBufferChar:
char Draw_Stuff::DrawBufferChar(SWTFT tft, Data_Buffers dB, int selection, int count, int charSpace)
{
char data;
data = dB.GetDataBufferChar(selection, count);
tft.drawChar(TEXTXPOS*charSpace, TEXTYPOS + 30, data, BLACK, WHITE, EXTTEXTSIZE);
return data;
}
Main loop:
dspWord[wordCount] = writeKeyboard.WriteKeybrdNum(p, dataBuffer, selection, wordCount);
Serial.print("data\t"); Serial.println(dspWord[wordCount]);// Serial.print("\n");
dspWord[wordCount] = drawStuff.DrawBufferChar(tft, dataBuffer, selection, wordCount, wordSpace);
Serial.print("data1\t"); Serial.println(dspWord[wordCount]); //Serial.print("\n");
The Get and Set functions are storing data and getting data from buffers that are established as private buffers in Data_buffers class. The whole point is to be able to set these data buffers in one function, and get them using another function. For the first serial print, the data that is being set in the WriteKeybrdNum function is actually displayed. Then when I call DrawBufferChar, the second serial port print has no data. Am I missing something here. Both DrawBufferChar and WriteKeybrdNum are calling the exact same GetDataBufferChar function with the same "selection" and same "wordCount" yet data is being returned in one function and not the other. Doesn't make sense to me.
Any Help would be greatly appreciated.
Thanks.

Check if bit is changed

I want transmit the state of a bit. When it is set, it should be transmetted for 10 secondes even if its status changes.
here is my solution:
unsigned long Time;
unsigned char State;
unsigned char Flag;/*It is set by an other function*/
unsigned char Bit;
#define BITDETECTION 1
#define COUNT 2
void My_Function ()
{
Bit = (Flag == 0)?0:1;
switch(State)
{
case BITDETECTION:
if(Bit == 0) Transmitte(Bit);
else {State = COUNT; time = GetTime();/*Get the current time*/}
break;
case COUNT:
if( GetTime() - time) <= 10 ) Transmitte(Bit);
else State = BITDETECTION;
break;
default:break;
}
}
Is it correct?
Here is a proposal:
void My_Function ()
{
Bit = (Flag == 0)?0:1;
switch(State)
{
case COUNT:
if( GetTime() - time) <= 10 )
{
Transmitte(Bit);
break;
}
else
{
State = BITDETECTION;
/* fall through to next case */
}
case BITDETECTION:
if(Bit != 0)
{
State = COUNT;
time = GetTime();/*Get the current time*/
}
Transmitte(Bit);
break;
default: abort();
}
}

C SDL Keyboard Events SDL_KEYUP Triggering When Key Is Down

I am using SDL in C, and I'm trying to make a character move on the screen when a key is pressed, and stop when it is released, but it seems as if the KEYUP event is triggering when the key is still being held down. If I remove the KEYUP section in pressed(), the characters will slide across the screen, but obviously won't stop on their own. If I leave the KEYUP section in, I have to press the key repeatedly to move them across the screen.
Any idea what I'm doing wrong?
Here's what I have:
...
int done = 0;
while (done==0)
{
pressed();
if (kenter == 1)
{
state = 1;
subscreen();
}
if (kescape == 1)
{
done = 1;
}
if (kup == 1)
{
playery += -2;
}
if (kdown == 1)
{
playery += 2;
}
if (kright == 1)
{
playerx += 2;
}
if (kleft == 1)
{
playerx += - 2;
}
...
int pressed ()
{
SDL_Event keyevent;
while (SDL_PollEvent(&keyevent))
{
switch(keyevent.type)
{
case SDL_KEYDOWN:
switch(keyevent.key.keysym.sym)
{
case SDLK_RETURN:
{
kenter = 1;
break;
}
case SDLK_ESCAPE:
{
kescape = 1;
break;
}
case SDLK_a:
{
ka = 1;
break;
}
case SDLK_s:
{
ks = 1;
break;
}
case SDLK_UP:
{
kup = 1;
break;
}
case SDLK_DOWN:
{
kdown = 1;
break;
}
case SDLK_RIGHT:
{
kright = 1;
break;
}
case SDLK_LEFT:
{
kleft = 1;
break;
}
default:
break;
}
}
switch(keyevent.type)
{
case SDL_KEYUP:
switch(keyevent.key.keysym.sym)
{
case SDLK_RETURN:
{
kenter = 0;
break;
}
case SDLK_ESCAPE:
{
kescape = 0;
break;
}
case SDLK_a:
{
ka = 0;
break;
}
case SDLK_s:
{
ks = 0;
break;
}
case SDLK_UP:
{
kup = 0;
break;
}
case SDLK_DOWN:
{
kdown = 0;
break;
}
case SDLK_RIGHT:
{
kright = 0;
break;
}
case SDLK_LEFT:
{
kleft = 0;
break;
}
default:
break;
}
}
}
return 0;
}
I think your switch statements are broken.
Use this less confusing way
int pressed ()
{
SDL_Event event;
while(SDL_PollEvent(&event) )
{
if(event.type == SDLK_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
doStuff = 1
break;
default:
break;
}
}
if(event.type == SDLK_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
doStuff = 0;
break;
default:
break;
}
}
}
}
Also important:
SDL Tutorials: Practical Keyboard Input
Oh and avoid using global variables!
Your use of two switch statements is odd and confusing, you should probably fix that.
The issues you're seeing are likely due to keyboard repeat, see the SDL_EnableKeyRepeat() call for how to disable it.
don't use switch. I experienced same thing, but I resolved into using 'if' like this. Maybe switch has 'else if'.
if(event.type == SDL_KEYDOWN){
....
}
if(event.type == SDL_KEYUP){
....
}

Resources