home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso
/
altsrc
/
articles
/
11240
< prev
next >
Wrap
Internet Message Format
|
1994-09-11
|
47KB
Path: wupost!kuhub.cc.ukans.edu!nrlvx1.nrl.navy.mil!ra!news.pop.psu.edu!news.cac.psu.edu!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!news.duke.edu!godot.cc.duq.edu!newsfeed.pitt.edu!uunet!news.sprintlink.net!demon!hunting2.demon.co.uk!zondo
Newsgroups: alt.sources
Subject: Wander: puzzle game (1 of 6)
Message-ID: <778924728snz@hunting2.demon.co.uk>
From: zondo@hunting2.demon.co.uk (Zondo Pillock)
Date: Wed, 7 Sep 1994 07:58:48 +0000
Reply-To: zondo@hunting2.demon.co.uk
Sender: usenet@demon.co.uk
Organization: Hunting Engineering Limited
X-Newsreader: Demon Internet Simple News v1.29
Lines: 2028
This is wander, version 1.0.
Wander is a game where you wander around the screen collecting
treasures, solving puzzles and avoiding the nasty monsters. It's
really a new version of an old game called 'wanderer', written by
Steven Shipway back in 1988. Ah, wanderer... excellent game, shame
about the source code. I loved the game so much I rewrote it to
(hopefully) make it more slick and expandable. See the file CHANGES
for the main differences between this version and the old one.
Wander uses curses and has been tested on a DECstation 5000 (ULTRIX)
and SGI Indigo (IRIX).
__o
zondo@hunting2.demon.co.uk _`\<,_
............................(_)/ (_)
Submitted-by: zondo@hunting2.demon.co.uk
Archive-name: wander/part01
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is wander, a shell archive (produced by GNU shar 4.0)
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1994-09-07 08:32 BST by <zondo@hunting2.demon.co.uk>.
# Source directory was `/ss/glen/files/cprogs/wander'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 5023 -r--r--r-- Makefile
# 8612 -r--r--r-- main.c
# 7220 -r--r--r-- pos.c
# 4266 -r--r--r-- mon.c
# 12690 -r--r--r-- draw.c
# 11194 -r--r--r-- move.c
# 5452 -r--r--r-- score.c
# 5346 -r--r--r-- save.c
# 1318 -r--r--r-- keys.c
# 1987 -r--r--r-- timer.c
# 1983 -r--r--r-- help.c
# 3094 -r--r--r-- will.c
# 2846 -r--r--r-- misc.c
# 2998 -r--r--r-- defs.h
# 4115 -r--r--r-- data.h
# 5552 -r--r--r-- effect.h
# 783 -r--r--r-- config.h
# 2569 -rw-r--r-- proto.h
# 367 -r--r--r-- version.h
# 5756 -rw-r--r-- README
# 758 -rw-r--r-- CHANGES
# 12488 -rw-r--r-- COPYING
# 8280 -r--r--r-- wander.doc
# 6699 -rw-rw-r-- wander.man
# 7968 -rw-rw-r-- wander.txt
# 1163 -r--r--r-- cmds.help
# 1526 -r--r--r-- full.help
# 691 -r--r--r-- mini.help
# 702 -rw-r--r-- screens/screen.1
# 700 -rw-r--r-- screens/screen.10
# 700 -rw-r--r-- screens/screen.11
# 700 -rw-r--r-- screens/screen.12
# 701 -rw-r--r-- screens/screen.2
# 701 -rw-r--r-- screens/screen.3
# 700 -rw-r--r-- screens/screen.4
# 700 -rw-r--r-- screens/screen.5
# 702 -rw-r--r-- screens/screen.6
# 700 -rw-r--r-- screens/screen.7
# 700 -rw-r--r-- screens/screen.8
# 702 -rw-r--r-- screens/screen.9
# 351 -rw-r--r-- sol/sol.4
# 500 -rw-r--r-- sol/sol.6
# 244 -rw-r--r-- sol/sol.7
# 785 -rw-r--r-- sol/sol.9
# 472 -rw-r--r-- sol/sol.1
# 575 -rw-r--r-- sol/sol.3
# 660 -rw-r--r-- sol/sol.5
# 450 -rw-r--r-- sol/sol.10
# 926 -rw-r--r-- sol/sol.11
# 617 -rw-r--r-- sol/sol.12
# 473 -rw-r--r-- sol/sol.2
# 258 -rw-r--r-- sol/sol.8
# 3341 -rw-r--r-- icons/backslide_bm
# 3329 -rw-r--r-- icons/brick_bm
# 3326 -rw-r--r-- icons/cage_bm
# 3335 -rw-r--r-- icons/diamond_bm
# 3326 -rw-r--r-- icons/dirt_bm
# 3338 -rw-r--r-- icons/fwdslide_bm
# 3296 -rw-r--r-- icons/landmine_bm
# 3332 -rw-r--r-- icons/larrow_bm
# 3335 -rw-r--r-- icons/monster_bm
# 3290 -rw-r--r-- icons/player_bm
# 3378 -rw-r--r-- icons/playerl_bm
# 3293 -rw-r--r-- icons/playerr_bm
# 3332 -rw-r--r-- icons/rarrow_bm
# 3326 -rw-r--r-- icons/rock_bm
# 3329 -rw-r--r-- icons/space_bm
# 3332 -rw-r--r-- icons/sprite_bm
# 3296 -rw-r--r-- icons/teleport_bm
# 3347 -rw-r--r-- icons/timecapsule_bm
# 3326 -rw-r--r-- icons/wall_bm
# 3338 -rw-r--r-- icons/wanderer_bm
# 3332 -rw-r--r-- icons/wayout_bm
# 3332 -rw-r--r-- icons/whoops_bm
# 304 -rw-r--r-- icons/backslide_tbm
# 292 -rw-r--r-- icons/brick_tbm
# 289 -rw-r--r-- icons/cage_tbm
# 298 -rw-r--r-- icons/diamond_tbm
# 289 -rw-r--r-- icons/dirt_tbm
# 301 -rw-r--r-- icons/fwdslide_tbm
# 299 -rw-r--r-- icons/landmine_tbm
# 295 -rw-r--r-- icons/larrow_tbm
# 298 -rw-r--r-- icons/monster_tbm
# 295 -rw-r--r-- icons/player_tbm
# 295 -rw-r--r-- icons/rarrow_tbm
# 289 -rw-r--r-- icons/rock_tbm
# 292 -rw-r--r-- icons/space_tbm
# 295 -rw-r--r-- icons/sprite_tbm
# 299 -rw-r--r-- icons/teleport_tbm
# 310 -rw-r--r-- icons/timecapsule_tbm
# 289 -rw-r--r-- icons/wall_tbm
# 295 -rw-r--r-- icons/wayout_tbm
# 295 -rw-r--r-- icons/whoops_tbm
# 147 -rw-rw-r-- icons/README
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo 'WARNING: not restoring timestamps'
fi
rm -f 1231235999 $$.touch
#
# ============= Makefile ==============
if test -f 'Makefile' && test X"$1" != X"-c"; then
echo 'x - skipping Makefile (File already exists)'
else
echo 'x - extracting Makefile (text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# Makefile for wander
X
# -------------------------- CUSTOMIZATION SECTION --------------------------
X
# Where to put the executable.
BINDIR = /work/bin
X
# Where to put the man page.
MANDIR = /work/man/man6
X
# Where you want the library files to live.
LIBDIR = /netdat/data/wander
X
# If you're on one of the predefined systems below, you're in luck.
# Just type the associated command to make the program. Otherwise
# you'll have to continue customizing.
#
# DEC Ultrix make dec
# Silicon Graphics SGI make sgi
X
# Your system type (currently either BSD42 or SYSVR3).
SYSTEM = BSD42
#SYSTEM = SYSVR3
X
# Type of curses library you're using (either BSD curses or X curses).
# BSD curses has no attribute modes (apart from standout), so it's
# preferable to use X curses if you have it.
CURSES = BSDCURSES
#CURSES = XCURSES
X
# Uncomment this if your version of curses has provision for extended
# character sets. BSD curses doesn't, nor do some versions of X curses
# (my Ultrix implementation doesn't, anyway).
#XCHARS = -DXCHARS
X
# Name of your curses library. Some systems (well, Ultrix anyway)
# have both BSD and X curses, so the names may be slightly different.
CURSESLIB = curses
#CURSESLIB = cursesX
X
# Extra compilation flags
FLAGS = -g
X
# ---------------------- END OF CUSTOMIZATION SECTION -----------------------
X
SRCS = main.c pos.c mon.c draw.c move.c score.c save.c \
X keys.c timer.c help.c will.c misc.c
X
OBJS = main.o pos.o mon.o draw.o move.o score.o save.o \
X keys.o timer.o help.o will.o misc.o
X
HDRS = defs.h data.h effect.h config.h proto.h version.h
X
DEFS = -D$(SYSTEM) -D$(CURSES) $(XCHARS) -DLIBDIR=\"$(LIBDIR)\"
X
DOCS = README CHANGES COPYING wander.doc wander.man wander.txt \
X cmds.help full.help mini.help
X
CFLAGS = $(FLAGS) $(DEFS)
X
LOADLIBES = -l$(CURSESLIB) -ltermcap
X
# ---------------------------- Main program ----------------------------
X
all: wander
X
wander: $(OBJS)
X cc -o wander $(OBJS) $(LDFLAGS) $(LOADLIBES)
X
# --------------------------- Specific systems -------------------------
X
dec:; @make SYSTEM=BSD42 \
X XCHARS= \
X CURSES=XCURSES \
X CURSESLIB=cursesX
X
sgi:; @make SYSTEM=SYSVR3 \
X XCHARS=-DXCHARS \
X CURSES=XCURSES \
X CURSESLIB=curses
X
# ---------------------------- Documentation ---------------------------
X
MKMAN = sed -e "s^%%LIBDIR%%^$(LIBDIR)^"
X
wander.man: wander.doc
X srctoman - wander.doc > wander.man
X
wander.txt: wander.man
X tbl wander.man | nroff -man > wander.txt
X
# ---------------------------- Installation ----------------------------
X
install-bsd: install-prog install-man install-data install-help
X
install-sysv: install-prog install-catman install-data install-help
X
install-prog: wander
X cp wander $(BINDIR)
X strip $(BINDIR)/wander
X chmod 711 $(BINDIR)/wander
X
install-man: wander.man
X $(MKMAN) wander.man > $(MANDIR)/wander.6
X
install-catman: wander.txt
X $(MKMAN) wander.txt > $(MANDIR)/wander
X rm -f $(MANDIR)/wander.z
X pack -f $(MANDIR)/wander
X
install-data:
X -mkdir $(LIBDIR)
X -mkdir $(LIBDIR)/screens
X cp screens/* $(LIBDIR)/screens
X chmod 644 $(LIBDIR)/screens/*
X touch $(LIBDIR)/scores
X chmod 666 $(LIBDIR)/scores
X
install-help:
X -mkdir $(LIBDIR)
X cp *.help $(LIBDIR)
X chmod 644 $(LIBDIR)/*.help
X
install-sol:
X -mkdir $(LIBDIR)
X -mkdir $(LIBDIR)/sol
X cp sol/* $(LIBDIR)/sol
X chmod 644 $(LIBDIR)/sol/*
X
# ---------------------- Miscellaneous other stuff -------------------
X
proto:; cproto $(DEFS) -F"int\tmain(a, b)" $(SRCS) > proto.h
X @make wander
X
tags: TAGS
X
TAGS: $(SRCS) $(HDRS)
X etags $(SRCS) $(HDRS)
X
depend: $(SRCS)
X mkdep $(CFLAGS) $(SRCS)
X
clean:; rm -f wander $(OBJS)
X
lint:; lint -habx $(DEFS) $(SRCS)
X
# ---------------------------- Distribution --------------------------
X
NETNAME = zondo@hunting2.demon.co.uk
X
SHARDIR = /work/pc
SHARNAME = wshar
SHAROPTS = -n wander -o $(SHARNAME) -l 50 -s $(NETNAME) -acT
SHAR = Makefile $(SRCS) $(HDRS) $(DOCS) screens sol icons
X
shar: SHAR $(SHAR)
X shar $(SHAROPTS) $(SHAR)
X for i in $(SHARNAME)*; do \
X cat SHAR $$i > $(SHARDIR)/$$i; \
X rm $$i; \
X done
X
# --------------------------- Dependencies ---------------------------
X
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
main.o: main.c defs.h data.h proto.h config.h version.h
pos.o: pos.c defs.h data.h proto.h config.h
mon.o: mon.c defs.h data.h proto.h config.h
draw.o: draw.c defs.h data.h effect.h proto.h config.h
move.o: move.c defs.h data.h proto.h config.h
score.o: score.c defs.h data.h proto.h config.h
save.o: save.c defs.h data.h proto.h config.h
keys.o: keys.c defs.h
timer.o: timer.c defs.h
help.o: help.c defs.h data.h proto.h config.h
will.o: will.c config.h
misc.o: misc.c defs.h data.h proto.h config.h
X
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
$shar_touch -am 0907082494 'Makefile' &&
chmod 0444 'Makefile' ||
echo 'restore of Makefile failed'
shar_count="`wc -c < 'Makefile'`"
test 5023 -eq "$shar_count" ||
echo "Makefile: original size 5023, current size $shar_count"
fi
# ============= main.c ==============
if test -f 'main.c' && test X"$1" != X"-c"; then
echo 'x - skipping main.c (File already exists)'
else
echo 'x - extracting main.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
/*
X * Wander version 1.0, Copyright (C) 1994 G. Hutchings
X * Wander comes with ABSOLUTELY NO WARRANTY.
X * This is free software, and you are welcome to redistribute it
X * under certain conditions; see the file COPYING for details.
X */
X
/* Main routine */
X
#ifndef lint
static char rcsid[] = "$Id: main.c,v 1.37 1994/06/29 14:27:40 glen Exp $";
#endif
X
#define MAIN
X
#include <stdio.h>
#include <stdarg.h>
#include "defs.h"
#include "data.h"
#include "proto.h"
#include "config.h"
#include "version.h"
X
char progname[BUFSIZ]; /* Duhh... guess what */
char myname[BUFSIZ]; /* Your player name */
X
int
main(int argc, char *argv[])
{
X int scoretable = 0; /* Display score table? */
X int levelscores = 0; /* Display your level scores? */
X int levelset = 0; /* Have you specified your level? */
X int letmebewiz = 0; /* Do you want to be wizard? */
X
X char buf[BUFSIZ], *getenv(char *name), *opts;
X extern int opterr, optind;
X extern char *optarg;
X int c, canbewiz;
X
X /* Randomize */
X RANDINIT;
X
X /* Who am I? */
X strcpy(progname, argv[0]);
X
X /* Who are you? */
X strcpy(myname, playername());
X
X /* Check wizard status */
X myuid = userid();
X canbewiz = (myuid == WIZUID);
X
X /* Parse options */
X opts = getenv("WANDEROPTS");
X while (opts != NULL && *opts != '\0') {
X switch (*opts) {
X case 'b':
X if (*++opts != '\0')
X bordersize = *opts-'0';
X else
X fatal("`b' requires digit argument in WANDEROPTS");
X break;
X case 'h':
X hidescore = 1;
X break;
X case 'x':
X xchars = 1;
X break;
X }
X
X opts++;
X }
X
X /* Parse arguments */
X opterr = 0;
X while ((c = getopt(argc, argv, "b:l:svwxS")) != EOF) {
X switch (c) {
X case 'b':
X bordersize = atoi(optarg);
X break;
X case 'l':
X level = atoi(optarg);
X levelset = 1;
X break;
X case 's':
X levelscores = 1;
X break;
X case 'S':
X scoretable = 1;
X break;
X case 'v':
X printf(vformat, version);
X exit(0);
X case 'w':
X letmebewiz = 1;
X break;
X case 'x':
X xchars = !xchars;
X break;
X default:
X usage();
X break;
X }
X }
X
X /* Last argument (if any) is a level test file */
X if (optind != argc) leveltest(argv[optind]);
X
X /* Check for becoming wizard */
X if (letmebewiz) {
X if (!canbewiz) {
X printf("Magic wizzy password: ");
X gets(buf);
X canbewiz = !strcmp(buf, WIZWORD);
X }
X
X if (canbewiz) {
X wizard = 1;
X minidisplay = 1;
X } else {
X printf("Thou art not worthy, thou %s!\n", willie_phrase());
X endscreen();
X exit(0);
X }
X }
X
X /* Get no. of available levels */
X nlevels = numlevels();
X if (nlevels == 0) {
X if (!wizard)
X fatal("can't find screen files!");
X else
X fatal("no screen files below this directory");
X }
X
X /* Read current scores */
X readscores();
X
X /* Show scores and exit if required */
X if (scoretable) {
X showscores();
X exit(0);
X }
X
X if (levelscores) {
X showlevels(myuid);
X exit(0);
X }
X
X /* Set level if not yet specified */
X maxlevel = getlevel(myuid);
X if (!levelset)
X level = (maxlevel > nlevels ? nlevels : maxlevel);
X
X /* Check valid level */
X if (level <= 0) {
X printf("Invalid level, thou %s!\n", willie_phrase());
X exit(0);
X } else if (level > nlevels) {
X printf("There are only %d levels to play, thou %s!\n",
X nlevels, willie_phrase());
X exit(0);
X } else if (level > maxlevel && !wizard) {
X printf("You can't play level %d - you haven't done level %d yet!\n",
X level, maxlevel);
X exit(0);
X }
X
X donelevel = (level < maxlevel);
X
X /* Start up screen stuff */
X initscreen();
X
X /* Play levels */
X while (1) {
X /* Read new level from file */
X curpos = readpos(level);
X
X /* Play it */
X if (playscreen()) {
X /* Go to next level */
X level++;
X if (level > maxlevel) maxlevel = level;
X donelevel = (level < maxlevel);
X
X /* Has player done the lot? */
X if (level > nlevels) {
X doeffect(curpos->pline, curpos->pcol, WINNER);
X endscreen();
X return 0;
X }
X } else {
X /* Quitted */
X doeffect(curpos->pline, curpos->pcol, GAVEUP);
X endscreen();
X return 0;
X }
X }
X
X /* NOTREACHED */
}
X
/* Play the current screen */
int
playscreen()
{
X int cmd, nextlevel = 0, jump;
X char buf[BUFSIZ], *reply;
X
X /* Initialise */
X initpos();
X recentre();
X exited = 0;
X
X /* Appear on the screen */
X curpos->dead = 1; /* for first picture - no player */
X drawpos(curpos);
X doeffect(curpos->pline, curpos->pcol, APPEAR);
X drawpos(curpos);
X curpos->dead = 0;
X
X while (!nextlevel) {
X /* Scroll screen if required */
X scroll();
X
X /* Draw current position */
X drawpos(curpos);
X
X /* Get keypress */
X cmd = keypress();
X
X /* Do the command */
X switch (cmd) {
X case QUIT:
X if (query("Really quit? ", 0)) return 0;
X break;
X case STAYPUT:
X case GONORTH:
X case GOEAST:
X case GOSOUTH:
X case GOWEST:
X movecmd(cmd);
X break;
X case BACKWARD:
X if (!exited && (wizard || donelevel)) backpos();
X break;
X case FORWARD:
X if (!exited && (wizard || donelevel)) forwardpos();
X break;
X case RESTART:
X if (curpos->dead || query("Restart this screen? ", 0)) {
X curpos = firstpos;
X exited = 0;
X recentre();
X }
X break;
X case FIRSTPOS:
X if (!exited && (wizard || donelevel)) {
X curpos = firstpos;
X recentre();
X }
X break;
X case LASTPOS:
X if (!exited && (wizard || donelevel)) {
X curpos = lastpos;
X recentre();
X }
X break;
X case JUMPLEVEL:
X if (wizard && !testlevel) {
X sprintf(buf, "Level to jump to (1-%d): ", nlevels);
X if ((reply = getstring(buf)) == NULL) break;
X jump = atoi(reply);
X if (jump == 0) break;
X if (jump >= 1 && jump <= nlevels) {
X level = jump;
X curpos = readpos(level);
X initpos();
X recentre();
X exited = 0;
X } else {
X message("Thou %s!", willie_phrase());
X beep();
X }
X }
X break;
X case SAVE:
X if (exited || donelevel || wizard) {
X save();
X } else {
X message("You haven't finished the level yet!");
X beep();
X }
X break;
X case RESTORE:
X if (donelevel || wizard) {
X restore();
X } else {
X message("Can't restore to this level");
X beep();
X }
X break;
X case NEXTLEVEL:
X if (exited) {
X nextlevel = 1;
X } else {
X message("You haven't finished the level yet!");
X beep();
X }
X break;
X case TOGGLEWIN:
X if (wizard) {
X minidisplay = !minidisplay;
X } else {
X minidisplay = 1;
X message("Type %c for help, any other to return", DISPHELP);
X drawpos(curpos);
X
X while ((cmd = keypress()) == DISPHELP) {
X displayinfo();
X drawpos(curpos);
X }
X
X minidisplay = 0;
X }
X
X recentre();
X break;
X case SOLUTION:
X if (!testlevel) showsolution();
X break;
X case RECENTRE:
X recentre();
X break;
X case REDRAW:
X redraw();
X break;
X case CMDHELP:
X cmdinfo();
X break;
X case DISPHELP:
X displayinfo();
X break;
X default:
X message("Type ? for help");
X beep();
X break;
X }
X }
X
X return 1;
}
X
/* Process a move command */
void
movecmd(int cmd)
{
X int dir;
X
X if (exited) {
X message("You've finished this level - type %c to go to the next one",
X NEXTLEVEL);
X return;
X }
X
X if (curpos->dead) {
X message("You're dead - type %c to restart the level", RESTART);
X return;
X }
X
X switch (cmd) {
X case STAYPUT:
X dir = NONE;
X break;
X case GONORTH:
X dir = NORTH;
X break;
X case GOSOUTH:
X dir = SOUTH;
X break;
X case GOEAST:
X dir = EAST;
X break;
X case GOWEST:
X dir = WEST;
X break;
X }
X
X if (canmove(dir)) domove(dir);
}
X
/* Test out a level file */
void
leveltest(char *path)
{
X /* Let them be wizard */
X wizard = 1;
X testlevel = 1;
X minidisplay = 1;
X
X /* Start up screen stuff */
X initscreen();
X
X /* Read new level from file */
X curpos = readposfile(path);
X
X /* Play the level */
X playscreen();
X
X /* Finish up */
X endscreen();
X exit(0);
}
X
/* Give a fatal error */
void
fatal(char *fmt, ...)
{
X va_list args;
X
X endscreen();
X fprintf(stderr, "%s: Fatal: ", progname);
X va_start(args, fmt);
X vfprintf(stderr, fmt, args);
X fprintf(stderr, "\n");
X va_end(args);
X exit(1);
}
X
/* Print usage message */
void
usage()
{
X printf("Usage: %s [options]\n\n", progname);
X printf("-l level\tstart at specified level\n");
X printf("-b size\t\tset scroll border size\n");
X printf("-x\t\tuse extended display characters\n");
X printf("-w\t\tenter wizard mode\n");
X printf("-v\t\tprint program version\n");
X printf("-s\t\tshow your scores per level\n");
X printf("-S\t\tshow total scores\n");
X exit(0);
}
SHAR_EOF
$shar_touch -am 0629152894 'main.c' &&
chmod 0444 'main.c' ||
echo 'restore of main.c failed'
shar_count="`wc -c < 'main.c'`"
test 8612 -eq "$shar_count" ||
echo "main.c: original size 8612, current size $shar_count"
fi
# ============= pos.c ==============
if test -f 'pos.c' && test X"$1" != X"-c"; then
echo 'x - skipping pos.c (File already exists)'
else
echo 'x - extracting pos.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'pos.c' &&
/*
X * Wander version 1.0, Copyright (C) 1994 G. Hutchings
X * Wander comes with ABSOLUTELY NO WARRANTY.
X * This is free software, and you are welcome to redistribute it
X * under certain conditions; see the file COPYING for details.
X */
X
/* Position stack functions */
X
#ifndef lint
static char rcsid[] = "$Id: pos.c,v 1.11 1994/06/16 15:38:58 glen Exp $";
#endif
X
#include <stdio.h>
#include "defs.h"
#include "data.h"
#include "proto.h"
#include "config.h"
X
/* Read and return a new screen position */
struct pos *
readpos(int num)
{
X return readposfile(levelpath(num));
}
X
/* Read and return a new screen position from a file */
struct pos *
readposfile(char *path)
{
X int nbaby = 0, ncage = 0, ndiamonds = 0, nexit = 0;
X int teleport = 0, tfound = 0, nmonsters = 0;
X int pline, pcol, pfound = 0, nmoves;
X int **screen, nlin = 0, ncol = 0;
X int ll[MAXHEIGHT], i, j, len;
X char buf[BUFSIZ];
X struct pos *p;
X FILE *fp;
X
X /* Open file and read header */
X if ((fp = fopen(path, "r")) == NULL)
X fatal("Can't open %s", path);
X
X if (fgets(buf, BUFSIZ, fp) == NULL)
X fatal("Error reading %s", path);
X if (sscanf(buf, "%d", &nmoves) != 1)
X fatal("Can't find move limit in %s", path);
X
X /* Read screen data */
X screen = ALLOC(int *, MAXHEIGHT);
X while (fgets(buf, BUFSIZ, fp) != NULL) {
X len = strlen(buf)-1;
X buf[len] = NULL; /* strip trailing newline */
X ll[nlin] = len;
X screen[nlin] = ALLOC(int, len);
X for (i = 0; i < len; i++) screen[nlin][i] = lookup(buf[i]);
X if (ncol < len) ncol = len;
X nlin++;
X }
X
X fclose(fp);
X if (ncol < MINWIDTH || nlin < MINHEIGHT)
X fatal("%dx%d screen in %s is too small", ncol, nlin, path);
X if (ncol > MAXWIDTH || nlin > MAXHEIGHT)
X fatal("%dx%d screen in %s is too big", ncol, nlin, path);
X
X /* Pad out rows to max row length */
X for (i = 0; i < nlin; i++) {
X if (ll[i] < ncol) {
X screen[i] = REALLOC(screen[i], int, ncol);
X for (j = ll[i]; j < ncol; j++)
X screen[i][j] = BLANK;
X }
X }
X
X /* Check for screen consistency */
X for (i = 0; i < nlin; i++) {
X for (j = 0; j < ncol; j++) {
X switch (obj[screen[i][j]].type) {
X case FILLER:
X screen[i][j] = BLANK;
X break;
X case PLAYER:
X if (pfound)
X fatal("More than one start position in %s", path);
X pfound = 1;
X pline = i;
X pcol = j;
X break;
X case TELEPORT:
X if (teleport)
X fatal("More than one teleport in %s", path);
X teleport = 1;
X break;
X case ARRIVE:
X screen[i][j] = BLANK;
X if (tfound)
X fatal("More than one teleport point in %s", path);
X tfound = 1;
X tline = i;
X tcol = j;
X break;
X case MONSTER:
X nmonsters++;
X break;
X case BABY:
X fatal("Baby with no start direction in %s", path);
X break;
X case BABYNORTH:
X case BABYEAST:
X case BABYSOUTH:
X case BABYWEST:
X nmonsters++;
X nbaby++;
X break;
X case CAGE:
X ncage++;
X break;
X case TREASURE:
X ndiamonds++;
X break;
X case EXIT:
X nexit++;
X break;
X }
X }
X }
X
X if (!pfound)
X fatal("No start position in %s", path);
X if (teleport && !tfound)
X fatal("No teleport point in %s", path);
X if (nexit > 1)
X fatal("More than one exit in %s", path);
X if (nexit == 0)
X fatal("No exit in %s", path);
X
X /* Construct new position */
X p = newpos(screen, pline, pcol);
X p->nmoves = nmoves;
X p->diamonds = ndiamonds;
X p->monsters = nmonsters;
X p->diamonds += (nbaby < ncage ? nbaby : ncage);
X
X /* Add monsters */
X for (i = 0; i < nlin; i++) {
X for (j = 0; j < ncol; j++) {
X switch (screen[i][j]) {
X case BABYNORTH:
X addmonster(p, BABY, i, j, NORTH, BLANK, 0);
X screen[i][j] = BABY;
X break;
X case BABYEAST:
X addmonster(p, BABY, i, j, EAST, BLANK, 0);
X screen[i][j] = BABY;
X break;
X case BABYSOUTH:
X addmonster(p, BABY, i, j, SOUTH, BLANK, 0);
X screen[i][j] = BABY;
X break;
X case BABYWEST:
X addmonster(p, BABY, i, j, WEST, BLANK, 0);
X screen[i][j] = BABY;
X break;
X case MONSTER:
X addmonster(p, MONSTER, i, j, NONE, BLANK, 0);
X break;
X }
X }
X }
X
X nlines = nlin;
X ncols = ncol;
X
X return p;
}
X
/* Create and return a new position */
struct pos *
newpos(int **data, int pline, int pcol)
{
X struct pos *new = ALLOC(struct pos, 1);
X
X if (new == NULL) fatal("Out of memory");
X new->data = data;
X new->pline = pline;
X new->pcol = pcol;
X new->ml = NULL;
X new->score = 0;
X new->nmoves = 0;
X new->diamonds = 0;
X new->monsters = 0;
X new->dead = 0;
X new->dir = NONE;
X new->prev = NULL;
X new->next = NULL;
X
X return new;
}
X
/* Copy and return a position */
struct pos *
copypos(struct pos *p)
{
X struct pos *new = newpos(NULL, p->pline, p->pcol);
X struct monster *m;
X int **data = ALLOC(int *, nlines);
X int i, j;
X
X /* Copy screen */
X for (i = 0; i < nlines; i++) {
X data[i] = ALLOC(int, ncols);
X for (j = 0; j < ncols; j++)
X data[i][j] = p->data[i][j];
X }
X new->data = data;
X
X /* Copy attributes */
X new->score = p->score;
X new->nmoves = p->nmoves;
X new->dead = p->dead;
X new->diamonds = p->diamonds;
X new->monsters = p->monsters;
X new->dir = p->dir;
X
X /* Copy monsters */
X for (m = p->ml; m != NULL; m = m->next) {
X addmonster(new, m->type, m->line, m->col, m->heading,
X m->under, m->dead);
X }
X
X return new;
}
X
/* Initialize positions */
void
initpos()
{
X struct pos *p, *pnext;
X
X for (p = firstpos; p != NULL; p = pnext) {
X pnext = p->next;
X destpos(p);
X }
X
X firstpos = lastpos = curpos;
}
X
/* Destroy a position */
void
destpos(struct pos *p)
{
X int i;
X struct monster *ml = p->ml, *mnext;
X
X /* Kill monster list */
X while (ml != NULL) {
X mnext = ml->next;
X DEALLOC(ml);
X ml = mnext;
X }
X
X /* Kill screen data */
X for (i = 0; i < nlines; i++) DEALLOC(p->data[i]);
X DEALLOC(p->data);
X
X /* Finally, kill position */
X DEALLOC(p);
}
X
/* Add a position to the position stack */
void
addpos(struct pos *p)
{
X lastpos->next = p;
X p->prev = lastpos;
X lastpos = p;
}
X
/* Remove all 'future' positions from the stack */
void
removepos()
{
X struct pos *p;
X
X while (lastpos != curpos) {
X p = lastpos->prev;
X destpos(lastpos);
X lastpos = p;
X }
}
X
/* Back up one position */
void
backpos()
{
X if (curpos != firstpos) {
X curpos = curpos->prev;
X } else {
X beep();
X }
}
X
/* Move forward one position */
void
forwardpos()
{
X if (curpos != lastpos) {
X curpos = curpos->next;
X } else {
X beep();
X }
}
X
/* Look up symbol type */
int
lookup(char sym)
{
X int i;
X
X for (i = 0; i < numobj; i++) {
X if (obj[i].sym == sym) return i;
X }
X
X fatal("Unrecognized symbol: %c", sym);
X return 0; /* to shut lint up */
}
X
/* Return whether a position is on screen */
int
onscreen(int line, int col)
{
X if (line < 0 || line >= nlines) return 0;
X if (col < 0 || col >= ncols) return 0;
X
X return 1;
}
X
/* Return a location value */
struct loc
curloc(struct pos *p, int line, int col)
{
X struct loc l;
X
X l.line = line;
X l.col = col;
X l.type = (onscreen(line, col) ? p->data[line][col] : ROCK1);
X
X return l;
}
X
/* Return new location after a move */
struct loc
moveto(int line, int col, int dir)
{
X return curloc(curpos, line+dirs[dir].line, col+dirs[dir].col);
}
SHAR_EOF
$shar_touch -am 0616164094 'pos.c' &&
chmod 0444 'pos.c' ||
echo 'restore of pos.c failed'
shar_count="`wc -c < 'pos.c'`"
test 7220 -eq "$shar_count" ||
echo "pos.c: original size 7220, current size $shar_count"
fi
# ============= mon.c ==============
if test -f 'mon.c' && test X"$1" != X"-c"; then
echo 'x - skipping mon.c (File already exists)'
else
echo 'x - extracting mon.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'mon.c' &&
/*
X * Wander version 1.0, Copyright (C) 1994 G. Hutchings
X * Wander comes with ABSOLUTELY NO WARRANTY.
X * This is free software, and you are welcome to redistribute it
X * under certain conditions; see the file COPYING for details.
X */
X
/* Monster movement stuff */
X
#ifndef lint
static char rcsid[] = "$Id: mon.c,v 1.10 1994/06/16 14:16:44 glen Exp $";
#endif
X
#include <stdio.h>
#include "defs.h"
#include "data.h"
#include "proto.h"
#include "config.h"
X
/* Add a monster to a position */
void
addmonster(struct pos *p, int type, int line, int col,
X int heading, int under, int dead)
{
X struct monster *new = newmonster(line, col, heading);
X
X new->type = type;
X new->under = under;
X new->dead = dead;
X new->next = p->ml;
X p->ml = new;
}
X
/* Return a newly allocated monster */
struct monster *
newmonster(int line, int col, int heading)
{
X struct monster *new = ALLOC(struct monster, 1);
X
X if (new == NULL)
X fatal("Out of memory");
X
X new->line = line;
X new->col = col;
X new->heading = heading;
X new->under = BLANK;
X new->dead = 0;
X new->next = NULL;
X
X return new;
}
X
/* Move the monsters */
void
movemonsters()
{
X struct monster *m, *found;
X struct loc l;
X int line, col, type, lnew, cnew, i, dist, d, dir;
X
X /* Don't bother if you're dead */
X if (curpos->dead) return;
X
X for (m = curpos->ml; m != NULL; m = m->next) {
X /* Skip if dead */
X if (m->dead) continue;
X
X line = m->line;
X col = m->col;
X type = curpos->data[line][col];
X lnew = line;
X cnew = col;
X
X switch (type) {
X case MONSTER:
X /* Heads straight for you */
X dist = range(line, col, curpos->pline, curpos->pcol);
X
X for (dir = 0; dir < numdir; dir++) {
X l = moveto(line, col, dir);
X if (l.type == BLANK ||
X l.type == PLAYER) {
X d = range(l.line, l.col, curpos->pline, curpos->pcol);
X if (d > dist) continue;
X lnew = l.line;
X cnew = l.col;
X dist = d;
X }
X }
X
X break;
X case BABY:
X /* Follows left-hand rule */
X m->heading = (m->heading+numdir-1) % numdir;
X
X /* Try to turn */
X for (i = 0; i < numdir; i++) {
X l = moveto(line, col, m->heading);
X if (l.type == BLANK ||
X l.type == EARTH || /* pass straight through earth */
X l.type == CAGE || /* can enter cages */
X l.type == BABY || /* ignore each other */
X l.type == PLAYER) { /* yum! */
X lnew = l.line;
X cnew = l.col;
X break;
X }
X
X m->heading = (m->heading+1) % numdir;
X }
X
X break;
X default:
X fatal("Monster movement error");
X }
X
X /* Remove monster from screen temporarily */
X m->line = m->col = -1;
X
X /* Replace contents of old position */
X if ((found = findmonster(line, col)) != NULL)
X curpos->data[line][col] = found->type;
X else
X curpos->data[line][col] = m->under;
X
X /* Update what monster is now on top of */
X if ((found = findmonster(lnew, cnew)) != NULL)
X m->under = found->under;
X else
X m->under = curpos->data[lnew][cnew];
X
X /* Move monster to new position */
X curpos->data[lnew][cnew] = type;
X m->line = lnew;
X m->col = cnew;
X
X /* Check for moving objects */
X vacate(line, col);
X moveinto(lnew, cnew);
X
X /* Check for monster munch */
X if (lnew == curpos->pline && cnew == curpos->pcol) {
X doeffect(lnew, cnew, EATEN);
X die("You've been eaten by a hungry monster!");
X }
X
X /* Check for caged baby monster */
X if (type == BABY && m->under == CAGE) {
X m->under = TREASURE;
X doeffect(lnew, cnew, CAUGHT);
X killmonster(lnew, cnew);
X }
X }
}
X
/* Kill a monster */
void
killmonster(int line, int col)
{
X struct monster *m;
X int type = curpos->data[line][col];
X
X for (m = curpos->ml; m != NULL; m = m->next) {
X if (m->line == line && m->col == col) {
X curpos->data[line][col] = m->under;
X curpos->score += obj[type].score;
X curpos->monsters--;
X m->dead = 1;
X }
X }
}
X
/* Return first monster found at specified location */
struct monster *
findmonster(int line, int col)
{
X struct monster *m;
X
X for (m = curpos->ml; m != NULL; m = m->next) {
X if (m->line == line && m->col == col && !m->dead) return m;
X }
X
X return NULL;
}
X
/* Return the range twixt two squares */
int
range(int l1, int c1, int l2, int c2)
{
X int ldif = l1-l2;
X int cdif = c1-c2;
X
X return ldif*ldif+cdif*cdif;
}
SHAR_EOF
$shar_touch -am 0616151894 'mon.c' &&
chmod 0444 'mon.c' ||
echo 'restore of mon.c failed'
shar_count="`wc -c < 'mon.c'`"
test 4266 -eq "$shar_count" ||
echo "mon.c: original size 4266, current size $shar_count"
fi
# ============= draw.c ==============
if test -f 'draw.c' && test X"$1" != X"-c"; then
echo 'x - skipping draw.c (File already exists)'
else
echo 'x - extracting draw.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'draw.c' &&
/*
X * Wander version 1.0, Copyright (C) 1994 G. Hutchings
X * Wander comes with ABSOLUTELY NO WARRANTY.
X * This is free software, and you are welcome to redistribute it
X * under certain conditions; see the file COPYING for details.
X */
X
/* Screen drawing functions */
X
#ifndef lint
static char rcsid[] = "$Id: draw.c,v 1.32 1994/06/23 14:56:12 glen Exp $";
#endif
X
#if defined(BSDCURSES) || defined(SYSVR3)
#include <curses.h>
#else
#include <cursesX.h>
#endif
X
#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#include "defs.h"
#include "data.h"
#include "effect.h"
#include "proto.h"
#include "config.h"
X
/* Screen display strings */
#define TITLE " W A N D E R "
#define WIZSTRING "Wizard"
#define DONESTRING "Old level"
#define TESTSTRING "Testing level"
#define ALERTSTRING "Monster alert!"
X
/* File for panic saves */
#define PANICFILE "WANDERBUG"
X
/* Border characters */
#define VLINE '|'
#define HLINE '-'
#define ULCORNER '+'
#define URCORNER '+'
#define LLCORNER '+'
#define LRCORNER '+'
X
/* Special mini-display characters */
#define BLOCK '#'
#define ALEFT '<'
#define ARIGHT '>'
#define DIAMOND '*'
X
/* Extended characters (if available) */
#ifndef XCHARS
#define X_VLINE VLINE
#define X_HLINE HLINE
#define X_ULCORNER ULCORNER
#define X_URCORNER URCORNER
#define X_LLCORNER LLCORNER
#define X_LRCORNER LRCORNER
#define X_BLOCK BLOCK
#define X_ALEFT ALEFT
#define X_ARIGHT ARIGHT
#define X_DIAMOND DIAMOND
#else
#define X_VLINE ACS_VLINE
#define X_HLINE ACS_HLINE
#define X_ULCORNER ACS_ULCORNER
#define X_URCORNER ACS_URCORNER
#define X_LLCORNER ACS_LLCORNER
#define X_LRCORNER ACS_LRCORNER
#define X_BLOCK ACS_CKBOARD
#define X_ALEFT ACS_LARROW
#define X_ARIGHT ACS_RARROW
#define X_DIAMOND ACS_DIAMOND
#endif
X
char msgtext[BUFSIZ]; /* Message text */
int showmessage = 0; /* Whether to display it */
X
/* Set up screen */
void
initscreen()
{
X if (!screeninit) {
#ifdef BSDCURSES
X if (initscr() == ERR)
X fatal("Can't initialize terminal");
#else
X if (initscr() == NULL)
X fatal("Can't initialize terminal");
X fixterm();
X intrflush(stdscr, FALSE);
#endif
X signal(SIGINT, quit);
#ifdef BSD42
X signal(SIGSEGV, panic);
X signal(SIGBUS, panic);
X signal(SIGILL, panic);
X signal(SIGFPE, panic);
#endif
X nonl();
X noecho();
X cbreak();
X
X screeninit = 1;
X }
}
X
/* Finish with screen */
void
endscreen()
{
X if (screeninit) {
X mvcur(0, COLS-1, LINES-1, 0);
#ifdef BSDCURSES
X nocbreak();
X echo();
X nl();
#else
X resetterm();
#endif
X endwin();
X screeninit = 0;
X }
}
X
/* Draw a position */
void
drawpos(struct pos *p)
{
X int startline, startcol, line, col, i, j, sym;
X struct monster *m;
X struct loc l;
X char buf[BUFSIZ], str[BUFSIZ];
X
X /* Do nothing if not updating picture */
X if (!redrawscreen) return;
X
X /* Wipe old picture */
X erase();
X
X /* Draw title */
X move(0, (COLS+1-strlen(TITLE))/2);
X setbold(1);
X standout();
X addstr(TITLE);
X standend();
X setbold(0);
X
X if (wizard && !testlevel) {
X move(0, (COLS-strlen(WIZSTRING)));
X standout();
X addstr(WIZSTRING);
X standend();
X } else if (wizard && testlevel) {
X move(0, (COLS-strlen(TESTSTRING)));
X standout();
X addstr(TESTSTRING);
X standend();
X } else if (donelevel) {
X move(0, (COLS-strlen(DONESTRING)));
X standout();
X addstr(DONESTRING);
X standend();
X }
X
X /* Draw stats */
X if (!testlevel)
X sprintf(buf, "Level: %d", level);
X else
X strcpy(buf, "");
X
X sprintf(str, " Score: %d Diamonds: %d",
X curpos->score, curpos->diamonds);
X strcat(buf, str);
X
X if (curpos->nmoves >= 0) {
X sprintf(str, " Moves left: %d", curpos->nmoves);
X strcat(buf, str);
X }
X
X move(2, (COLS+1-strlen(buf))/2);
X addstr(buf);
X
X /* Draw monster alert if required */
X if (curpos->monsters > 0) {
X move(0, 0);
X standout();
X addstr(ALERTSTRING);
X standend();
X }
X
X /* Display message if required */
X if (showmessage) {
X move(LINES-1, 0);
X clrtoeol();
X move(LINES-1, (COLS+1-strlen(msgtext))/2);
X addstr(msgtext);
X showmessage = 0;
X }
X
X /* Draw the screen piccie */
X if (minidisplay) {
X startline = (LINES-nlines)/2;
X if (startline < 4) startline = 4;
X startcol = (COLS-ncols)/2;
X screenborder(startline, startcol, nlines, ncols);
X
X for (i = 0; i < nlines; i++) {
X line = i+startline;
X for (j = 0; j < ncols; j++) {
X col = j+startcol;
X
X l = curloc(p, i, j);
X switch (l.type) {
X case PLAYER:
X /* Don't draw player if they're dead or */
X /* they've left the level */
X if (exited || p->dead) l.type = BLANK;
X break;
X case MONSTER:
X case BABY:
X /* Can only see monsters here if wizard */
X if (!wizard) {
X m = findmonster(i, j);
X if (m == NULL)
X fatal("monster movement error");
X else
X l.type = m->under;
X }
X break;
X }
X
X /* Check for extended character if required */
X sym = obj[l.type].sym;
X if (xchars) sym = extendchar(sym);
X
X if (obj[l.type].bold) setbold(1);
X mvaddch(line, col, sym);
X if (obj[l.type].bold) setbold(0);
X }
X }
X
X if (p->dead || exited)
X move(LINES-1, 0);
X else
X move(p->pline+startline, p->pcol+startcol);
X } else {
X startline = (LINES-(WINLINES*2))/2;
X if (startline < 4) startline = 4;
X startcol = (COLS-(WINCOLS*3))/2;
X screenborder(startline, startcol, WINLINES*2, WINCOLS*3);
X
X for (i = wline; i < wline+WINLINES; i++) {
X line = 2*(i-wline)+startline;
X for (j = wcol; j < wcol+WINCOLS; j++) {
X col = 3*(j-wcol)+startcol;
X l = curloc(p, i, j);
X
X /* Don't draw player if they're dead or they've */
X /* left the level */
X if (l.type == PLAYER)
X if (exited || p->dead) l.type = BLANK;
X
X if (obj[l.type].bold) setbold(1);
X mvaddstr(line , col, obj[l.type].bigsym[0]);
X mvaddstr(line+1, col, obj[l.type].bigsym[1]);
X if (obj[l.type].bold) setbold(0);
X }
X }
X
X move(LINES-1, 0);
X }
X
X refresh();
}
X
/* Draw a border around screen */
void
screenborder(int slin, int scol, int nlin, int ncol)
{
X int i;
X
X /* Left/right */
X for (i = slin-1; i <= slin+nlin; i++) {
X mvaddch(i, scol-1 , (xchars ? X_VLINE : VLINE));
X mvaddch(i, scol+ncol, (xchars ? X_VLINE : VLINE));
X }
X
X /* Top/bottom */
X for (i = scol-1; i <= scol+ncol; i++) {
X mvaddch(slin-1 , i, (xchars ? X_HLINE : HLINE));
X mvaddch(slin+nlin, i, (xchars ? X_HLINE : HLINE));
X }
X
X /* Corners */
X mvaddch(slin-1 , scol-1, (xchars ? X_ULCORNER : ULCORNER));
X mvaddch(slin-1 , scol+ncol, (xchars ? X_URCORNER : URCORNER));
X mvaddch(slin+nlin, scol-1 , (xchars ? X_LLCORNER : LLCORNER));
X mvaddch(slin+nlin, scol+ncol, (xchars ? X_LRCORNER : LRCORNER));
}
X
/* Do a special effect sequence */
void
doeffect(int i, int j, int num)
{
X int startline, startcol, line, col, len;
X int nlin = 0, ncol = 0, effnum, k;
X char ***seq, c;
X WINDOW *w;
X
X /* No effects in minidisplay mode */
X if (minidisplay) return;
X
X /* Look up effect */
X for (effnum = 0; effnum < numeff; effnum++) {
X if (effs[effnum].type == num) break;
X }
X if (effnum == numeff) return;
X
X /* Find where to draw it */
X if (minidisplay) {
X startline = (LINES-nlines)/2;
X if (startline < 4) startline = 4;
X startcol = (COLS-ncols)/2;
X line = startline+i;
X col = startcol+j;
X } else {
X if (i < wline || i >= wline+WINLINES) return;
X if (j < wcol || j >= wcol+WINCOLS) return;
X startline = (LINES-(WINLINES*2))/2;
X if (startline < 4) startline = 4;
X startcol = (COLS-(WINCOLS*3))/2;
X line = 2*(i-wline)+startline;
X col = 3*(j-wcol)+startcol+1;
X }
X
X /* Find dimensions of sequence */
X seq = effs[effnum].seq;
X for (i = 0; seq[i] != NULL; i++) {
X for (j = 0; seq[i][j] != NULL; j++)
X if ((len = strlen(seq[i][j])) > ncol) ncol = len;
X if (j > nlin) nlin = j;
X }
X
X /* Set up window to display it */
X line -= nlin/2-1;
X col -= ncol/2;
X w = newwin(nlin+1, ncol+1, line, col);
X
X /* Make sure screen is up to date */
X drawpos(curpos);
X
X /* Pause before first frame if required */
X if (effs[effnum].startdelay > 0) {
X move(0, 0);
X refresh();
X freeze(effs[effnum].startdelay);
X }
X
X /* Draw frames */
X for (k = 0; seq[k] != NULL; k++) {
X for (i = 0; i <= nlin; i++) {
X for (j = 0; j <= ncol; j++) {
X move(line+i, col+j);
X mvwaddch(w, i, j, inch());
X }
X }
X
X for (i = 0; seq[k][i] != NULL; i++) {
X for (j = 0; (c = seq[k][i][j]) != '\0'; j++) {
X switch (c) {
X case ' ':
X break;
X case '?':
X c = ' ';
X /* FALLTHROUGH */
X default:
X mvwaddch(w, i, j, c);
X }
X }
X }
X
X wrefresh(w);
X
X /* Pause between frames if required */
X if (effs[effnum].delay > 0) {
X move(0, 0);
X refresh();
X freeze(effs[effnum].delay);
X }
X }
X
X /* Pause on last frame if required */
X if (effs[effnum].enddelay > 0) {
X move(0, 0);
X refresh();
X freeze(effs[effnum].enddelay);
X }
X
X /* Delete effects window */
X delwin(w);
}
X
/* Return an extended character */
int
extendchar(int c)
{
X if (xchars) {
X switch (c) {
X case BLOCK:
X return X_BLOCK;
X case ALEFT:
X return X_ALEFT;
X case ARIGHT:
X return X_ARIGHT;
X case DIAMOND:
X return X_DIAMOND;
X }
X }
X
X return c;
}
X
/* Recentre you on the screen */
void
recentre()
{
X wline = curpos->pline-(WINLINES/2);
X wcol = curpos->pcol-(WINCOLS/2);
X
X wallscroll();
}
X
/* Scroll window if required */
void
scroll()
{
X int lines = WINLINES-(2*bordersize);
X int cols = WINCOLS-(2*bordersize);
X
X if (lines > 0 && cols > 0 && bordersize > 0) {
X while (curpos->pline-wline < bordersize) wline -= lines;
X while (curpos->pline-wline > WINLINES-1-bordersize) wline += lines;
X while (curpos->pcol-wcol < bordersize) wcol -= cols;
X while (curpos->pcol-wcol > WINCOLS-1-bordersize) wcol += cols;
X
X wallscroll();
X } else {
X recentre();
X }
}
X
/* Scroll so that outer walls only show at most one thickness */
void
wallscroll()
{
X while (wline < -1) wline++;
X while (wline+WINLINES > nlines+1) wline--;
X while (wcol < -1) wcol++;
X while (wcol+WINCOLS > ncols+1) wcol--;
}
X
/* Redraw screen */
void
redraw()
{
X clearok(curscr, TRUE);
X wrefresh(curscr);
}
X
/* Set/unset bold display */
void
setbold(int flag)
{
#ifdef BSDCURSES
X /* No-op */
#else
X attrset(flag ? A_BOLD : 0);
#endif
}
X
/* Return a typed-in string */
char *
getstring(char *msg)
{
X static char buf[BUFSIZ];
X int col = (COLS+1-strlen(msg))/2;
X int pcol = col+strlen(msg);
X int i = 0, key;
X
X move(LINES-1, 0);
X clrtoeol();
X move(LINES-1, col);
X addstr(msg);
X move(LINES-1, pcol);
X
X while (1) {
X refresh();
X key = keypress();
X
X switch (key) {
X case 10: /* RET - send string */
X move(LINES-1, 0);
X clrtoeol();
X refresh();
X buf[i] = '\0';
X return (strlen(buf) > 0 ? buf : NULL);
X case 21: /* Ctrl-U - kill line */
X while (i > 0) {
X i--;
X move(LINES-1, pcol+i);
X delch();
X }
X break;
X case 127: /* DEL - backup one */
X if (i > 0) {
X i--;
X move(LINES-1, pcol+i);
X delch();
X }
X break;
X default: /* if printable, print it */
X if (isprint(key)) {
X addch(key);
X buf[i++] = key;
X }
X }
X }
X
X /* NOTREACHED */
}
X
/* Return answer to a yes/no question */
int
query(char *msg, int def)
{
X int reply, c, col = (COLS+1-strlen(msg))/2;
X
X move(LINES-1, 0);
X clrtoeol();
X move(LINES-1, col);
X addstr(msg);
X
X move(LINES-1, col+strlen(msg));
X refresh();
X
X c = keypress();
X switch (c) {
X case 'y':
X case 'Y':
X reply = 1;
X break;
X case 'n':
X case 'N':
X reply = 0;
X break;
X default:
X reply = def;
X break;
X }
X
X move(LINES-1, 0);
X clrtoeol();
X refresh();
X
X return reply;
}
X
/* Write a message at bottom of screen */
void
message(char *fmt, ...)
{
X va_list args;
X
X va_start(args, fmt);
X vsprintf(msgtext, fmt, args);
X va_end(args);
X
X showmessage = 1;
}
X
/* Catch a quit signal */
void
quit()
{
#ifdef XCURSES
X flushinp();
#endif
X
X /* Can't get SYSV signals to work properly yet. When I get */
X /* around to it... */
#ifdef SYSVR3
X endscreen();
X exit(0);
#else
X signal(SIGINT, SIG_IGN);
X if (query("Really *quit*? ", 0)) {
X endscreen();
X exit(0);
X } else {
X signal(SIGINT, quit);
X drawpos(curpos);
X }
#endif
}
X
/* Catch a program fault */
void
panic()
{
X FILE *fp = fopen(PANICFILE, "w");
X
X endscreen();
X
X /* Try to save the moves that led up to it in a file */
X printf("PANIC!!! Major program failure!\n");
X if (fp != NULL) {
X writemoves(fp);
X fclose(fp);
X printf("Moves saved to file %s\n", PANICFILE);
X printf("Now get %s to sort out the problem.\n", WIZARD);
X } else {
X printf("Typical! I can't even open the panic save file.\n");
X printf("I give up!\n");
X }
X
X exit(1);
}
X
#ifdef BSDCURSES
/* Ring the bell */
void
beep()
{
X putchar('');
}
#endif
SHAR_EOF
$shar_touch -am 0623155894 'draw.c' &&
chmod 0444 'draw.c' ||
echo 'restore of draw.c failed'
shar_count="`wc -c < 'draw.c'`"
test 12690 -eq "$shar_count" ||
echo "draw.c: original size 12690, current size $shar_count"
fi
: || echo 'restore of move.c failed'
echo 'End of part 1, continue with part 2'
exit 0
--