[comp.sources.games] v01i054: sdi - missle command game for Suns, Part01/06

games-request@tekred.UUCP (06/17/87)

Submitted by: Mark Weiser <weiser.pa@xerox.com>
Comp.sources.games: Volume 1, Issue 54
Archive-name: sdi/Part01

	[This looks like a really neat game - I just wish we had
	 a Sun so I could play it, too!   -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 6)."
# Contents:  README MANIFEST HISTORY.nr control.c cursor.c helpers.c
#   icons.c piemenu_track.c
# Wrapped by billr@tekred on Wed Jun 17 11:20:41 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1174 characters\)
sed "s/^X//" >README <<'END_OF_README'
XThis is a single-player (sigh!) game for SunView on Sun-3's.  It is probably
Xtoo dear in computrons for a Sun-2 (although I have not tried it).
XIt is distributed in six shar-format files, each about 50kbytes.
X
XIt compiles under 3.0 and 3.2, at least, and runs on 3/160's, 75's and 3/50's.
X(I guess it will not work well in color since I didn't think much about this.
XI'm told it looks ok on color Sun-3/160's and 110's.  No reports on 260's, yet.
X
XFor 3.0, you will want to define the SUN3.0 variable in the makefile.
XThe game will compile under 3.2 with the SUN3.0 variable define, but
Xthe pie menu is not quite so pleasant.
X
XThe game object itself is close to a megabyte, and another megabyte of
Xtemporary storage for .o's and things needs to be available during the
Xmake process.
X
XTo get going, just say 'make'.  (I presume you have already unshared it
Xif you are reading this.)  If you want a scorefile, edit the first
Xline of the makefile to point to it, make the file (rw to all).  You should
Xexplicitly then install the game someplace handy (such as /usr/local/bin),
Xand the man entry as well.
X
XOther information is in the files NOTES, TODO, HISTORY.nr, and sdi.man.
END_OF_README
if test 1174 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(3294 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X HISTORY.nr                1	
X MANIFEST                  1	This shipping list
X NOTES                     6	
X README                    1	
X TODO                      2	
X about_msg.h               6	
X argv.c                    3	
X blast.c                   3	
X center.h                  6	
X circles.c                 2	
X cities.c                  2	
X city_icon1.h              4	
X city_icon2.h              6	
X city_icon3.h              4	
X city_icon4.h              4	
X city_icon5.h              4	
X city_icon6.h              4	
X city_icon7.h              4	
X city_icon8.h              4	
X control.c                 1	
X control_procs.c           3	
X cross_picture.h           6	
X cursor.c                  1	
X cursor.h                  6	
X default_city.h            4	
X dyna_picture.h            6	
X dynacursor.h              6	
X editall                   6	
X expert_advice.h           6	
X fancy_icon1.h             6	
X fancy_icon10.h            5	
X fancy_icon11.h            5	
X fancy_icon12.h            5	
X fancy_icon13.h            5	
X fancy_icon14.h            5	
X fancy_icon15.h            5	
X fancy_icon16.h            5	
X fancy_icon17.h            5	
X fancy_icon18.h            5	
X fancy_icon19.h            5	
X fancy_icon2.h             6	
X fancy_icon20.h            5	
X fancy_icon21.h            5	
X fancy_icon22.h            5	
X fancy_icon23.h            5	
X fancy_icon24.h            5	
X fancy_icon3.h             6	
X fancy_icon4.h             6	
X fancy_icon5.h             5	
X fancy_icon6.h             5	
X fancy_icon7.h             6	
X fancy_icon8.h             5	
X fancy_icon9.h             6	
X foe_ground_picture.h      6	
X foe_picture.h             6	
X game_over.c               4	
X gameover.h                5	
X genmessage.c              4	
X global.c                  4	
X helpers.c                 1	
X icon.h                    5	
X icons.c                   1	
X image_impl.h              6	
X incoming.c                3	
X incoming_picture.h        6	
X input.c                   2	
X instructions.h            6	
X interceptor_picture.h     3	
X intersect.c               3	
X laser.c                   4	
X laser.h                   5	
X laser_picture.h           6	
X laserkill.h               4	
X longfile.nr               6	
X lookup.h                  6	
X main.c                    2	
X makefile                  3	
X makehistory.awk           6	
X makeman.sed               6	
X makeversion               6	
X melt.h                    5	
X menu.c                    4	
X missile.c                 2	
X missilekill.h             4	
X mushroom.h                5	
X notify.c                  4	
X novice_advice.h           6	
X occasional_advice.h       6	
X pie_generic_cursor.h      6	
X piemenu.h                 6	
X piemenu_track.c           1	
X pr_helpers.c              2	
X random.c                  6	
X rock_picture.h            6	
X rocks.c                   5	
X rocks.h                   6	
X save_game.c               3	
X scores.c                  3	
X sdi.h                     3	
X sdi.man                   2	
X silly_picture.h           6	
X source_converter.c        6	
X talkingmark.h             4	
X text.c                    3	
X version.c                 6	
X walkmenu_impl.h           4	
END_OF_MANIFEST
if test 3294 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f HISTORY.nr -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"HISTORY.nr\"
else
echo shar: Extracting \"HISTORY.nr\" \(8021 characters\)
sed "s/^X//" >HISTORY.nr <<'END_OF_HISTORY.nr'
X.\" feed me through tbl and the me macros
X.tp
X.\" Add the 'po' line if sending to normal printer.
X.\"po 1i
X.sz 18
X.ce 99
XHistory of the SDI code.
X.ce 0
X.lp
X.sz 13
X.TS
Xtab(:);
Xc cw(4i) c
Xl l l.
XDate:What:Hours
X_
XDec. 31, '86:T{
XHacked up a little program to draw expanding and
Xcontracting circles.  This program still exists (called wormtest), and
Xallowed the tuning of blast aesthetics, and makes pretty output itself.
XT}:6
XJan. 1, '87:T{
XOrganized blasting code onto a linked list, tested it, in preparation
Xfor missile code.  Fooled around with multiple window presentation
Xand subframes.
XT}:8
XJan. 3, '87:T{
XPut in missle launching code.
XT}:4
XJan. 4, '87:T{
XTried various versions of missile drawing.  Sent lots of mail to
Xbugs@sun complaining about their vector algorithms not agreeing with
Xthe documentation. Finally adopted my own increment-with-correction
Xcode, which still makes noticable mistakes but not often enough to 
Xrise above fixit threshold.
XT}:8
XJan. 5, '87:T{
XFirst playable game in a single window.  Played it, discovered that at high missle and
Xblast densities the notifier prioritized mouse events such that it was
Ximpossible to get a blast out ahead of a fast moving missle.
XStarted thinking about a solution.
XT}:4
XJan. 6, '87:T{
XTried various notification schemes, mostly in toy programs to see if
Xthey did the job.  Discovered that asynchronous notification could
Xnot be relied upon, and that there were bugs in the sun suntools
Xinput_event_handler.  However, by a combination of ugly hacks and double
Xfirewalls got something that worked with fcntrl NOBLOCK.  Still occasionally
Xdropped mouseclicks, but all that were seen were seen immediately.
XT}:8
XJan. 8, '87:T{
XStarted getting annoyed with dropped mouseclicks, looked into other schemes:
Xlike changing the notifier priorities (not tried at this time, be used eventually), like registering asynchronous
Xevent handlers (tried).  Nothing tried worked.
XGprofed a long run, and discovered all the time was going into
Xrops (as is reasonable).  Reorganized code to update everything
Xat fixed intervals (blast_delay), rather than setting separate
Xnotifications for everything.  Fixed intervals meant I could lock
Xand batch all rops.  Big performance improvement.
XNow there was really lots of cpu
Xtime left (on a Sun-3/75-4) even with the busiest screen, and so
XI could probably return to synchronous.  Tried it.  Upped polling
Xtime to 150 milliseconds, and it worked.  #ifdef'd (ASYNCH) the asynch
Xcode in case it was ever needed again.
XT}:10
XJan. 9, '87:T{
XAdded second playing window, for missiles launching up.  As planned, the
Xmissile launching and drawing code worked backwards and forwards.
XT}:6
XJan. 10, '87:T{
XPlayed with city melting.  Fell asleep at 4am with it not working.
XT}:8
XJan. 11, '87:T{
XGot melting working right away.  Started working on GAME OVER blowup
Xcode.  Wasted lots of time on the genmessage program thinking Vax
Xbit/byte order, worked immediately after I made the code explicit
Xabout Endians.
XT}:8
XJan. 12, '87:T{
XStarted working on panels.  Split panel into separate control window.
XGot the basic buttons in.  Fooled
Xaround with making every button work whenever pushed (e.g.
Xnew game in the middle of a game.)  Suspend/Resume did
Xnot work.
XT}:6
XJan. 13, '87:T{
XCleaned up some global switches that even I wasn't sure about, and
Xgot suspend/resume and game over working clean under all conditions.
XFixed some races in notification of end-of-game under unusual conditions.
XT}:4
XJan. 15, '87:T{
XCleaned up the structure, created argv.c, helpers.c, and global.c.
XWorked on resize problem.  (Had to go back to 3.0 manuals because
X3.2 lacks an examples of popup menus which grab the input).
XT}:6
XJan. 16, '87:T{
XGot resize popup to work.  Now the game could not be thwarted by any
Xinadvertent user action.  Put game on file server, sent mail to a
Xfew friends announcing availability.
XT}:6
XJan. 17, '87:T{
XA solid game!  Played a few rounds.  Tuned launch distribution
Xand missile speed to make game more playable at higher levels.
XAdded srandom() call to main.c
XT}:4
XFeb. 3, '87:T{
XAdded lasers, prettier screen arrangement, continuous mode.
XT}:6
XFeb. 4, '87:T{
XGround away at some nagging intermittent bugs.  Discovered a dangling
Xpointer problem in 'doto_missiles' and 'doto_blasts', and writing to
Xarrays out of bounds in 'melt' and 'start_blast'.  Now, I can't make
Xit crash (but someone will, I'm sure.)
XT}:2
XFeb. 6, '87:T{
XMore clean up.
XT}:3
XFeb. 7, '87:T{
XDrew a new city, much nicer.  Added 'end-game', skill level, score files,
Ximproved melting speed.
XT}:6
XFeb. 9, '87:T{
XAdded 'advice'.  (Fought with bug in using window_loop to display text subwindows.  The bug won.)  Gprofed the world again, added LINE_GRAIN to intersect.c
Xto cut down excessive cpu there.  Back to good old mem_rop eating
Xall my time (about which I can do nothing.)
XT}:4
XFeb. 12, '87:T{
XWorked on active icons.  Sure wish I could get directly to that pixwin--keep
Xgetting flicker.  Hand drew 24 miniature game frame, wrote icontest to
Xanimate them.  Looks bad.
XT}:4
XFeb. 16, '87:T{
XDrew a different set of 8 icons for animation.  Subtle, just lights flickering
Xand two quiet missiles.  Still flicker, but good enough to put into game.
XT}:2
XFeb. 21, '87:T{
XIntense notifier hacking to make response good even at very high levels of missiles and blasts.  Finally went to my own notifier scheduler, and turning
Xasynchronicity on and off at each round.
XT}:4
XFeb. 22, '87:T{
XFinished notifier hacking.  Seems good, but now a little too easy too play.
XReduced the blast size of a blown up missile so self-sustaining blast walls
Xdo not occur.
XT}:4
XFeb. 27, '87:T{
XAdded the source and history buttons.  Fun!
XT}:2
XMarch 6, '87:T{
XAdded the -t and -l options for the Maryland open house.
XT}:1
XMarch 15, '87:T{
XCommented uncommented routines.
XT}:2
XMarch 30, '87:T{
XPut in changes suggested by my Beta testers on the net (thanks everyone!):
X(a) slight delay after click-to-start,
X(b) saving and restoring games,
X(c) look in /usr/game/lib/sdi_scores before tmp,
X(d) initial position of the three windows,
X(e) explain scoring better in the man entry, add a 'man' button,
X(f) improve source, history, and man fiddling,
X(g) disable menus for launch and city frames.
XT}:6
XMarch 31, '87:T{
XPut in rocks.  Added shift and meta button modifications.
XT}:4
XApril 1, '87:T{
XAn all too appropriate date for discovering and working around yet another
XSun notification bug (in SunOs 3.2) which causes the middle mouse button down transition
Xto be lost when the input focus is transfered into the canvas and not
Xrefused.  Wrote the keytest tool to graphically illustrate the problem
Xand mailed it to bugs@sun.  Wrote a workaround into sdi.
XT}:3
XApril 2, '87:T{
XFixed a lurking bug in the -r option.
XT}:1
XApril 4, '87:T{
XAdded the dynamic cursor.
XT}:2
XApril 5,6,7,8,9,10,11, '87:T{
XTuning, playing, massive re-arrangment of control panel items into sub
Xwindows, a little at a time.
XT}:8
XApril 12, '87:T{
XPie-menu version of 'Things to Read'.
XT}:4
XApril 13 thru 23, '87:T{
XLittle tunings.
XT}:6
XMay 1 thru 5, '87:T{
XBackground border, message when saving to existing file, pie dynamic cursor.
XSpent many, many hours wasted trying to get a window to properly reshape
Xwhen it has a panel at the bottom.  Could not do it.  (The 'foe on the
Xground' slider really belongs on the bottom of the launch frame.)
XT}:16
X.TE
X.hl
X.lp
XNOTES.
X.np
XAlmost all programming was done at home after 10pm at night.
X.np
XVery little time was spent not at the terminal.  There were no design
Xdocuments, not even scrawled notes.  The only large offline time
Xwas spent reading Foley and van Dam for ideas on clipping vectors,
Xand it was useless time.
X.np
XIncluded in the above times is some mail and news reading interleaved
Xwith waiting for compiles.  I don't know how to separate that out.  It might
Xbe as much as half the time.
X.np
XAlso included in the above times is some general Sun manual and code
Xreading, paticularily about the notifier.  This is probably not
Xmore than 2-3 hours, however.
END_OF_HISTORY.nr
if test 8021 -ne `wc -c <HISTORY.nr`; then
    echo shar: \"HISTORY.nr\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f control.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"control.c\"
else
echo shar: Extracting \"control.c\" \(9160 characters\)
sed "s/^X//" >control.c <<'END_OF_control.c'
X/*****************************  control.c  ******************************/
X#include <sunwindow/notify.h>
X#include "sdi.h"
X
X/*
X * Copyright 1987 by Mark Weiser.
X * Permission to reproduce and use in any manner whatsoever on Suns is granted
X * so long as this copyright and other identifying marks of authorship
X * in the code and the game remain intact and visible.  Use of this code
X * in other products is reserved to me--I'm working on Mac and IBM versions.
X */
X
X/*
X * The main code for setting up the control panel lives here.
X * Other panel-related code is in control_procs.c, helpers.c, and main.c.
X */
X
Xstatic short i_pic_array[] = {
X#include "interceptor_picture.h"
X};
Xmpr_static(interceptor_pic, 16, 16, 1, i_pic_array);
X
Xstatic short l_pic_array[] = {
X#include "laser_picture.h"
X};
Xmpr_static(laser_pic, 16, 16, 1, l_pic_array);
X
Xstatic short r_pic_array[] = {
X#include "rock_picture.h"
X};
Xmpr_static(rock_pic, 16, 16, 1, r_pic_array);
X
Xstatic short f_pic_array[] = {
X#include "foe_picture.h"
X};
Xmpr_static(foe_pic, 16, 16, 1, f_pic_array);
X
Xstatic short c1_pic_array[] = {
X#include "cursor.h"
X};
Xmpr_static(normal_pic, 16, 16, 1, c1_pic_array);
X
Xstatic short c2_pic_array[] = {
X#include "dyna_picture.h"
X};
Xmpr_static(dyna_pic, 16, 16, 1, c2_pic_array);
X
Xstatic short c3_pic_array[] = {
X#include "cross_picture.h"
X};
Xmpr_static(cross_pic, 16, 16, 1, c3_pic_array);
X
Xstatic short c4_pic_array[] = {
X#include "silly_picture.h"
X};
Xmpr_static(silly_pic, 16, 16, 1, c4_pic_array);
X
Xextern void next_round_proc(), quit_proc(), master_proc(), no_events(),
X	suspend_proc(), resume_proc(), open_proc(), scores_proc(), end_proc(),
X	help_proc(), about_proc(), higher_proc(), cycle_time_proc(),
X	save_proc(), restore_proc(), text_options_proc(), instructions_proc(),
X	cursor_notify_proc(), icon_option_proc(), misc_options_proc(),
X	ballistic_time_proc(), new_game_proc(), non_stop_notify_proc(),
X	version_proc();
Xextern Panel_setting save_file_notify_proc(), name_notify_proc();
X
XPanel_item cycle_time_item, timeout_item;
X
X/*
X * Build and place all the items in the control panel.
X */
Xinit_control(panel)
XPanel panel;
X{
X	extern Panel_item rock_item;
X	extern int gamemaster, continuous, time_to_play, starting_skill;
X	extern struct pixfont *bigfont, *buttonfont; /* use 'struct pixfont', not 'Pixfont',
X											 for 3.0 compatibility */
X	if ((bigfont = (struct pixfont *)pf_open(
X		"/usr/lib/fonts/fixedwidthfonts/screen.b.14")) == NULL) {
X			bigfont = (struct pixfont *)pf_default();
X	}
X	if ((buttonfont = (struct pixfont *)pf_open(
X		"/usr/lib/fonts/fixedwidthfonts/screen.r.12")) == NULL) {
X			buttonfont = (struct pixfont *)pf_default();
X	}
X	next_round_item = panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Next Round", 12, buttonfont),
X		PANEL_NOTIFY_PROC, next_round_proc,
X		PANEL_SHOW_ITEM, FALSE,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Quit", 6, buttonfont),
X		PANEL_NOTIFY_PROC, quit_proc,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "New Game", 10, buttonfont),
X		PANEL_NOTIFY_PROC, new_game_proc,
X		0);
X	suspend_item = panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Suspend", 9, buttonfont),
X		PANEL_NOTIFY_PROC, suspend_proc, 
X		0);
X	resume_item = panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Resume", 9, buttonfont),
X		PANEL_NOTIFY_PROC, resume_proc,
X		PANEL_SHOW_ITEM, FALSE,
X		PANEL_ITEM_X, panel_get(suspend_item, PANEL_ITEM_X), 
X		PANEL_ITEM_Y, panel_get(suspend_item ,PANEL_ITEM_Y), 
X		0);
X	level_item = panel_create_item(panel, PANEL_TEXT,
X		PANEL_LABEL_STRING, "Level:", 
X		PANEL_VALUE, "0",
X		(char *)PANEL_EVENT_PROC, (char *)no_events,
X		PANEL_VALUE_DISPLAY_LENGTH, 2,
X		0);
X	score_item = panel_create_item(panel, PANEL_TEXT,
X		PANEL_LABEL_STRING, "Score:", 
X		PANEL_VALUE, "0",
X		PANEL_VALUE_DISPLAY_LENGTH, 8,
X		(char *)PANEL_EVENT_PROC, (char *)no_events,
X		PANEL_VALUE_FONT, bigfont,
X		0);
X	interceptor_item = panel_create_item(panel, PANEL_SLIDER,
X		ATTR_LIST, panel_common,
X#ifdef STRINGLABELS
X		PANEL_LABEL_STRING, "Interceptors:     ",
X#else
X		PANEL_LABEL_IMAGE, &interceptor_pic,
X#endif
X		0);
X	rock_item = panel_create_item(panel, PANEL_SLIDER,
X		ATTR_LIST, panel_common,
X#ifdef STRINGLABELS
X		PANEL_LABEL_STRING, "Rocks:            ",
X#else
X		PANEL_LABEL_IMAGE, &rock_pic,
X#endif
X		0);
X	laser_item = panel_create_item(panel, PANEL_SLIDER,
X		ATTR_LIST, panel_common,
X#ifdef STRINGLABELS
X		PANEL_LABEL_STRING, "X-ray lasers:     ",
X#else
X		PANEL_LABEL_IMAGE, &laser_pic,
X#endif
X		0);
X#define FOE_WIDTH 270
X	foe_item = panel_create_item(panel, PANEL_SLIDER,
X		ATTR_LIST, panel_common,
X#ifdef STRINGLABELS
X		PANEL_LABEL_STRING, "Foe in flight:", 
X#else
X		PANEL_LABEL_IMAGE, &foe_pic,
X#endif
X		PANEL_SLIDER_WIDTH, FOE_WIDTH,
X		0);
X	total_foe_item = panel_create_item(panel, PANEL_TEXT,
X		PANEL_LABEL_STRING, "Total foe killed:", 
X		PANEL_VALUE, "0",
X		PANEL_VALUE_DISPLAY_LENGTH, 24,
X		(char *)PANEL_EVENT_PROC, (char *)no_events,
X		0);
X	if (time_to_play) {
X		timeout_item = panel_create_item(panel, PANEL_SLIDER,
X			ATTR_LIST, panel_common,
X			PANEL_LABEL_STRING, "Seconds remaining:", 
X			PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, time_to_play,
X			PANEL_VALUE, time_to_play,
X			PANEL_SLIDER_WIDTH, 500,
X			0);
X		continuous = 1;
X		start_timeout(timeout_item);
X	}
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Options", 9, buttonfont),
X		PANEL_NOTIFY_PROC, misc_options_proc,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Things to Read", 16, buttonfont),
X		PANEL_NOTIFY_PROC, text_options_proc,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Icon Options", 14, buttonfont),
X		PANEL_NOTIFY_PROC, icon_option_proc,
X		0);
X	skill_item = panel_create_item(panel, PANEL_CYCLE,
X		PANEL_LABEL_STRING, " Skill:",
X		PANEL_CHOICE_STRINGS, "Novice", "Occasional", "Expert", 0,
X		PANEL_NOTIFY_PROC, new_game_proc,
X		PANEL_VALUE, starting_skill,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Instructions", 14, buttonfont),
X		PANEL_NOTIFY_PROC, instructions_proc,
X		0);
X	if (gamemaster) {
X		(void) panel_create_item(panel, PANEL_TOGGLE,
X			PANEL_CHOICE_STRINGS, "Gamemaster", 0,
X			PANEL_NOTIFY_PROC, master_proc,
X			PANEL_SHOW_ITEM, TRUE,
X			0);
X	}
X}
X
Xvoid
Xmisc_options_proc()
X{
X	extern int cursor_type, ballistic_delay;
X	extern struct pixfont *buttonfont; /* use 'struct pixfont' for 3.0 compatiblity */
X	char *s;
X	Panel panel, make_popup_panel();
X	void options_done();
X	if ((panel = make_popup_panel("      SDI Options", options_done)) == NULL) {
X		return;
X	}
X
X	(void) panel_create_item(panel, PANEL_CYCLE,
X		PANEL_LABEL_STRING, "Cursor:",
X		PANEL_CHOICE_IMAGES, &normal_pic, &dyna_pic, &cross_pic, &silly_pic, 0,
X		PANEL_MENU_CHOICE_STRINGS, "normal", "dynamic", "crosshair", "silly", 0,
X		PANEL_NOTIFY_PROC, cursor_notify_proc,
X		PANEL_VALUE, cursor_type,
X		0);
X	(void) panel_create_item(panel, PANEL_TOGGLE,
X		PANEL_CHOICE_STRINGS, "Non-stop", 0,
X		PANEL_NOTIFY_PROC, non_stop_notify_proc,
X		PANEL_VALUE, continuous,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Melt", 4, buttonfont),
X		PANEL_NOTIFY_PROC, end_proc,
X		0);
X	if (user_name[0] == '\0') {
X		s = (char *)get_name();
X		if (s[0] != '\0') strcpy(user_name, s);
X	}
X	user_name_item =  panel_create_item(panel, PANEL_TEXT,
X		PANEL_LABEL_STRING, "Name: ",
X		PANEL_VALUE_DISPLAY_LENGTH, 16,
X		PANEL_VALUE_STORED_LENGTH, 63,
X		PANEL_VALUE, user_name,
X		0);
X	panel_fit_width(panel);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Save", 6, buttonfont),
X		PANEL_NOTIFY_PROC, save_proc,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Restore", 7, buttonfont),
X		PANEL_NOTIFY_PROC, restore_proc,
X		0);
X	save_file_item = panel_create_item(panel, PANEL_TEXT,
X		PANEL_LABEL_STRING, "Save file:",
X		PANEL_VALUE_DISPLAY_LENGTH, 16,
X		PANEL_VALUE_STORED_LENGTH, 63,
X		PANEL_VALUE, save_file_name,
X		0);
X	(void) panel_create_item(panel, PANEL_SLIDER,
X		PANEL_LABEL_STRING, "Cycle time (ms): ", 
X		PANEL_NOTIFY_LEVEL, PANEL_ALL,
X		PANEL_SLIDER_WIDTH, 100,
X		PANEL_MIN_VALUE, 50,
X		PANEL_MAX_VALUE, 250,
X		PANEL_SHOW_RANGE, FALSE,
X		PANEL_SHOW_VALUE, TRUE,
X		PANEL_VALUE, blast_delay/1000,
X		PANEL_SHOW_ITEM, TRUE,
X		PANEL_NOTIFY_PROC, cycle_time_proc,
X		0);
X	(void) panel_create_item(panel, PANEL_SLIDER,
X		PANEL_LABEL_STRING, "Ballistic time: ", 
X		PANEL_SLIDER_WIDTH, 50,
X		PANEL_MIN_VALUE, 0,
X		PANEL_MAX_VALUE, 10,
X		PANEL_SHOW_RANGE, FALSE,
X		PANEL_SHOW_VALUE, TRUE,
X		PANEL_VALUE, ballistic_delay,
X		PANEL_SHOW_ITEM, TRUE,
X		PANEL_NOTIFY_PROC, ballistic_time_proc,
X		0);
X	user_name[0] = '\0';
X	save_file_name[0] = '\0';
X	display_popup_panel(panel);
X}
X
Xvoid
Xoptions_done()
X{
X	strcpy(user_name, panel_get_value(user_name_item));
X	strcpy(save_file_name, panel_get_value(save_file_item));
X}
END_OF_control.c
if test 9160 -ne `wc -c <control.c`; then
    echo shar: \"control.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cursor.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cursor.c\"
else
echo shar: Extracting \"cursor.c\" \(3504 characters\)
sed "s/^X//" >cursor.c <<'END_OF_cursor.c'
X/*****************************  cursor.c  ******************************/
X#include "sdi.h"
X
X/*
X * Copyright 1987 by Mark Weiser.
X * Permission to reproduce and use in any manner whatsoever on Suns is granted
X * so long as this copyright and other identifying marks of authorship
X * in the code and the game remain intact and visible.  Use of this code
X * in other products is reserved to me--I'm working on Mac and IBM versions.
X */
X
X/*
X * Code to manage the dynamic cursor.
X */
X
Xstruct cursor *compute_cursor();
Xstruct pixrect *compute_cursor_image();
X
Xstatic short dynacursor_data[] = {
X#include "dynacursor.h"
X};
Xmpr_static(dynabase_cursor_pr, 16, 16, 1, dynacursor_data);
X
Xstatic short cursor_data[] = {
X#include "cursor.h"
X};
Xmpr_static(base_cursor_pr, 16, 16, 1, cursor_data);
X
Xstruct cursor *
Xinit_cursor()
X{
X	static struct cursor *main_cursor = NULL;
X	extern int cursor_type;
X	if (main_cursor) {
X		cursor_destroy(main_cursor);
X	}
X	switch(cursor_type) {
X		case 0:
X			main_cursor = (struct cursor *)cursor_create(CURSOR_IMAGE, &base_cursor_pr,
X				CURSOR_XHOT, 8, CURSOR_YHOT, 8,
X				CURSOR_OP, PIX_SRC ^ PIX_DST,
X				0);
X			break;
X		case 1:
X			main_cursor = (struct cursor *)cursor_create(CURSOR_OP, PIX_SRC ^ PIX_DST,
X				CURSOR_IMAGE, &dynabase_cursor_pr,
X				CURSOR_XHOT, 8, CURSOR_YHOT, 3,
X				0);
X			break;
X		case 2:
X			main_cursor  = (struct cursor *)cursor_create(CURSOR_SHOW_CROSSHAIRS, TRUE,
X				CURSOR_OP, PIX_SRC ^ PIX_DST,
X				0);
X			break;
X		case 3:
X			main_cursor = (struct cursor *)cursor_create(CURSOR_SHOW_CROSSHAIRS, TRUE,
X				CURSOR_OP, PIX_SRC ^ PIX_DST,
X				CURSOR_IMAGE, &dynabase_cursor_pr,
X				CURSOR_XHOT, 8, CURSOR_YHOT, 3,
X				0);
X			break;
X		}
X	window_set(launchcanvas, WIN_CURSOR, main_cursor, 0);
X	window_set(citycanvas, WIN_CURSOR, main_cursor, 0);
X}
X
Xupdate_cursor()
X{
X	extern int cursor_type;
X	switch (cursor_type) {
X		case 1: case 3:
X			window_set(launchcanvas,
X				WIN_CURSOR, compute_cursor(window_get(launchcanvas, WIN_CURSOR)),
X				0);
X			window_set(citycanvas,
X				WIN_CURSOR, compute_cursor(window_get(citycanvas, WIN_CURSOR)),
X				0);
X			break;
X		default:
X			break;
X	}
X}
X
Xstruct cursor *
Xcompute_cursor(c)
Xstruct cursor * c;
X{
X	cursor_set(c, 
X		CURSOR_IMAGE, compute_cursor_image(cursor_get(c, CURSOR_IMAGE)),
X		0);
X	return c;
X}
X
X/* Returns a static structure, so get rid of it before reusing it. */
Xstruct pixrect *
Xcompute_cursor_image(pr)
Xstruct pixrect *pr;
X{
X	extern Panel_item rock_item;
X	int left_current = (int)panel_get_value(interceptor_item);
X	int left_max = (int)panel_get(interceptor_item, PANEL_MAX_VALUE);
X	int middle_current = (int)panel_get_value(rock_item);
X	int middle_max = (int)panel_get(rock_item, PANEL_MAX_VALUE);
X	int right_current = (int)panel_get_value(laser_item);
X	int right_max = (int)panel_get(laser_item, PANEL_MAX_VALUE);
X
X	pr_rop(pr, 0, 0, 16, 16, PIX_SRC, &dynabase_cursor_pr, 0, 0);
X	put_line(pr, 1, 8, 15, left_current, left_max);
X	put_line(pr, 7, 8, 15, middle_current, middle_max);
X	put_line(pr, 13, 8, 15, right_current, right_max);
X	return pr;
X}
X
X/*
X * Draw a double-width line in pr from start to finish, with 
X * length equal current/max. assumes finish > start.
X */
Xput_line(pr, x, start, finish, current, max)
Xstruct pixrect *pr;
X{
X	int length = (current*(finish-start+1))/max;
X	if (length == 0 && current != 0) length = 1;
X	pr_vector(pr, x, start-1, x, start+length-1, PIX_SRC, 1);
X	pr_vector(pr, x+1, start-1, x+1, start+length-1, PIX_SRC, 1);
X	pr_vector(pr, x+2, start-1, x+2, start+length-1, PIX_SRC, 1);
X}
END_OF_cursor.c
if test 3504 -ne `wc -c <cursor.c`; then
    echo shar: \"cursor.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f helpers.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"helpers.c\"
else
echo shar: Extracting \"helpers.c\" \(9565 characters\)
sed "s/^X//" >helpers.c <<'END_OF_helpers.c'
X/*********************  helpers.c ************************************/
X#include <sunwindow/notify.h>
X#include <fcntl.h>
X#include <sys/ioctl.h>
X#include <stdio.h>
X#include <errno.h>
X#include "sdi.h"
X#include <suntool/textsw.h>
X
X/*
X * Copyright 1987 by Mark Weiser.
X * Permission to reproduce and use in any manner whatsoever on Suns is granted
X * so long as this copyright and other identifying marks of authorship
X * in the code and the game remain intact and visible.  Use of this code
X * in other products is reserved to me--I'm working on Mac and IBM versions.
X */
X
X/*
X * This file contains routines providing help throughout sdi, although
X * especially to the control panel.
X */
X
X
Xstatic short background_array[] = {
X#include "/usr/include/images/square_17.pr"
X};
Xmpr_static(background_pr, 16, 16, 1, background_array);
X
Xvoid generic_slider_notify();
X
X/* Used as an event_proc in panels to make an item read only */
Xvoid
Xno_events(item, event)
XPanel_item item;
XEvent *event;
X{
X}
X
X/* need functions, not macros, because of non-idempotent funcall arguments */
Xmax(x,y)
X{
X	return x<y ? y : x;
X}
X
Xmin(x,y)
X{
X	return x<y ? x : y;
X}
X
X/*
X * Used to initiate the panel timer countdown associated with the
X * '-t' option.
X */
Xstart_timeout(item)
XPanel_item item;
X{
X	Notify_value timeout_proc();
X	struct itimerval timer;
X
X	timer.it_interval.tv_usec = 0;
X	timer.it_interval.tv_sec = 1;
X	timer.it_value.tv_usec = 0;
X	timer.it_value.tv_sec = 1;
X	notify_set_itimer_func(item, timeout_proc, ITIMER_REAL, &timer, NULL);
X}
X
X/*
X * The proc that takes the timer notifications for the panel timer countdown
X * associated with the '-t' option.  Started by proc 'start_timeout'.
X */
XNotify_value
Xtimeout_proc(item, which)
XPanel_item item;
Xint which;
X{
X	extern int continuous;
X	struct itimerval timer;
X	int val = (int)panel_get_value(item);
X	val -= 1;
X	if (running) panel_set_value(item, val);
X	if (val <= 0) {
X		continuous = 0;
X		end_proc();
X		continuous = 1;
X		panel_set_value(item, panel_get(item, PANEL_MAX_VALUE));
X		return;
X	}
X}
X
X/*
X * The remaining code in helper.c is concerned with different kinds
X * of popups or pseudo-popups (for textsw's).  First a few local variables
X */
Xstatic Frame popup_frame = NULL;
Xstatic Textsw popup_text;
Xstatic Panel popup_panel;
Xstatic Panel_item popup_msg_item;
Xstatic void popup_yes_proc(), popup_no_proc(), popup_textsw_done();
X
X/* 
X * Pop a warning on the screen.  Return 1 if yes, 0 if no 
X * Event is used to determine the x,y position of the popup, and Frame
X * is the frame in which the event was received.
X * Msg is a single-line string containing the message.  It should be
X * in the form of a yes/no question, because it will be followed
X * in the window by 'yes' and 'no' selection boxes.
X */
Xpopup_warning(frame, event, msg)
XFrame *frame;
XEvent *event;
Xchar *msg;
X{
X	int value;
X	init_popup_warn(frame, msg);
X	window_set(popup_frame, WIN_X, event_x(event),
X		WIN_Y, event_y(event),
X		0);
X	value = (int)window_loop(popup_frame);
X	window_set(popup_frame, FRAME_NO_CONFIRM, TRUE, 0);
X	window_destroy(popup_frame);
X	popup_frame = NULL;
X	return value;
X}
X
X/*
X * Pop up a message inside a textsw.  Since textsw's don't really
X * popup (in SunOS 3.2), just display it and put up a 'done' button
X * to kill it when the user is done.
X * Frame should be the frame in which Event occured.  Msg can
X * contain imbedded newlines.
X */
Xpopup_msg(frame, event, msg)
XFrame *frame;
XEvent *event;
Xchar *msg;
X{
X	int lines = count_lines(msg);
X	if (popup_frame != NULL) {
X		/* Can only do one of these at a time. */
X		return;
X	}
X	suspend_proc();
X	init_popup_msg(frame, msg, lines);
X	textsw_insert(popup_text, msg, strlen(msg));
X	window_set(popup_frame, WIN_X, event_x(event),
X		WIN_Y, event_y(event),
X		WIN_SHOW, TRUE,
X		0);
X}
X
X/*
X * A helper routine to do all the real work of setting up windows for warnings
X */ 
Xinit_popup_warn(baseframe, msg)
XFrame baseframe;
Xchar *msg;
X{
X	popup_frame = window_create(baseframe, FRAME,
X		WIN_ERROR_MSG, "Can't create window.",
X		FRAME_DONE_PROC, popup_no_proc,
X		WIN_GRAB_ALL_INPUT, TRUE,
X		0);
X	popup_panel = window_create(popup_frame, PANEL,
X		WIN_ERROR_MSG, "Can't create window.",
X		PANEL_LAYOUT, PANEL_VERTICAL,
X		0);
X	popup_msg_item = panel_create_item(popup_panel, PANEL_MESSAGE,
X		0);
X	panel_create_item(popup_panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(popup_panel, "Yes", 3, NULL),
X		PANEL_NOTIFY_PROC, popup_yes_proc,
X		PANEL_ITEM_Y, ATTR_ROW(1),
X		0);
X	panel_create_item(popup_panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(popup_panel, "No", 2, NULL),
X		PANEL_NOTIFY_PROC, popup_no_proc,
X		PANEL_ITEM_Y, ATTR_ROW(1),
X		0);
X	panel_set(popup_msg_item, PANEL_LABEL_STRING, msg, 0);
X	window_fit(popup_panel);
X	window_fit(popup_frame);
X}
X
X/*
X * popup_yes_proc and popup_no_proc are helpers used for warning popups.
X */
Xstatic void
Xpopup_yes_proc(item, event)
XPanel_item item;
XEvent *event;
X{
X	window_return(1);
X}
X
Xstatic void
Xpopup_no_proc(item, event)
XPanel_item item;
XEvent *event;
X{
X	window_return(0);
X}
X
X/*
X * A helper proc to do all the work of window creation for message popups
X */
Xinit_popup_msg(baseframe, msg, lines)
XFrame baseframe;
Xchar *msg;
X{
X	popup_frame = window_create(baseframe, FRAME,
X		WIN_ERROR_MSG, "Can't create window.",
X		FRAME_DONE_PROC, popup_textsw_done,
X		0);
X	popup_panel = window_create(popup_frame, PANEL,
X		/* WIN_BELOW, popup_text, */
X		WIN_X, ATTR_COL(0),		/* bug workaround, should not be necessary */
X		0);
X	panel_create_item(popup_panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(popup_panel, "Done", 4, NULL),
X		PANEL_NOTIFY_PROC, popup_textsw_done,
X		0);
X	window_fit(popup_panel);
X	popup_text = window_create(popup_frame, TEXTSW,
X		WIN_ERROR_MSG, "Can't create window.",
X		WIN_ROWS, min(30, lines),
X		WIN_COLUMNS, max_line(msg)+3,
X		TEXTSW_IGNORE_LIMIT, TEXTSW_INFINITY,
X		TEXTSW_CONTENTS, msg,
X		TEXTSW_BROWSING, TRUE,
X		TEXTSW_DISABLE_LOAD, TRUE,
X		TEXTSW_DISABLE_CD, TRUE,
X		0);
X	window_fit(popup_frame);
X}
X
X/* A helper for killing message popups. */
Xstatic void
Xpopup_textsw_done()
X{
X	window_set(popup_frame, FRAME_NO_CONFIRM, TRUE, 0);
X	window_destroy(popup_frame);
X	popup_frame = NULL;
X	resume_proc();
X}
X
XMenu
Xnull_menu_gen(m, operation)
XMenu m;
XMenu_generate operation;
X{
X	/*
X	 * If I destroy the menu, then under very rapid buttoning on the
X	 * border someone gets confused and passes me a bad menu descripter.
X	 * menu_destroy(m);
X	 */
X	m = menu_create(0);
X	return m;
X}
X
X/*
X * Fake an event, so anyone can popup a message. 
X */
Xeasy_pop(msg)
Xchar *msg;
X{
X	Event event;
X	event_x(&event) = (int)window_get(controlframe, WIN_X); 
X	event_y(&event) = (int)window_get(controlframe, WIN_Y);
X	popup_msg(controlframe, &event, msg);
X}
X
Xeasy_warn(msg)
Xchar *msg;
X{
X	Event event;
X	event_x(&event) = (int)window_get(controlframe, WIN_X); 
X	event_y(&event) = (int)window_get(controlframe, WIN_Y);
X	return popup_warning(controlframe, &event, msg);
X}
X
Xstatic Frame popup_panel_frame = 0;
Xstatic int (*popup_panel_user_done_func)();
X
X/*
X * Helper for make_popup_panel, below.
X */
Xstatic
Xpopup_panel_done()
X{
X	if (popup_panel_user_done_func)
X		(*popup_panel_user_done_func)();
X	window_set(popup_panel_frame, FRAME_NO_CONFIRM, TRUE, 0);
X	window_destroy(popup_panel_frame);
X	popup_panel_frame = 0;
X	resume_proc();
X}
X
XPanel
Xmake_popup_panel(panel_name, user_done_func)
Xchar *panel_name;
Xint (*user_done_func)();
X{
X	extern struct pixfont *buttonfont; /* use 'struct pixfont' for 3.0 compatiblity */
X	Panel panel;
X	if (popup_panel_frame) {
X		/* don't permit nested calls. */
X		return NULL;
X	}
X	suspend_proc();
X	popup_panel_user_done_func = user_done_func;
X	popup_panel_frame = window_create(controlframe, FRAME,
X		FRAME_SHOW_LABEL, TRUE,
X		FRAME_DONE_PROC, popup_panel_done,
X		FRAME_LABEL, panel_name,
X		WIN_ERROR_MSG, "Can't create popup panel frame.",
X		0);
X	panel = window_create(popup_panel_frame, PANEL,
X		WIN_ERROR_MSG, "Can't create popup panel panel.",
X		PANEL_ITEM_X_GAP, 30,
X		PANEL_ITEM_Y_GAP, 15,
X		0);
X	(void) panel_create_item(panel, PANEL_BUTTON,
X		PANEL_LABEL_IMAGE, panel_button_image(panel, "Done", 6, buttonfont),
X		PANEL_NOTIFY_PROC, popup_panel_done,
X		0);
X	return panel;
X}
X
Xdisplay_popup_panel(panel)
XPanel panel;
X{
X	if (panel == NULL || popup_panel_frame == NULL)
X		return;
X	window_fit(panel);
X	window_fit(popup_panel_frame);
X	window_set(popup_panel_frame, WIN_SHOW, TRUE, 0);
X}
X
Xstart_next_round()
X{
X	extern void start_running_proc(), init_blast();
X	/* 
X	 * Notice that things will break if blast_delay+1000
X	 * is greater than 999,999.
X	 */
X	panel_set(skill_item, PANEL_EVENT_PROC, (char *)no_events, 0);
X	clear_fields();
X	place_cities(citypw);
X	init_incoming();
X	update_cursor();
X	do_with_delay(start_running_proc, 0, blast_delay+1000);
X	do_with_delay(init_blast, 1, blast_delay);
X}
X
X/*
X * helper to delay the startup.
X */
Xvoid
Xstart_running_proc()
X{
X	running = 1;
X}
X
Xput_text(y, s)
Xint y;
Xchar *s;
X{
X	struct pr_size size;
X	size = pf_textwidth(strlen(s), font, s);
X	pw_text(citypw, max_x / 2 - size.x / 2, max_y / 2 - 35 - (size.y/2)+ y, PIX_SRC, font, s);
X	pw_text(launchpw, max_x / 2 - size.x / 2, max_y / 2 - 35 - (size.y/2)+ y, PIX_SRC, font, s);
X}
X
Xdraw_canvas_background(canvas)
XCanvas canvas;
X{
X    pw_replrop(window_get(canvas, CANVAS_PIXWIN), 0, 0, 
X	    window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), 
X	    PIX_SRC, &background_pr, 0, 0);
X}
X
Xdraw_background()
X{
X	draw_canvas_background(citycanvas);
X	draw_canvas_background(launchcanvas);
X}
X
Xclear_fields()
X{
X	pw_writebackground(citypw, 0, 0, max_x, max_y, PIX_SRC);
X	pw_writebackground(launchpw, 0, 0, max_x, max_y+max_y
X, PIX_SRC);
X}
END_OF_helpers.c
if test 9565 -ne `wc -c <helpers.c`; then
    echo shar: \"helpers.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f icons.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"icons.c\"
else
echo shar: Extracting \"icons.c\" \(9019 characters\)
sed "s/^X//" >icons.c <<'END_OF_icons.c'
X/********************************  icons.c  ****************************/
X#include "sdi.h"
X#include <sunwindow/notify.h>
X
X/*
X * Copyright 1987 by Mark Weiser.
X * Permission to reproduce and use in any manner whatsoever on Suns is granted
X * so long as this copyright and other identifying marks of authorship
X * in the code and the game remain intact and visible.  Use of this code
X * in other products is reserved to me--I'm working on Mac and IBM versions.
X */
X
X/*
X * This file contains the code and data to keep the icon busy.
X */
X
X#define ICON_TYPE Icon *
X
X/*
X * The standard macro forces background pixel writing, 
X * which causes icon flicker
X */
X#define	MARKS_OWN_DEFINE_ICON_FROM_IMAGE(name, image)				\
X	static struct mpr_data CAT(name,_data) = {			\
X	    mpr_linebytes(ICON_DEFAULT_WIDTH,1), (short *)(image),	\
X	    {0, 0}, 0, 0};						\
X	extern struct pixrectops mem_ops;				\
X	static struct pixrect CAT(name,_mpr) = {			\
X	    &mem_ops, ICON_DEFAULT_WIDTH, ICON_DEFAULT_HEIGHT, 1,	\
X	    (caddr_t)&CAT(name,_data)};					\
X	static struct icon name = {					\
X	    ICON_DEFAULT_WIDTH, ICON_DEFAULT_HEIGHT,			\
X	    (struct pixrect *)0,					\
X	    0, 0, ICON_DEFAULT_WIDTH, ICON_DEFAULT_HEIGHT,		\
X	    &CAT(name,_mpr),						\
X	    0, 0, ICON_DEFAULT_WIDTH, ICON_DEFAULT_HEIGHT,		\
X	    NULL, (struct pixfont *)0, 0};
X
X
Xstatic short icon1_image[] = {
X#include "city_icon1.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon1, icon1_image);
X
Xstatic short icon2_image[] = {
X#include "city_icon2.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon2, icon2_image);
X
Xstatic short icon3_image[] = {
X#include "city_icon3.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon3, icon3_image);
X
Xstatic short icon4_image[] = {
X#include "city_icon4.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon4, icon4_image);
X
Xstatic short icon5_image[] = {
X#include "city_icon5.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon5, icon5_image);
X
Xstatic short icon6_image[] = {
X#include "city_icon6.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon6, icon6_image);
X
Xstatic short icon7_image[] = {
X#include "city_icon7.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon7, icon7_image);
X
Xstatic short icon8_image[] = {
X#include "city_icon8.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(icon8, icon8_image);
X
Xstatic short fancy_icon1_image[] = {
X#include "fancy_icon1.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon1, fancy_icon1_image);
X
Xstatic short fancy_icon2_image[] = {
X#include "fancy_icon2.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon2, fancy_icon2_image);
X
Xstatic short fancy_icon3_image[] = {
X#include "fancy_icon3.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon3, fancy_icon3_image);
X
Xstatic short fancy_icon4_image[] = {
X#include "fancy_icon4.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon4, fancy_icon4_image);
X
Xstatic short fancy_icon5_image[] = {
X#include "fancy_icon5.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon5, fancy_icon5_image);
X
Xstatic short fancy_icon6_image[] = {
X#include "fancy_icon6.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon6, fancy_icon6_image);
X
Xstatic short fancy_icon7_image[] = {
X#include "fancy_icon7.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon7, fancy_icon7_image);
X
Xstatic short fancy_icon8_image[] = {
X#include "fancy_icon8.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon8, fancy_icon8_image);
X
Xstatic short fancy_icon9_image[] = {
X#include "fancy_icon9.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon9, fancy_icon9_image);
X
Xstatic short fancy_icon10_image[] = {
X#include "fancy_icon10.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon10, fancy_icon10_image);
X
Xstatic short fancy_icon11_image[] = {
X#include "fancy_icon11.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon11, fancy_icon11_image);
X
Xstatic short fancy_icon12_image[] = {
X#include "fancy_icon12.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon12, fancy_icon12_image);
X
Xstatic short fancy_icon13_image[] = {
X#include "fancy_icon13.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon13, fancy_icon13_image);
X
Xstatic short fancy_icon14_image[] = {
X#include "fancy_icon14.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon14, fancy_icon14_image);
X
Xstatic short fancy_icon15_image[] = {
X#include "fancy_icon15.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon15, fancy_icon15_image);
X
Xstatic short fancy_icon16_image[] = {
X#include "fancy_icon16.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon16, fancy_icon16_image);
X
Xstatic short fancy_icon17_image[] = {
X#include "fancy_icon17.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon17, fancy_icon17_image);
X
Xstatic short fancy_icon18_image[] = {
X#include "fancy_icon18.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon18, fancy_icon18_image);
X
Xstatic short fancy_icon19_image[] = {
X#include "fancy_icon19.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon19, fancy_icon19_image);
X
Xstatic short fancy_icon20_image[] = {
X#include "fancy_icon20.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon20, fancy_icon20_image);
X
Xstatic short fancy_icon21_image[] = {
X#include "fancy_icon21.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon21, fancy_icon21_image);
X
Xstatic short fancy_icon22_image[] = {
X#include "fancy_icon22.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon22, fancy_icon22_image);
X
Xstatic short fancy_icon23_image[] = {
X#include "fancy_icon23.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon23, fancy_icon23_image);
X
Xstatic short fancy_icon24_image[] = {
X#include "fancy_icon24.h"
X};
XMARKS_OWN_DEFINE_ICON_FROM_IMAGE(fancy_icon24, fancy_icon24_image);
X
XICON_TYPE fancy_icon_list[] = {
X	(ICON_TYPE)&fancy_icon1,
X	(ICON_TYPE)&fancy_icon2,
X	(ICON_TYPE)&fancy_icon3,
X	(ICON_TYPE)&fancy_icon4,
X	(ICON_TYPE)&fancy_icon5,
X	(ICON_TYPE)&fancy_icon6,
X	(ICON_TYPE)&fancy_icon7,
X	(ICON_TYPE)&fancy_icon8,
X	(ICON_TYPE)&fancy_icon9,
X	(ICON_TYPE)&fancy_icon10,
X	(ICON_TYPE)&fancy_icon11,
X	(ICON_TYPE)&fancy_icon12,
X	(ICON_TYPE)&fancy_icon13,
X	(ICON_TYPE)&fancy_icon14,
X	(ICON_TYPE)&fancy_icon15,
X	(ICON_TYPE)&fancy_icon16,
X	(ICON_TYPE)&fancy_icon17,
X	(ICON_TYPE)&fancy_icon18,
X	(ICON_TYPE)&fancy_icon19,
X	(ICON_TYPE)&fancy_icon20,
X	(ICON_TYPE)&fancy_icon21,
X	(ICON_TYPE)&fancy_icon22,
X	(ICON_TYPE)&fancy_icon23,
X	(ICON_TYPE)&fancy_icon24,
X	};
X
Xint MAX_FANCY_ICON = sizeof(fancy_icon_list)/sizeof(ICON_TYPE);
X
X
XICON_TYPE icon_list[] = {
X	(ICON_TYPE)&icon1,
X	(ICON_TYPE)&icon2,
X	(ICON_TYPE)&icon3,
X	(ICON_TYPE)&icon4,
X	(ICON_TYPE)&icon5,
X	(ICON_TYPE)&icon6,
X	(ICON_TYPE)&icon7,
X	(ICON_TYPE)&icon8
X	};
X
Xint MAX_ICON = sizeof(icon_list)/sizeof(ICON_TYPE);
X
Xstatic int ICON_USECS = 500000;
Xstatic int ICON_SECS = 0;
Xstatic int icon_update_time = 5;
Xstatic int icon_update_type = 1;
X
Xstatic int icon_no = 0;
X
Xinit_icons()
X{
X	extern int starting_icon;
X	extern int starting_icon_time;
X	icon_update_type = starting_icon;
X	icon_update_time = starting_icon_time;
X}
X
X/*
X * Update the icon through a rotating list of possible pixrects.
X * Started from within the file main.c when  a window close event
X * is detected.
X */
XNotify_value
Xupdate_icon()
X{
X	extern int running_icon_pictures;
X	switch (icon_update_type) {
X		case 0: break;
X		case 1: {
X			icon_no = (icon_no + 1) % MAX_ICON;
X			window_set(controlframe, FRAME_ICON, icon_list[icon_no], 0);
X			break;
X		}
X		case 2: {
X			icon_no = (icon_no + 1) % MAX_FANCY_ICON;
X			window_set(controlframe, FRAME_ICON, fancy_icon_list[icon_no], 0);
X			break;
X		}
X	}
X	if (running_icon_pictures) {
X		ICON_SECS = icon_update_time / 10;
X		ICON_USECS = (icon_update_time % 10) * 100000;
X		do_with_delay(update_icon, ICON_SECS, ICON_USECS);
X	}
X	return NOTIFY_DONE;
X}
X
Xstatic Frame icon_option_frame;
X
Xicon_option_done()
X{
X	window_set(icon_option_frame, FRAME_NO_CONFIRM, TRUE, 0);
X	window_destroy(icon_option_frame);
X	icon_option_frame = 0;
X	resume_proc();
X}
X
Xicon_update_time_proc(item, value, event)
XPanel_item item;
Xint value;
XEvent *event;
X{
X	icon_update_time = value;
X}
X
Xicon_update_type_proc(item, value, event)
XPanel_item item;
Xint value;
XEvent *event;
X{
X	icon_update_type = value;
X	if (icon_update_type == 0) {
X		window_set(controlframe, FRAME_ICON, icon_list[0], 0);
X	}
X}
X
X/*
X * Called as a notify proc from the main control panel.
X */
Xicon_option_proc()
X{
X	extern int starting_icon;
X	extern struct pixfont *buttonfont; /* use 'struct pixfont' for 3.0 compatiblity */
X	Panel panel, make_popup_panel();
X	if ((panel = make_popup_panel("     SDI Icon Options", NULL)) == NULL) {
X		return;
X	}
X	(void) panel_create_item(panel, PANEL_CYCLE,
X		PANEL_LABEL_STRING, " Icon:",
X		PANEL_CHOICE_STRINGS, "Plain", "Subtle", "Wild", 0,
X		PANEL_VALUE, icon_update_type,
X		PANEL_NOTIFY_PROC, icon_update_type_proc,
X		0);
X	(void) panel_create_item(panel, PANEL_SLIDER,
X		PANEL_NOTIFY_LEVEL, PANEL_ALL,
X		PANEL_NOTIFY_PROC, icon_update_time_proc,
X		PANEL_ITEM_X, ATTR_COL(0),
X		PANEL_ITEM_Y, ATTR_ROW(1),
X		PANEL_LABEL_STRING, "Icon update (tenths of secs): ", 
X		PANEL_NOTIFY_LEVEL, PANEL_ALL,
X		PANEL_SLIDER_WIDTH, 100,
X		PANEL_MIN_VALUE, 1,
X		PANEL_MAX_VALUE, 50,
X		PANEL_SHOW_RANGE, FALSE,
X		PANEL_SHOW_VALUE, TRUE,
X		PANEL_VALUE, icon_update_time,
X		PANEL_SHOW_ITEM, TRUE,
X		0);
X	display_popup_panel(panel);
X	}
END_OF_icons.c
if test 9019 -ne `wc -c <icons.c`; then
    echo shar: \"icons.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f piemenu_track.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"piemenu_track.c\"
else
echo shar: Extracting \"piemenu_track.c\" \(9938 characters\)
sed "s/^X//" >piemenu_track.c <<'END_OF_piemenu_track.c'
X#include <pixrect/pixrect_hs.h>
X#include <sunwindow/notify.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <math.h>
X#include "walkmenu_impl.h"
X#include "image_impl.h"
X#undef min
X#undef max
X#undef fabs
X
X/*
X * Copyright 1987 by Mark Weiser.
X * Permission to reproduce and use in any manner whatsoever on Suns is granted
X * so long as this copyright and other identifying marks of authorship
X * in the code and the game remain intact and visible.  Use of this code
X * in other products is reserved to me--I'm working on Mac and IBM versions.
X */
X
X
X/*
X * Preliminary implementation of pie menus (Patent Applied for.)
X */
X
X#ifndef M_PI
X#define M_PI	3.14159265358979323846
X#endif
X
Xstatic short pie_cursor_array[] = {
X#include "pie_generic_cursor.h"
X};
Xmpr_static(pie_generic_cursor, 16, 16, 1, pie_cursor_array);
X
Xdouble fabs();
X
Xint dead_zone = 5;	/* this is not used consistently. */
X
Xstatic Notify_value main_event_proc();
X
Xdouble angle, fabs(), fmin(), fmax();
X
Xstruct menu_item *menu_track_helper();
X
Xstatic int done;
Xstatic caddr_t done_val;
Xstatic Frame mainframe;
Xstatic Canvas maincanvas;
Xstatic int (*return_proc)();
X
Xstruct menu_item *
Xpie_menu(m, event, x, y, w, f, s)
Xstruct menu *m;
XEvent *event;
XWindow w;
Xint (*f)();
Xchar *s;
X{
X	struct menu_item *value;
X
X	construct_pie_frame(w, x, y, m, s);
X
X	window_set(mainframe, WIN_SHOW, TRUE, 0);
X
X	return_proc = f;
X}
X
Xconstruct_pie_frame(w, x, y, m, s)
XWindow w;
Xstruct menu *m;
Xchar *s;
X{
X	int width, height;
X	int max_len;
X	Pixwin *pw;
X	if (m->default_image.font == NULL)
X		m->default_image.font = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.b.12");
X	if (m->default_image.font == NULL)
X		m->default_image.font = pf_default();
X
X	max_len = pie_process_args(m);
X	m->default_image.width = m->default_image.height = 3.5*(float)max_len+dead_zone + 1;
X
X	mainframe = window_create(w, FRAME,
X		FRAME_LABEL, s,
X		FRAME_SHOW_LABEL, TRUE,
X		FRAME_NO_CONFIRM, TRUE,
X		0);
X
X	maincanvas = window_create(mainframe, CANVAS,
X		WIN_WIDTH, m->default_image.width,
X		WIN_HEIGHT, m->default_image.height,
X		WIN_CLIENT_DATA, m,
X#ifndef SUNOS3_0
X		WIN_GRAB_ALL_INPUT, TRUE,
X#endif
X		WIN_CONSUME_PICK_EVENT, WIN_IN_TRANSIT_EVENTS, 0,
X		0);
X	window_set(maincanvas,
X		WIN_EVENT_PROC, main_event_proc,
X		0);
X	window_fit(mainframe);
X	(Pixwin *)m->default_image.pr = pw = canvas_pixwin(maincanvas);
X	(Canvas)m->dynamic_info = maincanvas;
X
X	window_set(mainframe, 
X		WIN_X, x - m->default_image.width/2,
X		WIN_Y, y - m->default_image.height/2,
X		0);
X
X	init_pies(m, pw);
X	new_cursor(0.0, -1);
X}
X
X#define DESELECT_ON_EXIT
X
Xstatic Notify_value
Xmain_event_proc(win, event, arg)
XWindow win;
XEvent *event;
Xcaddr_t arg;
X{
X	struct menu *m = (struct menu *)window_get(win, WIN_CLIENT_DATA);
X	Pixwin *pw = (Pixwin *)m->default_image.pr;
X	int id = event_id(event);
X	int x = event_x(event);
X	int y = event_y(event);
X	int x_inc, y_inc;
X	double theta;
X	double inc = 2.0*M_PI/m->nitems;
X	int i;
X	int pie_x = m->default_image.width/2;
X	int pie_y = m->default_image.height/2;
X	static outside_window = 0;
X
X	if (id == WIN_RESIZE) {
X		window_set(win, WIN_MOUSE_XY, pie_x, pie_y, 0);
X	}
X
X	
X	if ((!outside_window && (id == LOC_MOVE || event_is_button(event)))
X		|| id == LOC_WINENTER || id == LOC_RGNENTER) {
X		outside_window = 0;
X		x_inc = pie_x - x;
X		y_inc = pie_y - y;
X		if (abs(x_inc) > dead_zone || abs(y_inc) > dead_zone ||
X			(int)sqrt((double)(x_inc*x_inc + y_inc*y_inc)) > dead_zone) {
X			/* Found an item */
X			theta = M_PI + atan2((double)x_inc, (double)y_inc);
X			i = ((theta+inc)/inc) - 1;
X			if (i >= m->nitems)
X				i = m->nitems - 1;
X			if (i != m->selected_position) {
X				/* Remove old highlighting, if any */
X				if (m->selected_position != -1) 
X					draw_item(pw, m, PIX_SRC, m->selected_position );
X				/* Highlight new selection */
X				m->selected_position = i;
X				draw_item(pw, m, PIX_NOT(PIX_SRC), m->selected_position);
X			}
X		} else if (m->selected_position != -1) {
X			/* Remove old highlighting */
X			draw_item(pw, m, PIX_SRC, m->selected_position);
X			m->selected_position = -1;
X		}
X	}
X	else if (id == LOC_WINEXIT || id == LOC_RGNEXIT) {
X#ifdef SUNOS3_0
X#ifdef DESELECT_ON_EXIT
X#undef DESELECT_ON_EXIT
X#endif
X#define DESELECT_ON_EXIT
X#endif
X#ifdef DESELECT_ON_EXIT
X		outside_window = 1;
X		if (m->selected_position != -1) {
X			/* Remove old highlighting */
X			draw_item(pw, m, PIX_SRC, m->selected_position);
X			m->selected_position = -1;
X		}
X		m->selected_position = -1;
X#else SELECT_ON_EXIT
X		if (m->selected_position == -1) {
X			pie_window_return(NULL, event, m);
X		} else {
X			pie_window_return(m->item_list[m->selected_position], event,m);
X		}
X#endif
X	}
X	if (event_is_up(event) && event_is_button(event)) {
X		/* Selecting an item */
X		Frame owner = (Frame)window_get(m->dynamic_info, WIN_OWNER);
X		if (m->selected_position == -1) {
X			if (m->parent) {
X				/* finished a subwindow without a selection */
X				window_set(win, WIN_CLIENT_DATA, m->parent->parent, 0);
X				/* this breaks: window_done(owner); */
X				/* and for some reason, this leaves the window visible: */
X				window_set(owner, WIN_SHOW, FALSE, 0);
X			} else {
X				/* this is the top */
X				pie_window_return(NULL, event,m);
X			}
X		} else if (! m->item_list[m->selected_position]->pullright) {
X			pie_window_return(m->item_list[m->selected_position], event,m);
X		} else {
X/*	nesting temporarily disabled
X			Frame newframe;
X			struct menu *newm = (struct menu *)m->item_list[m->selected_position]->value;
X			newframe = construct_pie_frame(x+window_get(owner, WIN_X),
X				y+window_get(owner, WIN_Y), newm, 0);
X			window_set(win, WIN_CLIENT_DATA, newm, 0);
X			window_set(newframe, WIN_SHOW, TRUE, 0);
X*/
X		}
X	}
X	new_cursor(m->selected_position*inc+(inc/2.0), m->selected_position);
X	return NOTIFY_DONE;
X}
X
Xstatic int
Xpie_process_args(m)
Xstruct menu *m;
X{
X	int itemnum = 0;
X	struct menu_item **argv = m->item_list;
X	struct pr_size size;
X	int max_len = 0;
X	while (itemnum++ < m->nitems) {
X		struct image *im = (*argv)->image;
X		if (im->pr) {
X			/* got an image */
X			size = im->pr->pr_size;
X		} else {
X			if (! im->string) {
X				im->string = "(null)";
X			}
X			size = pf_textwidth(strlen(im->string), m->default_image.font, im->string);
X		}
X		im->width = size.x;
X		im->height = size.y;
X		if (size.x > max_len)
X			max_len = size.x;
X		if (size.y > max_len)
X			max_len = size.y;
X		argv++;
X	}
X	return max_len;
X}
X
X/* center for 5 bit radius deadzone */
Xshort center_data[] = {
X#include "center.h"
X};
Xmpr_static(center_pr, 11, 11, 1, center_data);
X
X/* Serious abuse of the image structure here.
X   'left_margin' is used to store the x position
X   'right_margin' is used to store the y position
X*/
X
Xinit_pies(m, pw)
Xstruct menu *m;
XPixwin *pw;
X{
X	struct menu_item **pies = m->item_list;
X	double diameter = (double)m->default_image.width;
X	double fr = diameter/2;
X	double fr2 = fr/2.0;
X	int i;
X	double inc = 2.0*M_PI/(double)m->nitems;
X	double theta = inc/2.0;
X	for(i = 0; i < m->nitems; i++) {
X		/* compute x position of upper lefthand corner */
X		pies[i]->image->left_margin = fmax(0.0, 
X			fmin((double)(diameter-pies[i]->image->width+2), 
X				fmax(2.0,
X					fr*sin(theta) + fr - pies[i]->image->width/2)));
X		/* compute y position of upper lefthand corner */
X		pies[i]->image->right_margin = fmax(0.0,
X			fmin((double)(diameter-pies[i]->image->height-2),
X				fmax(2.0,
X					fr*cos(theta) + fr - pies[i]->image->height/2)));
X		theta += inc;
X		draw_item(pw, m, PIX_SRC, i);
X	}
X	pw_rop(pw, m->default_image.width/2-5, m->default_image.height/2-5, 11, 11, PIX_SRC, &center_pr, 0, 0);
X}
X
Xstatic min(x,y)
X{
Xreturn x < y ? x : y;
X}
X
Xstatic max(x,y)
X{
Xreturn x < y ? y : x;
X}
X
Xdouble
Xfabs(x)
Xdouble x;
X{
X	return x < 0 ? -x : x;
X}
X
Xdouble
Xfmin(x,y)
Xdouble x, y;
X{
Xreturn x < y ? x : y;
X}
X
Xdouble
Xfmax(x,y)
Xdouble x, y;
X{
Xreturn x < y ? y : x;
X}
X
Xdraw_item(pw, m, op, item)
XPixwin *pw;
Xstruct menu *m;
Xint item;
X{
X	struct image *im = m->item_list[item]->image;
X	if (im->pr) {
X		pw_rop(pw,
X			im->left_margin,
X			im->right_margin,
X			im->width,
X			im->height,
X			op, im->pr, 0, 0);
X	} else {
X		pw_text(pw,
X			im->left_margin,
X			im->right_margin + im->height, /* text posn is from baseline */
X			op, m->default_image.font, im->string);
X	}
X}
X
X/* Why all the extra levels of function calls?  Well, at one time
X   they all added value.  But as the organization changed, more
X   and action got pressed into the event_procs, and hollow shells
X   were left up here.  They could be removed...
X*/
Xstruct menu_item *
Xmenu_track(m, w, event, f, s)
Xstruct menu *m;
XEvent *event;
XWindow w;
Xint (*f)();
X{
X	struct menu_item *rval;
X	rval = pie_menu(m, event, event_x(event), event_y(event), w, f, s);
X	return rval;
X}
X
Xpie_window_return(rval,e,m)
Xcaddr_t rval;
XEvent *e;
Xstruct menu *m;
X{
X	caddr_t real_rval;
X	window_set(mainframe, FRAME_NO_CONFIRM, TRUE, 0);
X	window_destroy(mainframe);
X	if (rval == NULL)
X		real_rval = (caddr_t)rval;
X	if (! m->notify_proc) {
X		real_rval = (caddr_t)MENU_DEFAULT_NOTIFY_PROC(m, rval);
X	} else {
X		real_rval = (caddr_t)(m->notify_proc)(m, rval);
X	}
X	(*return_proc)(real_rval, e);
X}
X
X#define PIN(x) (max(0,min((x),15)))
X
Xnew_cursor(theta, item_num)
Xdouble theta;
Xint item_num;
X{
X	int headx, heady;
X	Cursor cursor = window_get(maincanvas, WIN_CURSOR);
X	struct pixrect *pr = (struct pixrect *)cursor_get(cursor, CURSOR_IMAGE);
X	if (item_num == -1) {
X		pr_rop(pr, 0, 0, 16, 16, PIX_SRC, &pie_generic_cursor, 0, 0);
X		cursor_set(cursor, CURSOR_XHOT, 8, CURSOR_YHOT, 8, 0);
X	} else {
X		pr_rop(pr, 0, 0, 16, 16, PIX_SRC, NULL, 0, 0);
X		pr_vector(pr, 8+(int)(sin(theta)*(double)20.0), 8+(int)(cos(theta)*(double)20.0),
X			8+(int)(sin(theta)*(double)(-20.0)), 8+(int)(cos(theta)*(double)(-20.0)),
X			PIX_SRC, 1);
X		headx = PIN(7+(int)(sin(theta)*(double)8.0));
X		heady = PIN(7+(int)(cos(theta)*(double)8.0));
X		pr_rop(pr, headx, heady, 3, 3, PIX_NOT(PIX_SRC), NULL, 0, 0);
X		cursor_set(cursor, CURSOR_XHOT, headx, CURSOR_YHOT, heady, 0);
X	}
X	cursor_set(cursor, CURSOR_IMAGE, pr, 0);
X	window_set(maincanvas, WIN_CURSOR, cursor, 0);
X}
END_OF_piemenu_track.c
if test 9938 -ne `wc -c <piemenu_track.c`; then
    echo shar: \"piemenu_track.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 6\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0