📄 main.c
字号:
#ifndef lintstatic char *sccsid = "@(#)main.c 4.2 (ULTRIX) 9/1/88";#endif lint/************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/* * main.c * * Name: starship * Purpose: Main, curses setup, shared mem setup. * Usage: starship [-bs] * Environment: Ultrix-32, optionally with shared memory * Compile: see Makefile * Date: April 18, 1985 * Author: Al Delorey * Remarks: These are the voyages of the independent star ships.Whose lifetime mission: To explore strange new galaxies, To seek out and destroy other star ships, To boldly go where no other star ship dares!*//* * Modification history * * 4-18-85 * Derived from former file "one.c" which had main & cmd input * together. Main & cmd input are now split into main.c & cmd.c */#include "star.h"#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <curses.h>#include <signal.h>#include <fcntl.h>#include <sys/file.h>#include <errno.h>/* Global to the program - Will be externals in other files */struct univ *uptr; /* ptr to global data struct */WINDOW *scanwin; /* for sub window: short & long range scan */#ifdef SHMEMint shmid; /* shared memorey id */char *shmat(); /* shared mem attach routine */#endif SHMEM/* Define new access paths to variables that are now in "univ" struct, * to facilitate shared memory. */#define universe uptr->quadrants#define num_users uptr->Num_users#define wait uptr->Wait#define ships uptr->Ships#define drones uptr->Dronesint scanf_cc; /* char count accumulated in scanf_buf */char scanf_buf [READSIZE]; /* cmd input buffer */boolean clr_cmd_flag; /* true to clear cmd line */char local_ship; /* char to represent ship */boolean redraw; /* set true in "scanf_input" by N command */boolean gotchar; /* set true when input char read, false when echoed */char esc; /* esc char */char bell; /* bell char or null if no bell option in use */boolean userabort; /* set true if user quits */extern int errno;/* local variables */struct sigvec *vec; /* signal vector for asynch input */int sflag; /* slower screen update if set */unsigned int pausetime; /* pause longer if -s flag used */int dafter; /* incr once for each drone after you *//* for average kills per game, score keeping */char *home; /* for environment var "HOME" */char scorepath[50]; /* path to user's HOME/.starship */int games; /* number of games played, from .starship */int kills; /* number of total kills, from .starship */float ave; /* average (kills/games) */int ruid; /* real uid */boolean mustcreate = false;/* function declarations */char *getenv(); /* to get the tty type out of the environ var */FILE *fopen(); /* to keep average number of kills per game */char *calloc(); /* funct type decl */int scanf_input(); /* funct type decl for signal vector *//*****************************************************************************//* *//* START INTERNAL PROCEDURES *//* *//*****************************************************************************/main (argc,argv) int argc; char *argv[]; { int i; /* loop index to move thru drones array */ register struct ship *pships; /* Process command line arguments */ bell='\07'; for(i = 1; argc>1 && argv[i][0]=='-'; argc--,i++) switch(argv[i][1]) { case 's': /* slower screen update; good for dialup */ sflag++; continue; case 'b': bell='\0'; continue; } /* * Before call to shmget due to 8k malloc limit after shmget */ if (initscr() == ERR) { printf ("%s: initscr() failed\n", argv[0]); exit(-1); } if ((scanwin = subwin(stdscr,SRSCANROWS+2,MAPDISPC,0,0)) == ERR) { printf ("%s: subwin() failed\n", argv[0]); exit(-1); } if (sflag) pausetime = 2; else pausetime = 1; /* * Get user's average score. */ getave(); /* * Create and attach to shared memory segment. * RACE CONDITION POTENTIAL: if the shared mem seg does not exist yet, * and more than 1 process starts to create it, we could get more * than 1 shared memory segment. * NOTE: We attach the shared memory segment 64k above current end * of process space to leave room for other mallocs. */# ifdef SHMEM if ((shmid = shmget(ftok("/usr/games/starship", 'a'), sizeof(struct univ), IPC_CREAT | 0666)) < 0) { printf("%s: shmget failed, errno = %d\n", argv[0], errno); perror("starship"); exit(-1); } if ((uptr = (struct univ *) shmat(shmid, sbrk(0) + 64*1024, 0)) < 0) { printf("%s: shmat failed, errno = %d\n", argv[0], errno); perror("starship"); exit(-1); }# else uptr = (struct univ *) malloc(sizeof(struct univ));# endif SHMEM /* * Ignore signals that would exit the process ungracefully */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); /* * RACE CONDITION POTENTIAL: if num_users == 0, and more than one * process enters this section of code before one of them sets * num_users to 1, the data base could get initialized twice. */ if (num_users == 0) { /* you are the first user */ num_users = 1; wait = true; /* we will make other players wait for db inits */ init_d_s(); } else { /* not 1st player */ num_users++; while (wait) ; /* wait for global inits to be done */ }; /* * Do local initializations, print instructions (& get ship name), */ local_init(); instructs(); pships = ships + (local_ship - A); pships->avekills = ave;# ifndef DEBUG noecho(); crmode();# endif draw_screen();# ifndef DEBUG# ifdef ASYNC /* This section sets up: * 1. the handler routine (scanf_input) for asynchronous input. * 2. the signal to catch & handle (SIGIO). */ vec = (struct sigvec *) calloc (1, sizeof (struct sigvec)); if (vec == NULL) { perror("starship (sigvec calloc)"); exit(-1); } vec->sv_handler = scanf_input; vec->sv_mask = SIGIO; vec->sv_onstack = 0; /* fcntl enables SIGIO for the file descriptor 0 (stdin) */ if (fcntl (0, F_SETFL, FASYNC) == -1) { fprintf (stderr, "sigin: fcntl call failed\n"); perror ("sigin"); exit (-1); } /* Call sigvec to activate signal handling (of SIGIO on stdin) */ sigvec (SIGIO, vec, 0);# endif ASYNC# endif DEBUG /* loop until ship out of energy */ for (; pships->energy > 0 || pships->shields > 0;) {# ifndef DEBUG# ifndef ASYNC /* * Only sleep for 1/4 second at a time so that we can keep * checking for cmd input. Sleep enough 1/4 seconds to add * up to "pausetime" seconds. */ for (i = 0; i < 4 * pausetime; i++) { starsleep(0, 250000); /* 250,000 usec => 1/4 sec */ scanf_input(); }# else ASYNC starsleep(pausetime,0);# endif ASYNC# else DEBUG scanf_input();# endif DEBUG if (userabort) break; if (redraw) redraw_screen(); /* re-draw entire screen */ ship_action (local_ship); /* carry out commands, move_to torps */ update_screen (local_ship); /* change screen image */# ifdef DRONE /* If you are fighting the drone, run the drone */ if (dafter) { for (i = 0; i < NUMDRONES; i++) if (drones[i].d_after == local_ship) run_drone(i); }# endif if (clr_cmd_flag) { move_to (COMMANDR,COMMANDC); clear_to_eol(); refresh_scr(); clr_cmd_flag = false; }; } /* * Call update_screen one last time to show what killed the ship, * save number of kills, exit the ship from the game, then update * the .starship score file (done last since it changes effective uid). */ update_screen (local_ship); kills += ships[local_ship - A].kills; exit_a_ship (local_ship, false); /* clean-up & exit */ saveave(); /* restore tty */# ifndef DEBUG nocrmode(); echo();# endif endwin(); } /* end main */string_out(str) char *str; /* Handle output of a string. */ { addstr(str); }char_out(ch) char ch; /* Handle output of a char. */ { addch(ch); }move_to(row,col) int row,col; /* Handle moving to row,col. */ { move(row,col); }refresh_scr() /* cause screen to be updated. */ { refresh(); }clear_screen() /* Handle clearing the screen. */ { clear(); }clear_to_eol() /* Handle clearing to eol. */ { clrtoeol(); }local_init() /* Initialize local variables (global to main star). * and set up for unsolicited input. */ { clr_cmd_flag = false; userabort = false; redraw = false; scanf_cc = 0; gotchar = false; dafter = 0; }; /* proc local_init */getave() /* * Get average number of kills per game out of user's home directory. * We keep a .starship there with 2 integer numbers in it: * 1. the number of games played, 2. the total number of kills. * * The games and kills read from the file go into the global var's * "games" and "kills" to be used to update the file at exit time. */ { FILE *fp; /* file ptr to HOME/.starship */ if ((home = getenv("HOME")) == NULL) printf("Cannot access `HOME' environment variable"); else { strcpy(scorepath, home); strcat(scorepath, "/.starship"); /* * Attempt to open score file. */ if ((fp = fopen(scorepath, "r")) == NULL) { mustcreate = true; ave = 0; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -