From 7b728a631c9003a1e68026d9619af346838b0be3 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Mon, 29 Jul 2019 12:43:57 +0200 Subject: [PATCH] sail(6): Sync with NetBSD. This, among other things, fixes an old curses related bug that caused FreeBSD ports to take NetBSD's instead of ours (the games/bsdgames port takes our source as the distfile). They've since switched to debian's sail. See https://svnweb.freebsd.org/ports?view=revision&revision=495354 --- games/sail/Makefile | 2 +- games/sail/array.c | 123 +++ games/sail/array.h | 239 +++++ games/sail/assorted.c | 111 ++- games/sail/display.h | 44 + games/sail/dr_1.c | 150 ++-- games/sail/dr_2.c | 148 ++-- games/sail/dr_3.c | 105 ++- games/sail/dr_4.c | 33 +- games/sail/dr_5.c | 31 +- games/sail/dr_main.c | 81 +- games/sail/driver.h | 10 +- games/sail/{externs.h => extern.h} | 251 +++--- games/sail/game.c | 23 +- games/sail/globals.c | 98 ++- games/sail/lo_main.c | 110 ++- games/sail/machdep.h | 21 +- games/sail/main.c | 127 ++- games/sail/misc.c | 53 +- games/sail/parties.c | 37 +- games/sail/pathnames.h | 7 + games/sail/pl_1.c | 57 +- games/sail/pl_2.c | 118 ++- games/sail/pl_3.c | 116 +-- games/sail/pl_4.c | 42 +- games/sail/pl_5.c | 124 ++- games/sail/pl_6.c | 62 +- games/sail/pl_7.c | 1318 +++++++++++++++++++++++++--- games/sail/pl_main.c | 232 ++--- games/sail/player.h | 42 +- games/sail/restart.h | 32 + games/sail/sail.6 | 713 ++++++++------- games/sail/sync.c | 1021 ++++++++++++++++----- games/sail/version.c | 19 +- 34 files changed, 4103 insertions(+), 1597 deletions(-) create mode 100644 games/sail/array.c create mode 100644 games/sail/array.h create mode 100644 games/sail/display.h rename games/sail/{externs.h => extern.h} (59%) create mode 100644 games/sail/restart.h diff --git a/games/sail/Makefile b/games/sail/Makefile index bd22669b42..10c6c427ff 100644 --- a/games/sail/Makefile +++ b/games/sail/Makefile @@ -4,7 +4,7 @@ PROG= sail SRCS= main.c pl_main.c pl_1.c pl_2.c pl_3.c pl_4.c pl_5.c pl_6.c pl_7.c \ dr_main.c dr_1.c dr_2.c dr_3.c dr_4.c dr_5.c lo_main.c \ - assorted.c game.c globals.c misc.c parties.c sync.c version.c + array.c assorted.c game.c globals.c misc.c parties.c sync.c version.c MAN= sail.6 VARGAMES= GAMESCURSES= diff --git a/games/sail/array.c b/games/sail/array.c new file mode 100644 index 0000000000..af848e1b2c --- /dev/null +++ b/games/sail/array.c @@ -0,0 +1,123 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#define ARRAYINLINE +#include "array.h" + +struct array * +array_create(void) +{ + struct array *a; + + a = malloc(sizeof(*a)); + if (a != NULL) { + array_init(a); + } + return a; +} + +void +array_destroy(struct array *a) +{ + array_cleanup(a); + free(a); +} + +void +array_init(struct array *a) +{ + a->num = a->max = 0; + a->v = NULL; +} + +void +array_cleanup(struct array *a) +{ + arrayassert(a->num == 0); + free(a->v); +#ifdef ARRAYS_CHECKED + a->v = NULL; +#endif +} + +int +array_setsize(struct array *a, unsigned num) +{ + unsigned newmax; + void **newptr; + + if (num > a->max) { + newmax = a->max; + while (num > newmax) { + newmax = newmax ? newmax*2 : 4; + } + newptr = realloc(a->v, newmax*sizeof(*a->v)); + if (newptr == NULL) { + return -1; + } + a->v = newptr; + a->max = newmax; + } + a->num = num; + return 0; +} + +int +array_insert(struct array *a, unsigned index_) +{ + unsigned movers; + + arrayassert(a->num <= a->max); + arrayassert(index_ < a->num); + + movers = a->num - index_; + + if (array_setsize(a, a->num + 1)) { + return -1; + } + + memmove(a->v + index_+1, a->v + index_, movers*sizeof(*a->v)); + return 0; +} + +void +array_remove(struct array *a, unsigned index_) +{ + unsigned movers; + + arrayassert(a->num <= a->max); + arrayassert(index_ < a->num); + + movers = a->num - (index_ + 1); + memmove(a->v + index_, a->v + index_+1, movers*sizeof(*a->v)); + a->num--; +} diff --git a/games/sail/array.h b/games/sail/array.h new file mode 100644 index 0000000000..e605bd41cf --- /dev/null +++ b/games/sail/array.h @@ -0,0 +1,239 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ARRAY_H +#define ARRAY_H + +#define ARRAYS_CHECKED + +#ifdef ARRAYS_CHECKED +#include +#define arrayassert assert +#else +#define arrayassert(x) ((void)(x)) +#endif + +//////////////////////////////////////////////////////////// +// type and base operations + +struct array { + void **v; + unsigned num, max; +}; + +struct array *array_create(void); +void array_destroy(struct array *); +void array_init(struct array *); +void array_cleanup(struct array *); +unsigned array_num(const struct array *); +void *array_get(const struct array *, unsigned index_); +void array_set(const struct array *, unsigned index_, void *val); +int array_setsize(struct array *, unsigned num); +int array_add(struct array *, void *val, unsigned *index_ret); +int array_insert(struct array *a, unsigned index_); +void array_remove(struct array *a, unsigned index_); + +//////////////////////////////////////////////////////////// +// inlining for base operations + +#ifndef ARRAYINLINE +#define ARRAYINLINE extern __attribute__((__gnu_inline__)) __inline +#endif + +ARRAYINLINE unsigned +array_num(const struct array *a) +{ + return a->num; +} + +ARRAYINLINE void * +array_get(const struct array *a, unsigned index_) +{ + arrayassert(index_ < a->num); + return a->v[index_]; +} + +ARRAYINLINE void +array_set(const struct array *a, unsigned index_, void *val) +{ + arrayassert(index_ < a->num); + a->v[index_] = val; +} + +ARRAYINLINE int +array_add(struct array *a, void *val, unsigned *index_ret) +{ + unsigned index_ = a->num; + if (array_setsize(a, index_+1)) { + return -1; + } + a->v[index_] = val; + if (index_ret != NULL) { + *index_ret = index_; + } + return 0; +} + +//////////////////////////////////////////////////////////// +// bits for declaring and defining typed arrays + +/* + * Usage: + * + * DECLARRAY_BYTYPE(foo, bar) declares "struct foo", which is + * an array of pointers to "bar", plus the operations on it. + * + * DECLARRAY(foo) is equivalent to DECLARRAY_BYTYPE(fooarray, struct foo). + * + * DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that + * they define the operations, and both take an extra argument INLINE. + * For C99 this should be INLINE in header files and empty in the + * master source file, the same as the usage of ARRAYINLINE above and + * in array.c. + * + * Example usage in e.g. item.h of some game: + * + * DECLARRAY_BYTYPE(stringarray, char); + * DECLARRAY(potion); + * DECLARRAY(sword); + * + * #ifndef ITEMINLINE + * #define ITEMINLINE INLINE + * #endif + * + * DEFARRAY_BYTYPE(stringarray, char, ITEMINLINE); + * DEFARRAY(potion, ITEMINLINE); + * DEFARRAY(sword, ITEMINLINE); + * + * Then item.c would do "#define ITEMINLINE" before including item.h. + */ + +#define DECLARRAY_BYTYPE(ARRAY, T) \ + struct ARRAY { \ + struct array arr; \ + }; \ + \ + struct ARRAY *ARRAY##_create(void); \ + void ARRAY##_destroy(struct ARRAY *a); \ + void ARRAY##_init(struct ARRAY *a); \ + void ARRAY##_cleanup(struct ARRAY *a); \ + unsigned ARRAY##_num(const struct ARRAY *a); \ + T *ARRAY##_get(const struct ARRAY *a, unsigned index_); \ + void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \ + int ARRAY##_setsize(struct ARRAY *a, unsigned num); \ + int ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret); \ + int ARRAY##_insert(struct ARRAY *a, unsigned index_); \ + void ARRAY##_remove(struct ARRAY *a, unsigned index_) + + +#define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \ + INLINE void \ + ARRAY##_init(struct ARRAY *a) \ + { \ + array_init(&a->arr); \ + } \ + \ + INLINE void \ + ARRAY##_cleanup(struct ARRAY *a) \ + { \ + array_cleanup(&a->arr); \ + } \ + \ + INLINE struct \ + ARRAY *ARRAY##_create(void) \ + { \ + struct ARRAY *a; \ + \ + a = malloc(sizeof(*a)); \ + if (a == NULL) { \ + return NULL; \ + } \ + ARRAY##_init(a); \ + return a; \ + } \ + \ + INLINE void \ + ARRAY##_destroy(struct ARRAY *a) \ + { \ + ARRAY##_cleanup(a); \ + free(a); \ + } \ + \ + INLINE unsigned \ + ARRAY##_num(const struct ARRAY *a) \ + { \ + return array_num(&a->arr); \ + } \ + \ + INLINE T * \ + ARRAY##_get(const struct ARRAY *a, unsigned index_) \ + { \ + return (T *)array_get(&a->arr, index_); \ + } \ + \ + INLINE void \ + ARRAY##_set(struct ARRAY *a, unsigned index_, T *val) \ + { \ + array_set(&a->arr, index_, (void *)val); \ + } \ + \ + INLINE int \ + ARRAY##_setsize(struct ARRAY *a, unsigned num) \ + { \ + return array_setsize(&a->arr, num); \ + } \ + \ + INLINE int \ + ARRAY##_add(struct ARRAY *a, T *val, unsigned *ret) \ + { \ + return array_add(&a->arr, (void *)val, ret); \ + } \ + \ + INLINE int \ + ARRAY##_insert(struct ARRAY *a, unsigned index_) \ + { \ + return array_insert(&a->arr, index_); \ + } \ + \ + INLINE void \ + ARRAY##_remove(struct ARRAY *a, unsigned index_) \ + { \ + return array_remove(&a->arr, index_); \ + } + +#define DECLARRAY(T) DECLARRAY_BYTYPE(T##array, struct T) +#define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE) + +//////////////////////////////////////////////////////////// +// basic array types + +DECLARRAY_BYTYPE(stringarray, char); +DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE); + +#endif /* ARRAY_H */ diff --git a/games/sail/assorted.c b/games/sail/assorted.c index 04584e4bc2..7c35d5c663 100644 --- a/games/sail/assorted.c +++ b/games/sail/assorted.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: assorted.c,v 1.19 2011/08/16 11:26:16 christos Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,19 +27,26 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)assorted.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/assorted.c,v 1.5 1999/11/30 03:49:31 billf Exp $ - * $DragonFly: src/games/sail/assorted.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)assorted.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: assorted.c,v 1.19 2011/08/16 11:26:16 christos Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include "extern.h" static void strike(struct ship *, struct ship *); void -table(int rig, int shot, int hittable, - struct ship *on, struct ship *from, int roll) +table(struct ship *from, struct ship *on, + int rig, int shot, int hittable, int roll) { int hhits = 0, chits = 0, ghits = 0, rhits = 0; int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0; @@ -45,8 +54,8 @@ table(int rig, int shot, int hittable, int crew[3]; int n; int rigg[4]; - const char *message = NULL; - struct Tables *tp; + const char *message; + const struct Tables *tp; pc = on->file->pcrew; hull = on->specs->hull; @@ -101,7 +110,7 @@ table(int rig, int shot, int hittable, rigg[3] -= rhits; } if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1)) - makesignal(on, "dismasted!", NULL); + makemsg(on, "dismasted!"); if (portside(from, on, 0)) { guns = on->specs->gunR; car = on->specs->carR; @@ -124,36 +133,44 @@ table(int rig, int shot, int hittable, ghits = 0; } hull -= ghits; - if (Ghit) - Write(portside(from, on, 0) ? W_GUNR : W_GUNL, - on, guns, car, 0, 0); + if (Ghit) { + if (portside(from, on, 0)) { + send_gunr(on, guns, car); + } else { + send_gunl(on, guns, car); + } + } hull -= hhits; hull = hull < 0 ? 0 : hull; if (on->file->captured != 0 && Chit) - Write(W_PCREW, on, pc, 0, 0, 0); + send_pcrew(on, pc); if (Hhit) - Write(W_HULL, on, hull, 0, 0, 0); + send_hull(on, hull); if (Chit) - Write(W_CREW, on, crew[0], crew[1], crew[2], 0); + send_crew(on, crew[0], crew[1], crew[2]); if (Rhit) - Write(W_RIGG, on, rigg[0], rigg[1], rigg[2], rigg[3]); + send_rigg(on, rigg[0], rigg[1], rigg[2], rigg[3]); switch (shot) { case L_ROUND: - message = "firing round shot on %s (%c%c)"; + message = "firing round"; break; case L_GRAPE: - message = "firing grape shot on %s (%c%c)"; + message = "firing grape"; break; case L_CHAIN: - message = "firing chain shot on %s (%c%c)"; + message = "firing chain"; break; case L_DOUBLE: - message = "firing double shot on %s (%c%c)"; + message = "firing double"; break; case L_EXPLODE: - message = "exploding shot on %s (%c%c)"; + message = "exploding"; + break; + default: + errx(1, "Unknown shot type %d", shot); + } - makesignal(from, message, on); + makesignal(from, "%s shot on $$", on, message); if (roll == 6 && rig) { switch(Rhit) { case 0: @@ -177,8 +194,10 @@ table(int rig, int shot, int hittable, case 7: message = "main topmast and mizzen mast shattered"; break; + default: + errx(1, "Bad Rhit = %d", Rhit); } - makesignal(on, message, NULL); + makemsg(on, "%s", message); } else if (roll == 6) { switch (Hhit) { case 0: @@ -198,28 +217,44 @@ table(int rig, int shot, int hittable, break; case 5: message = "rudder cables shot through"; - Write(W_TA, on, 0, 0, 0, 0); + send_ta(on, 0); break; case 6: message = "shot holes below the water line"; break; + default: + errx(1, "Bad Hhit = %d", Hhit); + } + makemsg(on, "%s", message); + } + /* + if (Chit > 1 && on->file->readyL & R_INITIAL && + on->file->readyR & R_INITIAL) { + on->specs->qual--; + if (on->specs->qual <= 0) { + makemsg(on, "crew mutinying!"); + on->specs->qual = 5; + Write(W_CAPTURED, on, on->file->index, 0, 0, 0); + } else { + makemsg(on, "crew demoralized"); } - makesignal(on, message, NULL); + Write(W_QUAL, on, on->specs->qual, 0, 0, 0); } + */ if (!hull) strike(on, from); } void -Cleansnag(struct ship *from, struct ship *to, char all, char flag) +Cleansnag(struct ship *from, struct ship *to, int all, int flag) { if (flag & 1) { - Write(W_UNGRAP, from, to->file->index, all, 0, 0); - Write(W_UNGRAP, to, from->file->index, all, 0, 0); + send_ungrap(from, to->file->index, all); + send_ungrap(to, from->file->index, all); } if (flag & 2) { - Write(W_UNFOUL, from, to->file->index, all, 0, 0); - Write(W_UNFOUL, to, from->file->index, all, 0, 0); + send_unfoul(from, to->file->index, all); + send_unfoul(to, from->file->index, all); } if (!snagged2(from, to)) { if (!snagged(from)) { @@ -242,20 +277,20 @@ strike(struct ship *ship, struct ship *from) if (ship->file->struck) return; - Write(W_STRUCK, ship, 1, 0, 0, 0); + send_struck(ship, 1); points = ship->specs->pts + from->file->points; - Write(W_POINTS, from, points, 0, 0, 0); + send_points(from, points); unboard(ship, ship, 0); /* all offense */ unboard(ship, ship, 1); /* all defense */ - switch (die()) { + switch (dieroll()) { case 3: case 4: /* ship may sink */ - Write(W_SINK, ship, 1, 0, 0, 0); + send_sink(ship, 1); break; case 5: case 6: /* ship may explode */ - Write(W_EXPLODE, ship, 1, 0, 0, 0); + send_explode(ship, 1); break; } - Writestr(W_SIGNAL, ship, "striking her colours!"); + send_signal(ship, "striking her colours!"); } diff --git a/games/sail/display.h b/games/sail/display.h new file mode 100644 index 0000000000..5826a2ed0b --- /dev/null +++ b/games/sail/display.h @@ -0,0 +1,44 @@ +/* $NetBSD: display.h,v 1.7 2009/03/15 03:33:56 dholland Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +void display_set_obp(int which, bool show); +void display_set_dbp(int which, bool show); + +void display_scroll_pageup(void); +void display_scroll_pagedown(void); +void display_adjust_view(void); + +void display_hide_prompt(void); +void display_reshow_prompt(void); +void display_force_full_redraw(void); +void display_redraw(void); diff --git a/games/sail/dr_1.c b/games/sail/dr_1.c index 6c1499e446..3a332410a0 100644 --- a/games/sail/dr_1.c +++ b/games/sail/dr_1.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: dr_1.c,v 1.27 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,11 +27,22 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dr_1.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/dr_1.c,v 1.7 1999/11/30 03:49:32 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dr_1.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: dr_1.c,v 1.27 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include "extern.h" #include "driver.h" static int fightitout(struct ship *, struct ship *, int); @@ -48,10 +61,10 @@ unfoul(void) nat = capship(sp)->nationality; foreachship(to) { if (nat != capship(to)->nationality && - !toughmelee(sp, to, 0, 0)) + !is_toughmelee(sp, to, 0, 0)) continue; for (i = fouled2(sp, to); --i >= 0;) - if (die() <= 2) + if (dieroll() <= 2) cleanfoul(sp, to, 0); } } @@ -129,15 +142,15 @@ fightitout(struct ship *from, struct ship *to, int key) int crewfrom[3], crewto[3], menfrom, mento; int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured; int topoints; - int idx, totalfrom = 0, totalto = 0; + int indx, totalfrom = 0, totalto = 0; int count; char message[60]; menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key); mento = mensent(to, from, crewto, &tocap, &pcto, 0); - if (fromcap == NULL) + if (fromcap == 0) fromcap = from; - if (tocap == NULL) + if (tocap == 0) tocap = to; if (key) { if (!menfrom) { /* if crew surprised */ @@ -157,15 +170,15 @@ fightitout(struct ship *from, struct ship *to, int key) ((fromstrength < strengthto * 3 && strengthto < fromstrength * 3) || fromstrength == -1) && count < 4; count++) { - idx = fromstrength/10; - if (idx > 8) - idx = 8; - toinjured = MT[idx][2 - die() / 3]; + indx = fromstrength/10; + if (indx > 8) + indx = 8; + toinjured = MT[indx][2 - dieroll() / 3]; totalto += toinjured; - idx = strengthto/10; - if (idx > 8) - idx = 8; - frominjured = MT[idx][2 - die() / 3]; + indx = strengthto/10; + if (indx > 8) + indx = 8; + frominjured = MT[indx][2 - dieroll() / 3]; totalfrom += frominjured; menfrom -= frominjured; mento -= toinjured; @@ -174,47 +187,44 @@ fightitout(struct ship *from, struct ship *to, int key) } if (fromstrength >= strengthto * 3 || count == 4) { unboard(to, from, 0); - subtract(from, totalfrom, crewfrom, fromcap, pcfrom); - subtract(to, totalto, crewto, tocap, pcto); - makesignal(from, "boarders from %s repelled", to); - sprintf(message, "killed in melee: %d. %s: %d", + subtract(from, fromcap, totalfrom, crewfrom, pcfrom); + subtract(to, tocap, totalto, crewto, pcto); + makemsg(from, "boarders from %s repelled", to->shipname); + snprintf(message, sizeof(message), + "killed in melee: %d. %s: %d", totalto, from->shipname, totalfrom); - Writestr(W_SIGNAL, to, message); + send_signal(to, message); if (key) return 1; } else if (strengthto >= fromstrength * 3) { unboard(from, to, 0); - subtract(from, totalfrom, crewfrom, fromcap, pcfrom); - subtract(to, totalto, crewto, tocap, pcto); + subtract(from, fromcap, totalfrom, crewfrom, pcfrom); + subtract(to, tocap, totalto, crewto, pcto); if (key) { if (fromcap != from) - Write(W_POINTS, fromcap, + send_points(fromcap, fromcap->file->points - from->file->struck ? from->specs->pts - : 2 * from->specs->pts, - 0, 0, 0); - -/* ptr1 points to the shipspec for the ship that was just unboarded. - I guess that what is going on here is that the pointer is multiplied - or something. */ + : 2 * from->specs->pts); - Write(W_CAPTURED, from, to->file->index, 0, 0, 0); + send_captured(from, to->file->index); topoints = 2 * from->specs->pts + to->file->points; if (from->file->struck) topoints -= from->specs->pts; - Write(W_POINTS, to, topoints, 0, 0, 0); + send_points(to, topoints); mento = crewto[0] ? crewto[0] : crewto[1]; if (mento) { - subtract(to, mento, crewto, tocap, pcto); - subtract(from, - mento, crewfrom, to, 0); + subtract(to, tocap, mento, crewto, pcto); + subtract(from, to, - mento, crewfrom, 0); } - sprintf(message, "captured by the %s!", - to->shipname); - Writestr(W_SIGNAL, from, message); - sprintf(message, "killed in melee: %d. %s: %d", + snprintf(message, sizeof(message), + "captured by the %s!", to->shipname); + send_signal(from, message); + snprintf(message, sizeof(message), + "killed in melee: %d. %s: %d", totalto, from->shipname, totalfrom); - Writestr(W_SIGNAL, to, message); + send_signal(to, message); mento = 0; return 0; } @@ -262,7 +272,7 @@ compcombat(void) struct ship *closest; int crew[3], men = 0, target, temp; int r, guns, ready, load, car; - int idx, rakehim, sternrake; + int indx, rakehim, sternrake; int shootat, hit; foreachship(sp) { @@ -303,7 +313,7 @@ compcombat(void) if ((ready & R_LOADED) == 0) continue; closest = closestenemy(sp, r ? 'r' : 'l', 0); - if (closest == NULL) + if (closest == 0) continue; if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1))) @@ -335,21 +345,21 @@ compcombat(void) if (temp > 8) temp -= 8; sternrake = temp > 4 && temp < 6; - idx = guns; + indx = guns; if (target < 3) - idx += car; - idx = (idx - 1) / 3; - idx = idx > 8 ? 8 : idx; + indx += car; + indx = (indx - 1) / 3; + indx = indx > 8 ? 8 : indx; if (!rakehim) - hit = HDT[idx][target-1]; + hit = HDT[indx][target-1]; else - hit = HDTrake[idx][target-1]; + hit = HDTrake[indx][target-1]; if (rakehim && sternrake) hit++; - hit += QUAL[idx][capship(sp)->specs->qual - 1]; + hit += QUAL[indx][capship(sp)->specs->qual - 1]; for (n = 0; n < 3 && sp->file->captured == 0; n++) { if (!crew[n]) { - if (idx <= 5) + if (indx <= 5) hit--; else hit -= 2; @@ -360,18 +370,18 @@ compcombat(void) sp->file->readyL &= ~R_INITIAL; else sp->file->readyR &= ~R_INITIAL; - if (idx <= 3) + if (indx <= 3) hit++; else hit += 2; } if (sp->file->captured != 0) { - if (idx <= 1) + if (indx <= 1) hit--; else hit -= 2; } - hit += AMMO[idx][load - 1]; + hit += AMMO[indx][load - 1]; temp = sp->specs->class; if ((temp >= 5 || temp == 1) && windspeed == 5) hit--; @@ -382,7 +392,8 @@ compcombat(void) if (hit >= 0) { if (load != L_GRAPE) hit = hit > 10 ? 10 : hit; - table(shootat, load, hit, closest, sp, die()); + table(sp, closest, shootat, load, hit, + dieroll()); } } } @@ -410,25 +421,24 @@ next(void) bestship = s; } } - if (best > 0.0) { - char *p = getenv("WOTD"); - if (p == NULL) { - char buf[6] = "Driver"; - p = buf; + if (best > 0.0 && bestship) { + char *tp = getenv("WOTD"); + const char *p; + if (tp == 0) + p = "Driver"; + else { + *tp = toupper((unsigned char)*tp); + p = tp; } - if (islower(*p)) - *p = toupper(*p); - strncpy(bestship->file->captain, p, + strlcpy(bestship->file->captain, p, sizeof bestship->file->captain); - bestship->file->captain - [sizeof bestship->file->captain - 1] = 0; - write_log(bestship); + logger(bestship); } return -1; } - Write(W_TURN, SHIP(0), turn, 0, 0, 0); - if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) { - switch (die()) { + send_turn(turn); + if (turn % 7 == 0 && (dieroll() >= cc->windchange || !windspeed)) { + switch (dieroll()) { case 1: winddir = 1; break; @@ -452,7 +462,7 @@ next(void) if (winddir < 1) winddir += 8; if (windspeed) - switch (die()) { + switch (dieroll()) { case 1: case 2: windspeed--; @@ -464,7 +474,7 @@ next(void) } else windspeed++; - Write(W_WIND, SHIP(0), winddir, windspeed, 0, 0); + send_wind( winddir, windspeed); } return 0; } diff --git a/games/sail/dr_2.c b/games/sail/dr_2.c index 770f0a2ab9..40a24839d0 100644 --- a/games/sail/dr_2.c +++ b/games/sail/dr_2.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: dr_2.c,v 1.27 2019/02/03 10:48:46 mrg Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,30 +27,43 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dr_2.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/dr_2.c,v 1.6 1999/11/30 03:49:32 billf Exp $ - * $DragonFly: src/games/sail/dr_2.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dr_2.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: dr_2.c,v 1.27 2019/02/03 10:48:46 mrg Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include #include +#include "extern.h" #include "driver.h" #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5) -static char strend(char *); -static int score(char *, struct ship *, struct ship *, char); -static void sail_move(char *, struct ship *, unsigned char *, short *, short *, char *); -static void try(char *, char *, int, int, int, int, int, struct ship *, struct ship *, int *, int); +static int str_end(const char *); +static int score(struct ship *, struct ship *, char *, size_t, int); +static void move_ship(struct ship *, const char *, unsigned char *, + short *, short *, int *); +static void try(struct ship *f, struct ship *t, + char *command, size_t commandmax, char *temp, size_t tempmax, + int ma, int ta, bool af, int vma, int dir, int *high, + int rakeme); static void rmend(char *); -int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */ +const int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */ void thinkofgrapples(void) { struct ship *sp, *sq; - char friendly; + bool friendly; foreachship(sp) { if (sp->file->captain[0] || sp->file->dir == 0) @@ -61,7 +76,7 @@ thinkofgrapples(void) if (range(sp, sq) != 1) continue; if (grappled2(sp, sq)) { - if (toughmelee(sp, sq, 0, 0)) + if (is_toughmelee(sp, sq, 0, 0)) ungrap(sp, sq); else grap(sp, sq); @@ -88,23 +103,28 @@ checkup(void) sink = sp->file->sink; if (explode != 1 && sink != 1) continue; - if (die() < 5) + if (dieroll() < 5) continue; - Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 2, 0, 0, 0); - Write(W_DIR, sp, 0, 0, 0, 0); + if (sink == 1) { + send_sink(sp, 2); + } else { + send_explode(sp, 2); + } + send_dir(sp, 0); if (snagged(sp)) foreachship(sq) cleansnag(sp, sq, 1); if (sink != 1) { - makesignal(sp, "exploding!", NULL); + makemsg(sp, "exploding!"); foreachship(sq) { if (sp != sq && sq->file->dir && range(sp, sq) < 4) - table(RIGGING, L_EXPLODE, - sp->specs->guns/13, sq, sp, 6); + table(sp, sq, RIGGING, L_EXPLODE, + sp->specs->guns/13, 6); } - } else - makesignal(sp, "sinking!", NULL); + } else { + makemsg(sp, "sinking!"); + } } } @@ -120,17 +140,19 @@ prizecheck(void) continue; if (sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3 > sp->file->pcrew * 6) { - Writestr(W_SIGNAL, sp, "prize crew overthrown"); - Write(W_POINTS, sp->file->captured, sp->file->captured->file->points - 2 * sp->specs->pts, 0, 0, 0); - Write(W_CAPTURED, sp, -1, 0, 0, 0); + send_signal(sp, "prize crew overthrown"); + send_points(sp->file->captured, + sp->file->captured->file->points + - 2 * sp->specs->pts); + send_captured(sp, -1); } } } -static char -strend(char *str) +static int +str_end(const char *str) { - char *p; + const char *p; for (p = str; *p; p++) ; @@ -138,20 +160,23 @@ strend(char *str) } void -closeon(struct ship *from, struct ship *to, char command[], int ta, int ma, int af) +closeon(struct ship *from, struct ship *to, char *command, size_t commandmax, + int ta, int ma, bool af) { int high; char temp[10]; temp[0] = command[0] = '\0'; high = -30000; - try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0); + try(from, to, command, commandmax, temp, sizeof(temp), + ma, ta, af, ma, from->file->dir, &high, 0); } static int -score(char movement[], struct ship *ship, struct ship *to, char onlytemp) +score(struct ship *ship, struct ship *to, char *movement, size_t movementmax, + int onlytemp) { - char drift; + int drift; int row, col, dir, total, ran; struct File *fp = ship->file; @@ -160,9 +185,9 @@ score(char movement[], struct ship *ship, struct ship *to, char onlytemp) row = fp->row; col = fp->col; drift = fp->drift; - sail_move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift); + move_ship(ship, movement, &fp->dir, &fp->row, &fp->col, &drift); if (!*movement) - strcpy(movement, "d"); + strlcpy(movement, "d", movementmax); ran = range(ship, to); total = -50 * ran; @@ -180,7 +205,8 @@ score(char movement[], struct ship *ship, struct ship *to, char onlytemp) } static void -sail_move(char *p, struct ship *ship, unsigned char *dir, short *row, short *col, char *drift) +move_ship(struct ship *ship, const char *p, unsigned char *dir, + short *row, short *col, int *drift) { int dist; char moved = 0; @@ -220,47 +246,57 @@ sail_move(char *p, struct ship *ship, unsigned char *dir, short *row, short *col } static void -try(char command[], char temp[], int ma, int ta, int af, int vma, int dir, struct ship *f, struct ship *t, int *high, int rakeme) +try(struct ship *f, struct ship *t, + char *command, size_t commandmax, + char *temp, size_t tempmax, + int ma, int ta, bool af, int vma, int dir, int *high, int rakeme) { int new, n; - char st[4]; + char st[11]; #define rakeyou (gunsbear(f, t) && !gunsbear(t, f)) - if ((n = strend(temp)) < '1' || n > '9') + if ((n = str_end(temp)) < '1' || n > '9') for (n = 1; vma - n >= 0; n++) { - sprintf(st, "%d", n); - strcat(temp, st); - new = score(temp, f, t, rakeme); + snprintf(st, sizeof(st), "%d", n); + strlcat(temp, st, tempmax); + new = score(f, t, temp, tempmax, rakeme); if (new > *high && (!rakeme || rakeyou)) { *high = new; - strcpy(command, temp); + strlcpy(command, temp, commandmax); } - try(command, temp, ma-n, ta, af, vma-n, - dir, f, t, high, rakeme); + try(f, t, command, commandmax, temp, tempmax, + ma-n, ta, af, vma-n, + dir, high, rakeme); rmend(temp); } - if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)) { - strcat(temp, "r"); - new = score(temp, f, t, rakeme); - if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))) { + if ((ma > 0 && ta > 0 && (n = str_end(temp)) != 'l' && n != 'r') || + !strlen(temp)) { + strlcat(temp, "r", tempmax); + new = score(f, t, temp, tempmax, rakeme); + if (new > *high && (!rakeme || + (gunsbear(f, t) && !gunsbear(t, f)))) { *high = new; - strcpy(command, temp); + strlcpy(command, temp, commandmax); } - try(command, temp, ma-1, ta-1, af, + try(f, t, command, commandmax, temp, tempmax, + ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), - (dir == 8 ? 1 : dir+1), f, t, high, rakeme); + (dir == 8 ? 1 : dir+1), high, rakeme); rmend(temp); } - if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)) { - strcat(temp, "l"); - new = score(temp, f, t, rakeme); - if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))) { + if ((ma > 0 && ta > 0 && (n = str_end(temp)) != 'l' && n != 'r') || + !strlen(temp)) { + strlcat(temp, "l", tempmax); + new = score(f, t, temp, tempmax, rakeme); + if (new > *high && (!rakeme || + (gunsbear(f, t) && !gunsbear(t, f)))) { *high = new; - strcpy(command, temp); + strlcpy(command, temp, commandmax); } - try(command, temp, ma-1, ta-1, af, + try(f, t, command, commandmax, temp, tempmax, + ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), - (dir-1 ? dir -1 : 8), f, t, high, rakeme); + (dir-1 ? dir -1 : 8), high, rakeme); rmend(temp); } } diff --git a/games/sail/dr_3.c b/games/sail/dr_3.c index 7eb84238b9..eb0280eaa3 100644 --- a/games/sail/dr_3.c +++ b/games/sail/dr_3.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: dr_3.c,v 1.19 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,17 +27,26 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dr_3.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/dr_3.c,v 1.6 1999/11/30 03:49:32 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dr_3.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: dr_3.c,v 1.19 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include "extern.h" #include "driver.h" -static bool stillmoving(int); -static bool isolated(struct ship *); -static bool push(struct ship *, struct ship *); -static void step(char, struct ship *, char *); +static int stillmoving(int); +static int is_isolated(struct ship *); +static int push(struct ship *, struct ship *); +static void step(struct ship *, int, char *); /* move all comp ships */ void @@ -53,7 +64,7 @@ moveall(void) foreachship(sp) { struct ship *closest; int ma, ta; - char af; + bool af; if (sp->file->captain[0] || sp->file->dir == 0) continue; @@ -62,10 +73,11 @@ moveall(void) ta = maxturns(sp, &af); ma = maxmove(sp, sp->file->dir, 0); closest = closestenemy(sp, 0, 0); - if (closest == NULL) + if (closest == 0) *sp->file->movebuf = '\0'; else closeon(sp, closest, sp->file->movebuf, + sizeof(sp->file->movebuf), ta, ma, af); } else *sp->file->movebuf = '\0'; @@ -104,7 +116,7 @@ moveall(void) if (!sp->file->movebuf[k]) sp->file->movebuf[k+1] = '\0'; else if (sp->file->dir) - step(sp->file->movebuf[k], sp, &moved[n]); + step(sp, sp->file->movebuf[k], &moved[n]); n++; } /* @@ -112,7 +124,7 @@ moveall(void) */ n = 0; foreachship(sp) { - if (sp->file->dir == 0 || isolated(sp)) + if (sp->file->dir == 0 || is_isolated(sp)) goto cont1; l = 0; foreachship(sq) { @@ -127,14 +139,12 @@ moveall(void) if (snagged2(sp, sq) && range(sp, sq) > 1) snap++; if (!range(sp, sq) && !fouled2(sp, sq)) { - makesignal(sp, - "collision with %s (%c%c)", sq); - if (die() < 4) { - makesignal(sp, - "fouled with %s (%c%c)", - sq); - Write(W_FOUL, sp, l, 0, 0, 0); - Write(W_FOUL, sq, n, 0, 0, 0); + makesignal(sp, "collision with $$", sq); + if (dieroll() < 4) { + makesignal(sp, "fouled with $$", + sq); + send_foul(sp, l); + send_foul(sq, n); } snap++; } @@ -165,19 +175,19 @@ moveall(void) if (sp->file->dir != 0) { *sp->file->movebuf = 0; if (row[n] != sp->file->row) - Write(W_ROW, sp, sp->file->row, 0, 0, 0); + send_row(sp, sp->file->row); if (col[n] != sp->file->col) - Write(W_COL, sp, sp->file->col, 0, 0, 0); + send_col(sp, sp->file->col); if (dir[n] != sp->file->dir) - Write(W_DIR, sp, sp->file->dir, 0, 0, 0); + send_dir(sp, sp->file->dir); if (drift[n] != sp->file->drift) - Write(W_DRIFT, sp, sp->file->drift, 0, 0, 0); + send_drift(sp, sp->file->drift); } n++; } } -static bool +static int stillmoving(int k) { struct ship *sp; @@ -188,8 +198,8 @@ stillmoving(int k) return 0; } -static bool -isolated(struct ship *ship) +static int +is_isolated(struct ship *ship) { struct ship *sp; @@ -200,7 +210,7 @@ isolated(struct ship *ship) return 1; } -static bool +static int push(struct ship *from, struct ship *to) { int bs, sb; @@ -215,7 +225,7 @@ push(struct ship *from, struct ship *to) } static void -step(char com, struct ship *sp, char *moved) +step(struct ship *sp, int com, char *moved) { int dist; @@ -256,7 +266,7 @@ step(char com, struct ship *sp, char *moved) } void -sendbp(struct ship *from, struct ship *to, int sections, char isdefense) +sendbp(struct ship *from, struct ship *to, int sections, int isdefense) { int n; struct BP *bp; @@ -265,17 +275,20 @@ sendbp(struct ship *from, struct ship *to, int sections, char isdefense) for (n = 0; n < NBP && bp[n].turnsent; n++) ; if (n < NBP && sections) { - Write(isdefense ? W_DBP : W_OBP, from, - n, turn, to->file->index, sections); + if (isdefense) { + send_dbp(from, n, turn, to->file->index, sections); + } else { + send_obp(from, n, turn, to->file->index, sections); + } if (isdefense) - makesignal(from, "repelling boarders", NULL); + makemsg(from, "repelling boarders"); else - makesignal(from, "boarding the %s (%c%c)", to); + makesignal(from, "boarding the $$", to); } } int -toughmelee(struct ship *ship, struct ship *to, int isdefense, int count) +is_toughmelee(struct ship *ship, struct ship *to, int isdefense, int count) { struct BP *bp; int obp = 0; @@ -296,9 +309,9 @@ toughmelee(struct ship *ship, struct ship *to, int isdefense, int count) } if (count || isdefense) return obp; - OBP = toughmelee(to, ship, 0, count + 1); - dbp = toughmelee(ship, to, 1, count + 1); - DBP = toughmelee(to, ship, 1, count + 1); + OBP = is_toughmelee(to, ship, 0, count + 1); + dbp = is_toughmelee(ship, to, 1, count + 1); + DBP = is_toughmelee(to, ship, 1, count + 1); if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10) return 1; else @@ -320,7 +333,7 @@ checksails(void) { struct ship *sp; int rig, full; - struct ship *closest; + struct ship *close; foreachship(sp) { if (sp->file->captain[0] != 0) @@ -329,17 +342,19 @@ checksails(void) if (windspeed == 6 || (windspeed == 5 && sp->specs->class > 4)) rig = 0; if (rig && sp->specs->crew3) { - closest = closestenemy(sp, 0, 0); - if (closest != NULL) { - if (range(sp, closest) > 9) + close = closestenemy(sp, 0, 0); + if (close != 0) { + if (range(sp, close) > 9) full = 1; else full = 0; - } else + } else { full = 0; - } else + } + } else { full = 0; + } if ((sp->file->FS != 0) != full) - Write(W_FS, sp, full, 0, 0, 0); + send_fs(sp, full); } } diff --git a/games/sail/dr_4.c b/games/sail/dr_4.c index 62fd496b37..db45a2587c 100644 --- a/games/sail/dr_4.c +++ b/games/sail/dr_4.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: dr_4.c,v 1.15 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,13 +27,19 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dr_4.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/dr_4.c,v 1.5 1999/11/30 03:49:32 billf Exp $ - * $DragonFly: src/games/sail/dr_4.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dr_4.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: dr_4.c,v 1.15 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include "extern.h" void ungrap(struct ship *from, struct ship *to) @@ -43,9 +51,9 @@ ungrap(struct ship *from, struct ship *to) return; friend = capship(from)->nationality == capship(to)->nationality; while (--k >= 0) { - if (friend || die() < 3) { + if (friend || dieroll() < 3) { cleangrapple(from, to, 0); - makesignal(from, "ungrappling %s (%c%c)", to); + makesignal(from, "ungrappling $$", to); } } } @@ -53,9 +61,10 @@ ungrap(struct ship *from, struct ship *to) void grap(struct ship *from, struct ship *to) { - if (capship(from)->nationality != capship(to)->nationality && die() > 2) + if (capship(from)->nationality != capship(to)->nationality && + dieroll() > 2) return; - Write(W_GRAP, from, to->file->index, 0, 0, 0); - Write(W_GRAP, to, from->file->index, 0, 0, 0); - makesignal(from, "grappled with %s (%c%c)", to); + send_grap(from, to->file->index); + send_grap(to, from->file->index); + makesignal(from, "grappled with $$", to); } diff --git a/games/sail/dr_5.c b/games/sail/dr_5.c index 203f3d205a..5846ccbb89 100644 --- a/games/sail/dr_5.c +++ b/games/sail/dr_5.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: dr_5.c,v 1.14 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,15 +27,23 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dr_5.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/dr_5.c,v 1.4 1999/11/30 03:49:33 billf Exp $ */ -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dr_5.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: dr_5.c,v 1.14 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include "extern.h" void -subtract(struct ship *from, int totalfrom, int crewfrom[3], struct ship *fromcap, int pcfrom) +subtract(struct ship *from, struct ship *fromcap, int totalfrom, int *crewfrom, + int pcfrom) { int n; @@ -47,16 +57,17 @@ subtract(struct ship *from, int totalfrom, int crewfrom[3], struct ship *fromcap totalfrom = 0; } } - Write(W_CREW, from, crewfrom[0], crewfrom[1], crewfrom[2], 0); + send_crew(from, crewfrom[0], crewfrom[1], crewfrom[2]); } else if (totalfrom) { pcfrom -= totalfrom; pcfrom = pcfrom < 0 ? 0 : pcfrom; - Write(W_PCREW, from, pcfrom, 0, 0, 0); + send_pcrew(from, pcfrom); } } int -mensent(struct ship *from, struct ship *to, int crew[3], struct ship **captured, int *pc, char isdefense) +mensent(struct ship *from, struct ship *to, int *crew, struct ship **captured, + int *pc, int isdefense) { /* returns # of crew squares sent */ int men = 0; int n; @@ -77,7 +88,7 @@ mensent(struct ship *from, struct ship *to, int crew[3], struct ship **captured, c1 = men/100 ? crew[0] : 0; c2 = (men%100)/10 ? crew[1] : 0; c3 = men/10 ? crew[2] : 0; - c3 = *captured == NULL ? crew[2] : *pc; + c3 = *captured == 0 ? crew[2] : *pc; } else c1 = c2 = c3 = 0; return(c1 + c2 + c3); diff --git a/games/sail/dr_main.c b/games/sail/dr_main.c index e59562192a..167c512aed 100644 --- a/games/sail/dr_main.c +++ b/games/sail/dr_main.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: dr_main.c,v 1.15 2010/08/06 09:14:40 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,13 +27,29 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)dr_main.c 8.2 (Berkeley) 4/16/94 - * $FreeBSD: src/games/sail/dr_main.c,v 1.4 1999/11/30 03:49:33 billf Exp $ - * $DragonFly: src/games/sail/dr_main.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dr_main.c 8.2 (Berkeley) 4/16/94"; +#else +__RCSID("$NetBSD: dr_main.c,v 1.15 2010/08/06 09:14:40 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include "extern.h" #include "driver.h" +#include "player.h" /* XXX for LEAVE_FORK */ +#include "restart.h" + +static int driver_wait_fd = -1; int dr_main(void) @@ -41,27 +59,28 @@ dr_main(void) int nat[NNATION]; int value = 0; + /* + * XXX need a way to print diagnostics back to the player + * process instead of stomping on the curses screen. + */ + signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, SIG_IGN); - if (issetuid) - setuid(geteuid()); if (game < 0 || game >= NSCENE) { - fprintf(stderr, "DRIVER: Bad game number %d\n", game); - exit(1); + errx(1, "\ndriver: Bad game number %d", game); } cc = &scene[game]; ls = SHIP(cc->vessels); if (sync_open() < 0) { - perror("driver: syncfile"); - exit(1); + err(1, "\ndriver: syncfile"); } for (n = 0; n < NNATION; n++) nat[n] = 0; foreachship(sp) { if (sp->file == NULL && (sp->file = calloc(1, sizeof (struct File))) == NULL) { - fprintf(stderr, "DRIVER: Out of memory.\n"); + fprintf(stderr, "\nDRIVER: Out of memory.\n"); exit(1); } sp->file->index = sp - SHIP(0); @@ -77,6 +96,12 @@ dr_main(void) windspeed = cc->windspeed; winddir = cc->winddir; people = 0; + + /* report back to the player process that we've started */ + if (driver_wait_fd >= 0) { + close(driver_wait_fd); + } + for (;;) { sleep(7); if (Sync() < 0) { @@ -103,3 +128,35 @@ dr_main(void) sync_close(1); return value; } + +void +startdriver(void) +{ + int fds[2]; + char c; + + if (pipe(fds)) { + warn("pipe"); + leave(LEAVE_FORK); + return; + } + + switch (fork()) { + case 0: + close(fds[0]); + driver_wait_fd = fds[1]; + longjmp(restart, MODE_DRIVER); + /*NOTREACHED*/ + case -1: + warn("fork"); + close(fds[0]); + close(fds[1]); + leave(LEAVE_FORK); + break; + default: + hasdriver++; + close(fds[1]); + read(fds[0], &c, 1); + close(fds[0]); + } +} diff --git a/games/sail/driver.h b/games/sail/driver.h index bfb19bcce0..422cddfdcf 100644 --- a/games/sail/driver.h +++ b/games/sail/driver.h @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: driver.h,v 1.8 2003/08/07 09:37:42 agc Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -26,9 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)driver.h 8.1 (Berkeley) 5/31/93 + * @(#)driver.h 8.2 (Berkeley) 5/3/95 */ -#include "externs.h" - -extern int dtab[]; +extern const int dtab[]; diff --git a/games/sail/externs.h b/games/sail/extern.h similarity index 59% rename from games/sail/externs.h rename to games/sail/extern.h index 2ae1c77955..75fb56d161 100644 --- a/games/sail/externs.h +++ b/games/sail/extern.h @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: extern.h,v 1.38 2011/08/29 20:30:37 joerg Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -29,34 +31,29 @@ * @(#)externs.h 8.1 (Berkeley) 5/31/93 */ -#include +#include #include -#include -#include -#include -#include -#include -#include -#include + #include "machdep.h" /* program mode */ extern int mode; -extern jmp_buf restart; #define MODE_PLAYER 1 #define MODE_DRIVER 2 #define MODE_LOGGER 3 /* command line flags */ -extern char debug; /* -D */ -extern char randomize; /* -x, give first available ship */ -extern char longfmt; /* -l, print score in long format */ -extern char nobells; /* -b, don't ring bell before Signal */ +extern bool randomize; /* -x, give first available ship */ +extern bool longfmt; /* -l, print score in long format */ +extern bool nobells; /* -b, don't ring bell before Signal */ - /* other initial modes */ -extern char issetuid; /* running setuid */ + /* other initial data */ +extern gid_t gid; +extern gid_t egid; +#define MAXNAMESIZE 20 +extern char myname[MAXNAMESIZE]; -#define die() (random() % 6 + 1) +#define dieroll() ((random()) % 6 + 1) #define sqr(a) ((a) * (a)) #define min(a,b) ((a) < (b) ? (a) : (b)) @@ -106,49 +103,9 @@ extern char issetuid; /* running setuid */ #define HULL 0 #define RIGGING 1 -#define W_CAPTAIN 1 -#define W_CAPTURED 2 -#define W_CLASS 3 -#define W_CREW 4 -#define W_DBP 5 -#define W_DRIFT 6 -#define W_EXPLODE 7 -#define W_FILE 8 -#define W_FOUL 9 -#define W_GUNL 10 -#define W_GUNR 11 -#define W_HULL 12 -#define W_MOVE 13 -#define W_OBP 14 -#define W_PCREW 15 -#define W_UNFOUL 16 -#define W_POINTS 17 -#define W_QUAL 18 -#define W_UNGRAP 19 -#define W_RIGG 20 -#define W_COL 21 -#define W_DIR 22 -#define W_ROW 23 -#define W_SIGNAL 24 -#define W_SINK 25 -#define W_STRUCK 26 -#define W_TA 27 -#define W_ALIVE 28 -#define W_TURN 29 -#define W_WIND 30 -#define W_FS 31 -#define W_GRAP 32 -#define W_RIG1 33 -#define W_RIG2 34 -#define W_RIG3 35 -#define W_RIG4 36 -#define W_BEGIN 37 -#define W_END 38 -#define W_DDEAD 39 - #define NLOG 10 struct logs { - char l_name[20]; + char l_name[MAXNAMESIZE]; int l_uid; int l_shipnum; int l_gamenum; @@ -156,8 +113,8 @@ struct logs { }; struct BP { - short turnsent; struct ship *toship; + short turnsent; short mensent; }; @@ -166,7 +123,7 @@ struct snag { short sn_turn; }; -#define NSCENE nscene +#define NSCENE /*nscene*/ 32 #define NSHIP 10 #define NBP 3 @@ -182,29 +139,29 @@ struct snag { struct File { int index; - char captain[20]; /* 0 */ + char captain[MAXNAMESIZE]; /* 0 */ short points; /* 20 */ unsigned char loadL; /* 22 */ unsigned char loadR; /* 24 */ - char readyL; /* 26 */ - char readyR; /* 28 */ + unsigned char readyL; /* 26 */ + unsigned char readyR; /* 28 */ struct BP OBP[NBP]; /* 30 */ struct BP DBP[NBP]; /* 48 */ char struck; /* 66 */ struct ship *captured; /* 68 */ short pcrew; /* 70 */ - char movebuf[60]; /* 72 */ - char drift; /* 132 */ + char movebuf[10]; /* 72 */ + char drift; /* 82 */ short nfoul; short ngrap; - struct snag foul[NSHIP]; /* 134 */ - struct snag grap[NSHIP]; /* 144 */ - char RH; /* 274 */ - char RG; /* 276 */ - char RR; /* 278 */ - char FS; /* 280 */ - char explode; /* 282 */ - char sink; /* 284 */ + struct snag foul[NSHIP]; /* 84 */ + struct snag grap[NSHIP]; /* 124 */ + char RH; /* 224 */ + char RG; /* 226 */ + char RR; /* 228 */ + char FS; /* 230 */ + char explode; /* 232 */ + char sink; /* 234 */ unsigned char dir; short col; short row; @@ -230,7 +187,7 @@ struct scenario { const char *name; /* 14 */ struct ship ship[NSHIP]; /* 16 */ }; -extern struct scenario scene[]; +extern struct scenario scene[NSCENE]; extern int nscene; struct shipspecs { @@ -248,15 +205,14 @@ struct shipspecs { char gunR; char carL; char carR; - char rig1; - char rig2; - char rig3; - char rig4; + int rig1; + int rig2; + int rig3; + int rig4; short pts; }; -extern struct shipspecs specs[]; -extern struct scenario *cc; /* the current scenario */ +extern struct scenario *cc; /* the current scenario */ extern struct ship *ls; /* &cc->ship[cc->vessels] */ #define SHIP(s) (&cc->ship[s]) @@ -265,29 +221,30 @@ extern struct ship *ls; /* &cc->ship[cc->vessels] */ struct windeffects { char A, B, C, D; }; -extern struct windeffects WET[7][6]; +extern const struct windeffects WET[7][6]; struct Tables { char H, G, C, R; }; -extern struct Tables RigTable[11][6]; -extern struct Tables HullTable[11][6]; +extern const struct Tables RigTable[11][6]; +extern const struct Tables HullTable[11][6]; -extern char AMMO[9][4]; -extern char HDT[9][10]; -extern char HDTrake[9][10]; -extern char QUAL[9][5]; -extern char MT[9][3]; +extern const char AMMO[9][4]; +extern const char HDT[9][10]; +extern const char HDTrake[9][10]; +extern const char QUAL[9][5]; +extern const char MT[9][3]; -extern const char *countryname[]; -extern const char *classname[]; -extern const char *directionname[]; -extern const char *qualname[]; -extern char loadname[]; +extern const char *const countryname[]; +extern const char *const shortclassname[]; +extern const char *const classname[]; +extern const char *const directionname[]; +extern const char *const qualname[]; +extern const char loadname[]; -extern char rangeofshot[]; +extern const char rangeofshot[]; -extern char dr[], dc[]; +extern const char dr[], dc[]; extern int winddir; extern int windspeed; @@ -295,11 +252,12 @@ extern int turn; extern int game; extern int alive; extern int people; -extern char hasdriver; +extern int hasdriver; + /* assorted.c */ -void table(int, int, int, struct ship *, struct ship *, int); -void Cleansnag(struct ship *, struct ship *, char, char); +void table(struct ship *, struct ship *, int, int, int, int); +void Cleansnag(struct ship *, struct ship *, int, int); /* dr_1.c */ void unfoul(void); @@ -312,12 +270,12 @@ int next(void); void thinkofgrapples(void); void checkup(void); void prizecheck(void); -void closeon(struct ship *, struct ship *, char *, int, int, int); +void closeon(struct ship *, struct ship *, char *, size_t, int, int, bool); /* dr_3.c */ void moveall(void); -void sendbp(struct ship *, struct ship *, int, char); -int toughmelee(struct ship *, struct ship *, int, int); +void sendbp(struct ship *, struct ship *, int, int); +int is_toughmelee(struct ship *, struct ship *, int, int); void reload(void); void checksails(void); @@ -326,31 +284,33 @@ void ungrap(struct ship *, struct ship *); void grap(struct ship *, struct ship *); /* dr_5.c */ -void subtract(struct ship *, int, int [3], struct ship *, int); -int mensent(struct ship *, struct ship *, int [3], struct ship **, int *, char); +void subtract(struct ship *, struct ship *, int, int [3], int); +int mensent(struct ship *, struct ship *, int[3], struct ship **, int *, int); /* dr_main.c */ int dr_main(void); +void startdriver(void); /* game.c */ -int maxturns(struct ship *, char *); +int maxturns(struct ship *, bool *); int maxmove(struct ship *, int, int); /* lo_main.c */ +void lo_curses(void); int lo_main(void); /* misc.c */ int range(struct ship *, struct ship *); -struct ship *closestenemy(struct ship *, char, char); -char gunsbear(struct ship *, struct ship *); +struct ship *closestenemy(struct ship *, int, int); +int gunsbear(struct ship *, struct ship *); int portside(struct ship *, struct ship *, int); -char colours(struct ship *); -void write_log(struct ship *); +int colours(struct ship *); +void logger(struct ship *); /* parties.c */ -bool meleeing(struct ship *, struct ship *); -bool boarding(struct ship *, char); -void unboard(struct ship *, struct ship *, char); +int meleeing(struct ship *, struct ship *); +int boarding(struct ship *, int); +void unboard(struct ship *, struct ship *, int); /* pl_1.c */ void leave(int) __dead2; @@ -358,6 +318,7 @@ void choke(int) __dead2; void child(int); /* pl_2.c */ +void newturn(int); void play(void) __dead2; /* pl_3.c */ @@ -369,7 +330,7 @@ void unfoulplayer(void); void changesail(void); void acceptsignal(void); void lookout(void); -const char *saywhat(struct ship *, char); +const char *saywhat(struct ship *, int); void eyeball(struct ship *); /* pl_5.c */ @@ -383,31 +344,67 @@ void loadplayer(void); /* pl_7.c */ void initscreen(void); void cleanupscreen(void); -void newturn(int); -void Signal(const char *, struct ship *, ...); -int sgetch(const char *, struct ship *, char); +void Signal(const char *, struct ship *, ...) __printflike(1,3); +void Msg(const char *, ...) __printflike(1,2); +int sgetch(const char *, struct ship *, int); void sgetstr(const char *, char *, int); -void draw_screen(void); -void draw_view(void); -void draw_turn(void); -void draw_stat(void); -void draw_slot(void); -void draw_board(void); void centerview(void); void upview(void); void downview(void); void leftview(void); void rightview(void); +void startup(void); /* pl_main.c */ -void pl_main(void) __dead2; +void pl_main_init(void); +void pl_main_uninit(void); +__dead2 void pl_main(void); /* sync.c */ void fmtship(char *, size_t, const char *, struct ship *); -void makesignal(struct ship *, const char *, struct ship *, ...); -bool sync_exists(int); +void makesignal(struct ship *, const char *, struct ship *, ...) + __printflike(2,4); +void makemsg(struct ship *, const char *, ...) __printflike(2, 3); +int sync_exists(int); int sync_open(void); -void sync_close(char); -void Write(int, struct ship *, int, int, int, int); -void Writestr(int, struct ship *, const char *); +void sync_close(int); int Sync(void); + +void send_captain(struct ship *ship, const char *astr); +void send_captured(struct ship *ship, long a); +void send_class(struct ship *ship, long a); +void send_crew(struct ship *ship, long a, long b, long c); +void send_dbp(struct ship *ship, long a, long b, long c, long d); +void send_drift(struct ship *ship, long a); +void send_explode(struct ship *ship, long a); +void send_foul(struct ship *ship, long a); +void send_gunl(struct ship *ship, long a, long b); +void send_gunr(struct ship *ship, long a, long b); +void send_hull(struct ship *ship, long a); +void send_move(struct ship *ship, const char *astr); +void send_obp(struct ship *ship, long a, long b, long c, long d); +void send_pcrew(struct ship *ship, long a); +void send_unfoul(struct ship *ship, long a, long b); +void send_points(struct ship *ship, long a); +void send_qual(struct ship *ship, long a); +void send_ungrap(struct ship *ship, long a, long b); +void send_rigg(struct ship *ship, long a, long b, long c, long d); +void send_col(struct ship *ship, long a); +void send_dir(struct ship *ship, long a); +void send_row(struct ship *ship, long a); +void send_signal(struct ship *ship, const char *astr); +void send_sink(struct ship *ship, long a); +void send_struck(struct ship *ship, long a); +void send_ta(struct ship *ship, long a); +void send_alive(void); +void send_turn(long a); +void send_wind(long a, long b); +void send_fs(struct ship *ship, long a); +void send_grap(struct ship *ship, long a); +void send_rig1(struct ship *ship, long a); +void send_rig2(struct ship *ship, long a); +void send_rig3(struct ship *ship, long a); +void send_rig4(struct ship *ship, long a); +void send_begin(struct ship *ship); +void send_end(struct ship *ship); +void send_ddead(void); diff --git a/games/sail/game.c b/games/sail/game.c index 3ae08e98e7..20d6d83c53 100644 --- a/games/sail/game.c +++ b/games/sail/game.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: game.c,v 1.13 2009/03/14 20:04:43 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,16 +27,23 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)game.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/game.c,v 1.5 1999/11/30 03:49:33 billf Exp $ - * $DragonFly: src/games/sail/game.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)game.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: game.c,v 1.13 2009/03/14 20:04:43 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include "extern.h" int -maxturns(struct ship *ship, char *af) +maxturns(struct ship *ship, bool *af) { int turns; diff --git a/games/sail/globals.c b/games/sail/globals.c index 4d8567b99b..331e6b6410 100644 --- a/games/sail/globals.c +++ b/games/sail/globals.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: globals.c,v 1.16 2010/08/06 09:14:40 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,32 +27,30 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)globals.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/globals.c,v 1.3 1999/11/30 03:49:34 billf Exp $ - * $DragonFly: src/games/sail/globals.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)globals.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: globals.c,v 1.16 2010/08/06 09:14:40 dholland Exp $"); +#endif +#endif /* not lint */ -int mode; -jmp_buf restart; - /* command line flags */ -char debug; /* -D */ -char randomize; /* -x, give first available ship */ -char longfmt; /* -l, print score in long format */ -char nobells; /* -b, don't ring bell before Signal */ +#include +#include +#include "extern.h" - /* other initial modes */ -char issetuid; /* running setuid */ +static struct shipspecs specs[]; -struct scenario scene[] = { +struct scenario scene[NSCENE] = { /* * int winddir; * int windspeed; * int windchange; * int vessels; - * const char *name; + * char *name; * struct ship ship[NSHIP]; */ { 5, 3, 5, 2, "Ranger vs. Drake", @@ -249,7 +249,7 @@ struct scenario scene[] = { { "Turenne", specs+10, N_F, 9, 35, 6, 0 }, { "Nightmare", specs+9, N_F, 7, 37, 6, 0 }, { "Paris", specs+53, N_F, 3, 45, 4, 0 }, - { "Napolean", specs+56, N_F, 1, 40, 6, 0 } + { "Napoleon", specs+56, N_F, 1, 40, 6, 0 } } }, { 6, 4, 7, 5, "Cape Horn", @@ -315,7 +315,7 @@ struct scenario scene[] = { }; int nscene = sizeof scene / sizeof (struct scenario); -struct shipspecs specs[] = { +static struct shipspecs specs[] = { /* bs fs ta guns hull crew1 crew3 gunR carR rig2 rig4 pts */ /* class qual crew2 gunL carL rig1 rig3 */ /*00*/{ 4, 7, 3, 19, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 4, 4, 4, 4, 7 }, @@ -406,10 +406,7 @@ struct shipspecs specs[] = { /* class qual crew2 gunL carL rig1 rig3 */ }; -struct scenario *cc; /* the current scenario */ -struct ship *ls; /* &cc->ship[cc->vessels] */ - -struct windeffects WET[7][6] = { +const struct windeffects WET[7][6] = { { {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9} }, { {3,2,2,0}, {3,2,1,0}, {3,2,1,0}, {3,2,1,0}, {2,1,0,0}, {2,1,0,0} }, { {1,1,1,0}, {1,1,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0} }, @@ -419,7 +416,7 @@ struct windeffects WET[7][6] = { { {2,1,1,0}, {3,2,1,0}, {3,2,1,0}, {3,2,1,0}, {3,3,2,0}, {3,3,2,0} } }; -struct Tables RigTable[11][6] = { +const struct Tables RigTable[11][6] = { { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,1,0} }, { {0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,1,0}, {1,0,0,1}, {0,1,1,1} }, { {0,0,0,0}, {0,0,0,1}, {0,0,1,1}, {0,1,0,1}, {0,1,0,1}, {1,0,1,2} }, @@ -432,7 +429,7 @@ struct Tables RigTable[11][6] = { { {1,1,0,4}, {1,0,1,4}, {2,0,0,5}, {0,2,1,5}, {0,1,2,6}, {0,2,0,7} }, { {1,0,1,5}, {0,2,0,6}, {1,2,0,6}, {1,1,1,6}, {2,0,2,6}, {1,1,2,7} } }; -struct Tables HullTable[11][6] = { +const struct Tables HullTable[11][6] = { { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,0,0,0}, {0,1,0,0} }, { {0,0,0,0}, {0,0,0,0}, {0,1,0,0}, {1,1,0,0}, {1,0,1,0}, {1,0,1,1} }, { {0,1,0,0}, {1,0,0,0}, {1,1,0,0}, {1,0,1,0}, {1,0,1,1}, {2,1,0,0} }, @@ -446,7 +443,7 @@ struct Tables HullTable[11][6] = { { {2,2,4,0}, {3,3,1,1}, {4,2,1,1}, {5,1,0,2}, {5,1,2,1}, {6,2,2,0} }, }; -char AMMO[9][4] = { +const char AMMO[9][4] = { { -1, 1, 0, 1 }, { -1, 1, 0, 1 }, { -1, 1, 0, 1 }, @@ -458,7 +455,7 @@ char AMMO[9][4] = { { -3, 2, 0, 3 } }; -char HDT[9][10] = { +const char HDT[9][10] = { { 1, 0,-1,-2,-3,-3,-4,-4,-4,-4 }, { 1, 1, 0,-1,-2,-2,-3,-3,-3,-3 }, { 2, 1, 0,-1,-2,-2,-3,-3,-3,-3 }, @@ -470,7 +467,7 @@ char HDT[9][10] = { { 5, 4, 3, 2, 1, 1, 0, 0, 0, 0 } }; -char HDTrake[9][10] = { +const char HDTrake[9][10] = { { 2, 1, 0,-1,-2,-2,-3,-3,-3,-3 }, { 2, 2, 1, 0,-1,-1,-2,-2,-2,-2 }, { 3, 2, 1, 0,-1,-1,-2,-2,-2,-2 }, @@ -482,7 +479,7 @@ char HDTrake[9][10] = { { 9, 8, 7, 6, 5, 5, 4, 4, 4, 4 } }; -char QUAL[9][5] = { +const char QUAL[9][5] = { { -1, 0, 0, 1, 1 }, { -1, 0, 0, 1, 1 }, { -1, 0, 0, 1, 2 }, @@ -494,7 +491,7 @@ char QUAL[9][5] = { { -2,-1, 0, 2, 3 } }; -char MT[9][3] = { +const char MT[9][3] = { { 1, 0, 0 }, { 1, 1, 0 }, { 2, 1, 0 }, @@ -506,7 +503,7 @@ char MT[9][3] = { { 4, 4, 2 } }; -char rangeofshot[] = { +const char rangeofshot[] = { 0, 1, /* grape */ 3, /* chain */ @@ -514,12 +511,12 @@ char rangeofshot[] = { 1 /* double */ }; -const char *countryname[] = { +const char *const countryname[] = { "American", "British", "Spanish", "French", "Japanese", "Federation", "Klingon", "Orion" }; -const char *classname[] = { +const char *const classname[] = { "Drift wood", "Ship of the Line", "Ship of the Line", @@ -529,7 +526,17 @@ const char *classname[] = { "Brig" }; -const char *directionname[] = { +const char *const shortclassname[] = { + "Rowboat", + "Ship", + "Ship", + "Frigate", + "Corvette", + "Sloop", + "Brig" +}; + +const char *const directionname[] = { "dead ahead", "off the starboard bow", "off the starboard beam", @@ -541,7 +548,7 @@ const char *directionname[] = { "dead ahead" }; -const char *qualname[] = { +const char *const qualname[] = { "dead", "mutinous", "green", @@ -550,10 +557,23 @@ const char *qualname[] = { "elite" }; -char loadname[] = { '-', 'G', 'C', 'R', 'D', 'E' }; +const char loadname[] = { '-', 'G', 'C', 'R', 'D', 'E' }; + +const char dr[] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 }; +const char dc[] = { 0, 0, -1, -1, -1, 0, 1, 1, 1 }; + +int mode; +jmp_buf restart; + +bool randomize; /* -x, give first available ship */ +bool longfmt; /* -l, print score in long format */ +bool nobells; /* -b, don't ring bell before Signal */ + +gid_t gid; +gid_t egid; -char dr[] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 }; -char dc[] = { 0, 0, -1, -1, -1, 0, 1, 1, 1 }; +struct scenario *cc; /* the current scenario */ +struct ship *ls; /* &cc->ship[cc->vessels] */ int winddir; int windspeed; @@ -561,4 +581,4 @@ int turn; int game; int alive; int people; -char hasdriver; +int hasdriver; diff --git a/games/sail/lo_main.c b/games/sail/lo_main.c index 59c759c289..48b19280d3 100644 --- a/games/sail/lo_main.c +++ b/games/sail/lo_main.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: lo_main.c,v 1.19 2010/08/06 09:14:40 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,63 +27,133 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)lo_main.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/lo_main.c,v 1.2 1999/11/30 03:49:34 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)lo_main.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: lo_main.c,v 1.19 2010/08/06 09:14:40 dholland Exp $"); +#endif +#endif /* not lint */ + /* * Print out the top ten SAILors * * -l force a long listing (print out real usernames) */ -#include + +#include +#include +#include +#include +#include #include -#include "externs.h" +#include + +#include "extern.h" #include "pathnames.h" -const char *title[] = { + +static const char *const title[] = { "Admiral", "Commodore", "Captain", "Captain", "Captain", "Captain", "Captain", "Commander", "Commander", "Lieutenant" }; +void +lo_curses(void) +{ + FILE *fp; + char sbuf[32]; + int n = 0, npeople; + int line; + struct passwd *pass; + struct logs log; + struct ship *ship; + + erase(); + + fp = fopen(_PATH_LOGFILE, "r"); + if (fp == NULL) { + mvprintw(5, 10, "%s: %s", _PATH_LOGFILE, strerror(errno)); + mvaddstr(7, 10, "Press any key..."); + getch(); + return; + } + switch (fread(&npeople, sizeof npeople, 1, fp)) { + case 0: + mvprintw(5, 10, "Nobody has sailed yet."); + mvaddstr(7, 10, "Press any key..."); + getch(); + return; + case 1: + break; + default: + mvprintw(5, 10, "%s: %s", _PATH_LOGFILE, strerror(errno)); + mvaddstr(7, 10, "Press any key..."); + getch(); + return; + } + line = 0; + while (fread(&log, sizeof log, 1, fp) == 1 && + log.l_name[0] != '\0' && + line < LINES - 2) { + if (longfmt && (pass = getpwuid(log.l_uid)) != NULL) + snprintf(sbuf, sizeof(sbuf), + "%10.10s (%s)", log.l_name, pass->pw_name); + else + snprintf(sbuf, sizeof(sbuf), + "%20.20s", log.l_name); + ship = &scene[log.l_gamenum].ship[log.l_shipnum]; + mvprintw(line, 0, + "%-10s %21s of the %15s %3d points, %5.2f equiv", + title[n++], sbuf, ship->shipname, log.l_netpoints, + (float) log.l_netpoints / ship->specs->pts); + line++; + } + fclose(fp); + mvprintw(line+1, 0, "%d people have played. Press any key.", npeople); + getch(); +} + int lo_main(void) { FILE *fp; char sbuf[32]; - int n = 0, ppl; + int n = 0, npeople; struct passwd *pass; struct logs log; struct ship *ship; - if ((fp = fopen(_PATH_LOGFILE, "r")) == NULL) { - perror(_PATH_LOGFILE); - exit(1); + if ((fp = fopen(_PATH_LOGFILE, "r")) == 0) { + err(1, "%s", _PATH_LOGFILE); } - switch (fread((char *)&ppl, sizeof ppl, 1, fp)) { + switch (fread(&npeople, sizeof npeople, 1, fp)) { case 0: printf("Nobody has sailed yet.\n"); exit(0); case 1: break; default: - perror(_PATH_LOGFILE); - exit(1); + err(1, "%s", _PATH_LOGFILE); } - while (fread((char *)&log, sizeof log, 1, fp) == 1 && + while (fread(&log, sizeof log, 1, fp) == 1 && log.l_name[0] != '\0') { if (longfmt && (pass = getpwuid(log.l_uid)) != NULL) - sprintf(sbuf, "%10.10s (%s)", - log.l_name, pass->pw_name); + snprintf(sbuf, sizeof(sbuf), + "%10.10s (%s)", log.l_name, pass->pw_name); else - sprintf(sbuf, "%20.20s", log.l_name); + snprintf(sbuf, sizeof(sbuf), + "%20.20s", log.l_name); ship = &scene[log.l_gamenum].ship[log.l_shipnum]; printf("%-10s %21s of the %15s %3d points, %5.2f equiv\n", title[n++], sbuf, ship->shipname, log.l_netpoints, (float) log.l_netpoints / ship->specs->pts); } - printf("\n%d people have played.\n", ppl); + fclose(fp); + printf("\n%d people have played.\n", npeople); return 0; } diff --git a/games/sail/machdep.h b/games/sail/machdep.h index e1cbb2082d..63e64ff692 100644 --- a/games/sail/machdep.h +++ b/games/sail/machdep.h @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: machdep.h,v 1.6 2008/01/28 01:58:01 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -27,7 +29,6 @@ * SUCH DAMAGE. * * @(#)machdep.h 8.1 (Berkeley) 5/31/93 - * $DragonFly: src/games/sail/machdep.h,v 1.2 2006/09/03 17:33:13 pavalos Exp $ */ #define TIMEOUT 300 /* Sync() timeout in seconds */ @@ -35,15 +36,15 @@ /* for POSIX systems */ #define blockalarm() \ do { \ - sigset_t sigset; \ - sigemptyset(&sigset); \ - sigaddset(&sigset, SIGALRM); \ - sigprocmask(SIG_BLOCK, &sigset, NULL); \ + sigset_t set; \ + sigemptyset(&set); \ + sigaddset(&set, SIGALRM); \ + sigprocmask(SIG_BLOCK, &set, (sigset_t *)0); \ } while (0) #define unblockalarm() \ do { \ - sigset_t sigset; \ - sigemptyset(&sigset); \ - sigaddset(&sigset, SIGALRM); \ - sigprocmask(SIG_UNBLOCK, &sigset, NULL); \ + sigset_t set; \ + sigemptyset(&set); \ + sigaddset(&set, SIGALRM); \ + sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)0); \ } while (0) diff --git a/games/sail/main.c b/games/sail/main.c index 3e07f5d84b..fdb9d83028 100644 --- a/games/sail/main.c +++ b/games/sail/main.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: main.c,v 1.26 2010/08/06 09:14:40 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,56 +27,132 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#) Copyright (c) 1983, 1993 The Regents of the University of California. All rights reserved. - * @(#)main.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/main.c,v 1.5 1999/11/30 03:49:34 billf Exp $ */ -#include "externs.h" +#include +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1983, 1993\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: main.c,v 1.26 2010/08/06 09:14:40 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extern.h" +#include "pathnames.h" +#include "restart.h" + +static void +initialize(void) +{ + int fd; + const char *name; + struct passwd *pw; + char *s; + + gid = getgid(); + egid = getegid(); + setegid(gid); + + fd = open("/dev/null", O_RDONLY); + if (fd < 3) + exit(1); + close(fd); + + if (chdir(_PATH_SAILDIR) < 0) { + err(1, "%s", _PATH_SAILDIR); + } + + srandom((u_long)time(NULL)); + + name = getenv("SAILNAME"); + if (name != NULL && *name != '\0') { + strlcpy(myname, name, sizeof(myname)); + } else { + pw = getpwuid(getuid()); + if (pw != NULL) { + strlcpy(myname, pw->pw_gecos, sizeof(myname)); + /* trim to just the realname */ + s = strchr(myname, ','); + if (s != NULL) { + *s = '\0'; + } + /* use just the first name */ + s = strchr(myname, ' '); + if (s != NULL) { + *s = '\0'; + } + /* should really do &-expansion properly */ + if (!strcmp(myname, "&")) { + strlcpy(myname, pw->pw_name, sizeof(myname)); + myname[0] = toupper((unsigned char)myname[0]); + } + } + } + if (*myname == '\0') { + strlcpy(myname, "Anonymous", sizeof(myname)); + } +} int -main(int argc __unused, char **argv) +main(int argc, char **argv) { char *p; - int i; + int a, i; + + initialize(); - srandomdev(); - issetuid = getuid() != geteuid(); - if ((p = rindex(*argv, '/'))) + if ((p = strrchr(*argv, '/')) != NULL) p++; else p = *argv; + if (strcmp(p, "driver") == 0 || strcmp(p, "saildriver") == 0) mode = MODE_DRIVER; else if (strcmp(p, "sail.log") == 0) mode = MODE_LOGGER; else mode = MODE_PLAYER; - while ((p = *++argv) && *p == '-') - switch (p[1]) { + + while ((a = getopt(argc, argv, "dsxlb")) != -1) + switch (a) { case 'd': mode = MODE_DRIVER; break; case 's': mode = MODE_LOGGER; break; - case 'D': - debug++; - break; case 'x': - randomize++; + randomize = true; break; case 'l': - longfmt++; + longfmt = true; break; case 'b': - nobells++; + nobells = true; break; default: - fprintf(stderr, "SAIL: Unknown flag %s.\n", p); - exit(1); + errx(1, "Usage: %s [-bdlsx] [scenario-number]", p); } + + argc -= optind; + argv += optind; + if (*argv) game = atoi(*argv); else @@ -85,13 +163,16 @@ main(int argc __unused, char **argv) switch (mode) { case MODE_PLAYER: - pl_main(); + initscreen(); + startup(); + cleanupscreen(); + return 0; case MODE_DRIVER: return dr_main(); case MODE_LOGGER: return lo_main(); default: - fprintf(stderr, "SAIL: Unknown mode %d.\n", mode); + warnx("Unknown mode %d", mode); abort(); } /*NOTREACHED*/ diff --git a/games/sail/misc.c b/games/sail/misc.c index 61e8345d91..ac94e29550 100644 --- a/games/sail/misc.c +++ b/games/sail/misc.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: misc.c,v 1.18 2009/03/14 19:35:13 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,13 +27,23 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)misc.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/misc.c,v 1.5 1999/11/30 03:49:34 billf Exp $ */ -#include -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)misc.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: misc.c,v 1.18 2009/03/14 19:35:13 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include "extern.h" #include "pathnames.h" #define distance(x,y) \ @@ -68,12 +80,12 @@ range(struct ship *from, struct ship *to) } struct ship * -closestenemy(struct ship *from, char side, char anyship) +closestenemy(struct ship *from, int side, int anyship) { struct ship *sp; char a; int olddist = 30000, dist; - struct ship *closest = NULL; + struct ship *closest = 0; a = capship(from)->nationality; foreachship(sp) { @@ -122,7 +134,7 @@ angle(int Dr, int Dc) } /* checks for target bow or stern */ -char +int gunsbear(struct ship *from, struct ship *to) { int Dr, Dc, i; @@ -163,7 +175,7 @@ portside(struct ship *from, struct ship *on, int quick) return ang < 5; } -char +int colours(struct ship *sp) { char flag = '\0'; @@ -177,11 +189,11 @@ colours(struct ship *sp) if (sp->file->struck) return flag; flag = *countryname[capship(sp)->nationality]; - return sp->file->FS ? flag : tolower(flag); + return sp->file->FS ? flag : tolower((unsigned char)flag); } void -write_log(struct ship *s) +logger(struct ship *s) { FILE *fp; int persons; @@ -190,15 +202,19 @@ write_log(struct ship *s) float net; struct logs *lp; - if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL) + setegid(egid); + if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL) { + setegid(gid); return; + } + setegid(gid); #ifdef LOCK_EX if (flock(fileno(fp), LOCK_EX) < 0) return; #endif net = (float)s->file->points / s->specs->pts; persons = getw(fp); - n = fread((char *)log, sizeof(struct logs), NLOG, fp); + n = fread(log, sizeof(struct logs), NLOG, fp); for (lp = &log[n]; lp < &log[NLOG]; lp++) lp->l_name[0] = lp->l_uid = lp->l_shipnum = lp->l_gamenum = lp->l_netpoints = 0; @@ -210,17 +226,14 @@ write_log(struct ship *s) for (lp = log; lp < &log[NLOG]; lp++) if (net > (float)lp->l_netpoints / scene[lp->l_gamenum].ship[lp->l_shipnum].specs->pts) { - fwrite((char *)log, - sizeof (struct logs), lp - log, fp); + fwrite(log, sizeof (struct logs), lp - log, fp); strcpy(log[NLOG-1].l_name, s->file->captain); log[NLOG-1].l_uid = getuid(); log[NLOG-1].l_shipnum = s->file->index; log[NLOG-1].l_gamenum = game; log[NLOG-1].l_netpoints = s->file->points; - fwrite((char *)&log[NLOG-1], - sizeof (struct logs), 1, fp); - fwrite((char *)lp, - sizeof (struct logs), &log[NLOG-1] - lp, fp); + fwrite(&log[NLOG-1], sizeof (struct logs), 1, fp); + fwrite(lp, sizeof (struct logs), &log[NLOG-1] - lp, fp); break; } #ifdef LOCK_EX diff --git a/games/sail/parties.c b/games/sail/parties.c index 76dc23cd0d..43e9441678 100644 --- a/games/sail/parties.c +++ b/games/sail/parties.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: parties.c,v 1.12 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,15 +27,21 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)parties.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/parties.c,v 1.5 1999/11/30 03:49:35 billf Exp $ - * $DragonFly: src/games/sail/parties.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ -#include "externs.h" +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)parties.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: parties.c,v 1.12 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include "extern.h" -bool +int meleeing(struct ship *from, struct ship *to) { struct BP *p = from->file->OBP; @@ -45,8 +53,8 @@ meleeing(struct ship *from, struct ship *to) return 0; } -bool -boarding(struct ship *from, char isdefense) +int +boarding(struct ship *from, int isdefense) { struct BP *p = isdefense ? from->file->DBP : from->file->OBP; struct BP *q = p + NBP; @@ -58,14 +66,19 @@ boarding(struct ship *from, char isdefense) } void -unboard(struct ship *ship, struct ship *to, char isdefense) +unboard(struct ship *ship, struct ship *to, int isdefense) { struct BP *p = isdefense ? ship->file->DBP : ship->file->OBP; int n; for (n = 0; n < NBP; p++, n++) { if (p->turnsent && - (p->toship == to || isdefense || ship == to)) - Write(isdefense ? W_DBP : W_OBP, ship, n, 0, 0, 0); + (p->toship == to || isdefense || ship == to)) { + if (isdefense) { + send_dbp(ship, n, 0, 0, 0); + } else { + send_obp(ship, n, 0, 0, 0); + } + } } } diff --git a/games/sail/pathnames.h b/games/sail/pathnames.h index 9e4fb8518a..1ee30fc93a 100644 --- a/games/sail/pathnames.h +++ b/games/sail/pathnames.h @@ -1,3 +1,5 @@ +/* $NetBSD: pathnames.h,v 1.6 2009/03/14 23:47:18 dholland Exp $ */ + /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -30,3 +32,8 @@ */ #define _PATH_LOGFILE "/var/games/saillog" +#define _PATH_SAILDIR "/tmp" + +/* in _PATH_SAILDIR */ +#define _FILE_SYNC "#sailsink.%d" +#define _FILE_LOCK "#saillock.%d" diff --git a/games/sail/pl_1.c b/games/sail/pl_1.c index 193fdebfac..9dae48d933 100644 --- a/games/sail/pl_1.c +++ b/games/sail/pl_1.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_1.c,v 1.21 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,13 +27,24 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_1.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_1.c,v 1.2 1999/11/30 03:49:36 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_1.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_1.c,v 1.21 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + #include #include +#include +#include +#include +#include +#include "extern.h" #include "player.h" /* @@ -52,28 +65,24 @@ leave(int conditions) signal(SIGCHLD, SIG_IGN); if (done_curses) { - Signal("It looks like you've had it!", - NULL); + Msg("It looks like you've had it!"); switch (conditions) { case LEAVE_QUIT: break; case LEAVE_CAPTURED: - Signal("Your ship was captured.", - NULL); + Msg("Your ship was captured."); break; case LEAVE_HURRICAN: - Signal("Hurricane! All ships destroyed.", - NULL); + Msg("Hurricane! All ships destroyed."); break; case LEAVE_DRIVER: - Signal("The driver died.", NULL); + Msg("The driver died."); break; case LEAVE_SYNC: - Signal("Synchronization error.", NULL); + Msg("Synchronization error."); break; default: - Signal("A funny thing happened (%d).", - NULL, conditions); + Msg("A funny thing happened (%d).", conditions); } } else { switch (conditions) { @@ -83,7 +92,6 @@ leave(int conditions) printf("The driver died.\n"); break; case LEAVE_FORK: - perror("fork"); break; case LEAVE_SYNC: printf("Synchronization error\n."); @@ -95,34 +103,37 @@ leave(int conditions) } if (ms != 0) { - write_log(ms); + logger(ms); if (conditions != LEAVE_SYNC) { - makesignal(ms, "Captain %s relinquishing.", - NULL, mf->captain); - Write(W_END, ms, 0, 0, 0, 0); + makemsg(ms, "Captain %s relinquishing.", + mf->captain); + send_end(ms); Sync(); } } sync_close(!hasdriver); + sleep(5); cleanupscreen(); exit(0); } +/*ARGSUSED*/ void -choke(__unused int sig) +choke(int n __unused) { leave(LEAVE_QUIT); } +/*ARGSUSED*/ void -child(__unused int sig) +child(int n __unused) { - pid_t pid; int status; + int pid; signal(SIGCHLD, SIG_IGN); do { - pid = wait3(&status, WNOHANG, NULL); + pid = wait3(&status, WNOHANG, (struct rusage *)0); if (pid < 0 || (pid > 0 && !WIFSTOPPED(status))) hasdriver = 0; } while (pid > 0); diff --git a/games/sail/pl_2.c b/games/sail/pl_2.c index c20f104d6f..57d5756ef4 100644 --- a/games/sail/pl_2.c +++ b/games/sail/pl_2.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_2.c,v 1.13 2009/03/15 03:33:56 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,20 +27,91 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_2.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_2.c,v 1.4 1999/11/30 03:49:36 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_2.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_2.c,v 1.13 2009/03/15 03:33:56 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include "display.h" +#include "extern.h" #include "player.h" +/*ARGSUSED*/ +void +newturn(int n __unused) +{ + repaired = loaded = fired = changed = 0; + movebuf[0] = '\0'; + + alarm(0); + if (mf->readyL & R_LOADING) { + if (mf->readyL & R_DOUBLE) + mf->readyL = R_LOADING; + else + mf->readyL = R_LOADED; + } + if (mf->readyR & R_LOADING) { + if (mf->readyR & R_DOUBLE) + mf->readyR = R_LOADING; + else + mf->readyR = R_LOADED; + } + if (!hasdriver) + send_ddead(); + + display_hide_prompt(); + if (Sync() < 0) + leave(LEAVE_SYNC); + if (!hasdriver) + leave(LEAVE_DRIVER); + display_reshow_prompt(); + + if (turn % 50 == 0) + send_alive(); + if (mf->FS && (!mc->rig1 || windspeed == 6)) + send_fs(ms, 0); + if (mf->FS == 1) + send_fs(ms, 2); + + if (mf->struck) + leave(LEAVE_QUIT); + if (mf->captured != 0) + leave(LEAVE_CAPTURED); + if (windspeed == 7) + leave(LEAVE_HURRICAN); + + display_adjust_view(); + display_redraw(); + + signal(SIGALRM, newturn); + alarm(7); +} + void play(void) { struct ship *sp; for (;;) { - switch (sgetch("~\b", NULL, 0)) { + blockalarm(); + display_redraw(); + unblockalarm(); + + switch (sgetch("~ ", (struct ship *)0, 0)) { + case 14: /* ^N */ + display_scroll_pagedown(); + break; + case 16: /* ^P */ + display_scroll_pageup(); + break; case 'm': acceptmove(); break; @@ -52,7 +125,7 @@ play(void) unfoulplayer(); break; case 'v': - Signal("%s", NULL, version); + Msg("%s", version); break; case 'b': acceptboard(); @@ -70,26 +143,23 @@ play(void) repair(); break; case 'B': - Signal("'Hands to stations!'", NULL); + Msg("'Hands to stations!'"); unboard(ms, ms, 1); /* cancel DBP's */ unboard(ms, ms, 0); /* cancel offense */ break; case '\f': centerview(); - blockalarm(); - draw_board(); - draw_screen(); - unblockalarm(); + display_force_full_redraw(); break; case 'L': mf->loadL = L_EMPTY; mf->loadR = L_EMPTY; mf->readyL = R_EMPTY; mf->readyR = R_EMPTY; - Signal("Broadsides unloaded", NULL); + Msg("Broadsides unloaded"); break; case 'q': - Signal("Type 'Q' to quit", NULL); + Msg("Type 'Q' to quit"); break; case 'Q': leave(LEAVE_QUIT); @@ -100,50 +170,32 @@ play(void) eyeball(sp); break; case 'i': - if ((sp = closestenemy(ms, 0, 1)) == NULL) - Signal("No more ships left.", NULL); + if ((sp = closestenemy(ms, 0, 1)) == 0) + Msg("No more ships left."); else eyeball(sp); break; case 'C': centerview(); - blockalarm(); - draw_view(); - unblockalarm(); break; case 'U': upview(); - blockalarm(); - draw_view(); - unblockalarm(); break; case 'D': case 'N': downview(); - blockalarm(); - draw_view(); - unblockalarm(); break; case 'H': leftview(); - blockalarm(); - draw_view(); - unblockalarm(); break; case 'J': rightview(); - blockalarm(); - draw_view(); - unblockalarm(); break; case 'F': lookout(); break; case 'S': dont_adjust = !dont_adjust; - blockalarm(); - draw_turn(); - unblockalarm(); break; } } diff --git a/games/sail/pl_3.c b/games/sail/pl_3.c index e4d60b8224..b638acc415 100644 --- a/games/sail/pl_3.c +++ b/games/sail/pl_3.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_3.c,v 1.20 2009/03/15 03:33:56 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,11 +27,20 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_3.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_3.c,v 1.6 1999/11/30 03:49:37 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_3.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_3.c,v 1.20 2009/03/15 03:33:56 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include "extern.h" #include "player.h" void @@ -38,7 +49,7 @@ acceptcombat(void) int men = 0; int target, temp; int n, r; - int idx, rakehim, sternrake; + int index, rakehim, sternrake; int hhits = 0, ghits = 0, rhits = 0, chits = 0; int crew[3]; int load; @@ -80,18 +91,18 @@ acceptcombat(void) if (mf->struck || !crew[2]) goto cant; closest = closestenemy(ms, (r ? 'r' : 'l'), 1); - if (closest == NULL) + if (closest == 0) goto cant; if (closest->file->struck) goto cant; target = range(ms, closest); if (target > rangeofshot[load] || (!guns && target >= 3)) goto cant; - Signal("%s (%c%c) within range of %s broadside.", + Signal("$$ within range of %s broadside.", closest, r ? "right" : "left"); if (load > L_CHAIN && target < 6) { switch (sgetch("Aim for hull or rigging? ", - NULL, 1)) { + (struct ship *)0, 1)) { case 'r': shootat = RIGGING; break; @@ -100,14 +111,12 @@ acceptcombat(void) break; default: shootat = -1; - Signal("'Avast there! Hold your fire.'", - NULL); + Msg("'Avast there! Hold your fire.'"); } } else { - if (sgetch("Fire? ", NULL, 1) == 'n') { + if (sgetch("Fire? ", (struct ship *)0, 1) == 'n') { shootat = -1; - Signal("Belay that! Hold your fire.", - NULL); + Msg("Belay that! Hold your fire."); } else shootat = RIGGING; } @@ -123,42 +132,43 @@ acceptcombat(void) sternrake = temp > 4 && temp < 6; if (rakehim) { if (!sternrake) - Signal("Raking the %s!", closest); + Msg("Raking the %s!", closest->shipname); else - Signal("Stern Rake! %s splintering!", closest); + Msg("Stern Rake! %s splintering!", + closest->shipname); } - idx = guns; + index = guns; if (target < 3) - idx += car; - idx = (idx - 1)/3; - idx = idx > 8 ? 8 : idx; + index += car; + index = (index - 1)/3; + index = index > 8 ? 8 : index; if (!rakehim) - hit = HDT[idx][target-1]; + hit = HDT[index][target-1]; else - hit = HDTrake[idx][target-1]; + hit = HDTrake[index][target-1]; if (rakehim && sternrake) hit++; - hit += QUAL[idx][mc->qual-1]; + hit += QUAL[index][mc->qual-1]; for (n = 0; n < 3 && mf->captured == 0; n++) if (!crew[n]) { - if (idx <= 5) + if (index <= 5) hit--; else hit -= 2; } if (ready & R_INITIAL) { - if (idx <= 3) + if (index <= 3) hit++; else hit += 2; } if (mf->captured != 0) { - if (idx <= 1) + if (index <= 1) hit--; else hit -= 2; } - hit += AMMO[idx][load - 1]; + hit += AMMO[index][load - 1]; if (((temp = mc->class) >= 5 || temp == 1) && windspeed == 5) hit--; if (windspeed == 6 && temp == 4) @@ -166,11 +176,11 @@ acceptcombat(void) if (windspeed == 6 && temp <= 3) hit--; if (hit >= 0) { - roll = die(); + roll = dieroll(); if (load == L_GRAPE) chits = hit; else { - struct Tables *t; + const struct Tables *t; if (hit > 10) hit = 10; t = &(shootat == RIGGING ? RigTable : HullTable) @@ -186,12 +196,11 @@ acceptcombat(void) hhits = 0; } } - table(shootat, load, hit, closest, ms, roll); + table(ms, closest, shootat, load, hit, roll); } - Signal("Damage inflicted on the %s:", - NULL, closest->shipname); - Signal("\t%d HULL, %d GUNS, %d CREW, %d RIGGING", - NULL, hhits, ghits, chits, rhits); + Msg("Damage inflicted on the %s:", closest->shipname); + Msg("\t%d HULL, %d GUNS, %d CREW, %d RIGGING", + hhits, ghits, chits, rhits); if (!r) { mf->loadL = L_EMPTY; mf->readyL = R_EMPTY; @@ -201,12 +210,8 @@ acceptcombat(void) } continue; cant: - Signal("Unable to fire %s broadside", - NULL, r ? "right" : "left"); + Msg("Unable to fire %s broadside", r ? "right" : "left"); } - blockalarm(); - draw_stat(); - unblockalarm(); } void @@ -220,32 +225,29 @@ grapungrap(void) continue; if (range(ms, sp) > 1 && !grappled2(ms, sp)) continue; - switch (sgetch("Attempt to grapple or ungrapple %s (%c%c): ", + switch (sgetch("Attempt to grapple or ungrapple $$: ", sp, 1)) { case 'g': - if (die() < 3 + if (dieroll() < 3 || ms->nationality == capship(sp)->nationality) { - Write(W_GRAP, ms, sp->file->index, 0, 0, 0); - Write(W_GRAP, sp, player, 0, 0, 0); - Signal("Attempt succeeds!", NULL); - makesignal(ms, "grappled with %s (%c%c)", sp); + send_grap(ms, sp->file->index); + send_grap(sp, player); + Msg("Attempt succeeds!"); + makesignal(ms, "grappled with $$", sp); } else - Signal("Attempt fails.", NULL); + Msg("Attempt fails."); break; case 'u': for (i = grappled2(ms, sp); --i >= 0;) { if (ms->nationality == capship(sp)->nationality - || die() < 3) { + || dieroll() < 3) { cleangrapple(ms, sp, 0); - Signal("Attempt succeeds!", - NULL); - makesignal(ms, - "ungrappling with %s (%c%c)", + Msg("Attempt succeeds!"); + makesignal(ms, "ungrappling with $$", sp); } else - Signal("Attempt fails.", - NULL); + Msg("Attempt fails."); } break; } @@ -261,15 +263,15 @@ unfoulplayer(void) foreachship(to) { if (fouled2(ms, to) == 0) continue; - if (sgetch("Attempt to unfoul with the %s (%c%c)? ", to, 1) != 'y') + if (sgetch("Attempt to unfoul with the $$? ", to, 1) != 'y') continue; for (i = fouled2(ms, to); --i >= 0;) { - if (die() <= 2) { + if (dieroll() <= 2) { cleanfoul(ms, to, 0); - Signal("Attempt succeeds!", NULL); - makesignal(ms, "Unfouling %s (%c%c)", to); + Msg("Attempt succeeds!"); + makesignal(ms, "Unfouling $$", to); } else - Signal("Attempt fails.", NULL); + Msg("Attempt fails."); } } } diff --git a/games/sail/pl_4.c b/games/sail/pl_4.c index 37bacac6c6..710be027a0 100644 --- a/games/sail/pl_4.c +++ b/games/sail/pl_4.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_4.c,v 1.16 2009/03/14 22:52:52 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,12 +27,20 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_4.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_4.c,v 1.5 1999/11/30 03:49:37 billf Exp $ - * $DragonFly: src/games/sail/pl_4.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_4.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_4.c,v 1.16 2009/03/14 22:52:52 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include "extern.h" #include "player.h" void @@ -45,19 +55,19 @@ changesail(void) if (mc->crew3 && rig) { if (!full) { if (sgetch("Increase to Full sails? ", - NULL, 1) == 'y') { + (struct ship *)0, 1) == 'y') { changed = 1; - Write(W_FS, ms, 1, 0, 0, 0); + send_fs(ms, 1); } } else { if (sgetch("Reduce to Battle sails? ", - NULL, 1) == 'y') { - Write(W_FS, ms, 0, 0, 0, 0); + (struct ship *)0, 1) == 'y') { + send_fs(ms, 0); changed = 1; } } } else if (!rig) - Signal("Sails rent to pieces", NULL); + Msg("Sails rent to pieces"); } void @@ -72,7 +82,7 @@ acceptsignal(void) ; p[-1] = '"'; *p = 0; - Writestr(W_SIGNAL, ms, buf); + send_signal(ms, buf); } void @@ -85,7 +95,7 @@ lookout(void) sgetstr("What ship? ", buf, sizeof buf); foreachship(sp) { c = *countryname[sp->nationality]; - if ((c == *buf || tolower(c) == *buf || colours(sp) == *buf) + if ((tolower((unsigned char)c) == *buf || colours(sp) == *buf) && (sp->file->stern == buf[1] || sterncolour(sp) == buf[1] || buf[1] == '?')) { eyeball(sp); @@ -94,7 +104,7 @@ lookout(void) } const char * -saywhat(struct ship *sp, char flag) +saywhat(struct ship *sp, int flag) { if (sp->file->captain[0]) return sp->file->captain; @@ -114,12 +124,12 @@ eyeball(struct ship *ship) int i; if (ship->file->dir != 0) { - Signal("Sail ho! (range %d, %s)", - NULL, range(ms, ship), saywhat(ship, 0)); + Msg("Sail ho! (range %d, %s)", + range(ms, ship), saywhat(ship, 0)); i = portside(ms, ship, 1) - mf->dir; if (i <= 0) i += 8; - Signal("%s (%c%c) %s %s %s.", + Signal("$$ %s %s %s.", ship, countryname[ship->nationality], classname[ship->specs->class], directionname[i]); } diff --git a/games/sail/pl_5.c b/games/sail/pl_5.c index d8a10f2f8d..240ac0b9d9 100644 --- a/games/sail/pl_5.c +++ b/games/sail/pl_5.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_5.c,v 1.26 2019/02/03 03:19:25 mrg Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,39 +27,51 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_5.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_5.c,v 1.6 1999/11/30 03:49:37 billf Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_5.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_5.c,v 1.26 2019/02/03 03:19:25 mrg Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include #include +#include "extern.h" #include "player.h" +#include "display.h" #define turnfirst(x) (*x == 'r' || *x == 'l') -static void parties(int [3], struct ship *, char, char); +static void parties(struct ship *, int *, int, int); void acceptmove(void) { int ta; int ma; - char af; - int moved = 0; + bool af; + bool moved = false; int vma, dir; - char prompt[60]; + char promptstr[60]; char buf[60], last = '\0'; char *p; if (!mc->crew3 || snagged(ms) || !windspeed) { - Signal("Unable to move", NULL); + Msg("Unable to move"); return; } ta = maxturns(ms, &af); ma = maxmove(ms, mf->dir, 0); - sprintf(prompt, "move (%d,%c%d): ", ma, af ? '\'' : ' ', ta); - sgetstr(prompt, buf, sizeof buf); + snprintf(promptstr, sizeof(promptstr), + "move (%d,%c%d): ", ma, af ? '\'' : ' ', ta); + sgetstr(promptstr, buf, sizeof buf); dir = mf->dir; vma = ma; for (p = buf; *p; p++) @@ -71,8 +85,7 @@ acceptmove(void) else if (dir == 9) dir = 1; if (last == 't') { - Signal("Ship can't turn that fast.", - NULL); + Msg("Ship can't turn that fast."); *p-- = '\0'; } last = 't'; @@ -99,48 +112,45 @@ acceptmove(void) case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (last == '0') { - Signal("Can't move that fast.", - NULL); + Msg("Can't move that fast."); *p-- = '\0'; } last = '0'; - moved = 1; + moved = true; ma -= *p - '0'; vma -= *p - '0'; if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; default: - if (!isspace(*p)) { - Signal("Input error.", NULL); + if (!isspace((unsigned char)*p)) { + Msg("Input error."); *p-- = '\0'; } } if ((ta < 0 && moved) || (vma < 0 && moved) || (af && turnfirst(buf) && moved)) { - Signal("Movement error.", NULL); + Msg("Movement error."); if (ta < 0 && moved) { if (mf->FS == 1) { - Write(W_FS, ms, 0, 0, 0, 0); - Signal("No hands to set full sails.", - NULL); + send_fs(ms, 0); + Msg("No hands to set full sails."); } } else if (ma >= 0) buf[1] = '\0'; } if (af && !moved) { if (mf->FS == 1) { - Write(W_FS, ms, 0, 0, 0, 0); - Signal("No hands to set full sails.", - NULL); + send_fs(ms, 0); + Msg("No hands to set full sails."); } } if (*buf) - strcpy(movebuf, buf); + strlcpy(movebuf, buf, sizeof(movebuf)); else - strcpy(movebuf, "d"); - Writestr(W_MOVE, ms, movebuf); - Signal("Helm: %s.", NULL, movebuf); + strlcpy(movebuf, "d", sizeof(movebuf)); + send_move(ms, movebuf); + Msg("Helm: %s.", movebuf); } void @@ -178,26 +188,24 @@ acceptboard(void) if (ms->nationality == capship(sp)->nationality) continue; if (meleeing(ms, sp) && crew[2]) { - c = sgetch("How many more to board the %s (%c%c)? ", + c = sgetch("How many more to board the $$? ", sp, 1); - parties(crew, sp, 0, c); + parties(sp, crew, 0, c); } else if ((fouled2(ms, sp) || grappled2(ms, sp)) && crew[2]) { - c = sgetch("Crew sections to board the %s (%c%c) (3 max) ?", sp, 1); - parties(crew, sp, 0, c); + c = sgetch("Crew sections to board the $$ (3 max) ?", + sp, 1); + parties(sp, crew, 0, c); } } if (crew[2]) { c = sgetch("How many sections to repel boarders? ", - NULL, 1); - parties(crew, ms, 1, c); + (struct ship *)0, 1); + parties(ms, crew, 1, c); } - blockalarm(); - draw_slot(); - unblockalarm(); } static void -parties(int crew[3], struct ship *to, char isdefense, char buf) +parties(struct ship *to, int *crew, int isdefense, int buf) { int k, j, men; struct BP *ptr; @@ -209,7 +217,7 @@ parties(int crew[3], struct ship *to, char isdefense, char buf) ptr = isdefense ? to->file->DBP : to->file->OBP; for (j = 0; j < NBP && ptr[j].turnsent; j++) ; - if (!ptr[j].turnsent && buf > '0') { + if (j < NBP && !ptr[j].turnsent && buf > '0') { men = 0; for (k = 0; k < 3 && buf > '0'; k++) { men += crew[k] @@ -219,34 +227,24 @@ parties(int crew[3], struct ship *to, char isdefense, char buf) buf--; } if (buf > '0') - Signal("Sending all crew sections.", - NULL); - Write(isdefense ? W_DBP : W_OBP, ms, - j, turn, to->file->index, men); + Msg("Sending all crew sections."); + if (isdefense) { + send_dbp(ms, j, turn, to->file->index, men); + } else { + send_obp(ms, j, turn, to->file->index, men); + } if (isdefense) { - wmove(slot_w, 2, 0); for (k=0; k < NBP; k++) - if (temp[k] && !crew[k]) - waddch(slot_w, k + '1'); - else - wmove(slot_w, 2, 1 + k); - mvwaddstr(slot_w, 3, 0, "DBP"); - makesignal(ms, "repelling boarders", - NULL); + display_set_dbp(k, + temp[k] && !crew[k]); + makemsg(ms, "repelling boarders"); } else { - wmove(slot_w, 0, 0); for (k=0; k < NBP; k++) - if (temp[k] && !crew[k]) - waddch(slot_w, k + '1'); - else - wmove(slot_w, 0, 1 + k); - mvwaddstr(slot_w, 1, 0, "OBP"); - makesignal(ms, "boarding the %s (%c%c)", to); + display_set_obp(k, + temp[k] && !crew[k]); + makesignal(ms, "boarding the $$", to); } - blockalarm(); - wrefresh(slot_w); - unblockalarm(); } else - Signal("Sending no crew sections.", NULL); + Msg("Sending no crew sections."); } } diff --git a/games/sail/pl_6.c b/games/sail/pl_6.c index b4eebea84c..0a5200664f 100644 --- a/games/sail/pl_6.c +++ b/games/sail/pl_6.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_6.c,v 1.14 2009/03/15 03:33:56 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,15 +27,22 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_6.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_6.c,v 1.5 1999/11/30 03:49:37 billf Exp $ - * $DragonFly: src/games/sail/pl_6.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ */ +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_6.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_6.c,v 1.14 2009/03/15 03:33:56 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include "extern.h" #include "player.h" -static bool turned(void); +static int turned(void); void repair(void) @@ -47,10 +56,10 @@ repair(void) ? (ptr->x += count, count = 0) : (count -= m - ptr->x, ptr->x = m)) if (repaired || loaded || fired || changed || turned()) { - Signal("No hands free to repair", NULL); + Msg("No hands free to repair"); return; } - c = sgetch("Repair (hull, guns, rigging)? ", NULL, 1); + c = sgetch("Repair (hull, guns, rigging)? ", (struct ship *)0, 1); switch (c) { case 'h': repairs = &mf->RH; @@ -62,7 +71,7 @@ repair(void) repairs = &mf->RR; break; default: - Signal("Avast heaving!", NULL); + Msg("Avast heaving!"); return; } if (++*repairs >= 3) { @@ -72,7 +81,7 @@ repair(void) int max = ptr->guns/4; if (ptr->hull < max) { FIX(hull, max); - Write(W_HULL, ms, ptr->hull, 0, 0, 0); + send_hull(ms, ptr->hull); } break; } @@ -81,15 +90,13 @@ repair(void) int max = ptr->guns/5 - ptr->carL; if (ptr->gunL < max) { FIX(gunL, max); - Write(W_GUNL, ms, ptr->gunL, - ptr->carL, 0, 0); + send_gunl(ms, ptr->gunL, ptr->carL); } } else { int max = ptr->guns/5 - ptr->carR; if (ptr->gunR < max) { FIX(gunR, max); - Write(W_GUNR, ms, ptr->gunR, - ptr->carR, 0, 0); + send_gunr(ms, ptr->gunR, ptr->carR); } } break; @@ -97,39 +104,33 @@ repair(void) #define X 2 if (ptr->rig4 >= 0 && ptr->rig4 < X) { FIX(rig4, X); - Write(W_RIG4, ms, ptr->rig4, 0, 0, 0); + send_rig4(ms, ptr->rig4); } if (count && ptr->rig3 < X) { FIX(rig3, X); - Write(W_RIG3, ms, ptr->rig3, 0, 0, 0); + send_rig3(ms, ptr->rig3); } if (count && ptr->rig2 < X) { FIX(rig2, X); - Write(W_RIG2, ms, ptr->rig2, 0, 0, 0); + send_rig2(ms, ptr->rig2); } if (count && ptr->rig1 < X) { FIX(rig1, X); - Write(W_RIG1, ms, ptr->rig1, 0, 0, 0); + send_rig1(ms, ptr->rig1); } break; } if (count == 2) { - Signal("Repairs completed.", NULL); + Msg("Repairs completed."); *repairs = 2; } else { *repairs = 0; - blockalarm(); - draw_stat(); - unblockalarm(); } } - blockalarm(); - draw_slot(); - unblockalarm(); repaired = 1; } -static bool +static int turned(void) { char *p; @@ -147,14 +148,14 @@ loadplayer(void) int loadL, loadR, ready, load; if (!mc->crew3) { - Signal("Out of crew", NULL); + Msg("Out of crew"); return; } loadL = mf->loadL; loadR = mf->loadR; if (!loadL && !loadR) { c = sgetch("Load which broadside (left or right)? ", - NULL, 1); + (struct ship *)0, 1); if (c == 'r') loadL = 1; else @@ -162,7 +163,7 @@ loadplayer(void) } if ((!loadL && loadR) || (loadL && !loadR)) { c = sgetch("Reload with (round, double, chain, grape)? ", - NULL, 1); + (struct ship *)0, 1); switch (c) { case 'r': load = L_ROUND; @@ -181,8 +182,7 @@ loadplayer(void) ready = 0; break; default: - Signal("Broadside not loaded.", - NULL); + Msg("Broadside not loaded."); return; } if (!loadR) { diff --git a/games/sail/pl_7.c b/games/sail/pl_7.c index 542ede7486..a1ad878733 100644 --- a/games/sail/pl_7.c +++ b/games/sail/pl_7.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_7.c,v 1.42 2011/08/26 06:18:18 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,46 +27,151 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_7.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_7.c,v 1.7 1999/11/30 03:49:37 billf Exp $ */ -#include +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_7.c,v 1.42 2011/08/26 06:18:18 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include #include +#include +#include "array.h" +#include "extern.h" #include "player.h" +#include "display.h" + +/* + * Use values above KEY_MAX for custom keycodes. (blymn@ says this is ok) + */ +#define KEY_ESC(ch) (KEY_MAX+10+ch) /* * Display interface */ -static char sc_hasprompt; +static void draw_view(void); +static void draw_turn(void); +static void draw_stat(void); +static void draw_slot(void); +static void draw_board(void); + +static struct stringarray *sc_lines; +static unsigned sc_scrollup; +static bool sc_hasprompt; +static bool sc_hideprompt; static const char *sc_prompt; static const char *sc_buf; -static int sc_line; -static void Scroll(void); -static void prompt(const char *, struct ship *); -static void endprompt(char); -static void adjustview(void); +static WINDOW *view_w; +static WINDOW *turn_w; +static WINDOW *stat_w; +static WINDOW *slot_w; +static WINDOW *scroll_w; + +static bool obp[3]; +static bool dbp[3]; + +int done_curses; +static bool ingame; +int loaded, fired, changed, repaired; +int dont_adjust; +static int viewrow, viewcol; +char movebuf[sizeof SHIP(0)->file->movebuf]; +int player; +struct ship *ms; /* memorial structure, &cc->ship[player] */ +struct File *mf; /* ms->file */ +struct shipspecs *mc; /* ms->specs */ + +//////////////////////////////////////////////////////////// +// overall initialization + +static +void +define_esc_key(int ch) +{ + char seq[3] = { '\x1b', ch, 0 }; + + define_key(seq, KEY_ESC(ch)); +} void initscreen(void) { - /* initscr() already done in SCREENTEST() */ + int ch; + + sc_lines = stringarray_create(); + if (sc_lines == NULL) { + err(1, "malloc"); + } + + if (signal(SIGTSTP, SIG_DFL) == SIG_ERR) { + err(1, "signal(SIGTSTP)"); + } + + if (initscr() == NULL) { + errx(1, "Can't sail on this terminal."); + } + if (STAT_R >= COLS || SCROLL_Y <= 0) { + errx(1, "Window/terminal not large enough."); + } + view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L); slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L); scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L); stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L); turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L); - done_curses++; + + if (view_w == NULL || + slot_w == NULL || + scroll_w == NULL || + stat_w == NULL || + turn_w == NULL) { + endwin(); + errx(1, "Curses initialization failed."); + } + leaveok(view_w, 1); leaveok(slot_w, 1); leaveok(stat_w, 1); leaveok(turn_w, 1); noecho(); cbreak(); + + /* + * Define esc-x keys + */ +#if 0 + for (ch = 0; ch < 127; ch++) { + if (ch != '[' && ch != 'O') { + define_esc_key(ch); + } + } +#else + (void)ch; + (void)define_esc_key; +#endif + + keypad(stdscr, 1); + keypad(view_w, 1); + keypad(slot_w, 1); + keypad(scroll_w, 1); + keypad(stat_w, 1); + keypad(turn_w, 1); + + done_curses++; } void @@ -72,65 +179,219 @@ cleanupscreen(void) { /* alarm already turned off */ if (done_curses) { - wmove(scroll_w, SCROLL_Y - 1, 0); - wclrtoeol(scroll_w); - draw_screen(); + if (ingame) { + wmove(scroll_w, SCROLL_Y - 1, 0); + wclrtoeol(scroll_w); + display_redraw(); + } else { + move(LINES-1, 0); + clrtoeol(); + } endwin(); } } -void -newturn(__unused int sig) +//////////////////////////////////////////////////////////// +// curses utility functions + +/* + * fill to eol with spaces + * (useful with A_REVERSE since cleartoeol() does not clear to reversed) + */ +static void +filltoeol(void) { - repaired = loaded = fired = changed = 0; - movebuf[0] = '\0'; + int x; - alarm(0); - if (mf->readyL & R_LOADING) { - if (mf->readyL & R_DOUBLE) - mf->readyL = R_LOADING; - else - mf->readyL = R_LOADED; + for (x = getcurx(stdscr); x < COLS; x++) { + addch(' '); } - if (mf->readyR & R_LOADING) { - if (mf->readyR & R_DOUBLE) - mf->readyR = R_LOADING; - else - mf->readyR = R_LOADED; +} + +/* + * Add a maybe-selected string. + * + * Place strings starting at (Y0, X0); this is string ITEM; CURITEM + * is the selected one; WIDTH is the total width. STR is the string. + */ +static void +mvaddselstr(int y, int x0, int item, int curitem, + size_t width, const char *str) +{ + size_t i, len; + + len = strlen(str); + + move(y, x0); + if (curitem == item) { + attron(A_REVERSE); + } + addstr(str); + if (curitem == item) { + for (i=len; i 0) { + (*posp)--; } - if (!hasdriver) - Write(W_DDEAD, SHIP(0), 0, 0, 0, 0); + if (scrollp != NULL) { + if (*posp < *scrollp) { + *scrollp = *posp; + } + } +} + +/* + * Move down by 1, scrolling if needed. MAX is the total number of + * items; VISIBLE is the number that can be visible at once. + */ +static void +down(int *posp, int *scrollp, int max, int visible) +{ + if (max > 0 && *posp < max - 1) { + (*posp)++; + } + if (scrollp != NULL) { + if (*posp > *scrollp + visible - 1) { + *scrollp = *posp - visible + 1; + } + } +} + +/* + * Complain briefly. + */ +static void __printflike(3, 4) +oops(int y, int x, const char *fmt, ...) +{ + int oy, ox; + va_list ap; + + oy = getcury(stdscr); + ox = getcurx(stdscr); + move(y, x); + va_start(ap, fmt); + vwprintw(stdscr, fmt, ap); + va_end(ap); + move(oy, ox); + wrefresh(stdscr); + sleep(1); +} + +//////////////////////////////////////////////////////////// +// scrolling message area + +static void +scrollarea_add(const char *text) +{ + char *copy; + int errsave; - if (sc_hasprompt) { - wmove(scroll_w, sc_line, 0); - wclrtoeol(scroll_w); + copy = strdup(text); + if (copy == NULL) { + goto nomem; } - if (Sync() < 0) - leave(LEAVE_SYNC); - if (!hasdriver) - leave(LEAVE_DRIVER); - if (sc_hasprompt) - wprintw(scroll_w, "%s%s", sc_prompt, sc_buf); + if (stringarray_add(sc_lines, copy, NULL)) { + goto nomem; + } + return; + +nomem: + /* + * XXX this should use leave(), but that won't + * currently work right. + */ + errsave = errno; +#if 0 + leave(LEAVE_MALLOC); +#else + cleanupscreen(); + sync_close(!hasdriver); + errno = errsave; + err(1, "malloc"); +#endif +} + +static void +draw_scroll(void) +{ + unsigned total_lines; + unsigned visible_lines; + unsigned index_of_top; + unsigned index_of_y; + unsigned y; + unsigned cursorx; - if (turn % 50 == 0) - Write(W_ALIVE, SHIP(0), 0, 0, 0, 0); - if (mf->FS && (!mc->rig1 || windspeed == 6)) - Write(W_FS, ms, 0, 0, 0, 0); - if (mf->FS == 1) - Write(W_FS, ms, 2, 0, 0, 0); + werase(scroll_w); - if (mf->struck) - leave(LEAVE_QUIT); - if (mf->captured != 0) - leave(LEAVE_CAPTURED); - if (windspeed == 7) - leave(LEAVE_HURRICAN); + /* XXX: SCROLL_Y and whatnot should be unsigned too */ + visible_lines = SCROLL_Y - 1; - adjustview(); - draw_screen(); + total_lines = stringarray_num(sc_lines); + if (total_lines > visible_lines) { + index_of_top = total_lines - visible_lines; + } else { + index_of_top = 0; + } + if (index_of_top < sc_scrollup) { + index_of_top = 0; + } else { + index_of_top -= sc_scrollup; + } - signal(SIGALRM, newturn); - alarm(7); + for (y = 0; y < visible_lines; y++) { + index_of_y = index_of_top + y; + if (index_of_y >= total_lines) { + break; + } + wmove(scroll_w, y, 0); + waddstr(scroll_w, stringarray_get(sc_lines, index_of_y)); + } + if (sc_hasprompt && !sc_hideprompt) { + wmove(scroll_w, SCROLL_Y-1, 0); + waddstr(scroll_w, sc_prompt); + waddstr(scroll_w, sc_buf); + cursorx = strlen(sc_prompt) + strlen(sc_buf); + wmove(scroll_w, SCROLL_Y-1, cursorx); + } + else { + wmove(scroll_w, SCROLL_Y-1, 0); + } } /*VARARGS2*/ @@ -139,69 +400,107 @@ Signal(const char *fmt, struct ship *ship, ...) { va_list ap; char format[BUFSIZ]; + char buf[BUFSIZ]; if (!done_curses) return; va_start(ap, ship); - if (*fmt == '\a') - putchar(*fmt++); - if (ship == NULL) - vw_printw(scroll_w, fmt, ap); - else { - fmtship(format, sizeof(format), fmt, ship); - vw_printw(scroll_w, format, ap); + if (*fmt == '\a') { + beep(); + fmt++; } + fmtship(format, sizeof(format), fmt, ship); + vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); - Scroll(); + scrollarea_add(buf); } -static void -Scroll(void) +/*VARARGS2*/ +void +Msg(const char *fmt, ...) { - if (++sc_line >= SCROLL_Y) - sc_line = 0; - wmove(scroll_w, sc_line, 0); - wclrtoeol(scroll_w); + va_list ap; + char buf[BUFSIZ]; + + if (!done_curses) + return; + va_start(ap, fmt); + if (*fmt == '\a') { + beep(); + fmt++; + } + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + scrollarea_add(buf); } static void prompt(const char *p, struct ship *ship) { - static char buf[60]; + static char buf[BUFSIZ]; - if (ship != NULL) { - printf(buf, p, ship->shipname, colours(ship), - sterncolour(ship)); - p = buf; - } - sc_prompt = p; + fmtship(buf, sizeof(buf), p, ship); + sc_prompt = buf; sc_buf = ""; - sc_hasprompt = 1; - waddstr(scroll_w, p); + sc_hasprompt = true; } static void -endprompt(char flag) +endprompt(void) +{ + sc_prompt = NULL; + sc_buf = NULL; + sc_hasprompt = false; +} + +/* + * Next two functions called from newturn() to poke display. Shouldn't + * exist... XXX + */ + +void +display_hide_prompt(void) +{ + sc_hideprompt = true; + draw_scroll(); + wrefresh(scroll_w); +} + +void +display_reshow_prompt(void) { - sc_hasprompt = 0; - if (flag) - Scroll(); + sc_hideprompt = false; + draw_scroll(); + wrefresh(scroll_w); } + int -sgetch(const char *p, struct ship *ship, char flag) +sgetch(const char *p, struct ship *ship, int flag) { int c; + char input[2]; prompt(p, ship); + input[0] = '\0'; + input[1] = '\0'; + sc_buf = input; blockalarm(); + draw_scroll(); wrefresh(scroll_w); + fflush(stdout); unblockalarm(); while ((c = wgetch(scroll_w)) == EOF) ; - if (flag && c >= ' ' && c < 0x7f) - waddch(scroll_w, c); - endprompt(flag); + if (flag && c >= ' ' && c < 0x7f) { + blockalarm(); + input[0] = c; + draw_scroll(); + wrefresh(scroll_w); + fflush(stdout); + unblockalarm(); + } + endprompt(); return c; } @@ -211,47 +510,63 @@ sgetstr(const char *pr, char *buf, int n) int c; char *p = buf; - prompt(pr, NULL); + prompt(pr, (struct ship *)0); sc_buf = buf; for (;;) { *p = 0; blockalarm(); + draw_scroll(); wrefresh(scroll_w); + fflush(stdout); unblockalarm(); while ((c = wgetch(scroll_w)) == EOF) ; switch (c) { case '\n': case '\r': - endprompt(1); + endprompt(); return; case '\b': if (p > buf) { - waddstr(scroll_w, "\b \b"); + /*waddstr(scroll_w, "\b \b");*/ p--; } break; default: if (c >= ' ' && c < 0x7f && p < buf + n - 1) { *p++ = c; - waddch(scroll_w, c); + /*waddch(scroll_w, c);*/ } else - putchar(CTRL('g')); + beep(); } } } +//////////////////////////////////////////////////////////// +// drawing of other panes + +void +display_force_full_redraw(void) +{ + clear(); +} + void -draw_screen(void) +display_redraw(void) { + draw_board(); draw_view(); draw_turn(); draw_stat(); draw_slot(); - wrefresh(scroll_w); /* move the cursor */ + draw_scroll(); + /* move the cursor */ + wrefresh(scroll_w); + /* paranoia */ + fflush(stdout); } -void +static void draw_view(void) { struct ship *sp; @@ -275,7 +590,7 @@ draw_view(void) wrefresh(view_w); } -void +static void draw_turn(void) { wmove(turn_w, 0, 0); @@ -283,7 +598,7 @@ draw_turn(void) wrefresh(turn_w); } -void +static void draw_stat(void) { wmove(stat_w, STAT_1, 0); @@ -327,16 +642,28 @@ draw_stat(void) void draw_slot(void) { + int i; + if (!boarding(ms, 0)) { mvwaddstr(slot_w, 0, 0, " "); mvwaddstr(slot_w, 1, 0, " "); - } else + } else { + wmove(slot_w, 0, 0); + for (i = 0; i < 3; i++) { + waddch(slot_w, obp[i] ? '1'+i : ' '); + } mvwaddstr(slot_w, 1, 0, "OBP"); + } if (!boarding(ms, 1)) { mvwaddstr(slot_w, 2, 0, " "); mvwaddstr(slot_w, 3, 0, " "); - } else + } else { + wmove(slot_w, 2, 0); + for (i = 0; i < 3; i++) { + waddch(slot_w, dbp[i] ? '1'+i : ' '); + } mvwaddstr(slot_w, 3, 0, "DBP"); + } wmove(slot_w, SLOT_Y-4, 0); if (mf->RH) @@ -393,15 +720,13 @@ draw_board(void) { int n; - clear(); + erase(); werase(view_w); werase(slot_w); werase(scroll_w); werase(stat_w); werase(turn_w); - sc_line = 0; - move(BOX_T, BOX_L); for (n = 0; n < BOX_X; n++) addch('-'); @@ -418,12 +743,14 @@ draw_board(void) mvaddch(BOX_B, BOX_R, '+'); refresh(); +#if 0 #define WSaIM "Wooden Ships & Iron Men" wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2); waddstr(view_w, WSaIM); wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2); waddstr(view_w, cc->name); wrefresh(view_w); +#endif move(LINE_T, LINE_L); printw("Class %d %s (%d guns) '%s' (%c%c)", @@ -436,6 +763,49 @@ draw_board(void) refresh(); } +void +display_set_obp(int which, bool show) +{ + obp[which] = show; +} + +void +display_set_dbp(int which, bool show) +{ + dbp[which] = show; +} + +//////////////////////////////////////////////////////////// +// external actions on the display + +void +display_scroll_pageup(void) +{ + unsigned total_lines, visible_lines, limit; + unsigned pagesize = SCROLL_Y - 2; + + total_lines = stringarray_num(sc_lines); + visible_lines = SCROLL_Y - 1; + limit = total_lines - visible_lines; + + sc_scrollup += pagesize; + if (sc_scrollup > limit) { + sc_scrollup = limit; + } +} + +void +display_scroll_pagedown(void) +{ + unsigned pagesize = SCROLL_Y - 2; + + if (sc_scrollup < pagesize) { + sc_scrollup = 0; + } else { + sc_scrollup -= pagesize; + } +} + void centerview(void) { @@ -467,8 +837,9 @@ rightview(void) viewcol += VIEW_X / 5; } -static void -adjustview(void) +/* Called from newturn()... rename? */ +void +display_adjust_view(void) { if (dont_adjust) return; @@ -481,3 +852,738 @@ adjustview(void) else if (mf->col > viewcol + (VIEW_X - VIEW_X/8)) viewcol = mf->col - VIEW_X/8; } + +//////////////////////////////////////////////////////////// +// starting game + +static bool shipselected; +static int loadpos; + +static int +nextload(int load) +{ + switch (load) { + case L_ROUND: return L_GRAPE; + case L_GRAPE: return L_CHAIN; + case L_CHAIN: return L_DOUBLE; + case L_DOUBLE: return L_ROUND; + } + return L_ROUND; +} + +static int +loadbychar(int ch) +{ + switch (ch) { + case 'r': return L_ROUND; + case 'g': return L_GRAPE; + case 'c': return L_CHAIN; + case 'd': return L_DOUBLE; + } + return L_ROUND; +} + +static const char * +loadstr(int load) +{ + switch (load) { + case L_ROUND: return "round"; + case L_GRAPE: return "grape"; + case L_CHAIN: return "chain"; + case L_DOUBLE: return "double"; + } + return "???"; +} + +static void +displayshiplist(void) +{ + struct ship *sp; + int which; + + erase(); + + attron(A_BOLD); + mvaddstr(1, 4, cc->name); + attroff(A_BOLD); + + which = 0; + foreachship(sp) { + mvselprintw(which + 3, 4, which, player, 60, + " %2d: %-10s %-15s (%-2d pts) %s", + sp->file->index, + countryname[sp->nationality], + sp->shipname, + sp->specs->pts, + saywhat(sp, 1)); + which++; + } + + if (!shipselected) { + mvaddstr(15, 4, "Choose your ship"); + move(player + 3, 63); + } else { + mvselprintw(15, 4, 0, loadpos, 32, + "Initial left broadside: %s", loadstr(mf->loadL)); + mvselprintw(16, 4, 1, loadpos, 32, + "Initial right broadside: %s", loadstr(mf->loadR)); + mvselprintw(17, 4, 2, loadpos, 32, "Set sail"); + move(loadpos+15, 35); + } + + wrefresh(stdscr); +} + +static int +pickship(void) +{ + struct File *fp; + struct ship *sp; + bool done; + int ch; + + for (;;) { + foreachship(sp) + if (sp->file->captain[0] == 0 && !sp->file->struck + && sp->file->captured == 0) + break; + if (sp >= ls) { + return -1; + } + player = sp - SHIP(0); + if (randomize) { + /* nothing */ + } else { + done = false; + while (!done) { + displayshiplist(); + + ch = getch(); + switch (ch) { + case 12 /*^L*/: + clear(); + break; + case '\r': + case '\n': + done = true; + break; + case 7 /*^G*/: + case 8 /*^H*/: + case 27 /*ESC*/: + case 127 /*^?*/: + beep(); + break; + case 16 /*^P*/: + case KEY_UP: + up(&player, NULL); + break; + case 14 /*^N*/: + case KEY_DOWN: + down(&player, NULL, cc->vessels, + cc->vessels); + break; + default: + beep(); + break; + } + } + } + if (player < 0) + continue; + if (Sync() < 0) + leave(LEAVE_SYNC); + fp = SHIP(player)->file; + if (fp->captain[0] || fp->struck || fp->captured != 0) + oops(16, 4, "That ship is taken."); + else + break; + } + return 0; +} + +static void +pickload(void) +{ + bool done; + int ch; + + mf->loadL = L_ROUND; + mf->loadR = L_ROUND; + + loadpos = 0; + done = false; + while (!done) { + displayshiplist(); + + ch = getch(); + switch (ch) { + case 12 /*^L*/: + clear(); + break; + case 'r': + case 'g': + case 'c': + case 'd': + switch (loadpos) { + case 0: mf->loadL = loadbychar(ch); break; + case 1: mf->loadR = loadbychar(ch); break; + case 2: beep(); break; + } + break; + case '\r': + case '\n': + switch (loadpos) { + case 0: mf->loadL = nextload(mf->loadL); break; + case 1: mf->loadR = nextload(mf->loadR); break; + case 2: done = true; break; + } + break; + case 7 /*^G*/: + case 8 /*^H*/: + case 27 /*ESC*/: + case 127 /*^?*/: + beep(); + break; + case 16 /*^P*/: + case KEY_UP: + up(&loadpos, NULL); + break; + case 14 /*^N*/: + case KEY_DOWN: + down(&loadpos, NULL, 3, 3); + break; + default: + beep(); + break; + } + } + mf->readyR = R_LOADED|R_INITIAL; + mf->readyL = R_LOADED|R_INITIAL; +} + +static void +startgame(void) +{ + + ingame = true; + shipselected = false; + + pl_main_init(); + + hasdriver = sync_exists(game); + if (sync_open() < 0) { + oops(21, 10, "syncfile: %s", strerror(errno)); + pl_main_uninit(); + ingame = false; + return; + } + + if (hasdriver) { + mvaddstr(21, 10, "Synchronizing with the other players..."); + wrefresh(stdscr); + fflush(stdout); + if (Sync() < 0) + leave(LEAVE_SYNC); + } else { + mvaddstr(21, 10, "Starting driver..."); + wrefresh(stdscr); + fflush(stdout); + startdriver(); + } + + if (pickship() < 0) { + oops(21, 10, "All ships taken in that scenario."); + sync_close(0); + people = 0; + pl_main_uninit(); + ingame = false; + return; + } + shipselected = true; + + ms = SHIP(player); + mf = ms->file; + mc = ms->specs; + + pickload(); + + pl_main(); + ingame = false; +} + +//////////////////////////////////////////////////////////// +// scenario picker + +static int pickerpos; +static int pickerscroll; + +static const char * +absdirectionname(int dir) +{ + switch (dir) { + case 1: return "South"; + case 2: return "Southwest"; + case 3: return "West"; + case 4: return "Northwest"; + case 5: return "North"; + case 6: return "Northeast"; + case 7: return "East"; + case 8: return "Southeast"; + } + return "?"; +} + +static const char * +windname(int wind) +{ + switch (wind) { + case 0: return "calm"; + case 1: return "light breeze"; + case 2: return "moderate breeze"; + case 3: return "fresh breeze"; + case 4: return "strong breeze"; + case 5: return "gale"; + case 6: return "full gale"; + case 7: return "hurricane"; + } + return "???"; +} + +static const char * +nationalityname(int nationality) +{ + switch (nationality) { + case N_A: return "a"; + case N_B: return "b"; + case N_S: return "s"; + case N_F: return "f"; + case N_J: return "j"; + case N_D: return "d"; + case N_K: return "k"; + case N_O: return "o"; + } + return "?"; +} + +static void +drawpicker(void) +{ + int y, sc, i; + struct ship *ship; + + erase(); + + mvaddstr(0, 0, "## SHIPS TITLE"); + for (y=1; ynationality), + ship->shipname, + ship->specs->guns, + shortclassname[ship->specs->class], + qualname[ship->specs->qual], + ship->specs->pts); + } + + move(1 + pickerpos - pickerscroll, 55); + wrefresh(stdscr); +} + +static int +pickscenario(int initpos) +{ + int ch; + + pickerpos = initpos; + if (pickerpos < 0) { + pickerpos = 0; + } + + while (1) { + drawpicker(); + ch = getch(); + switch (ch) { + case 12 /*^L*/: + clear(); + break; + case '\r': + case '\n': + return pickerpos; + case 7 /*^G*/: + case 8 /*^H*/: + case 27 /*ESC*/: + case 127 /*^?*/: + return initpos; + case 16 /*^P*/: + case KEY_UP: + up(&pickerpos, &pickerscroll); + break; + case 14 /*^N*/: + case KEY_DOWN: + down(&pickerpos, &pickerscroll, NSCENE, LINES-12); + break; + default: + beep(); + break; + } + } + return pickerpos; +} + +//////////////////////////////////////////////////////////// +// setup menus + +#define MAINITEMS_NUM 5 +#define STARTITEMS_NUM 4 +#define OPTIONSITEMS_NUM 5 + +static int mainpos; +static bool connected; + +static bool joinactive; +static int joinpos; +static int joinscroll; +static int joinable[NSCENE]; +static int numjoinable; + +static bool startactive; +static int startpos; +static int startscenario; + +static bool optionsactive; +static int optionspos; +static char o_myname[MAXNAMESIZE]; +static bool o_randomize; +static bool o_longfmt; +static bool o_nobells; + + +/* + * this and sgetstr() should share code + */ +static void +startup_getstr(int y, int x, char *buf, size_t max) +{ + size_t pos = 0; + int ch; + + for (;;) { + buf[pos] = 0; + move(y, x); + addstr(buf); + clrtoeol(); + wrefresh(stdscr); + fflush(stdout); + + ch = getch(); + switch (ch) { + case '\n': + case '\r': + return; + case '\b': + if (pos > 0) { + /*waddstr(scroll_w, "\b \b");*/ + pos--; + } + break; + default: + if (ch >= ' ' && ch < 0x7f && pos < max - 1) { + buf[pos++] = ch; + } else { + beep(); + } + } + } +} + +static void +changename(void) +{ + mvaddstr(LINES-2, COLS/2, "Enter your name:"); + startup_getstr(LINES-1, COLS/2, o_myname, sizeof(o_myname)); +} + +static void +checkforgames(void) +{ + int i; + int prev; + + if (numjoinable > 0) { + prev = joinable[joinpos]; + } else { + prev = 0; + } + + numjoinable = 0; + for (i = 0; i < NSCENE; i++) { + if (!sync_exists(i)) { + continue; + } + if (i < prev) { + joinpos = numjoinable; + } + joinable[numjoinable++] = i; + } + if (joinpos > numjoinable) { + joinpos = (numjoinable > 0) ? numjoinable - 1 : 0; + } + if (joinscroll > joinpos) { + joinscroll = (joinpos > 0) ? joinpos - 1 : 0; + } +} + +static void +drawstartmenus(void) +{ + const int mainy0 = 8; + const int mainx0 = 12; + + erase(); + + mvaddstr(5, 10, "Wooden Ships & Iron Men"); + + mvaddselstr(mainy0+0, mainx0, 0, mainpos, 17, "Join a game"); + mvaddselstr(mainy0+1, mainx0, 1, mainpos, 17, "Start a game"); + mvaddselstr(mainy0+2, mainx0, 2, mainpos, 17, "Options"); + mvaddselstr(mainy0+3, mainx0, 3, mainpos, 17, "Show high scores"); + mvaddselstr(mainy0+4, mainx0, 4, mainpos, 17, "Quit"); + + mvprintw(15, 10, "Captain %s", myname); + if (connected) { + mvaddstr(16, 10, "Connected via scratch files."); + } else { + mvaddstr(16, 10, "Not connected."); + } + + if (joinactive) { + int y0, leavey = 0, i, sc; + + mvaddstr(0, COLS/2, "## SHIPS TITLE"); + y0 = 1; + for (i = 0; i < numjoinable; i++) { + if (i >= joinscroll && i < joinscroll + LINES-1) { + move(y0 + i - joinscroll, COLS/2); + if (i == joinpos) { + attron(A_REVERSE); + } + sc = joinable[i]; + printw("%-2d %-5d %s", + sc, scene[sc].vessels, scene[sc].name); + if (i == joinpos) { + filltoeol(); + attroff(A_REVERSE); + leavey = y0 + i - joinscroll; + } + } + } + mvaddstr(19, 10, "(Esc to abort)"); + if (numjoinable > 0) { + mvaddstr(18, 10, "Choose a game to join."); + move(leavey, COLS-1); + } else { + mvaddstr(2, COLS/2, "No games."); + mvaddstr(18, 10, "Press return to refresh."); + } + + } else if (startactive) { + const char *name; + + mvaddstr(18, 10, "Start a new game"); + mvaddstr(19, 10, "(Esc to abort)"); + mvaddstr(2, COLS/2, "New game"); + + name = (startscenario < 0) ? + "not selected" : scene[startscenario].name; + + mvselprintw(4, COLS/2, 0, startpos, COLS/2 - 1, + "Scenario: %s", name); + mvaddselstr(5, COLS/2, 1, startpos, COLS/2 - 1, + "Visibility: local"); + mvaddselstr(6, COLS/2, 2, startpos, COLS/2 - 1, + "Password: unset"); + mvaddselstr(7, COLS/2, 3, startpos, COLS/2 - 1, + "Start game"); + move(4+startpos, COLS - 2); + + } else if (optionsactive) { + mvaddstr(18, 10, "Adjust options"); + mvaddstr(19, 10, "(Esc to abort)"); + mvaddstr(2, COLS/2, "Adjust options"); + + mvselprintw(4, COLS/2, 0, optionspos, COLS/2-1, + "Your name: %s", o_myname); + mvselprintw(5, COLS/2, 1, optionspos, COLS/2-1, + "Auto-pick ships: %s", o_randomize ? "ON" : "off"); + mvselprintw(6, COLS/2, 2, optionspos, COLS/2-1, + "Usernames in scores: %s", + o_longfmt ? "ON" : "off"); + mvselprintw(7, COLS/2, 3, optionspos, COLS/2-1, + "Beeping: %s", o_nobells ? "OFF" : "on"); + mvselprintw(8, COLS/2, 4, optionspos, COLS/2-1, + "Apply changes"); + move(4+optionspos, COLS - 2); + + } else { + move(mainy0 + mainpos, mainx0 + 16); + } + + wrefresh(stdscr); + fflush(stdout); +} + +void +startup(void) +{ + int ch; + + connected = false; + mainpos = 0; + + joinactive = false; + joinpos = 0; + joinscroll = 0; + numjoinable = 0; + + startactive = false; + startpos = 0; + startscenario = -1; + + optionsactive = false; + optionspos = 0; + + while (1) { + if (joinactive) { + checkforgames(); + } + drawstartmenus(); + ch = getch(); + switch (ch) { + case 12 /*^L*/: + clear(); + break; + case '\r': + case '\n': + if (joinactive && numjoinable > 0) { + game = joinable[joinpos]; + startgame(); + joinactive = false; + } else if (startactive) { + switch (startpos) { + case 0: + startscenario = pickscenario(startscenario); + startpos = 3; + break; + case 1: + case 2: + oops(21, 10, "That doesn't work yet."); + break; + case 3: + if (startscenario >= 0) { + game = startscenario; + /* can't do this here yet */ + /*startdriver();*/ + startgame(); + startactive = false; + startscenario = -1; + } else { + oops(21, 10, + "Pick a scenario."); + } + break; + } + } else if (optionsactive) { + switch (optionspos) { + case 0: changename(); break; + case 1: o_randomize = !o_randomize; break; + case 2: o_longfmt = !o_longfmt; break; + case 3: o_nobells = !o_nobells; break; + case 4: + strlcpy(myname, o_myname, + sizeof(myname)); + randomize = o_randomize; + longfmt = o_longfmt; + nobells = o_nobells; + optionsactive = false; + break; + } + } else { + switch (mainpos) { + case 0: joinactive = true; break; + case 1: startactive = true; break; + case 2: + strlcpy(o_myname, myname, + sizeof(o_myname)); + o_randomize = randomize; + o_longfmt = longfmt; + o_nobells = nobells; + optionsactive = true; + break; + case 3: lo_curses(); break; + case 4: return; + } + } + break; + case 7 /*^G*/: + case 8 /*^H*/: + case 27 /*ESC*/: + case 127 /*^?*/: + if (joinactive) { + joinactive = false; + } else if (startactive) { + startactive = false; + } else if (optionsactive) { + optionsactive = false; + } else { + /* nothing */ + } + break; + case 16 /*^P*/: + case KEY_UP: + if (joinactive) { + up(&joinpos, &joinscroll); + } else if (startactive) { + up(&startpos, NULL); + } else if (optionsactive) { + up(&optionspos, NULL); + } else { + up(&mainpos, NULL); + } + break; + case 14 /*^N*/: + case KEY_DOWN: + if (joinactive) { + down(&joinpos, &joinscroll, + numjoinable, LINES-1); + } else if (startactive) { + down(&startpos, NULL, + STARTITEMS_NUM, STARTITEMS_NUM); + } else if (optionsactive) { + down(&optionspos, NULL, + OPTIONSITEMS_NUM, OPTIONSITEMS_NUM); + } else { + down(&mainpos, NULL, + MAINITEMS_NUM, MAINITEMS_NUM); + } + break; + default: + beep(); + break; + } + } +} diff --git a/games/sail/pl_main.c b/games/sail/pl_main.c index ed92697967..f13f1f8183 100644 --- a/games/sail/pl_main.c +++ b/games/sail/pl_main.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: pl_main.c,v 1.27 2010/08/06 09:14:40 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,62 +27,40 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)pl_main.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/pl_main.c,v 1.6 1999/11/30 03:49:38 billf Exp $ */ -#include -#include +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pl_main.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pl_main.c,v 1.27 2010/08/06 09:14:40 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include "display.h" +#include "extern.h" #include "player.h" +char myname[MAXNAMESIZE]; + static void initialize(void); -/*ARGSUSED*/ void -pl_main(void) -{ - - if (!SCREENTEST()) { - printf("Can't sail on this terminal.\n"); - exit(1); - } - initialize(); - Signal("Aye aye, Sir", NULL); - play(); -} - -static void -initialize(void) +pl_main_init(void) { - struct File *fp; - struct ship *sp; - char captain[20]; - char message[60]; - int load; - int n; - char *nameptr; int nat[NNATION]; + int n; + struct ship *sp; - if (game < 0) { - puts("Choose a scenario:\n"); - puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE"); - for (n = 0; n < NSCENE; n++) { - /* ( */ - printf("\t%d):\t%d\t%s\t%s\n", n, scene[n].vessels, - sync_exists(n) ? "YES" : "no", - scene[n].name); - } -reprint: - printf("\nScenario number? "); - fflush(stdout); - scanf("%d", &game); - while (getchar() != '\n' && !feof(stdin)) - ; - } if (game < 0 || game >= NSCENE) { - puts("Very funny."); - exit(1); + errx(1, "Very funny."); } cc = &scene[game]; ls = SHIP(cc->vessels); @@ -90,8 +70,7 @@ reprint: foreachship(sp) { if (sp->file == NULL && (sp->file = calloc(1, sizeof (struct File))) == NULL) { - puts("OUT OF MEMORY"); - exit(1); + err(1, "calloc"); } sp->file->index = sp - SHIP(0); sp->file->stern = nat[sp->nationality]++; @@ -104,139 +83,54 @@ reprint: signal(SIGHUP, choke); signal(SIGINT, choke); + signal(SIGCHLD, child); +} - hasdriver = sync_exists(game); - if (sync_open() < 0) { - perror("sail: syncfile"); - exit(1); - } +void +pl_main_uninit(void) +{ + struct ship *sp; - if (hasdriver) { - puts("Synchronizing with the other players..."); - fflush(stdout); - if (Sync() < 0) - leave(LEAVE_SYNC); - } - for (;;) { - foreachship(sp) - if (sp->file->captain[0] == 0 && !sp->file->struck - && sp->file->captured == 0) - break; - if (sp >= ls) { - puts("All ships taken in that scenario."); - foreachship(sp) - free(sp->file); - sync_close(0); - people = 0; - goto reprint; - } - if (randomize) { - player = sp - SHIP(0); - } else { - printf("%s\n\n", cc->name); - foreachship(sp) - printf(" %2d: %-10s %-15s (%-2d pts) %s\n", - sp->file->index, - countryname[sp->nationality], - sp->shipname, - sp->specs->pts, - saywhat(sp, 1)); - printf("\nWhich ship (0-%d)? ", cc->vessels-1); - fflush(stdout); - if (scanf("%d", &player) != 1 || player < 0 - || player >= cc->vessels) { - while (getchar() != '\n') - ; - puts("Say what?"); - player = -1; - } else - while (getchar() != '\n') - ; - } - if (player < 0) - continue; - if (Sync() < 0) - leave(LEAVE_SYNC); - fp = SHIP(player)->file; - if (fp->captain[0] || fp->struck || fp->captured != 0) - puts("That ship is taken."); - else - break; + foreachship(sp) { + free(sp->file); + sp->file = NULL; } +} - ms = SHIP(player); - mf = ms->file; - mc = ms->specs; +static void +initialize(void) +{ + char captain[MAXNAMESIZE]; + char message[60]; + + if (game < 0 || game >= NSCENE) { + errx(1, "Very funny."); + } - Write(W_BEGIN, ms, 0, 0, 0, 0); + send_begin(ms); if (Sync() < 0) leave(LEAVE_SYNC); - signal(SIGCHLD, child); - if (!hasdriver) - switch (fork()) { - case 0: - longjmp(restart, MODE_DRIVER); - /*NOTREACHED*/ - case -1: - perror("fork"); - leave(LEAVE_FORK); - break; - default: - hasdriver++; - } - +#if 0 printf("Your ship is the %s, a %d gun %s (%s crew).\n", ms->shipname, mc->guns, classname[mc->class], qualname[mc->qual]); - if ((nameptr = getenv("SAILNAME")) && *nameptr) - strncpy(captain, nameptr, sizeof captain); - else { - printf("Your name, Captain? "); - fflush(stdout); - fgets(captain, sizeof captain, stdin); - if (!*captain) - strcpy(captain, "no name"); - else - captain[sizeof(captain) - 1] = '\0'; - } - Writestr(W_CAPTAIN, ms, captain); - for (n = 0; n < 2; n++) { - char buf[10]; - - printf("\nInitial broadside %s (grape, chain, round, double): ", - n ? "right" : "left"); - fflush(stdout); - scanf("%9s", buf); - switch (*buf) { - case 'g': - load = L_GRAPE; - break; - case 'c': - load = L_CHAIN; - break; - case 'r': - load = L_ROUND; - break; - case 'd': - load = L_DOUBLE; - break; - default: - load = L_ROUND; - } - if (n) { - mf->loadR = load; - mf->readyR = R_LOADED|R_INITIAL; - } else { - mf->loadL = load; - mf->readyL = R_LOADED|R_INITIAL; - } - } +#endif + + strlcpy(captain, myname, sizeof(captain)); + send_captain(ms, captain); - initscreen(); - draw_board(); + display_redraw(); snprintf(message, sizeof message, "Captain %s assuming command", - captain); - Writestr(W_SIGNAL, ms, message); + captain); + send_signal(ms, message); newturn(0); } + +void +pl_main(void) +{ + initialize(); + Msg("Aye aye, Sir"); + play(); +} diff --git a/games/sail/player.h b/games/sail/player.h index 3c90e609e5..cb555a05b1 100644 --- a/games/sail/player.h +++ b/games/sail/player.h @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: player.h,v 1.13 2009/08/12 09:05:08 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -26,14 +28,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)player.h 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/player.h,v 1.2.6.1 2001/05/01 11:45:08 dwmalone Exp $ - * $DragonFly: src/games/sail/player.h,v 1.2 2003/06/17 04:25:25 dillon Exp $ + * @(#)player.h 8.2 (Berkeley) 5/3/95 */ -#include -#include "externs.h" - /* sizes and coordinates for the screen */ #define LINE_T 0 @@ -88,28 +85,15 @@ #define SLOT_B VIEW_B #define SLOT_R (SLOT_L+SLOT_X-1) -#ifdef SIGTSTP -#define SCREENTEST() (initscr() != NULL && signal(SIGTSTP, SIG_DFL) != SIG_ERR && STAT_R < COLS && SCROLL_Y > 0) -#else -#define SCREENTEST() (initscr() != NULL && STAT_R < COLS && SCROLL_Y > 0) -#endif - -WINDOW *view_w; -WINDOW *slot_w; -WINDOW *scroll_w; -WINDOW *stat_w; -WINDOW *turn_w; - -char done_curses; -char loaded, fired, changed, repaired; -char dont_adjust; -int viewrow, viewcol; -char movebuf[sizeof SHIP(0)->file->movebuf]; -extern char version[]; -int player; -struct ship *ms; /* memorial structure, &cc->ship[player] */ -struct File *mf; /* ms->file */ -struct shipspecs *mc; /* ms->specs */ +extern int done_curses; +extern int loaded, fired, changed, repaired; +extern int dont_adjust; +extern char movebuf[sizeof SHIP(0)->file->movebuf]; +extern const char version[]; +extern int player; +extern struct ship *ms; /* memorial structure, &cc->ship[player] */ +extern struct File *mf; /* ms->file */ +extern struct shipspecs *mc; /* ms->specs */ /* condition codes for leave() */ #define LEAVE_QUIT 0 diff --git a/games/sail/restart.h b/games/sail/restart.h new file mode 100644 index 0000000000..699ed612c4 --- /dev/null +++ b/games/sail/restart.h @@ -0,0 +1,32 @@ +/* $NetBSD: restart.h,v 1.4 2009/03/14 19:35:13 dholland Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +extern jmp_buf restart; diff --git a/games/sail/sail.6 b/games/sail/sail.6 index 72d5003322..e7d92f90cd 100644 --- a/games/sail/sail.6 +++ b/games/sail/sail.6 @@ -1,3 +1,5 @@ +.\" $NetBSD: sail.6,v 1.18 2009/03/02 10:16:54 dholland Exp $ +.\" .\" Copyright (c) 1988, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -25,10 +27,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)sail.6 8.2 (Berkeley) 12/30/93 -.\" $FreeBSD: src/games/sail/sail.6,v 1.5.2.1 2001/07/22 11:32:37 dd Exp $ +.\" @(#)sail.6 8.3 (Berkeley) 6/1/94 .\" -.Dd July 25, 2013 +.Dd March 2, 2009 .Dt SAIL 6 .Os .Sh NAME @@ -38,7 +39,7 @@ .Nm .Op Fl bx .Op Fl s Op Fl l -.Op Ar number +.Op Ar num .Sh DESCRIPTION .Nm is a computer version of Avalon Hill's game of fighting sail @@ -48,22 +49,23 @@ Players of .Nm take command of an old-fashioned Man of War and fight other players or the computer. -They may re-enact one of the many historical sea battles recorded -in the game, or they can choose a fictional battle. +They may re-enact one of the many +historical sea battles recorded in the game, or they can choose +a fictional battle. .Pp As a sea captain in the -.Nm +.Nm Sail Navy, the player has complete control over the workings of his ship. He must order every maneuver, change the set of his sails, and judge the right moment to let loose the terrible destruction of his broadsides. In addition to fighting the enemy, he must harness the powers of the wind and sea to make them work for him. -The outcome of many battles during the age of sail was decided by the -ability of one captain to hold the +The outcome of many battles during the +age of sail was decided by the ability of one captain to hold the .Sq weather gage . .Pp The flags are: -.Bl -tag -width flag +.Bl -tag -width flag -compact .It Fl b No bells. .It Fl l @@ -77,61 +79,61 @@ Play the first available ship instead of prompting for a choice. .El .Sh IMPLEMENTATION .Nm -is really two programs in one. -Each player starts up a process which runs his own ship. -In addition, a -.Em driver -process is forked -.Pq by the first player -to run the computer ships and take care of global bookkeeping. -.Pp -Because the driver must calculate moves for each ship it controls, the -more ships the computer is playing, the slower the game will appear. +is a multiplayer game. +Each player runs +.Nm +to either connect to an existing game or start a new one. +The game server (or +.Dq driver ) +is an extra fork of the +.Nm +program created when a game is started. +The driver coordinates the game and runs the computer ships. +.\" .Pp +.\" Because the +.\" driver +.\" must calculate moves for each ship it controls, the +.\" more ships the computer is playing, the slower the game will appear. .Pp -If a player joins a game in progress, he will synchronize -with the other players +If a player joins a game in progress, a synchronization process occurs .Pq a rather slow process for everyone , -and then he may play along with the rest. +and then the game continues. .Pp -To implement a multi-user game in -.Ux -Version 7, -which was the operating system +Note that while each scenario can be running independently with +different players, each scenario can also only be running once at any +given time. +.Ss COMMUNICATION +To implement a multi-user game in Version 7 UNIX, which was the operating +system .Nm was first written under, the communicating processes must use a common temporary file as a place to read and write messages. +For e.g. scenario 21, this file is +.Pa /var/games/sail/#sailsink.21 . +Corresponding file names are used for the other scenarios. +.Pp In addition, a locking mechanism must be provided to ensure exclusive access to the shared file. -For example, -.Nm -uses a temporary file named -.Pa /tmp/#sailsink.21 -for scenario 21, and corresponding file names for the other scenarios. -To provide exclusive access to the temporary file, .Nm uses a technique stolen from an old game called -.Ic pubcaves +.Dq pubcaves by Jeff Cohen. Processes do a busy wait in the loop .Bd -literal -offset indent -for (n = 0; link(sync_file, sync_lock) == -1 && n < 30; n++) - sleep(2); +for (n = 0; link(sync_file, sync_lock) \*[Lt] 0 \*[Am]\*[Am] n \*[Lt] 30; n++) + sleep(2); + .Ed -.Pp -until they are able to create a link to a file named -.Pa /tmp/#saillock.?? . -The -.Dq ?? -correspond to the scenario number of the game. -Since -.Ux -guarantees that a link will point to only one file, the process -that succeeds in linking will have exclusive access to the temporary file. +until they are able to create a hard link named e.g. +.Pa /var/games/sail/#saillock.21 . +where 21 is again the scenario number. +Since creating a hard link is atomic, a process where this succeeds +will have exclusive access to the temporary file. .Ss CONSEQUENCES OF SEPARATE PLAYER AND DRIVER PROCESSES When players do something of global interest, such as moving or firing, the driver must coordinate the action with the other ships in the game. For example, if a player wants to move in a certain direction, he writes a -message into the temporary file requesting that the driver move his ship. +message into the temporary file requesting the driver to move his ship. Each .Dq turn , the driver reads all the messages sent from the players and @@ -144,13 +146,13 @@ Suppose a player types a move for his ship and hits return. What happens then? The player process saves up messages to be written to the temporary file in a buffer. -Every 7 seconds or so, the player process gets exclusive access -to the temporary file and writes out its buffer to the file. +Every 7 seconds or so, the player process gets exclusive access to +the temporary file and writes out its buffer to the file. The driver, running asynchronously, must read in the movement command, process it, and write out the results. This takes two exclusive accesses to the temporary file. -Finally, when the player process gets around to doing another 7-second update, -the results of the move are displayed on the screen. +Finally, when the player process gets around to doing another 7-second +update, the results of the move are displayed on the screen. Hence, every movement requires four exclusive accesses to the temporary file (anywhere from 7 to 21 seconds depending upon asynchrony) before the player sees the results of his moves. @@ -159,8 +161,8 @@ In practice, the delays are not as annoying as they would appear. There is room for .Dq pipelining in the movement. -After the player writes out a first movement message, -a second movement command can then be issued. +After the player writes out +a first movement message, a second movement command can then be issued. The first message will be in the temporary file waiting for the driver, and the second will be in the file buffer waiting to be written to the file. Thus, by always typing moves a turn ahead of the time, the player can @@ -171,62 +173,69 @@ only the last movement command typed will be seen by the driver. Movement commands within the same update .Dq overwrite each other, in a sense. +.Ss DEFECTS OF THIS SYSTEM IN THE MODERN WORLD +Quite a few. +.Pp +It should be thrown out and replaced with something socket-based. .Sh HISTORICAL INFO Old square-riggers were very maneuverable ships capable of intricate sailing. Their only disadvantage was an inability to sail very close to the wind. -The design of a wooden ship allowed only for the -guns to bear to the left and right sides. -A few guns of small aspect -.Pq usually 6 or 9 pounders -could point forward, but their -effect was small compared to a 68-gun broadside of 24 or 32 pounders. +The design of a wooden ship allowed for the guns to bear only to the +left and right sides. +A few guns of small +aspect (usually 6 or 9 pounders) could point forward, but their +effect was small compared to a 68 gun broadside of 24- or 32-pounders. The guns bear approximately like so: .Bd -literal -offset indent - \e + + \\ b---------------- ---0 - \e - \e - \e up to a range of ten (for round shot) - \e - \e - \e + \\ + \\ + \\ up to a range of ten (for round shot) + \\ + \\ + \\ + .Ed -.Pp -An interesting phenomenon occurred when a broadside was fired -down the length of an enemy ship. -The shot tended to bounce along the deck and did several times more damage. -This phenomenon was called a rake. +Firing a broadside into a ship lengthwise, from bow to stern or stern +to bow, is called +.Em raking . +This did a great deal more damage, because the shot tended to bounce +along the deck. Because the bows of a ship are very strong and present a smaller -target than the stern, a stern rake -.Pq firing from the stern to the bow -causes more damage than a bow rake. +target than the stern, a stern rake (firing from the stern to the bow) causes +more damage than a bow rake. .Bd -literal -offset indent + b 00 ---- Stern rake! a + .Ed -.Pp -Most ships were equipped with carronades, which were very large, -close-range cannons. +Most ships were equipped with +.Em carronades , +which were very large, close range cannons. American ships from the revolution until the War of 1812 were almost entirely armed with carronades. .Pp The period of history covered in .Nm -is approximately from the 1770s until the end of Napoleonic France in 1815. -There are many excellent books about the age of sail -.Pq see Sx REFERENCES . +is approximately from the 1770's until the end of Napoleonic France in 1815. +There are many excellent books about the age of sail. +.Pq See Sx REFERENCES . .Pp Fighting ships came in several sizes classed by armament. -The mainstays of any fleet were its -.Dq Ships of the Line , +The mainstays of +any fleet were its +.Em ships of the line , or -.Dq Line of Battle Ships . -They were so named because these ships fought together in great lines. -They were close enough for mutual support, yet every ship could fire -both its broadsides. +.Em line of battle ships . +These were so named because in fleet actions they would sail in lines +so as to present all broadsides to the enemy at once. +.\" ... to sail close enough for mutual support. The modern terms .Dq ocean liner , and @@ -237,6 +246,8 @@ are derived from The pride of the fleet were the .Dq first-rates . These were huge three decked ships of the line mounting 80 to 136 guns. +The guns in the three tiers +were usually 18, 24, and 32 pounders in that order from top to bottom. .Pp Lesser ships were known as .Dq second-rates , @@ -245,158 +256,160 @@ and even .Dq fourth-rates . The most common size was the 74 gun two-decked ship of the line. The two gun decks usually mounted 18 and 24 pounder guns. -The guns in the three tiers were usually 18, 24, and 32 pounders in -that order from top to bottom. .Pp -Various other ships came next. -They were almost all -.Dq razees , -or ships of the line with one deck sawed off. -They mounted 40-64 guns and were +.Em Razees +were ships of the line with one deck sawed off. +These mounted 40-64 guns and were a poor cross between a frigate and a line of battle ship. They neither had the speed of the former nor the firepower of the latter. .Pp -Next came the -.Dq eyes of the fleet . -Frigates came in many sizes mounting anywhere from 32 to 44 guns. -They were very handy vessels. +The next class was the +.Em frigate . +Often called the +.Dq eyes of the fleet , +frigates came in many sizes mounting anywhere from 32 to 44 guns. +These were very handy vessels. They could outsail anything bigger and outshoot anything smaller. -Frigates didn't fight in lines of battle as the much bigger 74's did. -Instead, they harassed the enemy's rear or captured crippled ships. -They were much more useful in missions away from the fleet, -such as cutting out expeditions or boat actions. +Frigates did not generally fight in lines of battle as the much bigger +74s did. +Instead, they were sent on individual missions or in small groups to +harass the enemy's rear or capture crippled ships. +.\" cutting out expeditions or boat actions. +They were much more useful this way, in missions away from the fleet. They could hit hard and get away fast. .Pp Lastly, there were the corvettes, sloops, and brigs. These were smaller ships mounting typically fewer than 20 guns. -A corvette was only slightly smaller than a frigate, -so one might have up to 30 guns. -Sloops were used for carrying dispatches or passengers. -Brigs were something you built for land-locked lakes. -.Ss SAIL PARTICULARS +A corvette was only slightly +smaller than a frigate, so one might have up to 30 guns. +Sloops were used for carrying despatches or passengers. +Brigs were small vessels typically built for land-locked lakes. +.Sh SAIL PARTICULARS Ships in .Nm -are represented by two characters. -One character represents the bow of the ship, -and the other represents the stern. +are represented on the screen by two characters. +One character represents the bow of +the ship, and the other represents the stern. Ships have nationalities and numbers. The first ship of a nationality is number 0, the second number 1, etc. Therefore, the first British ship in a game would be printed as -.Sq b0 . +.Dq b0 . The second Brit would be -.Sq b1 , +.Dq b1 , and the fifth Don would be -.Sq s4 . +.Dq s4 . .Pp -Ships can set normal sails, called Battle Sails, or bend on extra canvas -called Full Sails. +Ships can set normal sails, called +.Em Battle Sails , +or bend on extra canvas called +.Em Full Sails . A ship under full sail is a beautiful sight indeed, -and it can move much faster than a ship under Battle Sails. +and it can move much faster than a ship under battle sails. The only trouble is, with full sails set, there is so much tension on sail and rigging that a well aimed round shot can burst a sail into ribbons where it would only cause a little hole in a loose sail. For this reason, rigging damage is doubled on a ship with full sails set. -Don't let that discourage you from using full sails: -I like to keep them up right into the heat of battle. -A ship with full sails set has a capital letter for its nationality. +This does not mean that full sails should never be used; the author +recommends keeping them up right into the heat of battle. +When a ship has full sails set, the letter for its nationality is +capitalized. E.g., a Frog, -.Sq f0 , +.Dq f0 , with full sails set would be printed as -.Sq F0 . +.Dq F0 . .Pp When a ship is battered into a listing hulk, the last man aboard -.Dq strikes the colors . +.Em strikes the colors . This ceremony is the ship's formal surrender. The nationality character of a surrendered ship is printed as -.Sq \&! . +.So +! +.Sc . E.g., the Frog of our last example would soon be -.Sq !0 . +.Dq !0 . .Pp -A ship has a random chance of catching fire or sinking when it reaches the -stage of listing hulk. -A sinking ship has a tilde +A ship that reaches this point has a chance of catching fire or sinking. +A sinking ship has a .Sq ~ -printed for its nationality, and a ship on fire and about to explode has a +printed for its nationality, +and a ship on fire and about to explode has a .Sq # printed. .Pp -Captured ships become the nationality of the prize crew. +Ships that have struck can be captured; +captured ships become the nationality of the prize crew. Therefore, if -an American ship captures a British ship, the British ship will have an +an American ship captures a British ship, the British ship will +thenceforth have an .Sq a printed for its nationality. In addition, the ship number is changed -to -.Sq & , -.Sq ' , -.Sq \&( , -.Sq \&) , -.Sq * , -or -.Sq + -depending upon the original number, -be it 0, 1, 2, 3, 4, or 5. +to one of the characters +.So +\*[Am]'()*+ +.Sc +corresponding to its original number +.So +012345 +.Sc . E.g., the -.Sq b0 +.Dq b0 captured by an American becomes the -.Sq a& . +.Dq a\*[Am] . The -.Sq s4 +.Dq s4 captured by a Frog becomes the -.Sq f* . +.Dq f* . .Pp The ultimate example is, of course, an exploding Brit captured by an American: -.Sq #& . -.Ss MOVEMENT +.Dq #\*[Am] . +.Sh MOVEMENT Movement is the most confusing part of .Nm to many. Ships can head in 8 directions: -.Bd -literal - 0 0 0 - b b b0 b b b 0b b - 0 0 0 +.Bd -literal -offset indent + 0 0 0 +b b b0 b b b 0b b +0 0 0 + .Ed -.Pp The stern of a ship moves when it turns. The bow remains stationary. Ships can always turn, regardless of the wind (unless they are becalmed). All ships drift when they lose headway. If a ship doesn't move forward at all for two turns, it will begin to drift. -If a ship has begun to drift, then it must move forward before it turns, if -it plans to do more than make a right or left turn, which is always -possible. +If a ship has begun to +drift, then it must move forward before it turns, if it plans to do +more than make a right or left turn, which is always possible. .Pp Movement commands to .Nm are a string of forward moves and turns. An example is -.Sq l3 . +.Dq l3 . It will turn a ship left and then move it ahead 3 spaces. In the drawing above, the -.Sq b0 +.Dq b0 made 7 successive left turns. When .Nm prompts you for a move, it prints three characters of import. E.g., -.Pp .Dl move (7, 4): -.Pp -The first number is the maximum number of moves you can make, -including turns. +The first number is the maximum number of moves you can make, including turns. The second number is the maximum number of turns you can make. Between the numbers is sometimes printed a quote -.Sq ' . +.Pq ' . If the quote is present, it means that your ship has been drifting, and you must move ahead to regain headway before you turn (see note above). Some of the possible moves for the example above are as follows: .Bd -literal -offset indent move (7, 4): 7 move (7, 4): 1 -move (7, 4): d /* drift, or do nothing */ +move (7, 4): d /* drift, or do nothing */ move (7, 4): 6r move (7, 4): 5r1 move (7, 4): 4r1r @@ -412,13 +425,15 @@ E.g., move (7, 4): l1l4 Movement Error; Helm: l1l + .Ed -.Pp -Moreover, whenever you make a turn, your movement allowance drops to -the lesser of what's left or what you would have at the new attitude. -In short, -if you turn closer to the wind, you most likely won't be able to sail the -full allowance printed in the "move" prompt. +Moreover, upon making a turn, the movement allowance drops to the +lesser of what remains this turn and what would be available when +going in the new direction. +Thus, any turn closer to the wind will generally preclude sailing the +full distance printed in the +.Dq move +prompt. .Pp Old sailing captains had to keep an eye constantly on the wind. Captains in @@ -429,54 +444,72 @@ The best angle possible is to have the wind off your quarter, that is, just off the stern. The direction rose on the side of the screen gives the possible movements for your ship at all positions to the wind. -Battle sail speeds are given first, -and full sail speeds are given in parentheses. +Battle +sail speeds are given first, and full sail speeds are given in parenthesis. .Bd -literal + 0 1(2) - \e|/ + \\|/ -^-3(6) - /|\e + /|\\ | 4(7) 3(6) + .Ed -.Pp Pretend the bow of your ship -.Pq the Sq ^ +.Pq the Dq ^ is pointing upward and the wind is blowing from the bottom to the top of the page. The numbers at the bottom -.Sq 3(6) -will be your speed under battle or full sails in such a situation. +.Dq 3(6) +will be your speed under battle or full +sails in such a situation. If the wind is off your quarter, then you can move -.Sq 4(7) . +.Dq 4(7) . If the wind is off your beam, -.Sq 3(6) . +.Dq 3(6) . If the wind is off your bow, then you can only move -.Sq 1(2) . -If you are facing into the wind, you can't move at all; -ships facing into the wind were said to be -.Dq in irons . -.Ss WINDSPEED AND DIRECTION -The windspeed and direction is displayed as a little weather vane on the +.Dq 1(2) . +Facing into the wind, you cannot move at all. +Ships facing into the wind are said to be +.Em in irons . +.Sh WINDSPEED AND DIRECTION +The windspeed and direction is displayed as a weather vane on the side of the screen. The number in the middle of the vane indicates the wind speed, and the + to - indicates the wind direction. -The wind blows from -the + sign (high pressure) to the - sign (low pressure). +The wind blows from the + sign (high pressure) to the - sign (low pressure). E.g., -.Bd -literal -offset indent-two -| -3 -+ +.Bd -literal + | + 3 + + .Ed .Pp -The wind speeds are 0 = becalmed, 1 = light breeze, 2 = moderate breeze, -3 = fresh breeze, 4 = strong breeze, 5 = gale, 6 = full gale, 7 = hurricane. +The wind speeds are: +.Bl -tag -width 012 -compact -offset indent +.It 0 +becalmed +.It 1 +light breeze +.It 2 +moderate breeze +.It 3 +fresh breeze +.It 4 +strong breeze +.It 5 +gale +.It 6 +full gale +.It 7 +hurricane +.El If a hurricane shows up, all ships are destroyed. -.Ss GRAPPLING AND FOULING +.Sh GRAPPLING AND FOULING If two ships collide, they run the risk of becoming tangled together. This is called -.Dq fouling . +.Em fouling . Fouled ships are stuck together, and neither can move. They can unfoul each other if they want to. Boarding parties can only be @@ -487,7 +520,7 @@ the other. .Pp The number of fouls and grapples you have are displayed on the upper right of the screen. -.Ss BOARDING +.Sh BOARDING Boarding was a very costly venture in terms of human life. Boarding parties may be formed in .Nm @@ -497,11 +530,12 @@ their ship as men left unorganized. .Pp The boarding strength of a crew depends upon its quality and upon the number of men sent. -.Ss CREW QUALITY +.Sh CREW QUALITY The British seaman was world renowned for his sailing abilities. American sailors, however, were actually the best seamen in the world. -Because the American Navy offered twice the wages of the Royal Navy, -British seamen who liked the sea defected to America by the thousands. +Because the +American Navy offered twice the wages of the Royal Navy, British seamen +who liked the sea defected to America by the thousands. .Pp In .Nm , @@ -520,20 +554,20 @@ A good rule of thumb is that .Em Crack or .Em Elite -crews get one extra hit per broadside compared to +crews get one extra hit +per broadside compared to .Em Mundane crews. Don't expect too much from .Em Green crews. -.Ss BROADSIDES -Your two broadsides may be loaded with four kinds of shot: -grape, chain, round, and double. +.Sh BROADSIDES +Your two broadsides may be loaded with four kinds of shot: grape, chain, +round, and double. You have guns and carronades in both the port and starboard batteries. Carronades only have a range of two, so you have to get in close to be able to fire them. -You have the choice of firing at the hull -or rigging of another ship. +You have the choice of firing at the hull or rigging of another ship. If the range of the ship is greater than 6, then you may only shoot at the rigging. .Pp @@ -564,12 +598,19 @@ Crew 4 4 2 Guns 4 4 Carr 2 2 Rigg 5 5 5 5 + .Ed -.Pp -"Load" shows what your port (left) and starboard (right) broadsides are +.Dq Load +shows what your port +.Pq left +and starboard +.Pq right +broadsides are loaded with. A -.Sq \&! +.So +! +.Sc after the type of shot indicates that it is an initial broadside. Initial broadside were loaded with care before battle and before the decks ran red with blood. @@ -579,14 +620,20 @@ A .Sq * after the type of shot indicates that the gun crews are still loading it, and you cannot fire yet. -"Hull" shows how much hull you have left. -"Crew" shows your three sections of crew. +.Dq Hull +shows how much hull you have left. +.Dq Crew +shows your three sections of crew. As your crew dies off, your ability to fire decreases. -"Guns" and "Carr" show your port and starboard guns. +.Dq Guns +and +.Dq Carr +show your port and starboard guns. As you lose guns, your ability to fire decreases. -"Rigg" shows how much rigging you have on your 3 or 4 masts. +.Dq Rigg +shows how much rigging you have on your 3 or 4 masts. As rigging is shot away, you lose mobility. -.Ss EFFECTIVENESS OF FIRE +.Sh EFFECTIVENESS OF FIRE It is very dramatic when a ship fires its thunderous broadsides, but the mere opportunity to fire them does not guarantee any hits. Many factors influence the destructive force of a broadside. @@ -594,39 +641,35 @@ First of all, and the chief factor, is distance. It is harder to hit a ship at range ten than it is to hit one sloshing alongside. Next is raking. -Raking fire, as mentioned before, -can sometimes dismast a ship at range ten. +Raking fire, as mentioned before, can sometimes dismast a ship at range ten. Next, crew size and quality affects the damage done by a broadside. -The number of guns firing also bears on the point, -so to speak. +The number of guns firing also bears on the point, so to speak. Lastly, weather affects the accuracy of a broadside. -If the seas are high (5 or 6), then the lower gunports of ships of the line -can't even be opened to run out the guns. +If the seas are high (5 or 6), then the lower gunports +of ships of the line can't even be opened to run out the guns. This gives frigates and other flush decked vessels an advantage in a storm. The scenario .Em Pellew vs. The Droits de L'Homme takes advantage of this peculiar circumstance. -.Ss REPAIRS +.Sh REPAIRS Repairs may be made to your Hull, Guns, and Rigging at the slow rate of two points per three turns. -The message "Repairs Completed" will be -printed if no more repairs can be made. -.Ss PECULIARITIES OF COMPUTER SHIPS +The message "Repairs Completed" will be printed if no more repairs can be made. +.Sh PECULIARITIES OF COMPUTER SHIPS Computer ships in .Nm follow all the rules above with a few exceptions. Computer ships never repair damage. If they did, the players could never beat them. They play well enough as it is. -As a consolation, the computer ships can fire double -shot every turn. +As a consolation, the computer ships can fire double shot every turn. That fluke is a good reason to keep your distance. The driver figures out the moves of the computer ships. -It computes them with a typical -A.I. distance function and a depth-first search to find the maximum +It computes them with a typical A.I. distance +function and a depth first search to find the maximum .Dq score . -It seems to work fairly well, although -it isn't perfect. +It seems to work fairly well, although I'll be the first to admit it isn't +perfect. .Sh HOW TO PLAY Commands are given to .Nm @@ -634,77 +677,79 @@ by typing a single character. You will then be prompted for further input. A brief summary of the commands follows. .Ss COMMAND SUMMARY -.Bl -tag -width xxx -.It f +.Bl -tag -width xD,xNxx -compact +.It Sq f Fire broadsides if they bear -.It l +.It Sq l Reload -.It L +.It Sq L Unload broadsides (to change ammo) -.It m +.It Sq m Move -.It i +.It Sq i Print the closest ship -.It I +.It Sq I Print all ships -.It F -Find a particular ship or ships (e.g.\& -.Sq a? -for all Americans) -.It s +.It Sq F +Find a particular ship or ships (e.g. "a?" for all Americans) +.It Sq s Send a message around the fleet -.It b +.It Sq b Attempt to board an enemy ship -.It B +.It Sq B Recall boarding parties -.It c +.It Sq c Change set of sail -.It r +.It Sq r Repair -.It u +.It Sq u Attempt to unfoul -.It g +.It Sq g Grapple/ungrapple -.It v +.It Sq v Print version number of game -.It ^L +.It Sq ^L Redraw screen -.It Q +.It Sq Q Quit -.It C +.Pp +.It Sq C Center your ship in the window -.It U +.It Sq U Move window up -.It D,N +.It Sq D, N Move window down -.It H +.It Sq H Move window left -.It J +.It Sq J Move window right -.It S +.It Sq S Toggle window to follow your ship or stay where it is .El .Sh SCENARIOS Here is a summary of the scenarios in .Nm : -.Ss Ranger vs. Drake: +.Ss Ranger vs. Drake : Wind from the N, blowing a fresh breeze. .Bd -literal (a) Ranger 19 gun Sloop (crack crew) (7 pts) (b) Drake 17 gun Sloop (crack crew) (6 pts) .Ed -.Ss The Battle of Flamborough Head: +.Ss The Battle of Flamborough Head : Wind from the S, blowing a fresh breeze. .Pp This is John Paul Jones' first famous battle. -Aboard the Bonhomme Richard, -he was able to overcome the Serapis's greater firepower +Aboard the +.Em Bonhomme Richard , +he was able to overcome the +.Em Serapis's +greater firepower by quickly boarding her. .Bd -literal (a) Bonhomme Rich 42 gun Corvette (crack crew) (11 pts) (b) Serapis 44 gun Frigate (crack crew) (12 pts) .Ed -.Ss Arbuthnot and Des Touches: +.Ss Arbuthnot and Des Touches : Wind from the N, blowing a gale. .Bd -literal (b) America 64 gun Ship of the Line (crack crew) (20 pts) @@ -718,7 +763,7 @@ Wind from the N, blowing a gale. (f) Provence 64 gun Ship of the Line (average crew) (18 pts) (f) Romulus 44 gun Ship of the Line (average crew) (10 pts) .Ed -.Ss Suffren and Hughes: +.Ss Suffren and Hughes : Wind from the S, blowing a fresh breeze. .Bd -literal (b) Monmouth 74 gun Ship of the Line (average crew) (24 pts) @@ -732,37 +777,37 @@ Wind from the S, blowing a fresh breeze. (f) Brilliant 80 gun Ship of the Line (crack crew) (31 pts) (f) Sphinx 80 gun Ship of the Line (average crew) (27 pts) .Ed -.Ss Nymphe vs. Cleopatre: +.Ss Nymphe vs. Cleopatre : Wind from the S, blowing a fresh breeze. .Bd -literal (b) Nymphe 36 gun Frigate (crack crew) (11 pts) (f) Cleopatre 36 gun Frigate (average crew) (10 pts) .Ed -.Ss Mars vs. Hercule: +.Ss Mars vs. Hercule : Wind from the S, blowing a fresh breeze. .Bd -literal (b) Mars 74 gun Ship of the Line (crack crew) (26 pts) (f) Hercule 74 gun Ship of the Line (average crew) (23 pts) .Ed -.Ss Ambuscade vs. Baionnaise: +.Ss Ambuscade vs. Baionnaise : Wind from the N, blowing a fresh breeze. .Bd -literal (b) Ambuscade 32 gun Frigate (average crew) (9 pts) (f) Baionnaise 24 gun Corvette (average crew) (9 pts) .Ed -.Ss Constellation vs. Insurgent: +.Ss Constellation vs. Insurgent : Wind from the S, blowing a gale. .Bd -literal (a) Constellation 38 gun Corvette (elite crew) (17 pts) (f) Insurgent 36 gun Corvette (average crew) (11 pts) .Ed -.Ss Constellation vs. Vengeance: +.Ss Constellation vs. Vengeance : Wind from the S, blowing a fresh breeze. .Bd -literal (a) Constellation 38 gun Corvette (elite crew) (17 pts) (f) Vengeance 40 gun Frigate (average crew) (15 pts) .Ed -.Ss The Battle of Lissa: +.Ss The Battle of Lissa : Wind from the S, blowing a fresh breeze. .Bd -literal (b) Amphion 32 gun Frigate (elite crew) (13 pts) @@ -776,31 +821,31 @@ Wind from the S, blowing a fresh breeze. (f) Corona 40 gun Frigate (green crew) (12 pts) (f) Carolina 32 gun Frigate (green crew) (7 pts) .Ed -.Ss Constitution vs. Guerriere: +.Ss Constitution vs. Guerriere : Wind from the SW, blowing a gale. .Bd -literal (a) Constitution 44 gun Corvette (elite crew) (24 pts) (b) Guerriere 38 gun Frigate (crack crew) (15 pts) .Ed -.Ss United States vs. Macedonian: +.Ss United States vs. Macedonian : Wind from the S, blowing a fresh breeze. .Bd -literal (a) United States 44 gun Frigate (elite crew) (24 pts) (b) Macedonian 38 gun Frigate (crack crew) (16 pts) .Ed -.Ss Constitution vs. Java: +.Ss Constitution vs. Java : Wind from the S, blowing a fresh breeze. .Bd -literal (a) Constitution 44 gun Corvette (elite crew) (24 pts) (b) Java 38 gun Corvette (crack crew) (19 pts) .Ed -.Ss Chesapeake vs. Shannon: +.Ss Chesapeake vs. Shannon : Wind from the S, blowing a fresh breeze. .Bd -literal (a) Chesapeake 38 gun Frigate (average crew) (14 pts) (b) Shannon 38 gun Frigate (elite crew) (17 pts) .Ed -.Ss The Battle of Lake Erie: +.Ss The Battle of Lake Erie : Wind from the S, blowing a light breeze. .Bd -literal (a) Lawrence 20 gun Sloop (crack crew) (9 pts) @@ -809,27 +854,27 @@ Wind from the S, blowing a light breeze. (b) Detroit 19 gun Sloop (crack crew) (7 pts) (b) Q. Charlotte 17 gun Sloop (crack crew) (6 pts) .Ed -.Ss Wasp vs. Reindeer: +.Ss Wasp vs. Reindeer : Wind from the S, blowing a light breeze. .Bd -literal (a) Wasp 20 gun Sloop (elite crew) (12 pts) (b) Reindeer 18 gun Sloop (elite crew) (9 pts) .Ed -.Ss Constitution vs. Cyane and Levant: +.Ss Constitution vs. Cyane and Levant : Wind from the S, blowing a moderate breeze. .Bd -literal (a) Constitution 44 gun Corvette (elite crew) (24 pts) (b) Cyane 24 gun Sloop (crack crew) (11 pts) (b) Levant 20 gun Sloop (crack crew) (10 pts) .Ed -.Ss Pellew vs. Droits de L'Homme: +.Ss Pellew vs. Droits de L'Homme : Wind from the N, blowing a gale. .Bd -literal (b) Indefatigable 44 gun Frigate (elite crew) (14 pts) (b) Amazon 36 gun Frigate (crack crew) (14 pts) (f) Droits L'Hom 74 gun Ship of the Line (average crew) (24 pts) .Ed -.Ss Algeciras: +.Ss Algeciras : Wind from the SW, blowing a moderate breeze. .Bd -literal (b) Caesar 80 gun Ship of the Line (crack crew) (31 pts) @@ -843,7 +888,7 @@ Wind from the SW, blowing a moderate breeze. (f) Indomptable 80 gun Ship of the Line (average crew) (27 pts) (f) Desaix 74 gun Ship of the Line (average crew) (24 pts) .Ed -.Ss Lake Champlain: +.Ss Lake Champlain : Wind from the N, blowing a fresh breeze. .Bd -literal (a) Saratoga 26 gun Sloop (crack crew) (12 pts) @@ -854,7 +899,7 @@ Wind from the N, blowing a fresh breeze. (b) Linnet 16 gun Sloop (elite crew) (10 pts) (b) Chubb 11 gun Brig (crack crew) (5 pts) .Ed -.Ss Last Voyage of the USS President: +.Ss Last Voyage of the USS President : Wind from the N, blowing a fresh breeze. .Bd -literal (a) President 44 gun Frigate (elite crew) (24 pts) @@ -862,7 +907,7 @@ Wind from the N, blowing a fresh breeze. (b) Pomone 44 gun Frigate (crack crew) (20 pts) (b) Tenedos 38 gun Frigate (crack crew) (15 pts) .Ed -.Ss Hornblower and the Natividad: +.Ss Hornblower and the Natividad : Wind from the E, blowing a gale. .Pp A scenario for you Horny fans. @@ -873,7 +918,7 @@ her crew is much bigger, albeit green. (b) Lydia 36 gun Frigate (elite crew) (13 pts) (s) Natividad 50 gun Ship of the Line (green crew) (14 pts) .Ed -.Ss Curse of the Flying Dutchman: +.Ss Curse of the Flying Dutchman : Wind from the S, blowing a fresh breeze. .Pp Just for fun, take the Piece of cake. @@ -881,7 +926,7 @@ Just for fun, take the Piece of cake. (s) Piece of Cake 24 gun Corvette (average crew) (9 pts) (f) Flying Dutchy 120 gun 3 Decker SOL (elite crew) (43 pts) .Ed -.Ss The South Pacific: +.Ss The South Pacific : Wind from the S, blowing a strong breeze. .Bd -literal (a) USS Scurvy 136 gun 3 Decker SOL (mutinous crew) (27 pts) @@ -889,7 +934,7 @@ Wind from the S, blowing a strong breeze. (s) Australian 32 gun Frigate (average crew) (9 pts) (f) Bikini Atoll 7 gun Brig (crack crew) (4 pts) .Ed -.Ss Hornblower and the battle of Rosas bay: +.Ss Hornblower and the battle of Rosas bay : Wind from the E, blowing a fresh breeze. .Pp The only battle Hornblower ever lost. @@ -902,7 +947,7 @@ See if you can do as well. (f) Paris 112 gun 3 Decker SOL (green crew) (27 pts) (f) Napoleon 74 gun Ship of the Line (green crew) (20 pts) .Ed -.Ss Cape Horn: +.Ss Cape Horn : Wind from the NE, blowing a strong breeze. .Bd -literal (a) Concord 80 gun Ship of the Line (average crew) (27 pts) @@ -911,7 +956,7 @@ Wind from the NE, blowing a strong breeze. (s) Madrid 112 gun 3 Decker SOL (green crew) (27 pts) (f) Musket 80 gun 3 Decker SOL (average crew) (27 pts) .Ed -.Ss New Orleans: +.Ss New Orleans : Wind from the SE, blowing a fresh breeze. .Pp Watch that little Cypress go! @@ -920,14 +965,14 @@ Watch that little Cypress go! (b) Firefly 74 gun Ship of the Line (crack crew) (27 pts) (b) Cypress 44 gun Frigate (elite crew) (14 pts) .Ed -.Ss Botany Bay: +.Ss Botany Bay : Wind from the N, blowing a fresh breeze. .Bd -literal (b) Shark 64 gun Ship of the Line (average crew) (18 pts) (f) Coral Snake 44 gun Corvette (elite crew) (24 pts) (f) Sea Lion 44 gun Frigate (elite crew) (24 pts) .Ed -.Ss Voyage to the Bottom of the Sea: +.Ss Voyage to the Bottom of the Sea : Wind from the NW, blowing a fresh breeze. .Pp This one is dedicated to Richard Basehart and David Hedison. @@ -937,14 +982,14 @@ This one is dedicated to Richard Basehart and David Hedison. (b) Mermaid 136 gun 3 Decker SOL (mutinous crew) (27 pts) (s) Giant Squid 112 gun 3 Decker SOL (green crew) (27 pts) .Ed -.Ss Frigate Action: +.Ss Frigate Action : Wind from the E, blowing a fresh breeze. .Bd -literal (a) Killdeer 40 gun Frigate (average crew) (15 pts) (b) Sandpiper 40 gun Frigate (average crew) (15 pts) (s) Curlew 38 gun Frigate (crack crew) (16 pts) .Ed -.Ss The Battle of Midway: +.Ss The Battle of Midway : Wind from the E, blowing a moderate breeze. .Bd -literal (a) Enterprise 80 gun Ship of the Line (crack crew) (31 pts) @@ -954,7 +999,7 @@ Wind from the E, blowing a moderate breeze. (j) Kaga 96 gun 3 Decker SOL (green crew) (24 pts) (j) Soryu 80 gun Ship of the Line (green crew) (23 pts) .Ed -.Ss Star Trek: +.Ss Star Trek : Wind from the S, blowing a fresh breeze. .Bd -literal (a) Enterprise 450 gun Ship of the Line (elite crew) (75 pts) @@ -969,63 +1014,82 @@ Wind from the S, blowing a fresh breeze. .Sh HISTORY Dave Riggle wrote the first version of .Nm -on a PDP 11/70 in the fall of 1980. -Needless to say, says Dave, the code was horrendous, +on a PDP\-11/70 in the fall of 1980. +Needless to say, the code was horrendous, not portable in any sense of the word, and didn't work. The program was not very modular and had -.Fn fseek Ns s +.Xr fseek 3 and -.Fn fwrite Ns s -every few lines. +.Xr fwrite 3 +calls every few lines. After a tremendous rewrite from the top down, -he got the first working version up by 1981. +the first working version was up and running by 1981. There were several annoying bugs concerning firing broadsides and finding angles. -.Nm -uses no floating point, by the way, so the direction routines are rather -tricky. +.\" No longer true... +.\" .Nm +.\" uses no floating point, by the way, so the direction routines are rather +.\" tricky. +.Pp Ed Wang rewrote the .Fn angle -routine in 1981 to be less incorrect, and he added code to let a player -select which ship he wanted at the start of the game. +routine in 1981 to be more correct. +He also added code to let a player select +which ship he wanted at the start of the game, instead of always +taking the first one available. .Pp Captain Happy (Craig Leres) is responsible for making .Nm portable for the first time. -This was no easy task, by the way. +This was no easy task. +Constants like 2 and 10 were very frequent in the code. +The +.Nm +code was also notorious for the use of +.Dq Riggle Memorial Structures . +Many structure references were so long that they ran off the line +printer page. +Here is an example, if you promise not to laugh: +.Bd -literal -offset indent +specs[scene[flog.fgamenum].ship[flog.fshipnum].shipnum].pts +.Ed .Pp .Nm received its fourth and most thorough rewrite in the summer and fall -of 1983: -Ed Wang rewrote and modularized the code -.Pq a monumental feat +of 1983. +Ed Wang rewrote and modularized the code (a monumental feat) almost from scratch. -Although he introduced many new bugs, the final -result was very much cleaner and -.Pq \&? -faster. +Although he introduced many new bugs, the final result was very much +cleaner and (?) faster. He added window movement commands and find ship commands. +.Pp +At some currently unknown time, +.Nm +was imported into +.Bx . .Sh AUTHORS .Nm has been a group effort. -.Pp -.An Dave Riggle -.Pp -.An Ed Wang , -co-author -.Pp -.An Craig Leres , -refitting +.Ss AUTHOR +Dave Riggle +.Ss CO-AUTHOR +Ed Wang +.Ss REFITTING +Craig Leres .Ss CONSULTANTS -.An -nosplit -.An Chris Guthrie , -.An Captain Happy , -.An Horatio Nelson +.Bl -item -compact +.It +Chris Guthrie +.It +Captain Happy +.It +Horatio Nelson +.El and many valiant others... .Sh REFERENCES .Rs -.%B Wooden Ships & Iron Men +.%B Wooden Ships \*[Am] Iron Men .%A "Avalon Hill" .Re .Pp @@ -1049,8 +1113,10 @@ and many valiant others... .Pp .Rs .%B The Complete Works of Captain Frederick Marryat +.%O "(about 20)" .Re -Of these, especially +.Pp +Of these, consider especially .Bl -item -offset indent -compact .It .%B Mr. Midshipman Easy @@ -1065,5 +1131,6 @@ Of these, especially .It .%B Frank Mildmay, or The Naval Officer .El -.Sh BUGS -Probably a few. +.\" .Sh BUGS +.\" Probably a few, and please report them to "riggle@ernie.berkeley.edu" and +.\" "edward@ucbarpa.berkeley.edu". diff --git a/games/sail/sync.c b/games/sail/sync.c index 468da58407..26b4c10c80 100644 --- a/games/sail/sync.c +++ b/games/sail/sync.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: sync.c,v 1.34 2013/10/19 17:23:08 christos Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,31 +27,143 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)sync.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/sync.c,v 1.9 1999/11/30 03:49:38 billf Exp $ */ -#include -#include -#include +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)sync.c 8.2 (Berkeley) 4/28/95"; +#else +__RCSID("$NetBSD: sync.c,v 1.34 2013/10/19 17:23:08 christos Exp $"); +#endif +#endif /* not lint */ + #include -#include "externs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extern.h" +#include "pathnames.h" #define BUFSIZE 4096 +/* Message types */ +#define W_CAPTAIN 1 +#define W_CAPTURED 2 +#define W_CLASS 3 +#define W_CREW 4 +#define W_DBP 5 +#define W_DRIFT 6 +#define W_EXPLODE 7 +/* W_FILE 8 not used */ +#define W_FOUL 9 +#define W_GUNL 10 +#define W_GUNR 11 +#define W_HULL 12 +#define W_MOVE 13 +#define W_OBP 14 +#define W_PCREW 15 +#define W_UNFOUL 16 +#define W_POINTS 17 +#define W_QUAL 18 +#define W_UNGRAP 19 +#define W_RIGG 20 +#define W_COL 21 +#define W_DIR 22 +#define W_ROW 23 +#define W_SIGNAL 24 +#define W_SINK 25 +#define W_STRUCK 26 +#define W_TA 27 +#define W_ALIVE 28 +#define W_TURN 29 +#define W_WIND 30 +#define W_FS 31 +#define W_GRAP 32 +#define W_RIG1 33 +#define W_RIG2 34 +#define W_RIG3 35 +#define W_RIG4 36 +#define W_BEGIN 37 +#define W_END 38 +#define W_DDEAD 39 + + +static void recv_captain(struct ship *ship, const char *astr); +static void recv_captured(struct ship *ship, long a); +static void recv_class(struct ship *ship, long a); +static void recv_crew(struct ship *ship, long a, long b, long c); +static void recv_dbp(struct ship *ship, long a, long b, long c, long d); +static void recv_drift(struct ship *ship, long a); +static void recv_explode(struct ship *ship, long a); +static void recv_foul(struct ship *ship, long a); +static void recv_gunl(struct ship *ship, long a, long b); +static void recv_gunr(struct ship *ship, long a, long b); +static void recv_hull(struct ship *ship, long a); +static void recv_move(struct ship *ship, const char *astr); +static void recv_obp(struct ship *ship, long a, long b, long c, long d); +static void recv_pcrew(struct ship *ship, long a); +static void recv_unfoul(struct ship *ship, long a, long b); +static void recv_points(struct ship *ship, long a); +static void recv_qual(struct ship *ship, long a); +static void recv_ungrap(struct ship *ship, long a, long b); +static void recv_rigg(struct ship *ship, long a, long b, long c, long d); +static void recv_col(struct ship *ship, long a); +static void recv_dir(struct ship *ship, long a); +static void recv_row(struct ship *ship, long a); +static void recv_signal(struct ship *ship, const char *astr); +static void recv_sink(struct ship *ship, long a); +static void recv_struck(struct ship *ship, long a); +static void recv_ta(struct ship *ship, long a); +static void recv_alive(void); +static void recv_turn(long a); +static void recv_wind(long a, long b); +static void recv_fs(struct ship *ship, long a); +static void recv_grap(struct ship *ship, long a); +static void recv_rig1(struct ship *ship, long a); +static void recv_rig2(struct ship *ship, long a); +static void recv_rig3(struct ship *ship, long a); +static void recv_rig4(struct ship *ship, long a); +static void recv_begin(struct ship *ship); +static void recv_end(struct ship *ship); +static void recv_ddead(void); + +static void Write(int, struct ship *, long, long, long, long); +static void Writestr(int, struct ship *, const char *); + static int sync_update(int, struct ship *, const char *, long, long, long, long); static char sync_buf[BUFSIZE]; static char *sync_bp = sync_buf; -static char sync_lock[25]; -static char sync_file[25]; static long sync_seek; static FILE *sync_fp; -#define SF "/tmp/#sailsink.%d" -#define LF "/tmp/#saillock.%d" +static const char * +get_sync_file(int scenario_number) +{ + static char sync_file[NAME_MAX]; + + snprintf(sync_file, sizeof(sync_file), _FILE_SYNC, scenario_number); + return sync_file; +} + +static const char * +get_lock_file(int scenario_number) +{ + static char sync_lock[NAME_MAX]; + + snprintf(sync_lock, sizeof(sync_lock), _FILE_LOCK, scenario_number); + return sync_lock; +} void fmtship(char *buf, size_t len, const char *fmt, struct ship *ship) @@ -74,58 +188,79 @@ fmtship(char *buf, size_t len, const char *fmt, struct ship *ship) *buf = '\0'; } + /*VARARGS3*/ void makesignal(struct ship *from, const char *fmt, struct ship *ship, ...) { - char message[80]; + char message[BUFSIZ]; char format[BUFSIZ]; va_list ap; va_start(ap, ship); - if (ship == NULL) - vsprintf(message, fmt, ap); - else { - fmtship(format, sizeof(format), fmt, ship); - vsprintf(message, format, ap); - } + fmtship(format, sizeof(format), fmt, ship); + vsnprintf(message, sizeof(message), format, ap); + va_end(ap); + send_signal(from, message); +} + +/*VARARGS2*/ +void +makemsg(struct ship *from, const char *fmt, ...) +{ + char message[BUFSIZ]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); - Writestr(W_SIGNAL, from, message); + send_signal(from, message); } -bool -sync_exists(int lgame) +int +sync_exists(int gamenum) { - char buf[sizeof sync_file]; + const char *path; struct stat s; time_t t; - sprintf(buf, SF, game); + path = get_sync_file(gamenum); time(&t); - if (stat(buf, &s) < 0) + setegid(egid); + if (stat(path, &s) < 0) { + setegid(gid); return 0; + } if (s.st_mtime < t - 60*60*2) { /* 2 hours */ - unlink(buf); - sprintf(buf, LF, lgame); - unlink(buf); + unlink(path); + path = get_lock_file(gamenum); + unlink(path); + setegid(gid); return 0; - } else + } else { + setegid(gid); return 1; + } } int sync_open(void) { + const char *sync_file; + struct stat tmp; + if (sync_fp != NULL) fclose(sync_fp); - sprintf(sync_lock, LF, game); - sprintf(sync_file, SF, game); - if (access(sync_file, 0) < 0) { - int omask = umask(issetuid ? 077 : 011); + sync_file = get_sync_file(game); + (void)get_lock_file(game); + setegid(egid); + if (stat(sync_file, &tmp) < 0) { + mode_t omask = umask(002); sync_fp = fopen(sync_file, "w+"); umask(omask); } else sync_fp = fopen(sync_file, "r+"); + setegid(gid); if (sync_fp == NULL) return -1; sync_seek = 0; @@ -133,19 +268,28 @@ sync_open(void) } void -sync_close(char rm) +sync_close(int doremove) { - if (sync_fp != NULL) + const char *sync_file; + + if (sync_fp != 0) fclose(sync_fp); - if (rm) + if (doremove) { + sync_file = get_sync_file(game); + setegid(egid); unlink(sync_file); + setegid(gid); + } } -void -Write(int type, struct ship *ship, int a, int b, int c, int d) +static void +Write(int type, struct ship *ship, long a, long b, long c, long d) { - sprintf(sync_bp, "%d %d 0 %d %d %d %d\n", - type, ship->file->index, a, b, c, d); + size_t max = sizeof(sync_buf) - (sync_bp - sync_buf); + int shipindex = (ship == NULL) ? 0 : ship->file->index; + + snprintf(sync_bp, max, "%d %d 0 %ld %ld %ld %ld\n", + type, shipindex, a, b, c, d); while (*sync_bp++) ; sync_bp--; @@ -154,10 +298,13 @@ Write(int type, struct ship *ship, int a, int b, int c, int d) sync_update(type, ship, NULL, a, b, c, d); } -void +static void Writestr(int type, struct ship *ship, const char *a) { - sprintf(sync_bp, "%d %d 1 %s\n", type, ship->file->index, a); + size_t max = sizeof(sync_buf) - (sync_bp - sync_buf); + int shipindex = (ship == NULL) ? 0 : ship->file->index; + + snprintf(sync_bp, max, "%d %d 1 %s\n", type, shipindex, a); while (*sync_bp++) ; sync_bp--; @@ -171,10 +318,16 @@ Sync(void) { sig_t sighup, sigint; int n; - int type, shipnum, isstr, a, b, c, d; + int type, shipnum, isstr; char *astr; + long a, b, c, d; char buf[80]; char erred = 0; +#ifndef LOCK_EX + const char *sync_file; + const char *sync_lock; +#endif + sighup = signal(SIGHUP, SIG_IGN); sigint = signal(SIGINT, SIG_IGN); for (n = TIMEOUT; --n >= 0;) { @@ -184,8 +337,14 @@ Sync(void) if (errno != EWOULDBLOCK) return -1; #else - if (link(sync_file, sync_lock) >= 0) + sync_file = get_sync_file(game); + sync_lock = get_lock_file(game); + setegid(egid); + if (link(sync_file, sync_lock) >= 0) { + setegid(gid); break; + } + setegid(gid); if (errno != EEXIST) return -1; #endif @@ -208,9 +367,13 @@ Sync(void) if (isstr != 0 && isstr != 1) goto bad; if (isstr) { + int ch; char *p; + for (p = buf;;) { - switch (*p++ = getc(sync_fp)) { + ch = getc(sync_fp); + *p++ = ch; + switch (ch) { case '\n': p--; case EOF: @@ -228,7 +391,8 @@ Sync(void) astr = p; a = b = c = d = 0; } else { - if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4) + if (fscanf(sync_fp, "%ld%ld%ld%ld", &a, &b, &c, &d) + != 4) goto bad; astr = NULL; } @@ -249,7 +413,9 @@ out: #ifdef LOCK_EX flock(fileno(sync_fp), LOCK_UN); #else + setegid(egid); unlink(sync_lock); + setegid(gid); #endif signal(SIGHUP, sighup); signal(SIGINT, sigint); @@ -257,200 +423,585 @@ out: } static int -sync_update(int type, struct ship *ship, const char *astr, long a, long b, - long c, long d) +sync_update(int type, struct ship *ship, const char *astr, + long a, long b, long c, long d) { switch (type) { - case W_DBP: { - struct BP *p = &ship->file->DBP[a]; - p->turnsent = b; - p->toship = SHIP(c); - p->mensent = d; - break; - } - case W_OBP: { - struct BP *p = &ship->file->OBP[a]; - p->turnsent = b; - p->toship = SHIP(c); - p->mensent = d; - break; - } - case W_FOUL: { - struct snag *p = &ship->file->foul[a]; - if (SHIP(a)->file->dir == 0) - break; - if (p->sn_count++ == 0) - p->sn_turn = turn; - ship->file->nfoul++; - break; - } - case W_GRAP: { - struct snag *p = &ship->file->grap[a]; - if (SHIP(a)->file->dir == 0) - break; - if (p->sn_count++ == 0) - p->sn_turn = turn; - ship->file->ngrap++; - break; - } - case W_UNFOUL: { - struct snag *p = &ship->file->foul[a]; - if (p->sn_count > 0) { - if (b) { - ship->file->nfoul -= p->sn_count; - p->sn_count = 0; - } else { - ship->file->nfoul--; - p->sn_count--; - } - } - break; - } - case W_UNGRAP: { - struct snag *p = &ship->file->grap[a]; - if (p->sn_count > 0) { - if (b) { - ship->file->ngrap -= p->sn_count; - p->sn_count = 0; - } else { - ship->file->ngrap--; - p->sn_count--; - } - } - break; - } - case W_SIGNAL: - if (mode == MODE_PLAYER) { - if (nobells) - Signal("%s (%c%c): %s", ship, astr); - else - Signal("\7%s (%c%c): %s", ship, astr); - } - break; - case W_CREW: { - struct shipspecs *s = ship->specs; - s->crew1 = a; - s->crew2 = b; - s->crew3 = c; - break; - } - case W_CAPTAIN: - strncpy(ship->file->captain, astr, - sizeof ship->file->captain - 1); - ship->file->captain[sizeof ship->file->captain - 1] = 0; - break; - case W_CAPTURED: - if (a < 0) - ship->file->captured = 0; - else - ship->file->captured = SHIP(a); - break; - case W_CLASS: - ship->specs->class = a; - break; - case W_DRIFT: - ship->file->drift = a; - break; - case W_EXPLODE: - if ((ship->file->explode = a) == 2) - ship->file->dir = 0; - break; - case W_FS: - ship->file->FS = a; - break; - case W_GUNL: { - struct shipspecs *s = ship->specs; - s->gunL = a; - s->carL = b; - break; - } - case W_GUNR: { - struct shipspecs *s = ship->specs; - s->gunR = a; - s->carR = b; - break; - } - case W_HULL: - ship->specs->hull = a; - break; - case W_MOVE: - strncpy(ship->file->movebuf, astr, - sizeof ship->file->movebuf - 1); - ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0; - break; - case W_PCREW: - ship->file->pcrew = a; - break; - case W_POINTS: - ship->file->points = a; - break; - case W_QUAL: - ship->specs->qual = a; - break; - case W_RIGG: { - struct shipspecs *s = ship->specs; - s->rig1 = a; - s->rig2 = b; - s->rig3 = c; - s->rig4 = d; - break; - } - case W_RIG1: - ship->specs->rig1 = a; - break; - case W_RIG2: - ship->specs->rig2 = a; - break; - case W_RIG3: - ship->specs->rig3 = a; - break; - case W_RIG4: - ship->specs->rig4 = a; - break; - case W_COL: - ship->file->col = a; - break; - case W_DIR: - ship->file->dir = a; - break; - case W_ROW: - ship->file->row = a; - break; - case W_SINK: - if ((ship->file->sink = a) == 2) - ship->file->dir = 0; - break; - case W_STRUCK: - ship->file->struck = a; - break; - case W_TA: - ship->specs->ta = a; - break; - case W_ALIVE: - alive = 1; - break; - case W_TURN: - turn = a; - break; - case W_WIND: - winddir = a; - windspeed = b; - break; - case W_BEGIN: - strcpy(ship->file->captain, "begin"); - people++; - break; - case W_END: - *ship->file->captain = 0; - ship->file->points = 0; - people--; - break; - case W_DDEAD: - hasdriver = 0; - break; + case W_CAPTAIN: recv_captain(ship, astr); break; + case W_CAPTURED: recv_captured(ship, a); break; + case W_CLASS: recv_class(ship, a); break; + case W_CREW: recv_crew(ship, a, b, c); break; + case W_DBP: recv_dbp(ship, a, b, c, d); break; + case W_DRIFT: recv_drift(ship, a); break; + case W_EXPLODE: recv_explode(ship, a); break; + case W_FOUL: recv_foul(ship, a); break; + case W_GUNL: recv_gunl(ship, a, b); break; + case W_GUNR: recv_gunr(ship, a, b); break; + case W_HULL: recv_hull(ship, a); break; + case W_MOVE: recv_move(ship, astr); break; + case W_OBP: recv_obp(ship, a, b, c, d); break; + case W_PCREW: recv_pcrew(ship, a); break; + case W_UNFOUL: recv_unfoul(ship, a, b); break; + case W_POINTS: recv_points(ship, a); break; + case W_QUAL: recv_qual(ship, a); break; + case W_UNGRAP: recv_ungrap(ship, a, b); break; + case W_RIGG: recv_rigg(ship, a, b, c, d); break; + case W_COL: recv_col(ship, a); break; + case W_DIR: recv_dir(ship, a); break; + case W_ROW: recv_row(ship, a); break; + case W_SIGNAL: recv_signal(ship, astr); break; + case W_SINK: recv_sink(ship, a); break; + case W_STRUCK: recv_struck(ship, a); break; + case W_TA: recv_ta(ship, a); break; + case W_ALIVE: recv_alive(); break; + case W_TURN: recv_turn(a); break; + case W_WIND: recv_wind(a, b); break; + case W_FS: recv_fs(ship, a); break; + case W_GRAP: recv_grap(ship, a); break; + case W_RIG1: recv_rig1(ship, a); break; + case W_RIG2: recv_rig2(ship, a); break; + case W_RIG3: recv_rig3(ship, a); break; + case W_RIG4: recv_rig4(ship, a); break; + case W_BEGIN: recv_begin(ship); break; + case W_END: recv_end(ship); break; + case W_DDEAD: recv_ddead(); break; default: fprintf(stderr, "sync_update: unknown type %d\r\n", type); return -1; } return 0; } + +/* + * Messages to send + */ + +void +send_captain(struct ship *ship, const char *astr) +{ + Writestr(W_CAPTAIN, ship, astr); +} + +void +send_captured(struct ship *ship, long a) +{ + Write(W_CAPTURED, ship, a, 0, 0, 0); +} + +void +send_class(struct ship *ship, long a) +{ + Write(W_CLASS, ship, a, 0, 0, 0); +} + +void +send_crew(struct ship *ship, long a, long b, long c) +{ + Write(W_CREW, ship, a, b, c, 0); +} + +void +send_dbp(struct ship *ship, long a, long b, long c, long d) +{ + Write(W_DBP, ship, a, b, c, d); +} + +void +send_drift(struct ship *ship, long a) +{ + Write(W_DRIFT, ship, a, 0, 0, 0); +} + +void +send_explode(struct ship *ship, long a) +{ + Write(W_EXPLODE, ship, a, 0, 0, 0); +} + +void +send_foul(struct ship *ship, long a) +{ + Write(W_FOUL, ship, a, 0, 0, 0); +} + +void +send_gunl(struct ship *ship, long a, long b) +{ + Write(W_GUNL, ship, a, b, 0, 0); +} + +void +send_gunr(struct ship *ship, long a, long b) +{ + Write(W_GUNR, ship, a, b, 0, 0); +} + +void +send_hull(struct ship *ship, long a) +{ + Write(W_HULL, ship, a, 0, 0, 0); +} + +void +send_move(struct ship *ship, const char *astr) +{ + Writestr(W_MOVE, ship, astr); +} + +void +send_obp(struct ship *ship, long a, long b, long c, long d) +{ + Write(W_OBP, ship, a, b, c, d); +} + +void +send_pcrew(struct ship *ship, long a) +{ + Write(W_PCREW, ship, a, 0, 0, 0); +} + +void +send_unfoul(struct ship *ship, long a, long b) +{ + Write(W_UNFOUL, ship, a, b, 0, 0); +} + +void +send_points(struct ship *ship, long a) +{ + Write(W_POINTS, ship, a, 0, 0, 0); +} + +void +send_qual(struct ship *ship, long a) +{ + Write(W_QUAL, ship, a, 0, 0, 0); +} + +void +send_ungrap(struct ship *ship, long a, long b) +{ + Write(W_UNGRAP, ship, a, b, 0, 0); +} + +void +send_rigg(struct ship *ship, long a, long b, long c, long d) +{ + Write(W_RIGG, ship, a, b, c, d); +} + +void +send_col(struct ship *ship, long a) +{ + Write(W_COL, ship, a, 0, 0, 0); +} + +void +send_dir(struct ship *ship, long a) +{ + Write(W_DIR, ship, a, 0, 0, 0); +} + +void +send_row(struct ship *ship, long a) +{ + Write(W_ROW, ship, a, 0, 0, 0); +} + +void +send_signal(struct ship *ship, const char *astr) +{ + Writestr(W_SIGNAL, ship, astr); +} + +void +send_sink(struct ship *ship, long a) +{ + Write(W_SINK, ship, a, 0, 0, 0); +} + +void +send_struck(struct ship *ship, long a) +{ + Write(W_STRUCK, ship, a, 0, 0, 0); +} + +void +send_ta(struct ship *ship, long a) +{ + Write(W_TA, ship, a, 0, 0, 0); +} + +void +send_alive(void) +{ + Write(W_ALIVE, NULL, 0, 0, 0, 0); +} + +void +send_turn(long a) +{ + Write(W_TURN, NULL, a, 0, 0, 0); +} + +void +send_wind(long a, long b) +{ + Write(W_WIND, NULL, a, b, 0, 0); +} + +void +send_fs(struct ship *ship, long a) +{ + Write(W_FS, ship, a, 0, 0, 0); +} + +void +send_grap(struct ship *ship, long a) +{ + Write(W_GRAP, ship, a, 0, 0, 0); +} + +void +send_rig1(struct ship *ship, long a) +{ + Write(W_RIG1, ship, a, 0, 0, 0); +} + +void +send_rig2(struct ship *ship, long a) +{ + Write(W_RIG2, ship, a, 0, 0, 0); +} + +void +send_rig3(struct ship *ship, long a) +{ + Write(W_RIG3, ship, a, 0, 0, 0); +} + +void +send_rig4(struct ship *ship, long a) +{ + Write(W_RIG4, ship, a, 0, 0, 0); +} + +void +send_begin(struct ship *ship) +{ + Write(W_BEGIN, ship, 0, 0, 0, 0); +} + +void +send_end(struct ship *ship) +{ + Write(W_END, ship, 0, 0, 0, 0); +} + +void +send_ddead(void) +{ + Write(W_DDEAD, NULL, 0, 0, 0, 0); +} + + +/* + * Actions upon message receipt + */ + +static void +recv_captain(struct ship *ship, const char *astr) +{ + strlcpy(ship->file->captain, astr, sizeof ship->file->captain); +} + +static void +recv_captured(struct ship *ship, long a) +{ + if (a < 0) + ship->file->captured = 0; + else + ship->file->captured = SHIP(a); +} + +static void +recv_class(struct ship *ship, long a) +{ + ship->specs->class = a; +} + +static void +recv_crew(struct ship *ship, long a, long b, long c) +{ + struct shipspecs *s = ship->specs; + + s->crew1 = a; + s->crew2 = b; + s->crew3 = c; +} + +static void +recv_dbp(struct ship *ship, long a, long b, long c, long d) +{ + struct BP *p = &ship->file->DBP[a]; + + p->turnsent = b; + p->toship = SHIP(c); + p->mensent = d; +} + +static void +recv_drift(struct ship *ship, long a) +{ + ship->file->drift = a; +} + +static void +recv_explode(struct ship *ship, long a) +{ + if ((ship->file->explode = a) == 2) + ship->file->dir = 0; +} + +static void +recv_foul(struct ship *ship, long a) +{ + struct snag *p = &ship->file->foul[a]; + + if (SHIP(a)->file->dir == 0) + return; + if (p->sn_count++ == 0) + p->sn_turn = turn; + ship->file->nfoul++; +} + +static void +recv_gunl(struct ship *ship, long a, long b) +{ + struct shipspecs *s = ship->specs; + + s->gunL = a; + s->carL = b; +} + +static void +recv_gunr(struct ship *ship, long a, long b) +{ + struct shipspecs *s = ship->specs; + + s->gunR = a; + s->carR = b; +} + +static void +recv_hull(struct ship *ship, long a) +{ + ship->specs->hull = a; +} + +static void +recv_move(struct ship *ship, const char *astr) +{ + strlcpy(ship->file->movebuf, astr, sizeof ship->file->movebuf); +} + +static void +recv_obp(struct ship *ship, long a, long b, long c, long d) +{ + struct BP *p = &ship->file->OBP[a]; + + p->turnsent = b; + p->toship = SHIP(c); + p->mensent = d; +} + +static void +recv_pcrew(struct ship *ship, long a) +{ + ship->file->pcrew = a; +} + +static void +recv_unfoul(struct ship *ship, long a, long b) +{ + struct snag *p = &ship->file->foul[a]; + + if (p->sn_count > 0) { + if (b) { + ship->file->nfoul -= p->sn_count; + p->sn_count = 0; + } else { + ship->file->nfoul--; + p->sn_count--; + } + } +} + +static void +recv_points(struct ship *ship, long a) +{ + ship->file->points = a; +} + +static void +recv_qual(struct ship *ship, long a) +{ + ship->specs->qual = a; +} + +static void +recv_ungrap(struct ship *ship, long a, long b) +{ + struct snag *p = &ship->file->grap[a]; + + if (p->sn_count > 0) { + if (b) { + ship->file->ngrap -= p->sn_count; + p->sn_count = 0; + } else { + ship->file->ngrap--; + p->sn_count--; + } + } +} + +static void +recv_rigg(struct ship *ship, long a, long b, long c, long d) +{ + struct shipspecs *s = ship->specs; + + s->rig1 = a; + s->rig2 = b; + s->rig3 = c; + s->rig4 = d; +} + +static void +recv_col(struct ship *ship, long a) +{ + ship->file->col = a; +} + +static void +recv_dir(struct ship *ship, long a) +{ + ship->file->dir = a; +} + +static void +recv_row(struct ship *ship, long a) +{ + ship->file->row = a; +} + +static void +recv_signal(struct ship *ship, const char *astr) +{ + if (mode == MODE_PLAYER) { + if (nobells) + Signal("$$: %s", ship, astr); + else + Signal("\a$$: %s", ship, astr); + } +} + +static void +recv_sink(struct ship *ship, long a) +{ + if ((ship->file->sink = a) == 2) + ship->file->dir = 0; +} + +static void +recv_struck(struct ship *ship, long a) +{ + ship->file->struck = a; +} + +static void +recv_ta(struct ship *ship, long a) +{ + ship->specs->ta = a; +} + +static void +recv_alive(void) +{ + alive = 1; +} + +static void +recv_turn(long a) +{ + turn = a; +} + +static void +recv_wind(long a, long b) +{ + winddir = a; + windspeed = b; +} + +static void +recv_fs(struct ship *ship, long a) +{ + ship->file->FS = a; +} + +static void +recv_grap(struct ship *ship, long a) +{ + struct snag *p = &ship->file->grap[a]; + + if (SHIP(a)->file->dir == 0) + return; + if (p->sn_count++ == 0) + p->sn_turn = turn; + ship->file->ngrap++; +} + +static void +recv_rig1(struct ship *ship, long a) +{ + ship->specs->rig1 = a; +} + +static void +recv_rig2(struct ship *ship, long a) +{ + ship->specs->rig2 = a; +} + +static void +recv_rig3(struct ship *ship, long a) +{ + ship->specs->rig3 = a; +} + +static void +recv_rig4(struct ship *ship, long a) +{ + ship->specs->rig4 = a; +} + +static void +recv_begin(struct ship *ship) +{ + strcpy(ship->file->captain, "begin"); + people++; +} + +static void +recv_end(struct ship *ship) +{ + *ship->file->captain = 0; + ship->file->points = 0; + people--; +} + +static void +recv_ddead(void) +{ + hasdriver = 0; +} diff --git a/games/sail/version.c b/games/sail/version.c index 3329077551..7eb59cac1e 100644 --- a/games/sail/version.c +++ b/games/sail/version.c @@ -1,4 +1,6 @@ -/*- +/* $NetBSD: version.c,v 1.6 2009/03/14 20:10:43 dholland Exp $ */ + +/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * @@ -25,10 +27,15 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)version.c 8.1 (Berkeley) 5/31/93 - * $FreeBSD: src/games/sail/version.c,v 1.2 1999/11/30 03:49:38 billf Exp $ - * $DragonFly: src/games/sail/version.c,v 1.2 2003/06/17 04:25:25 dillon Exp $ */ -char version[] = "Wooden Ships and Iron Men, Version 8.1 (93/05/31)"; +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)version.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: version.c,v 1.6 2009/03/14 20:10:43 dholland Exp $"); +#endif +#endif /* not lint */ + +const char version[] = "Wooden Ships and Iron Men, Version 8.1 (93/05/31)"; -- 2.41.0