--- /dev/null
+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.
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;
}
// 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
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
+#include <unistd.h>
+
#include "nInvaders.h"
#include "player.h"
#include "aliens.h"
*/
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;
}
// do movements and key-checking
readInput();
} while (0 == 0);
-
- return 0;
+
+ exit(EXIT_SUCCESS);
}
#include "view.h"
#include "globals.h"
+#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
+/* Pairs */
#define RED 1
#define GREEN 2
#define YELLOW 3
#define MAGENTA 6
#define WHITE 7
+bool curses_initialized = false;
+
WINDOW *wBattleField;
WINDOW *wEmpty;
WINDOW *wScores;
WINDOW *wPlayerMissile;
WINDOW *wAliens;
WINDOW *wAliensMissile;
+WINDOW *wAliensMissile1;
+WINDOW *wAliensMissile2;
WINDOW *wBunkers;
WINDOW *wGameOver;
WINDOW *wUfo;
WINDOW *wStatus;
WINDOW *wTitleScreen;
+
/**
* initialize player sprites
*/
*/
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;
}
*/
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);
}
*/
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);
}
*/
static void finish(int sig)
{
- curs_set(1);
- endwin(); // <curses.h> 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();
+ }
}
*/
void graphicEngineInit(void)
{
+ (void) atexit(cleanup);
+
(void) signal(SIGINT, finish); // <signal.h> on signal "SIGINT" call method "finish"
+
(void) initscr(); // <curses.h> do initialization work
+ curses_initialized = true;
+
curs_set(0);
keypad(stdscr, TRUE); // <curses.h> enable keypad for input
(void) nonl(); // <curses.h> disable translation return/ newline for detection of return key