How to wait an input without stop the program in Xlib - c

The problem is this, I, am writing a chip 8 emulator in C, and i am using a library that use Xlib, for writing sprites attending input etc, the method that the library have for wait an input is this:
char gfx_wait(){
XEvent event;
gfx_flush();
while(1) {
XNextEvent(gfx_display,&event);
if(event.type==KeyPress) {
saved_xpos = event.xkey.x;
saved_ypos = event.xkey.y;
return XLookupKeysym(&event.xkey,0);
} else if(event.type==ButtonPress) {
saved_xpos = event.xkey.x;
saved_ypos = event.xkey.y;
return event.xbutton.button;
}
}
}
when i call this method the program stops waiting for input, I, need a methods that is called just when i press or release a button.

I just solve my problem, using this function :
int gfx_event_waiting(unsigned char *ch)
{
XEvent event;
gfx_flush();
while (1) {
if(XCheckMaskEvent(gfx_display,-1,&event)) {
if(event.type==KeyPress) {
*ch = XLookupKeysym(&event.xkey,0);
return 1;
}else if(event.type==KeyRelease){
return 1;
}else if (event.type==ButtonPress) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
}
and this is the main :
int
main(int argc, char *argv[])
{
int x;
int i;
unsigned char key_pressed,key_released;
Init();
LoadRom(SELECTED_ROM);
gfx_open(WIDTH,HEIGHT,"Chip 8 Emulator");
gfx_color(255,250,250);
for(;;){
if(!gfx_event_waiting(&key_pressed)){
opcode_cycle();
key_wait(key_released,0);
#if DEBUG
printf("# %d | %c #",x,key_pressed);
#endif
key_wait(key_pressed,1);
key_released = key_pressed;
gfx_clear();
if(DrawFlag)
Draw();
/*Big for for simulate a delay*/
for(i = 0; i <= 100000; i++)
;
}else{
x++;
}
}
}
I, am sure that there is a better way for do this , but you know, It's work...

Related

My while loop is not breaking after my interrupt updates in C

I am implementing simon says as a small weekly project for school. Using arduino Uno, I'm making 10 levels each level has an extra pattern inside. example: level 1: [1], level 2: [1,2], etc... I have three buttons on my shield. the interrupts work and everything is gucci. My problem here is in this snippet
bool readInput(uint8_t pattern[], uint8_t length)
{
sei();
uint8_t current = 0;
while (current < length)
{
btnPushed = false;
while (!btnPushed)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
printf("here");
cli();
_delay_ms(200);
if (currentPushed == pattern[current])
{
printf("correct, you pushed %d\n", currentPushed);
}
else
{
printf("incorrect, lets try again\n");
return false;
}
}
btnPushed = false;
return true;
}
so basically I set my buttonPushed to false, and start listening for interrupts, once its true after clicking, I expect to exit the loop and check the input, however my interrupt is correct and I get visual feedback with a light that lights up once i push a button.
this is my ISR
ISR(PCINT1_vect)
{
uint8_t buttonCurr = currentButton();
if (buttonCurr != -1)
{
if (!btn1Pushed && buttonCurr == 0)
{
btn1Pushed = true;
}
currentPushed = buttonCurr;
blinkLed(currentPushed, 1);
btnPushed = true;
}
}
my current button returns 0-2 for buttons that are clicked, and -1 if nothing was clicked.
this is the rest of my code, which is working pretty much
int currentPushed = -1;
bool won;
bool btnPushed = false;
bool btn1Pushed = false;
ISR(PCINT1_vect)
{
uint8_t buttonCurr = currentButton();
if (buttonCurr != -1)
{
if (!btn1Pushed && buttonCurr == 0)
{
btn1Pushed = true;
}
currentPushed = buttonCurr;
blinkLed(currentPushed, 1);
btnPushed = true;
}
}
int main(void)
{
enableAllButtons();
enableAllLeds();
lightDownAllLeds();
prepareButtonsForInterrupt();
initUSART();
init();
play();
if (won)
{
printf("Simon says you win");
}
else
{
printf("simon says do better");
}
return 0;
}
void init(void)
{
printf("LETS PLAY SIMON SAYS\nPress button 1 to start!\n");
int seed = 0;
while (!btn1Pushed)
{
blinkLed(3, 4);
seed++;
}
srand(seed);
printf("Get ready!\n");
btnPushed = false;
cli();
}
void createRandomPattern(uint8_t array[], uint8_t length)
{
for (int i = 0; i < length; i++)
{
array[i] = rand() % 3;
}
}
void play(uint8_t pattern[])
{
uint8_t fullPattern[MAX_PATTERN_LENGTH];
createRandomPattern(fullPattern, MAX_PATTERN_LENGTH);
for (int i = 1; i <= MAX_PATTERN_LENGTH; i++)
{
printf("========LEVEL %d===========\n", i);
playPuzzle(fullPattern, i);
#ifdef DEBUG
printPuzzle(fullPattern, i);
#endif
readInput(fullPattern, i) ?: i--;
}
}
bool readInput(uint8_t pattern[], uint8_t length)
{
sei();
uint8_t current = 0;
while (current < length)
{
btnPushed = false;
while (!btnPushed)
{
}
cli();
if (currentPushed == pattern[current])
{
printf("correct, you pushed %d\n", currentPushed);
}
else
{
printf("incorrect, lets try again\n");
return false;
}
current++;
}
btnPushed = false;
return true;
}
void printPuzzle(uint8_t pattern[], uint8_t length)
{
printf("[ ");
for (int i = 0; i < length; i++)
{
printf("%d ", pattern[i]);
}
printf("]\n");
}
void playPuzzle(uint8_t pattern[], uint8_t length)
{
for (int i = 0; i < length; i++)
{
lightUpOneLed(pattern[i]);
_delay_ms(500);
lightDownOneLed(pattern[i]);
}
}
btnPushed is defined as bool btnPushed = false;.
So when you write:
while (!btnPushed)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
Nothing in the loop will change btnPushed so there is no point for the compiler to ever check btnPushed again. So what the compiler sees is this:
if (!btnPushed)
while(true)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
You have to tell the compiler that the value of btnPushed will change unexpectantly when the interrupt fires by using:
volatile bool btnPushed = false;

why this show() function produce two * and the element will stop sometimes .There is no error in the code

This is a plane game function I wrote. I use a two-dimensional array to represent the game variables but The running result is abnormal, and * will jump suddenly.
And there will be two * , at the same time, and the plane also will stop
There should be no two * in the process of traversing the two-dimensional array. I tried to modify the position of * but I still couldn't.It's OK to run part of the code alone, but when you use the key operation, the program makes an error, but I don't know what's wrong
#include<stdio.h>
#include <windows.h>
#include<stdlib.h>
#include<conio.h>
#define enemynum 3
int element [20][30];
int position_x,position_y;
int enemy_x[enemynum],enemy_y[enemynum];
int score;
void gotoxy(int x, int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = {1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void startup()
{ element[20][30]={0};
position_x=10;position_y=15;
element[position_x][position_y]=1;
for(int k=0;k<enemynum;k++)
{
enemy_x[k]=rand()%3;enemy_y[k]=rand()%20;
element[enemy_x[k]][enemy_y[k]]=3;
}
HideCursor();
}
This is an encapsulated pointer callback function. I don't think we need to consider the above functions
void show()
{ int i,j;
gotoxy(0,0);
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{ if(element[i][j]==1)
{
printf("*");
}else if(element[i][j]==3)
{
printf("#");
}
else
printf(" ");
}
printf("\n");
}
}
void updatewhithout()
{
int i,j;
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{
if(element[i][j]==2)
{
element[i][j]=0;
if(i>0)
element[i-1][j]=2;
}
}
} static int flag;
if(flag<20)
flag++;
if(flag==20)
{ for(int k=0;k<enemynum;k++)
{
if(enemy_x[k]==20)
{
enemy_x[k]=rand()%3;
enemy_y[k]=rand()%20;
}
element[enemy_x[k]][enemy_y[k]]=0;
enemy_x[k]++;
element[enemy_x[k]][enemy_y[k]]=3;
flag=0;
}
}
}
void updatewhith()
{ char ch;
if( kbhit())
ch=getch();
if(ch=='a')
{ element[position_x][position_y]=0;
position_y--;
element[position_x][position_y]=1;
}
if(ch=='d')
{ element[position_x][position_y]=0;
position_y++;
element[position_x][position_y]=1;
}
}
int main()
{startup();
while(1)
{show();
updatewhithout();
updatewhith();
}
}

Double buffering and printf

I am having trouble with getting my other basic functions to work with double buffer.
for example in the code below, it runs and I can press either down or up to move my cursor, and when I press enter I am supposed to get a printf saying either making a new char, load, or goodbye.
It shows up for a split second but then it immediately disappears. In these situations rewind(stdin) and getchar(); solves this issue but for this code, nothing seems to work.
Please help.
#define _CRT_SECURE_NO_WARNINGS
#include "conioex.h"
#include "DblBuffer.h"
enum //
{
NEW_GAME = 20,
LOAD,
EXIT,
MAX_NUM
};
void main (void)
{
DblBuffer db;
int Cursor_X, Cursor_Y; // cursorlocation
bool Key_flag = false; // pressandtrue
int type = NEW_GAME; // type
Cursor_X = 20;
Cursor_Y = 1;
int flag = 1;
while (flag)
{
for (int i = 1; i <= 3; i++)
{
db.setCursorPos(20,i);
db.write(" ");
}
db.setCursorPos(25,1);
db.write("New Game\n");
db.setCursorPos(25,2);
db.write("Load\n");
db.setCursorPos(25,3);
db.write("Exit\n");
if (inport(PK_DOWN))
{
if (Key_flag == false)
{
Cursor_Y = Cursor_Y + 1;
type = type + 1;
Key_flag = true;
}
}
else if (inport(PK_UP))
{
if (Key_flag == false)
{
Cursor_Y = Cursor_Y - 1;
type = type - 1;
Key_flag = true;
}
}
else if (inport(PK_ENTER))
{
flag = 0;
break;
}
else
{
Key_flag = false;
}
if (Cursor_Y < 1)
{
Cursor_Y = 1;
}
if (Cursor_Y > 3)
{
Cursor_Y = 3;
}
if (type < NEW_GAME)
{
type = NEW_GAME;
}
if (type >= MAX_NUM)
{
type = MAX_NUM - 1;
}
db.setCursorPos(Cursor_X, Cursor_Y);
db.write("→");
db.swap();
}
if(type == NEW_GAME)
{
printf("making a new game");
}
if (type == LOAD)
{
printf("will load");
}
if (type == EXIT)
{
printf("goodbye");
}
rewind(stdin);
getchar();
}
As for your problem, by "then it immediately disappears" I assume that the console window disappears quickly?
That's because the program exits.
You need to flush the input buffer connected to stdin to remove all key presses you made (by reading from stdin) and then call getchar one extra time to get a a kind of confirmation that the user wants to exit.

Only printing last line of txt file when reading into struct array in C

I am reading from a txt file into an array of structures. Example txt:
-4.5 -1 0 0
4.0 1 0 0
8 0 1 2
12.1 0 -6 1
-3.2 2.5 -3.0 4
The 4 values of each line correspond to the 4 values in the structure. The file may contain up to 100 lines (MAX is defined as 100). With the following code I am trying to store each line into the respective index of the struct array and then print:
FILE *fileName = NULL;
typedef struct chargeData_struct {
double Q, x, y, z;
} ChargeData;
ChargeData values[MAX], *p = values;
fileName = fopen("charge2.txt", "r");
if (fileName == NULL)
{
printf("ERROR: Could not open file.");
}
int k = 0;
while (fscanf(fileName, "%lf %lf %lf %lf", &p[k].Q, &p[k].x, &p[k].y, &p[k].z) != EOF);
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
fclose(fileName);
However, only the last line of the txt file is printed. Is the same index of the struct array being overwritten each time?
You are using an extra semicolon which makes all the trouble, here:
while (fscanf(...) != EOF);
{
...
Remove it and you should be fine.
What happens with your code is that while(..); is equivalent to this:
while(...)
{
; // do nothing
}
thus does not enter the body (the one you think is the body) of your loop (since the actual body does nothing). However scanf() continues to parse the file, and then this section of your code executes:
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
independently, where the curly braces are treated like they wanted to state scope.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LINE_BUFFER_LEN (512)
#define RESERVE_NEWLINDE 0
#define AUTO_FILTER_NEWLINDE 1
typedef int (* LINE_READER)(char * pstrLine, int uiBufferLen, void * pvData);
typedef struct st_HW_SSP_CONFIG
{
const char * pstrConfigPath;
LINE_READER pfLineReader;
FILE * pstFile;
void * pvData;
int CurrentLine;
int Flag;
} CONFIG_ST;
int CloseConfig(CONFIG_ST * pstConfig)
{
if (!pstConfig)
{
// record error
return -1;
}
if (fclose(pstConfig->pstFile))
{
// record error
}
return 0;
}
int OpenConfigFile(const char * pstrFilePath, CONFIG_ST * pstConfig)
{
FILE * pstFile = NULL;
if ((!pstrFilePath) || (!pstConfig))
{
return -1;
}
pstFile = fopen(pstrFilePath, "r");
if (!pstFile)
{
return -1;
}
pstConfig->pstFile = pstFile;
pstConfig->pstrConfigPath = pstrFilePath;
pstConfig->Flag = RESERVE_NEWLINDE;
return 0;
}
int IsNullStr(const char *pcStr)
{
const char *pcTmp = pcStr;
while ('\0' != *pcTmp)
{
if (!isspace(*pcTmp))
{
return 0;
}
pcTmp++;
}
return 1;
}
int IsEffectiveLine(char acFileLineBuffer[LINE_BUFFER_LEN])
{
if (0 == strlen(&acFileLineBuffer[0]))
{
return 0;
}
if ('#' == acFileLineBuffer[0]) // strip as a comment line
{
return 0;
}
if (IsNullStr(&acFileLineBuffer[0]))
{
return 0;
}
return 1;
}
void FilterNewLine(char* pcLine, int MaxNumLen)
{
int uiLen = strlen(pcLine);
if (uiLen > 1)
{
if ('\n' == pcLine[uiLen - 1])
{
pcLine[uiLen - 1] = '\0';
if (uiLen > 2)
{
if ('\r' == pcLine[uiLen - 2])
{
pcLine[uiLen - 2] = '\0';
}
}
}
}
return;
}
int ReadConfigFile(CONFIG_ST * pstConfig)
{
char acFileLineBuffer[LINE_BUFFER_LEN] = {0};
char * pstrRead = NULL;
int Ret = 0;
if (!pstConfig)
{
return -1;
}
if ((!pstConfig->pstFile) || (!pstConfig->pfLineReader))
{
return -1;
}
rewind(pstConfig->pstFile);
pstConfig->CurrentLine = 0;
do
{
memset((void *)&acFileLineBuffer[0], 0, LINE_BUFFER_LEN);
pstrRead = fgets(&acFileLineBuffer[0], LINE_BUFFER_LEN - 1, pstConfig->pstFile);
if (pstrRead)
{
pstConfig->CurrentLine ++;
if (0 == IsEffectiveLine(acFileLineBuffer))
{
continue;
}
if (AUTO_FILTER_NEWLINDE == pstConfig->Flag)
{
FilterNewLine(acFileLineBuffer, LINE_BUFFER_LEN - 1);
}
if (pstConfig->pfLineReader)
{
Ret = pstConfig->pfLineReader(&acFileLineBuffer[0],
LINE_BUFFER_LEN,
pstConfig->pvData);
if (Ret)
{
break;
}
}
}
}
while (pstrRead);
return Ret;
}
int ReadConfigFileEx(const char * pFilePath,
LINE_READER pfReader,
void * pData, int Flag)
{
int Ret = 0;
CONFIG_ST stConfig = {0};
Ret = OpenConfigFile(pFilePath, &stConfig);
if (Ret)
{
return Ret;
}
stConfig.pfLineReader = pfReader;
stConfig.pvData = pData;
stConfig.Flag = Flag;
Ret = ReadConfigFile(&stConfig);
CloseConfig(&stConfig);
return Ret;
}
int StringSplit(char *pcStr, char cFlag,
char * pstArray[], int MaxNum,
int *pNum)
{
char * pcStrTemp = 0;
unsigned int uiIndex = 0;
pcStrTemp = pcStr;
while (pcStrTemp)
{
pstArray[uiIndex] = pcStrTemp;
pcStrTemp = strchr(pcStrTemp, cFlag);
if (pcStrTemp)
{
*pcStrTemp = '\0';
pcStrTemp ++;
uiIndex ++;
}
if (uiIndex >= MaxNum)
{
break;
}
}
if (0 != MaxNum)
{
*pNum = uiIndex >= MaxNum ? (MaxNum - 1) : uiIndex;
}
else
{
*pNum = 0;
}
return 0;
}
int MyLineReader(char * pstrLine, int uiBufferLen, void * pvData)
{
printf("Read line:[%s]\r\n", pstrLine);
char *pArray[8] = {0};
int Num = 0;
int index = 0;
StringSplit(pstrLine, ' ', pArray, 8, &Num);
for (index = 0; index <= Num; index ++)
{
printf("Get value :[%s]\r\n", pArray[index]);
}
return 0;
}
int main(int argc, char * argv[])
{
int ret = 0;
if (argc != 2)
{
printf("Please input file to read.\r\n");
return 0;
}
ret = ReadConfigFileEx(argv[1], MyLineReader, NULL, AUTO_FILTER_NEWLINDE);
if (ret)
{
printf("Open file error.\r\n");
}
return 0;
}

find one string in another string using c

I have written following code to find str1 is present in str2 or not. But it doesn't work all scenarios.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int i,j,flag=1;
char str1[]="goa",str2[]="gogoa";
if (strlen(str1)>strlen(str2))
{
printf("not found");
return;
}
for ( i = 0; str2[i]; i++)
{
if (str1[0]==str2[i])
{
for ( j = 0; str1[j]; j++)
{
if (str1[j]!=str2[i+j])
{
printf("not found");
flag=0;
}
}
break;
}
}
if (flag==1)
{
printf("found at index %d ",i);
}
getchar();
}
its not working when str1 starting character is present multiple times in str2,otherwise it works fine.
How can I optimize this to make it work in all scenarios?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
int i, j, flag=0, len1, len2;
char str1[]="goa",str2[]="gogoa";
len1 = strlen(str1);
len2 = strlen(str2);
if (len1 > len2){
printf("not found");
return 0;
}
for (i = 0; i <= len2 - len1; ++i){
if (str1[0]==str2[i]){
flag = 1;
for (j = 1; str1[j]; ++j){
if (str1[j]!=str2[i+j]){
flag=0;
break;
}
}
if(flag==1)
break;
}
}
if (flag==1){
printf("found at index %d ",i);
} else {
printf("not found");
}
return 0;
}
try this:
int i,j,flag=0, match=0;
char str1[]="goa",str2[]="gogoa";
if (strlen(str1)>strlen(str2))
{
printf("not found");
return;
}
for ( i = 0; str2[i]; i++)
{
if (str1[0]==str2[i])
{
match=1;
for ( j = 0; str1[j]; j++)
{
if (str1[j]!=str2[i+j])
match=0;
}
if(match == 1)
{
flag = 1;
break;
}
}
}
if (flag==1)
printf("found at index %d ",i);
else
printf("not found");
I agree to comments that you should show what you have done. Please do that next time.
For now, I would like to suggest two approaches to debug out of sticky problems: use printfs and understand the flow OR use gdb. I have commented your program w.r.t. the printf approach. Have not tested all cases...but this should hopefully give you a direction to your debugging. Hope it helps. Remember to do this step before you post a question next time :-)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
int i,j,flag=1;
char str1[]="goa",str2[]="gogoa";
if (strlen(str1)>strlen(str2)) {
printf("not found");
return;
}
for ( i = 0; str2[i]; i++) {
/* If starting letter does not match, forget it */
if (str1[0]==str2[i]) {
flag = 1;
// Iterate thro' str1
for ( j = 0; str1[j]; j++) {
if (str1[j] != str2[i+j]) {
printf("%s not found at index %d of %s\n", str1, i, str2);
flag=0;
break; // out of inner for loop
}
}
if (j == strlen(str1)) {
// found the entire string.
break; // out of outer for loop
}
}
}
if (flag==1) {
printf("%s found at index %d of %s\n", str1, i, str2);
}
getchar();
}
I have rewritten the code with slight modifications in it and it's working for me,
check all your necessary scenarios, and let me know.
public static bool findString(string searchText, string fullText)
{
bool result = false;
if (searchText.Length > fullText.Length)
{
return false;
}
for (int i = 0; i <= (fullText.Length - searchText.Length); i++)
{
if (searchText[0] == fullText[i])
{
for (int j=0; j<searchText.Length ;j++)
{
if ((i+j)< fullText.Length && searchText[j] == fullText[i+j])
result = true;
else
{
result = false;
break;
}
}
}
if (result)
{
Console.WriteLine("found at index {0}", i);
break;
}
}
return result;
}
Sorry about the syntax, I only had c# available. you'll have to use strlen(string) for lengths and '%d' for '{0}', printf for Console.Writeline(" ");
#include <string.h>
if(strstr(str2, str1) != NULL) {
/* ... */
}
Please checkout the doc of strstr function.
//Declaration: char *strstr(const char *str1, const char *str2);
//Return: It returns a null pointer if no match is found.
#include <string.h>
#include <stdio.h>
int main(void)
{
char *p;
p = strstr("goa", "gogoa");
printf(p);
return 0;
}

Resources