From 231d674daa8e4d1f12f6e1900f7a34baf9935a0b Mon Sep 17 00:00:00 2001 From: Matthew Mondor Date: Tue, 11 Apr 2023 22:59:15 +0000 Subject: [PATCH] Commit custom improvements and description in MATT-README.txt --- MATT-README.txt | 37 ++++++++++++++++++++++++++++ Makefile | 11 +++++---- pacman | Bin 24196 -> 0 bytes pacman.c | 73 ++++++++++++++++++++++++++++++++++++++++++++------------ pacman.h | 7 ++++-- 5 files changed, 106 insertions(+), 22 deletions(-) create mode 100644 MATT-README.txt delete mode 100755 pacman diff --git a/MATT-README.txt b/MATT-README.txt new file mode 100644 index 0000000..c3bd514 --- /dev/null +++ b/MATT-README.txt @@ -0,0 +1,37 @@ +Fork derived from the original code found here: +http://archive.ubuntu.com/ubuntu/ubuntu/pool/universe/p/pacman4console/ + + +IMPROVEMENTS: + +- Applied patches from the ubuntu maintainer like adding a game + over screen. +- Disables the cursor, re-enabling it when requesting input in + blocking mode. +- Use blocking mode outside of the main action game loop. +- Toggle the hero between C and O characters so that it is animated + and "munches". +- Use flushinp(3) instead of ad hoc getch(3) to flush input. +- Added an atexit(3) cleanup handler for endwin(3). + + +BUGFIXES: + +- Used to take 100% CPU time in its delay loop. It assumed that no + character buffering occurs and that non-blocking getch() had to + be called in a loop until the time expired, when it can simply be + called after the timer expires. +- Used illegal usleep(1000000) with undefined behavior that waited + 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. + + +ISSUES: + +- The original makefile is buggy and includes uninstall in the + clean target. Can also easily use native BSD curses where + available rather than always depending on ncurses. Should ideally + detect the situation. +- The level editor crashes, it's possible that it requires porting + to 64-bit or other fixes. Did not bother. diff --git a/Makefile b/Makefile index 6d0bd53..c3e9d24 100755 --- a/Makefile +++ b/Makefile @@ -3,19 +3,20 @@ BINDIR=$(PREFIX)/bin DATAROOTDIR=$(PREFIX)/share all: - gcc pacman.c -o pacman -DDATAROOTDIR=\"$(DATAROOTDIR)\" $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -lncurses - gcc pacmanedit.c -o pacmanedit -DDATAROOTDIR=\"$(DATAROOTDIR)\" $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -lncurses +# gcc pacman.c -o pacman -DDATAROOTDIR=\"$(DATAROOTDIR)\" $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -lncurses + gcc pacman.c -o pacman -DDATAROOTDIR=\"$(DATAROOTDIR)\" $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -lcurses +# gcc pacmanedit.c -o pacmanedit -DDATAROOTDIR=\"$(DATAROOTDIR)\" $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -lncurses install: all install -D pacman $(DESTDIR)/usr/games/pacman4console - install -D pacmanedit $(DESTDIR)/usr/bin/pacman4consoleedit +# install -D pacmanedit $(DESTDIR)/usr/bin/pacman4consoleedit install -d $(DESTDIR)/usr/share/pacman4console/Levels install -m 644 Levels/*dat $(DESTDIR)/usr/share/pacman4console/Levels/ uninstall: rm -f $(DESTDIR)$(BINDIR)/pacman - rm -f $(DESTDIR)$(BINDIR)/pacmanedit +# rm -f $(DESTDIR)$(BINDIR)/pacmanedit rm -f $(DESTDIR)$(DATAROOTDIR)/pacman/Levels/level0[1-9].dat rm -f $(DESTDIR)$(DATAROOTDIR)/pacman/Levels/README rm -f $(DESTDIR)$(DATAROOTDIR)/pacman/Levels/template.dat @@ -24,4 +25,4 @@ uninstall: clean: rm -f pacman - rm -f pacmanedit +# rm -f pacmanedit diff --git a/pacman b/pacman deleted file mode 100755 index b9682e1603d0d018091a124a227af6121a86e961..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24196 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 bV1qpK1U87nPQX5Y1vc2no8!)kn)ZJH_0&?V diff --git a/pacman.c b/pacman.c index f75b993..093f20a 100755 --- a/pacman.c +++ b/pacman.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ void CheckScreenSize(); //Make sure resolution i 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 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 @@ -68,6 +70,13 @@ int LevelNumber = 0; //What level number are we on? int GhostsInARow = 0; //Keep track of how many points to give for eating ghosts int tleft = 0; //How long left for invincibility +//Hero +int hero = 'C'; + +//Curses cleanup +bool curses_initialized = false; + + /**************************************************************** * Function: main() * * Parameters: argc, argv (passed from command line) * @@ -113,8 +122,11 @@ int main(int argc, char *argv[100]) { InitCurses(); //Must be called to start ncurses CheckScreenSize(); //Make sure screen is big enough CreateWindows(29, 28, 1, 1); //Create the main and status windows + curses_initialized = true; + (void)atexit(Cleanup); IntroScreen(); //Show intro "movie" + (void)flushinp(); int start_lives = Lives; int start_points = Points; @@ -176,7 +188,7 @@ int CheckCollision() { GhostsInARow *= 2; wrefresh(win); //Update display - usleep(1000000); //and pause for a second + sleep(1); //and pause for a second //Reset the ghost's position to the starting location Loc[a][0] = StartingPoints[a][0]; Loc[a][1] = StartingPoints[a][1]; @@ -192,7 +204,7 @@ int CheckCollision() { //Subtract one life and pause for 1 second Lives--; - usleep(1000000); + sleep(1); //If no more lives, game over if(Lives == -1) return 1; @@ -213,7 +225,7 @@ int CheckCollision() { Dir[4][0] = 0; Dir[4][1] = -1; DrawWindow(); //Redraw window - usleep(1000000); //Pause for 1 second before continuing game + sleep(1); //Pause for 1 second before continuing game } } } @@ -260,9 +272,14 @@ int GameOverScreen() { //And wait int chtmp; + (void)flushinp(); + (void)curs_set(1); + (void)nodelay(stdscr, FALSE); do { chtmp = getch(); } while (chtmp == ERR); + (void)nodelay(stdscr, TRUE); + (void)curs_set(0); if(chtmp == 'q' || chtmp == 'Q') return 1; @@ -287,6 +304,7 @@ 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 @@ -299,6 +317,14 @@ void Delay() { 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) +{ + + usleep(1000000 / FPS); + GetInput(); +} /**************************************************************** * Function: DrawWindow() * @@ -366,8 +392,7 @@ void DrawWindow() { } //Display Pacman - wattron(win, COLOR_PAIR(Pacman)); mvwaddch(win, Loc[4][0], Loc[4][1], 'C'); - + wattron(win, COLOR_PAIR(Pacman)); mvwaddch(win, Loc[4][0], Loc[4][1], hero); wrefresh(win); //Update main window } @@ -379,10 +404,20 @@ void DrawWindow() { ****************************************************************/ void ExitProgram(const char *message) { endwin(); //Uninitialize ncurses and destroy windows + curses_initialized = false; printf("%s\n", message); //Display message exit(0); //End program, return 0 } +void Cleanup(void) +{ + + if (curses_initialized) { + endwin(); + curses_initialized = false; + } +} + /**************************************************************** * Function: GetInput() * * Parameters: none * @@ -437,7 +472,7 @@ void GetInput() { case 'p': case 'P': //Pause game PauseGame(); - chtmp = getch(); //Update buffered input +// chtmp = getch(); //Update buffered input break; case 'q': case 'Q': //End program @@ -456,13 +491,15 @@ void GetInput() { void InitCurses() { initscr(); //Needed for ncurses windows + start_color(); //Activate colors in console - curs_set(0); // Don't remember - keypad(stdscr, TRUE); //Activate arrow keys + curs_set(0); //Hide cursor + keypad(stdscr, TRUE); //Activate arrow key seq interpretation nodelay(stdscr, TRUE); //Allow getch to work without pausing - nonl(); // Don't remember - cbreak(); // Don't remember + nonl(); //Dont convert CR to NL + cbreak(); //Disable line buffering input noecho(); //Don't display input key + leaveok(stdscr, FALSE); //Leave cursor alone //Make custom text colors init_pair(Normal, COLOR_WHITE, COLOR_BLACK); @@ -488,7 +525,7 @@ void IntroScreen() { int a = 0; int b = 23; - a=getch(); a=getch(); a=getch();//Clear the buffer + (void)flushinp(); // Clear input buffer mvwprintw(win, 20, 8, "Press any key..."); @@ -505,7 +542,7 @@ void IntroScreen() { wattron(win, COLOR_PAIR(Pacman)); mvwprintw(win, 8, 12, "PACMAN"); wrefresh(win); - usleep(1000000); + sleep(1); //Ghosts chase Pacman for(a = 0; a < 23; a++) { @@ -520,7 +557,8 @@ void IntroScreen() { usleep(100000); } - usleep(150000); + sleep(1); + usleep(50000); //Pacman eats powerup and chases Ghosts for(a = 25; a > 2; a--) { @@ -618,7 +656,7 @@ int MainLoop() { DrawWindow(); //Draw the screen wrefresh(win); wrefresh(status); //Refresh it just to make sure - usleep(1000000); //Pause for a second so they know they're about to play + sleep(1); //Pause for a second so they know they're about to play /* Move Pacman. Move ghosts. Check for extra life awarded from points. Pause for a brief moment. Repeat until all pellets are eaten */ @@ -627,10 +665,11 @@ int MainLoop() { MoveGhosts(); DrawWindow(); if (CheckCollision() == 1) return 1; if(Points > FreeLife) { Lives++; FreeLife *= 2;} Delay(); + hero = (hero == 'C' ? 'O' : 'C'); } while (Food > 0); DrawWindow(); //Redraw window and... - usleep(1000000); //Pause, level complete + sleep(1); //Pause, level complete return 0; } @@ -802,9 +841,13 @@ void PauseGame() { wrefresh(win); //And wait until key is pressed + (void)curs_set(1); + (void)nodelay(stdscr, FALSE); do { chtmp = getch(); //Get input } while (chtmp == ERR); + (void)nodelay(stdscr, TRUE); + (void)curs_set(0); } diff --git a/pacman.h b/pacman.h index 008c141..d9d0792 100755 --- a/pacman.h +++ b/pacman.h @@ -1,10 +1,13 @@ // Some variables that you may want to change -#define DATAROOTDIR "/usr/share" -#define LEVELS_FILE DATAROOTDIR "/pacman4console/Levels/level__.dat" +#ifndef DATAROOTDIR +# define DATAROOTDIR "/usr/local/share" +#endif +#define LEVELS_FILE DATAROOTDIR "/pacman/level__.dat" char LevelFile[] = LEVELS_FILE; //Locations of default levels 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 -- 2.9.0