From: Matthew Mondor Date: Wed, 12 Apr 2023 08:41:18 +0000 (+0000) Subject: Various improvements: X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=e159d807418fc9dea962c27473e40a7be0aedb80;p=ninvaders.git Various improvements: - Use getopt(3) and atoi(3) instead of ad-hoc argument management - Make UFO missiles two animated rows to be closer to those in the original game. - Add a curses(3) atexit(3) cleanup handler. - Use stdlib EXIT_SUCCESS/EXIT_FAILURE. --- diff --git a/MATT-README.txt b/MATT-README.txt new file mode 100644 index 0000000..d40f615 --- /dev/null +++ b/MATT-README.txt @@ -0,0 +1,38 @@ +This code was based on ninvaders-0.1.1 then forked by Matthew +Mondor, mostly for personal use. + + +BUG FIXES + +- Header files were a mess some containing globals that should have + been in modules then declared in a header if needed, others + lacking proper prototypes, causing ABI and stability issues on + 64-bit. Fixed. + + +IMPROVEMENTS + +- Allow to build against BSD or other X/Open standard curses(3) + +- Use getopt(3) and atoi(3) instead of ad-hoc argument management + +- Make UFO missiles two animated rows to be closer to those in the + original game. + +- Add a curses(3) atexit(3) cleanup handler. + +- Use stdlib EXIT_SUCCESS/EXIT_FAILURE. + + +TODO + +- Display the last score+level on the title screen if any after a + game + +- Maybe allow to shoot UFO missiles + +- Make difficulty levels more gradual, from 0 to 1 is a chasm + already, when it goes up to 9. It would be more reasonable if + the default was around 3 or 5, with 1 rather difficult. It may + also be more intuitive if the difficulty increased with the level, + 9 being the hardest. diff --git a/aliens.c b/aliens.c index 242ddb2..ac1f67e 100644 --- a/aliens.c +++ b/aliens.c @@ -223,14 +223,14 @@ int aliensMissileMove() aliensMissileClear(alienshotx[i],alienshoty[i]); // clear old position // if missile hit the bunkers - if (bunkersHitCheck(alienshotx[i], alienshoty[i]) == 1) { + if (bunkersHitCheck(alienshotx[i], alienshoty[i] + 1) == 1) { alienshotx[i] = 0; // value of zero reloads missile } alienshoty[i]++; // move missile downwards // check if player was hit by an alien missile - if (playerHitCheck(alienshotx[i], alienshoty[i]) == 1) { + if (playerHitCheck(alienshotx[i], alienshoty[i] + 1) == 1) { alienshotx[i] = 0; // value of zero reloads missile fPlayerWasHit = 1; } @@ -253,7 +253,7 @@ int aliensMissileMove() // display missiles if still running or just launched; could have been modified in the above code if (alienshotx[i] != 0) { // if missile is out of battlefield - if (alienshoty[i] == SCREENHEIGHT - 1) { + if (alienshoty[i] == SCREENHEIGHT - 2) { alienshotx[i] = 0; // reload missile } else { aliensMissileDisplay(alienshotx[i], alienshoty[i]); // display Missile at new position diff --git a/globals.c b/globals.c index 8c0204c..a7ca058 100644 --- a/globals.c +++ b/globals.c @@ -72,7 +72,7 @@ void showUsage(void) fprintf(stderr, " where -l 0=NIGHTMARE\n"); fprintf(stderr, " -l 1=okay\n"); fprintf(stderr, " -l 9=May I play daddy?!\n"); - fprintf(stderr, "\n -gpl shows you the license file\n"); + fprintf(stderr, "\n -L display the distribution license\n"); } diff --git a/nInvaders.c b/nInvaders.c index 57a756d..d59b387 100644 --- a/nInvaders.c +++ b/nInvaders.c @@ -23,8 +23,11 @@ #include +#include #include #include +#include + #include "nInvaders.h" #include "player.h" #include "aliens.h" @@ -68,27 +71,32 @@ static void initLevel(void) */ static void evaluateCommandLine(int argc, char **argv) { - - // -l : set skill level - if (argc == 3 && strcmp(argv[1], "-l") == 0) { - if (argv[2][0] >= '0' && argv[2][0] <= '9') { - skill_level = argv[2][0] - 48; - } else { - argc = 2; + int ch, i; + + while ((ch = getopt(argc, argv, "?l:L")) != -1) { + switch (ch) { + case 'l': + if ((i = atoi(optarg)) > -1 && i < 10) + skill_level = i; + else { + showUsage(); + exit(EXIT_FAILURE); + } + break; + case 'L': + showGpl(); + exit(EXIT_SUCCESS); + break; + case '?': + default: /* FALLTHROUGH */ + showVersion(); + showUsage(); + exit(EXIT_FAILURE); + break; } } - - // -gpl : show GNU GPL - if (argc == 2 && strcmp(argv[1], "-gpl") == 0) { - showGpl(); - } - - // wrong command line: show usage - if (argc == 2 || (argc == 3 && strcmp(argv[1], "-l") != 0)) { - showVersion(); - showUsage(); - exit(1); - } + argc -= optind; + argv += optind; } @@ -349,8 +357,8 @@ int main(int argc, char **argv) // do movements and key-checking readInput(); } while (0 == 0); - - return 0; + + exit(EXIT_SUCCESS); } diff --git a/view.c b/view.c index 6196971..7e5b2f9 100644 --- a/view.c +++ b/view.c @@ -24,10 +24,12 @@ #include "view.h" #include "globals.h" +#include #include #include #include +/* Pairs */ #define RED 1 #define GREEN 2 #define YELLOW 3 @@ -36,6 +38,8 @@ #define MAGENTA 6 #define WHITE 7 +bool curses_initialized = false; + WINDOW *wBattleField; WINDOW *wEmpty; WINDOW *wScores; @@ -44,12 +48,15 @@ WINDOW *wPlayer; WINDOW *wPlayerMissile; WINDOW *wAliens; WINDOW *wAliensMissile; +WINDOW *wAliensMissile1; +WINDOW *wAliensMissile2; WINDOW *wBunkers; WINDOW *wGameOver; WINDOW *wUfo; WINDOW *wStatus; WINDOW *wTitleScreen; + /** * initialize player sprites */ @@ -171,10 +178,22 @@ void aliensClear(int x, int y, int wid, int hgt) */ static void aliensMissileInit(void) { - wAliensMissile = newpad(1, 1); // new pad - wclear(wAliensMissile); // clear pad - wattrset(wAliensMissile, COLOR_PAIR(CYAN)); // set color - waddch(wAliensMissile, ':'); // set sprite + wAliensMissile1 = newpad(2, 1); // new pad + wclear(wAliensMissile1); // clear pad + wattrset(wAliensMissile1, COLOR_PAIR(CYAN)); // set color + mvwaddch(wAliensMissile1, 0, 0, '|'); // set sprite + mvwaddch(wAliensMissile1, 1, 0, ')'); // set sprite + wrefresh(wAliensMissile1); + + wAliensMissile2 = newpad(2, 1); // new pad + wclear(wAliensMissile2); // clear pad + wattrset(wAliensMissile2, COLOR_PAIR(CYAN)); // set color + mvwaddch(wAliensMissile2, 0, 0, '('); // set sprite + mvwaddch(wAliensMissile2, 1, 0, '|'); // set sprite + wrefresh(wAliensMissile2); + + /* This pointer will alternate between the two shapes */ + wAliensMissile = wAliensMissile1; } @@ -183,7 +202,12 @@ static void aliensMissileInit(void) */ void aliensMissileDisplay(int x, int y) { - copywin(wAliensMissile,wBattleField,0,0,y,x,y,x,0); + int r = rand() % 2; + + copywin(wAliensMissile,wBattleField,0,0,y,x,y + 1,x,0); + + /* Toggle between shapes */ + wAliensMissile = (r == 0 ? wAliensMissile1 : wAliensMissile2); } @@ -192,7 +216,7 @@ void aliensMissileDisplay(int x, int y) */ void aliensMissileClear(int x, int y) { - copywin(wEmpty,wBattleField,0,0,y,x,y,x,0); + copywin(wEmpty,wBattleField,0,0,y,x,y + 1,x,0); } @@ -547,9 +571,16 @@ void refreshScreen(void) */ static void finish(int sig) { - curs_set(1); - endwin(); // reset terminal into proper non-visual mode - exit(0); + exit(EXIT_SUCCESS); +} + +static void cleanup(void) +{ + if (curses_initialized) { + curses_initialized = false; + (void) curs_set(1); + (void) endwin(); + } } @@ -558,8 +589,13 @@ static void finish(int sig) */ void graphicEngineInit(void) { + (void) atexit(cleanup); + (void) signal(SIGINT, finish); // on signal "SIGINT" call method "finish" + (void) initscr(); // do initialization work + curses_initialized = true; + curs_set(0); keypad(stdscr, TRUE); // enable keypad for input (void) nonl(); // disable translation return/ newline for detection of return key