📄 cmd.c
字号:
#ifndef lintstatic char *sccsid = "@(#)cmd.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. * * * ************************************************************************/* * cmd.c * * Name: starship * Purpose: command input. * 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>/* externals from main */extern struct univ *uptr; /* ptr to global data struct */extern WINDOW *scanwin; /* for sub window: short & long range scan *//* 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->Dronesextern int scanf_cc; /* char count accumulated in scanf_buf */extern char esc; /* esc char */extern char bell; /* bell char or null if no bell option in use */extern boolean userabort; /* set true if user quits */extern int errno;extern char scanf_buf [READSIZE]; /* cmd input buffer */extern char clr_cmd [12]; /* esc seq to clear cmd line */extern boolean clr_cmd_flag; /* true to clear cmd line */extern char local_ship; /* char to represent ship */extern boolean redraw; /* set true in "scanf_input" by N command */extern boolean gotchar; /* set true when input char read, false when echoed */extern int dafter; /* incr once for each drone after you *//* local variables */long int ioctl_cc; /* char count returned by ioctl *//*****************************************************************************//* *//* START INTERNAL PROCEDURES *//* *//*****************************************************************************/cvt_int (char_str, loc) char *char_str; int loc; /* CVT char string to int #. The function allows an optional +/- and upto 50000 for the int. for example: -35000 Params: char_str - char string that the number is in. loc - location within char_str where # starts. */ { int t_int; /* temp var */ boolean neg; /* set true if negative (-) */ int i; /* string index */ neg = false; i = loc; t_int = 0; if (char_str[i] == '-') { neg = true; i++; } else if (char_str[i] == '+') i++; for (; char_str [i] >= '0' && char_str [i] <= '9' && (t_int < 50000) ;) { t_int = t_int * 10 + ((int)char_str[i] - 48); i++; }; if (neg) t_int = - t_int; return (t_int); }; /* cvt_int */use_phasers() /* Called by scanf_input when user fires phasers. * Calls shipinrange() to determine if enemy ship is close enough * to hit, & if so, what its distance is. */ { register struct ship *pships; int dist; /* # of sectors away enemy ship is */ char ship_ch; /* ship hit by phaser */ int bearing; /* unused here, but needed as a param to shipinrange */ boolean ontarget; /* unused here, but needed as a param to shipinrange */ pships = ships + (local_ship - A); if (pships->phasers != 0) { strcpy (pships->msg_buf, "Phasers inoperative!"); pships->dis_msg = true; return; }; if (pships->docked) { strcpy (pships->msg_buf, "Can't fire when docked!"); pships->dis_msg = true; return; }; if (pships->cloak) { strcpy (pships->msg_buf, "Can't fire when cloaked!"); pships->dis_msg = true; return; }; ship_ch = scanf_buf[1]; if (ship_ch >= 'A' && ship_ch <= 'Z') { /* check to see if ship within phaser range */ if (ships[ship_ch - 'A'].cloak) { strcpy(pships->msg_buf, "Ship not in phaser range"); pships->dis_msg = true; return; }; if (shipinrange(local_ship,ship_ch,PHSRANGE,true,&dist,&bearing,&ontarget)) fire_phasers(local_ship, ship_ch, dist); else { pships = ships + (local_ship - A); strcpy(pships->msg_buf, "Ship not in phaser range"); pships->dis_msg = true; } } /* in A..Z */ }; /* proc use_phasers */fire_phasers(fireship, atship, dist) char fireship; /* ship firing */ char atship; /* ship being fired at */ int dist; /* distance between ships */ /* * Ship was found, by shipinrange(), to be within range, so this * routine is called to fire phasers. * Used by local ship & by drones. */ { register struct ship *pships; register int t_int; /* temp int. */ pships = ships + (fireship - A); if (PHASER_COST > pships->energy) t_int = pships->energy / 2; else t_int = PHASER_COST; pships->energy -= t_int; pships->dis_energy = true; /* calculate amount of hit based on the "dist" */ switch (dist) { case 0: case 1: t_int = (0.90 * t_int); break; case 2: t_int = (0.80 * t_int); break; case 3: t_int = (0.70 * t_int); break; case 4: t_int = (0.60 * t_int); break; case 5: t_int = (0.50 * t_int); break; default: t_int = 0; }; pships = ships + (atship - A); pships->dis_shields = true; pships->glow = 1; sprintf (pships->msg_buf, "Ship hit by phaser-%d",t_int); pships->dis_msg = true; if (pships->shields >= t_int) pships->shields = pships->shields - t_int; else { t_int = t_int - pships->shields; pships->energy = pships->energy-t_int; pships->dis_energy = true; pships->shields = 0; /* if phasored ship died, give attacker a kill! */ if (pships->energy <= 0) { universe[pships->q_row][pships->q_col].sectors [pships->s_row][pships->s_col].image = '-'; pships = ships + (fireship - A); pships->kills++; sprintf (pships->msg_buf, "The %s is destroyed",ships[atship-A].name); pships->dis_msg = true; } else damage (atship, t_int); } };locate (srow, scol, row, col) register int srow, scol; /* quad. row of col of local ship */ int *row, *col; /* quad. row & col of ship to return */ /* * Attempt to locate a ship near to "local ship". If one is found * its quadrant coordinates are returned in "row" & "col". */ { register struct ship *pships; char ch; register int lowest = 100; register int temp; for (ch = 'A'; ch <= 'Z'; ch++) { pships = ships + (ch - A); if ((pships->ship_ch != ' ') && (pships->ship_ch != local_ship)) { temp = abs(srow - pships->q_row) + abs(scol - pships->q_col); if (temp < lowest) { lowest = temp; *row = pships->q_row; *col = pships->q_col; } } } };scanf_input() /* tty input routine for user commands. 1st it clears the cmd line. */ { register int i; /* loop index */ char in_ch; /* input char */ boolean docmd; /* set true when cmd completed (by RETURN key) */ docmd = false;# ifdef DEBUG move_to (COMMANDR,COMMANDC); refresh_scr(); scanf("%s",scanf_buf); upcase (scanf_buf); docmd = true;# else DEBUG /* use ioctl call to see if any chars in input buffer, * if so, loop here and read 'ioctl_cc' characters. */ ioctl(0,FIONREAD,&ioctl_cc); for (i = 0; i < ioctl_cc; i++) {# ifdef ASYNC scanf("%c",&in_ch);# else read(0,&in_ch,1);# endif upchar (&in_ch); switch (scanf_cc) { case 0: /* 1st char */ switch (in_ch) { /* single char commands */ case 'C': case 'D': case 'G': case 'L': case 'M': case 'N': case 'Z': case '1': case '2': case '3': case '4': case '6': case '7': case '8': case '9': move_to (COMMANDR,COMMANDC + scanf_cc); char_out (in_ch); refresh_scr(); scanf_buf[scanf_cc] = in_ch; scanf_cc++; scanf_buf[scanf_cc] = '\0'; docmd = true; break; /* multi-char commands */ case 'I': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'W': case 'X': move_to (COMMANDR,COMMANDC + scanf_cc); char_out (in_ch); refresh_scr(); scanf_buf[scanf_cc] = in_ch; scanf_cc++; scanf_buf[scanf_cc] = '\0'; break; case 'E': if (local_ship == 'E') { move_to (COMMANDR,COMMANDC + scanf_cc); char_out (in_ch); refresh_scr(); scanf_buf[scanf_cc] = in_ch; scanf_cc++; scanf_buf[scanf_cc] = '\0'; docmd = true; } break; /* unrecognized cmds, ignore */ default: break; } break; case 1: /* 2nd char */ switch (in_ch) { case '\010': case '\177': /* backspace and delete */ if (scanf_cc > 0) { scanf_cc--; scanf_buf [scanf_cc] = '\0'; move_to (COMMANDR, COMMANDC + scanf_cc); char_out (' '); refresh_scr(); }; break; case '\025': /* ^U (erase line) */ if (scanf_cc > 0) { scanf_cc = 0; scanf_buf[0] = '\0'; move_to (COMMANDR, COMMANDC); clear_to_eol(); refresh_scr(); }; break; case RETURN: docmd = true; scanf_buf[scanf_cc] = '\0'; break; default: switch (scanf_buf[0]) { /* 2 char cmds */ case 'I': case 'P': case 'T': case 'W': case 'X': docmd = true; /* fall into */ default: move_to (COMMANDR,COMMANDC + scanf_cc); char_out (in_ch); refresh_scr(); scanf_buf[scanf_cc] = in_ch; scanf_cc++; scanf_buf[scanf_cc] = '\0'; break; } break; } /* end switch (in_char) */ break; case 2: /* 3rd char */ switch (in_ch) { case '\010': case '\177': /* backspace and delete */ if (scanf_cc > 0) { scanf_cc--; scanf_buf [scanf_cc] = '\0'; move_to (COMMANDR, COMMANDC + scanf_cc); char_out (' '); refresh_scr(); }; break; case '\025': /* ^U (erase line) */ if (scanf_cc > 0) { scanf_cc = 0; scanf_buf[0] = '\0'; move_to (COMMANDR, COMMANDC); clear_to_eol(); refresh_scr(); }; break; case RETURN: docmd = true; scanf_buf[scanf_cc] = '\0'; break; default: switch (scanf_buf[0]) { /* 3 char cmds */ case 'S': docmd = true; /* fall into */ default: move_to (COMMANDR,COMMANDC + scanf_cc); char_out (in_ch); refresh_scr(); scanf_buf[scanf_cc] = in_ch; scanf_cc++; scanf_buf[scanf_cc] = '\0'; break; } break; } /* end switch (in_char) */ break; default: /* 4th char & above */ switch(in_ch) { case '\010': case '\177': /* backspace and delete */ if (scanf_cc > 0) { scanf_cc--; scanf_buf [scanf_cc] = '\0'; move_to (COMMANDR, COMMANDC + scanf_cc); char_out (' '); refresh_scr(); }; break; case '\025': /* ^U (erase line) */ if (scanf_cc > 0) { scanf_cc = 0; scanf_buf[0] = '\0'; move_to (COMMANDR, COMMANDC); clear_to_eol(); refresh_scr(); }; break; case RETURN: docmd = true; scanf_buf[scanf_cc] = '\0'; break; default: move_to (COMMANDR,COMMANDC + scanf_cc); char_out (in_ch); refresh_scr(); scanf_buf[scanf_cc] = in_ch; scanf_cc++; scanf_buf[scanf_cc] = '\0'; break; } } /* end switch (scanf_cc) */ }; /* for */ /* if cmd not finished yet then return to caller */ if (!docmd) return; clr_cmd_flag = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -