diff options
-rw-r--r-- | sail/Makefile | 4 | ||||
-rw-r--r-- | sail/array.c | 123 | ||||
-rw-r--r-- | sail/array.h | 241 | ||||
-rw-r--r-- | sail/display.h | 14 | ||||
-rw-r--r-- | sail/extern.h | 10 | ||||
-rw-r--r-- | sail/inlinedefs.h | 39 | ||||
-rw-r--r-- | sail/pl_2.c | 41 | ||||
-rw-r--r-- | sail/pl_3.c | 7 | ||||
-rw-r--r-- | sail/pl_5.c | 12 | ||||
-rw-r--r-- | sail/pl_6.c | 10 | ||||
-rw-r--r-- | sail/pl_7.c | 313 | ||||
-rw-r--r-- | sail/pl_main.c | 7 |
12 files changed, 688 insertions, 133 deletions
diff --git a/sail/Makefile b/sail/Makefile index 6fac3b21..00426ca2 100644 --- a/sail/Makefile +++ b/sail/Makefile @@ -1,10 +1,10 @@ -# $NetBSD: Makefile,v 1.15 2008/01/28 07:03:59 dholland Exp $ +# $NetBSD: Makefile,v 1.16 2009/03/15 03:33:56 dholland Exp $ # @(#)Makefile 8.1 (Berkeley) 5/31/93 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 + assorted.c game.c globals.c misc.c parties.c sync.c array.c version.c MAN= sail.6 DPADD= ${LIBCURSES} LDADD= -lcurses diff --git a/sail/array.c b/sail/array.c new file mode 100644 index 00000000..af848e1b --- /dev/null +++ b/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 <stdlib.h> +#include <string.h> + +#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/sail/array.h b/sail/array.h new file mode 100644 index 00000000..efbaf99a --- /dev/null +++ b/sail/array.h @@ -0,0 +1,241 @@ +/*- + * 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 + +#include "inlinedefs.h" + +#define ARRAYS_CHECKED + +#ifdef ARRAYS_CHECKED +#include <assert.h> +#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 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/sail/display.h b/sail/display.h index bcd58b95..5826a2ed 100644 --- a/sail/display.h +++ b/sail/display.h @@ -1,4 +1,4 @@ -/* $NetBSD: display.h,v 1.6 2009/03/15 00:50:47 dholland Exp $ */ +/* $NetBSD: display.h,v 1.7 2009/03/15 03:33:56 dholland Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -31,10 +31,14 @@ #include <stdbool.h> -void display_show_obp(int which, bool show); -void display_show_dbp(int which, bool show); -void display_refresh_slot_w(void); +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_adjust_view(void); +void display_force_full_redraw(void); +void display_redraw(void); diff --git a/sail/extern.h b/sail/extern.h index dba55005..06006683 100644 --- a/sail/extern.h +++ b/sail/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.33 2009/03/14 22:54:05 dholland Exp $ */ +/* $NetBSD: extern.h,v 1.34 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -313,6 +313,7 @@ void choke(int) __attribute__((__noreturn__)); void child(int); /* pl_2.c */ +void newturn(int); void play(void) __attribute__((__noreturn__)); /* pl_3.c */ @@ -338,7 +339,6 @@ void loadplayer(void); /* pl_7.c */ void initscreen(void); void cleanupscreen(void); -void newturn(int); void Signal(const char *, struct ship *, ...) __attribute__((__format__(__printf__,1,3))); void Msg(const char *, ...) @@ -346,12 +346,6 @@ void Msg(const char *, ...) void prompt(const char *, struct ship *); 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); diff --git a/sail/inlinedefs.h b/sail/inlinedefs.h new file mode 100644 index 00000000..e7f02396 --- /dev/null +++ b/sail/inlinedefs.h @@ -0,0 +1,39 @@ +/*- + * 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. + */ + +#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__) +/* gcc's non-C99 inline semantics */ +#define INLINE extern inline +#elif defined(__STDC__) && __STDC_VERSION__ >= 199901L +/* C99 */ +#define INLINE inline +#else +/* something else; static inline is safest */ +#define INLINE static inline +#endif diff --git a/sail/pl_2.c b/sail/pl_2.c index c66ddae8..57d5756e 100644 --- a/sail/pl_2.c +++ b/sail/pl_2.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl_2.c,v 1.12 2009/03/15 00:50:47 dholland Exp $ */ +/* $NetBSD: pl_2.c,v 1.13 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pl_2.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pl_2.c,v 1.12 2009/03/15 00:50:47 dholland Exp $"); +__RCSID("$NetBSD: pl_2.c,v 1.13 2009/03/15 03:33:56 dholland Exp $"); #endif #endif /* not lint */ @@ -89,7 +89,7 @@ newturn(int n __unused) leave(LEAVE_HURRICAN); display_adjust_view(); - draw_screen(); + display_redraw(); signal(SIGALRM, newturn); alarm(7); @@ -101,7 +101,17 @@ play(void) struct ship *sp; for (;;) { - switch (sgetch("~\b", (struct ship *)0, 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; @@ -139,10 +149,7 @@ play(void) break; case '\f': centerview(); - blockalarm(); - draw_board(); - draw_screen(); - unblockalarm(); + display_force_full_redraw(); break; case 'L': mf->loadL = L_EMPTY; @@ -170,43 +177,25 @@ play(void) 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/sail/pl_3.c b/sail/pl_3.c index 58774e01..b638acc4 100644 --- a/sail/pl_3.c +++ b/sail/pl_3.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl_3.c,v 1.19 2009/03/14 22:52:52 dholland Exp $ */ +/* $NetBSD: pl_3.c,v 1.20 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pl_3.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pl_3.c,v 1.19 2009/03/14 22:52:52 dholland Exp $"); +__RCSID("$NetBSD: pl_3.c,v 1.20 2009/03/15 03:33:56 dholland Exp $"); #endif #endif /* not lint */ @@ -212,9 +212,6 @@ acceptcombat(void) cant: Msg("Unable to fire %s broadside", r ? "right" : "left"); } - blockalarm(); - draw_stat(); - unblockalarm(); } void diff --git a/sail/pl_5.c b/sail/pl_5.c index 2e72116a..d149b933 100644 --- a/sail/pl_5.c +++ b/sail/pl_5.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl_5.c,v 1.24 2009/03/15 00:35:42 dholland Exp $ */ +/* $NetBSD: pl_5.c,v 1.25 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pl_5.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pl_5.c,v 1.24 2009/03/15 00:35:42 dholland Exp $"); +__RCSID("$NetBSD: pl_5.c,v 1.25 2009/03/15 03:33:56 dholland Exp $"); #endif #endif /* not lint */ @@ -201,9 +201,6 @@ acceptboard(void) (struct ship *)0, 1); parties(ms, crew, 1, c); } - blockalarm(); - draw_slot(); - unblockalarm(); } static void @@ -237,16 +234,15 @@ parties(struct ship *to, int *crew, int isdefense, int buf) } if (isdefense) { for (k=0; k < NBP; k++) - display_show_dbp(k, + display_set_dbp(k, temp[k] && !crew[k]); makemsg(ms, "repelling boarders"); } else { for (k=0; k < NBP; k++) - display_show_obp(k, + display_set_obp(k, temp[k] && !crew[k]); makesignal(ms, "boarding the $$", to); } - display_refresh_slot_w(); } else Msg("Sending no crew sections."); } diff --git a/sail/pl_6.c b/sail/pl_6.c index 0d65fcb6..0a520066 100644 --- a/sail/pl_6.c +++ b/sail/pl_6.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl_6.c,v 1.13 2009/03/14 22:52:53 dholland Exp $ */ +/* $NetBSD: pl_6.c,v 1.14 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pl_6.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pl_6.c,v 1.13 2009/03/14 22:52:53 dholland Exp $"); +__RCSID("$NetBSD: pl_6.c,v 1.14 2009/03/15 03:33:56 dholland Exp $"); #endif #endif /* not lint */ @@ -125,14 +125,8 @@ repair(void) *repairs = 2; } else { *repairs = 0; - blockalarm(); - draw_stat(); - unblockalarm(); } } - blockalarm(); - draw_slot(); - unblockalarm(); repaired = 1; } diff --git a/sail/pl_7.c b/sail/pl_7.c index 23172567..2425104f 100644 --- a/sail/pl_7.c +++ b/sail/pl_7.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl_7.c,v 1.34 2009/03/15 00:50:47 dholland Exp $ */ +/* $NetBSD: pl_7.c,v 1.35 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,38 +34,54 @@ #if 0 static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pl_7.c,v 1.34 2009/03/15 00:50:47 dholland Exp $"); +__RCSID("$NetBSD: pl_7.c,v 1.35 2009/03/15 03:33:56 dholland Exp $"); #endif #endif /* not lint */ #include <curses.h> #include <err.h> +#include <errno.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "array.h" #include "extern.h" #include "player.h" #include "display.h" -static void Scroll(void); -static void endprompt(int); +/* + * 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 WINDOW *view_w; +static WINDOW *turn_w; +static WINDOW *stat_w; static WINDOW *slot_w; static WINDOW *scroll_w; -static WINDOW *stat_w; -static WINDOW *turn_w; + +static bool obp[3]; +static bool dbp[3]; int done_curses; int loaded, fired, changed, repaired; @@ -77,9 +93,28 @@ 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) { + int ch; + + sc_lines = stringarray_create(); + if (sc_lines == NULL) { + err(1, "malloc"); + } + if (signal(SIGTSTP, SIG_DFL) == SIG_ERR) { err(1, "signal(SIGTSTP)"); } @@ -113,6 +148,13 @@ initscreen(void) noecho(); cbreak(); + /* + * Define esc-x keys + */ + for (ch = 0; ch < 127; ch++) { + define_esc_key(ch); + } + done_curses++; } @@ -123,27 +165,110 @@ cleanupscreen(void) if (done_curses) { wmove(scroll_w, SCROLL_Y - 1, 0); wclrtoeol(scroll_w); - draw_screen(); + display_redraw(); endwin(); } } +//////////////////////////////////////////////////////////// +// scrolling message area + +static void +scrollarea_add(const char *text) +{ + char *copy; + int errsave; + + copy = strdup(text); + if (copy == NULL) { + goto nomem; + } + 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; + + werase(scroll_w); + + visible_lines = SCROLL_Y - 1; + + 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; + } + + for (y = 0; y < SCROLL_Y - 1; 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*/ void 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 (*fmt == '\a') { + beep(); + fmt++; + } fmtship(format, sizeof(format), fmt, ship); - vwprintw(scroll_w, format, ap); + vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); - Scroll(); + scrollarea_add(buf); } /*VARARGS2*/ @@ -151,24 +276,18 @@ void Msg(const char *fmt, ...) { va_list ap; + char buf[BUFSIZ]; if (!done_curses) return; va_start(ap, fmt); - if (*fmt == '\a') - putchar(*fmt++); - vwprintw(scroll_w, fmt, ap); + if (*fmt == '\a') { + beep(); + fmt++; + } + vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - Scroll(); -} - -static void -Scroll(void) -{ - if (++sc_line >= SCROLL_Y) - sc_line = 0; - wmove(scroll_w, sc_line, 0); - wclrtoeol(scroll_w); + scrollarea_add(buf); } void @@ -179,16 +298,15 @@ prompt(const char *p, struct ship *ship) fmtship(buf, sizeof(buf), p, ship); sc_prompt = buf; sc_buf = ""; - sc_hasprompt = 1; - waddstr(scroll_w, buf); + sc_hasprompt = true; } static void -endprompt(int flag) +endprompt(void) { - sc_hasprompt = 0; - if (flag) - Scroll(); + sc_prompt = NULL; + sc_buf = NULL; + sc_hasprompt = false; } /* @@ -199,17 +317,17 @@ endprompt(int flag) void display_hide_prompt(void) { - if (sc_hasprompt) { - wmove(scroll_w, sc_line, 0); - wclrtoeol(scroll_w); - } + sc_hideprompt = true; + draw_scroll(); + wrefresh(scroll_w); } void display_reshow_prompt(void) { - if (sc_hasprompt) - wprintw(scroll_w, "%s%s", sc_prompt, sc_buf); + sc_hideprompt = false; + draw_scroll(); + wrefresh(scroll_w); } @@ -217,15 +335,28 @@ int 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; } @@ -240,42 +371,58 @@ sgetstr(const char *pr, char *buf, int n) 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('\a'); + 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; @@ -299,7 +446,7 @@ draw_view(void) wrefresh(view_w); } -void +static void draw_turn(void) { wmove(turn_w, 0, 0); @@ -307,7 +454,7 @@ draw_turn(void) wrefresh(turn_w); } -void +static void draw_stat(void) { wmove(stat_w, STAT_1, 0); @@ -351,16 +498,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) @@ -417,15 +576,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('-'); @@ -442,12 +599,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)", @@ -460,29 +619,47 @@ draw_board(void) refresh(); } -/* Called after show_[od]bp. Shouldn't really exist... XXX */ void -display_refresh_slot_w(void) +display_set_obp(int which, bool show) { - blockalarm(); - wrefresh(slot_w); - unblockalarm(); + obp[which] = show; +} + +void +display_set_dbp(int which, bool show) +{ + dbp[which] = show; } +//////////////////////////////////////////////////////////// +// external actions on the display + void -display_show_obp(int which, bool show) +display_scroll_pageup(void) { - wmove(slot_w, 0, which); - waddch(slot_w, show ? '1' + which : ' '); - mvwaddstr(slot_w, 1, 0, "OBP"); + 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_show_dbp(int which, bool show) +display_scroll_pagedown(void) { - wmove(slot_w, 2, which); - waddch(slot_w, show ? '1' + which : ' '); - mvwaddstr(slot_w, 3, 0, "DBP"); + unsigned pagesize = SCROLL_Y - 2; + + if (sc_scrollup < pagesize) { + sc_scrollup = 0; + } else { + sc_scrollup -= pagesize; + } } void diff --git a/sail/pl_main.c b/sail/pl_main.c index 205a3cbe..619a99f1 100644 --- a/sail/pl_main.c +++ b/sail/pl_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: pl_main.c,v 1.25 2009/03/14 22:52:53 dholland Exp $ */ +/* $NetBSD: pl_main.c,v 1.26 2009/03/15 03:33:56 dholland Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pl_main.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pl_main.c,v 1.25 2009/03/14 22:52:53 dholland Exp $"); +__RCSID("$NetBSD: pl_main.c,v 1.26 2009/03/15 03:33:56 dholland Exp $"); #endif #endif /* not lint */ @@ -45,6 +45,7 @@ __RCSID("$NetBSD: pl_main.c,v 1.25 2009/03/14 22:52:53 dholland Exp $"); #include <stdlib.h> #include <string.h> #include <unistd.h> +#include "display.h" #include "extern.h" #include "player.h" #include "restart.h" @@ -249,7 +250,7 @@ reprint: printf("\n"); fflush(stdout); initscreen(); - draw_board(); + display_redraw(); snprintf(message, sizeof message, "Captain %s assuming command", captain); send_signal(ms, message); |