From: Matthew Mondor Date: Tue, 25 Apr 2023 06:19:16 +0000 (+0000) Subject: Improve user input handling and function prototypes X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=dcab820d8d412da3545908ab7d0db9425513533f;p=pacman.git Improve user input handling and function prototypes --- diff --git a/MATT-README.txt b/MATT-README.txt index b91c44f..a1c574f 100644 --- a/MATT-README.txt +++ b/MATT-README.txt @@ -14,6 +14,7 @@ IMPROVEMENTS: - Use flushinp(3) instead of ad hoc getch(3) to flush input. - Added an atexit(3) cleanup handler for endwin(3). - Added hiscore/level tracking and display, now requires 33 lines. +- More keys are accepted for movement. BUGFIXES: @@ -26,6 +27,8 @@ BUGFIXES: one secod on Linux+glibc but that doesn't sleep on NetBSD. These were replaced with sleep(1). This affected transitions and the score display. +- There were issues with input flushing, often preventing the Game + Over screen from displaying. ISSUES: @@ -38,3 +41,5 @@ ISSUES: to 64-bit or other fixes. Did not bother. - There are some globals in pacman.h that should really be macro definitions, and/or moved to the main module. +- Uses ad-hoc command line arguments processing rather than getopt(3). +- Should save/load/remember the high score. diff --git a/pacman.c b/pacman.c index 54f2e58..68f646d 100755 --- a/pacman.c +++ b/pacman.c @@ -22,7 +22,6 @@ #include "pacman.h" #define EXIT_MSG "Good bye!" -#define END_MSG "Game Over" #define QUIT_MSG "Bye" #define LEVEL_ERR "Cannot find level file: " #define LEVEL_WIDTH 28 @@ -31,21 +30,21 @@ /************* * PROTOTYPES * *************/ -void IntroScreen(); //Show introduction screen and menu -int CheckCollision(); //See if Pacman and Ghosts collided -void CheckScreenSize(); //Make sure resolution is at least 33x29 +void IntroScreen(void); //Show introduction screen and menu +int CheckCollision(void); //See if Pacman and Ghosts collided +void CheckScreenSize(void); //Make sure resolution is at least 33x29 void CreateWindows(int y, int x, int y0, int x0); //Make ncurses windows -void Delay(); //Slow down game for better control -void DrawWindow(); //Refresh display +void Delay(void); //Slow down game for better control +void DrawWindow(void); //Refresh display void Cleanup(void); //endwin(3) cleanup handler void ExitProgram(const char *message); //Exit and display something -void GetInput(); //Get user input -void InitCurses(); //Start up ncurses +void GetInput(void); //Get user input +void InitCurses(void); //Start up ncurses void LoadLevel(char *levelfile); //Load level into memory -int MainLoop(); //Main program function -void MoveGhosts(); //Update Ghosts' location -void MovePacman(); //Update Pacman's location -void PauseGame(); //Pause +int MainLoop(void); //Main program function +void MoveGhosts(void); //Update Ghosts' location +void MovePacman(void); //Update Pacman's location +void PauseGame(void); //Pause void PrintHelp(char* name); //Print help and exit /******************* @@ -256,40 +255,38 @@ void CheckScreenSize() { } int GameOverScreen() { - char chr = ' '; - int a, b; + int ch; if (Points > HiPoints) { HiPoints = Points; HiLevelNumber = LevelNumber; } - for(a = 0; a < 29; a++) for(b = 0; b < 28; b++) { - mvwaddch(win, a, b, chr); - } - + werase(win); wattron(win, COLOR_PAIR(Pacman)); mvwprintw(win, 8, 11, "Game Over"); - wattron(win, COLOR_PAIR(Normal)); mvwprintw(win, 14, 2, "Press q to quit ..."); mvwprintw(win, 16, 2, "... or any other key"); mvwprintw(win, 17, 6, "to play again"); - wrefresh(win); - //And wait - int chtmp; + sleep(1); + + /* For some reason we really need both */ (void)flushinp(); + while (getch() != ERR) ; + + /* Wait in blocking mode */ (void)curs_set(1); (void)nodelay(stdscr, FALSE); do { - chtmp = getch(); - } while (chtmp == ERR); + ch = getch(); + } while (ch == ERR); (void)nodelay(stdscr, TRUE); (void)curs_set(0); - if(chtmp == 'q' || chtmp == 'Q') + if(ch == 'q' || ch == 'Q') return 1; return 0; } @@ -312,20 +309,6 @@ void CreateWindows(int y, int x, int y0, int x0) { * Returns: none * * Description: Pause the game and still get keyboard input * ****************************************************************/ -#if 0 -void Delay() { - - //Needed to get time - struct timeb t_start, t_current; - ftime(&t_start); - - //Slow down the game a little bit - do { - GetInput(); //Still get the input from keyboard - ftime(&t_current); //Update time and check if enough time has overlapped - } while (abs(t_start.millitm - t_current.millitm) < SpeedOfGame); -} -#endif void Delay(void) { @@ -451,7 +434,7 @@ void GetInput() { //Determine which button is pushed switch (ch) { - case KEY_UP: case 'w': case 'W': //Move pacman up + case KEY_UP: case 'w': case 'i': case '8': //Move pacman up if(Loc[4][0] <= 0) tmp = LEVEL_HEIGHT - 1; else tmp = Loc[4][0] - 1; if((Level[tmp][Loc[4][1]] != 1) @@ -459,7 +442,7 @@ void GetInput() { { Dir[4][0] = -1; Dir[4][1] = 0; } break; - case KEY_DOWN: case 's': case 'S': //Move pacman down + case KEY_DOWN: case 's': case 'k': case '5': case '2': //Move pacman down if(Loc[4][0] >= 28) tmp = 0; else tmp = Loc[4][0] + 1; if((Level[tmp][Loc[4][1]] != 1) @@ -467,7 +450,7 @@ void GetInput() { { Dir[4][0] = 1; Dir[4][1] = 0; } break; - case KEY_LEFT: case 'a': case 'A': //Move pacman left + case KEY_LEFT: case 'a': case 'j': case '4': //Move pacman left if(Loc[4][1] <= 0) tmp = LEVEL_WIDTH - 1; else tmp = Loc[4][1] - 1; if((Level[Loc[4][0]][tmp] != 1) @@ -475,7 +458,7 @@ void GetInput() { { Dir[4][0] = 0; Dir[4][1] = -1; } break; - case KEY_RIGHT: case 'd': case 'D': //Move pacman right + case KEY_RIGHT: case 'd': case 'l': case '6': //Move pacman right if(Loc[4][1] >= 27) tmp = 0; else tmp = Loc[4][1] + 1; if((Level[Loc[4][0]][tmp] != 1) @@ -538,7 +521,9 @@ void IntroScreen() { int a = 0; int b = 23; - (void)flushinp(); // Clear input buffer + /* Flush input */ + (void)flushinp(); + while (getch() != ERR) ; mvwprintw(win, 20, 8, "Press any key..."); @@ -859,6 +844,7 @@ void PauseGame() { //And wait until key is pressed (void)flushinp(); + while (getch() != ERR) ; (void)curs_set(1); (void)nodelay(stdscr, FALSE); do { diff --git a/pacman.h b/pacman.h index d9d0792..db027f0 100755 --- a/pacman.h +++ b/pacman.h @@ -9,5 +9,4 @@ int FreeLife = 1000; //Starting points for free life int Points = 0; //Initial points int Lives = 3; //Number of lives you start with int HowSlow = 3; //How slow vulnerable ghost move -int SpeedOfGame = 175; //How much of a delay is in the game #define FPS 5