xonix-1.4/ 40755 153 7 0 6026014146 7617 5ustar jbinxonix-1.4/Imakefile100644 153 7 2230 6026013550 11520 0ustar jbin# # Imakefile,v 1.13 1995/09/14 11:52:08 j Exp # #ifndef SharedLibXpm #define SharedLibXpm HasSharedLibraries #endif XCOMM actually, not, but it doesn't matter XPMSRC = $(LIBSRC)/Xpm #if SharedLibXpm #ifndef SharedXpmRev #define SharedXpmRev 4.5 /* current SO revision (Xpm 3.4e) */ #endif SharedLibReferences(XPM,Xpm,$(XPMSRC),SOXPMREV,SharedXpmRev) #else UnsharedLibReferences(XPM,Xpm,$(XPMSRC)) #endif #define XpmDepLib $(XPMDEPLIB) #define XpmLib $(XPMLIB) PROG = xonix XONIXDIR = $(LIBDIR)/xonix CUTE = -DSEND_MAIL /* cute feature :-) */ DEPLIBS = XawClientDepLibs XpmDepLib LOCAL_LIBRARIES = XawClientLibs XpmLib MathLibrary EXTRA_DEFINES = -DUSE_X11 -DXONIXDIR=\"$(XONIXDIR)\" $(CUTE) /* CDEBUGFLAGS = DebuggableCDebugFlags */ SRCS = xonix.c x11.c stack.c OBJS = xonix.o x11.o stack.o ComplexProgramTarget($(PROG)) InstallAppDefaults(Xonix) /* * MakeDirectories() cannot be used due to the umask 0 requirement. */ install:: @umask 0; \ if [ -d $(DESTDIR)$(XONIXDIR) ] ; then \ exit 0 ; \ else \ ( set -x ; $(MKDIRHIER) $(DESTDIR)$(XONIXDIR) ) ; \ fi xonix-1.4/Makefile.std100644 153 7 6256 6020320727 12155 0ustar jbin# # standard Makefile for xonix # # Makefile.std,v 1.2 1995/08/28 11:00:39 j Exp #PROJECTROOT= /usr PROJECTROOT= /usr/X11R6 LIBDIR= $(PROJECTROOT)/lib/X11 INCDIR= $(PROJECTROOT)/include BINDIR= $(PROJECTROOT)/bin MANDIR= $(PROJECTROOT)/man/man1/ INSTALL_EXE= install -c -s #INSTALL_EXE= cp INSTALL_DAT= install -c #INSTALL_DAT= cp RM= rm -f MAKEDIRHIER= mkdirhier #MAKEDIRHIER= mkdir -p PROG= xonix XONIXDIR= $(LIBDIR)/xonix CUTE= -DSEND_MAIL # cute feature :-) XAWLIBS= -lXaw -lXmu -lXt -lX11 -lXt -lSM -lICE -lXExExt -lXext -lX11 XPMLIB= -lXpm SYSLIBS= -lm -lgnumalloc #COPTS= -O2 -pipe -m486 COPTS= -O EXTRA_DEFINES= -DUSE_X11 -DXONIXDIR=\"$(XONIXDIR)\" $(CUTE) INCLUDES= -I$(INCDIR) SRCS= xonix.c x11.c stack.c OBJS= xonix.o x11.o stack.o CFLAGS= $(COPTS) $(EXTRA_DEFINES) $(INCLUDES) $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) -L$(LIBDIR) \ $(XAWLIBS) $(XPMLIB) $(SYSLIBS) clean: $(RM) $(PROG) $(OBJS) install: $(INSTALL_EXE) $(PROG) $(BINDIR) $(INSTALL_DAT) Xonix.ad $(LIBDIR)/app-defaults/Xonix if [ -d $(XONIXDIR) ] ; then \ exit 0; \ else \ ( umask 0; $(MAKEDIRHIER) $(XONIXDIR) ) ; \ fi install.man: $(INSTALL_DAT) xonix.man $(MANDIR)/xonix.1 #################################################################### ## dependencies xonix.o: $(INCDIR)/X11/Xos.h $(INCDIR)/X11/Xosdefs.h xonix.o: $(INCDIR)/X11/Intrinsic.h xonix.o: $(INCDIR)/X11/Xlib.h $(INCDIR)/X11/X.h xonix.o: $(INCDIR)/X11/Xfuncproto.h /usr/include/stddef.h xonix.o: $(INCDIR)/X11/Xutil.h $(INCDIR)/X11/Xresource.h xonix.o: $(INCDIR)/X11/Core.h $(INCDIR)/X11/Composite.h xonix.o: $(INCDIR)/X11/Constraint.h $(INCDIR)/X11/Object.h xonix.o: $(INCDIR)/X11/RectObj.h stack.h x11.o: $(INCDIR)/X11/Xos.h $(INCDIR)/X11/Xosdefs.h x11.o: $(INCDIR)/X11/Intrinsic.h $(INCDIR)/X11/Xlib.h x11.o: $(INCDIR)/X11/X.h $(INCDIR)/X11/Xfuncproto.h x11.o: $(INCDIR)/X11/Xutil.h x11.o: $(INCDIR)/X11/Xresource.h $(INCDIR)/X11/Core.h x11.o: $(INCDIR)/X11/Composite.h $(INCDIR)/X11/Constraint.h x11.o: $(INCDIR)/X11/Object.h $(INCDIR)/X11/RectObj.h x11.o: $(INCDIR)/X11/StringDefs.h $(INCDIR)/X11/keysym.h x11.o: $(INCDIR)/X11/keysymdef.h $(INCDIR)/X11/Shell.h x11.o: $(INCDIR)/X11/SM/SMlib.h $(INCDIR)/X11/SM/SM.h x11.o: $(INCDIR)/X11/ICE/ICElib.h $(INCDIR)/X11/ICE/ICE.h x11.o: $(INCDIR)/X11/xpm.h xonix.xbm xonix_mask.xbm d0.xbm d1.xbm x11.o: d2.xbm d3.xbm d4.xbm d5.xbm d6.xbm d7.xbm d8.xbm d9.xbm colon.xbm x11.o: flyer.xpm runner.xpm eater.xpm empty.xpm way.xpm filled.xpm x11.o: $(INCDIR)/X11/Xaw/Form.h $(INCDIR)/X11/Xaw/Label.h x11.o: $(INCDIR)/X11/Xaw/Simple.h x11.o: $(INCDIR)/X11/Xmu/Converters.h x11.o: $(INCDIR)/X11/Xaw/Box.h $(INCDIR)/X11/Xaw/Command.h x11.o: $(INCDIR)/X11/Xaw/MenuButton.h x11.o: $(INCDIR)/X11/Xaw/SimpleMenu.h x11.o: $(INCDIR)/X11/Xaw/SmeLine.h $(INCDIR)/X11/Xaw/Sme.h x11.o: $(INCDIR)/X11/Xaw/SmeBSB.h patchlevel.h xonix.h stack.o: $(INCDIR)/X11/Xos.h stack.o: $(INCDIR)/X11/Xosdefs.h $(INCDIR)/X11/Intrinsic.h stack.o: $(INCDIR)/X11/Xlib.h $(INCDIR)/X11/X.h stack.o: $(INCDIR)/X11/Xfuncproto.h stack.o: $(INCDIR)/X11/Xutil.h $(INCDIR)/X11/Xresource.h stack.o: $(INCDIR)/X11/Core.h $(INCDIR)/X11/Composite.h stack.o: $(INCDIR)/X11/Constraint.h $(INCDIR)/X11/Object.h stack.o: $(INCDIR)/X11/RectObj.h stack.h xonix-1.4/Xonix.ad100644 153 7 6156 6020320730 11330 0ustar jbin! application resources ! the values shown are the defaults ! ! Xonix.ad,v 1.20 1995/08/28 11:00:40 j Exp ! ! step width between updates, in ms Xonix.timeStep: 50 ! default movement bindings *container.translations: #override\n\ Left: Left()\n\ Right: Right()\n\ Up: Up()\n\ Down: Down()\n\ Q: Quit()\n\ Escape: Quit()\n\ : Pause()\n\ P: Pause()\n\ : Continue() *container.background: lavender ! ! "game" menu ! *game_button.label: Game *game_button.background: dark green *game_button.foreground: yellow *game_menu*background: dark green *game_menu*foreground: yellow *game_menu.about.label: About... *game_menu.quit.label: Quit... ! ! the about box ! *about_shell.title: About xonix *about_shell*background: pale goldenrod *about_shell*foreground: black *about_shell*about_done.label: I see *about_shell*about_done.background: white ! ! the score box ! *score_shell.title: High score *score_shell*background: pale goldenrod *score_shell*foreground: black *score_shell*Label.borderWidth: 0 *score_shell*Box.borderWidth: 0 *score_shell*score_msg.label: Best Xonixers: *score_shell*score_headl.label: Score Level Date User ID Full name *score_shell*score_done.label: Great! *score_shell*score_done.background: white ! ! resources for the status display ! likely not to be changed *status*Label.borderWidth: 0 *status*Label.internalWidth: 0 *status*Label.internalHeight: 0 *status*Form.borderWidth: 0 *status.background: dim gray *status*Form.background: dim gray *status*Label.background: Yellow *status.percentage.perc_d10.horizDistance: 20 *status.percentage.perc_label.label: % filled: *status.percentage.perc_label.background: gray20 *status.percentage.perc_label.foreground: pale turquoise *status.level.lev_d10.horizDistance: 20 *status.level.lev_label.label: Level: *status.level.lev_label.background: gray20 *status.level.lev_label.foreground: pale turquoise *status.runner.run_d10.horizDistance: 20 *status.runner.run_label.label: Players: *status.runner.run_label.background: gray20 *status.runner.run_label.foreground: pale turquoise *status.time.mins_d10.horizDistance: 20 *status.time.time_label.label: Score: *status.time.time_label.background: gray20 *status.time.time_label.foreground: pale turquoise ! ! the game over dialog ! *gameover_shell.title: Pity! *gameover_box.background: khaki *gameover_box.orientation: vertical *gameover_buttonbox.orientation: horizontal *gameover_buttonbox.background: khaki *gameover_buttonbox.borderWidth: 0 *gameover_msg.label: Game over, dude! *gameover_msg.font: -*-new century schoolbook-bold-i-*-*-*-180-*-*-*-*-*-* *gameover_msg.borderWidth: 0 *gameover_msg.foreground: sienna *gameover_msg.background: khaki *gameover_iknow.label: I know :-( *gameover_iknow.foreground: light yellow *gameover_iknow.background: dark orchid *gameover_iknow.accelerators: #augment \ Q: set() notify() unset() \n\ Escape: set() notify() unset() *gameover_goon.label: Once more! :) *gameover_goon.foreground: light yellow *gameover_goon.background: dark orchid *gameover_goon.accelerators: #augment \ Return: set() notify() unset() xonix-1.4/colon.xbm100644 153 7 1030 5751362646 11547 0ustar jbin#define colon_width 10 #define colon_height 36 static unsigned char colon_bits[] = { 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xc7, 0x03, 0x83, 0x03, 0xc7, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xc7, 0x03, 0x83, 0x03, 0xc7, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03}; xonix-1.4/d0.xbm100644 153 7 1360 5747202412 10733 0ustar jbin#define d0_width 24 #define d0_height 36 static unsigned char d0_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xd0, 0x09, 0x00, 0xc8, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf9, 0xff, 0xcf, 0xfd, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xdf, 0xf9, 0xff, 0xcf, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0x09, 0x00, 0xc8, 0x05, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d1.xbm100644 153 7 1360 5747202413 10735 0ustar jbin#define d1_width 24 #define d1_height 36 static unsigned char d1_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d2.xbm100644 153 7 1360 5747202414 10737 0ustar jbin#define d2_width 24 #define d2_height 36 static unsigned char d2_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0x0f, 0x00, 0xc8, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0x07, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xf0, 0xf9, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x09, 0x00, 0xf8, 0x05, 0x00, 0xf0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d3.xbm100644 153 7 1360 5747202415 10741 0ustar jbin#define d3_width 24 #define d3_height 36 static unsigned char d3_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0x0f, 0x00, 0xc8, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0x07, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0x0f, 0x00, 0xc8, 0x07, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d4.xbm100644 153 7 1360 5747202417 10744 0ustar jbin#define d4_width 24 #define d4_height 36 static unsigned char d4_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xdf, 0xf9, 0xff, 0xcf, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf9, 0xff, 0xcf, 0x05, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d5.xbm100644 153 7 1360 5747202420 10737 0ustar jbin#define d5_width 24 #define d5_height 36 static unsigned char d5_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xf0, 0x09, 0x00, 0xf8, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x05, 0x00, 0xf0, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0x0f, 0x00, 0xc8, 0x07, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d6.xbm100644 153 7 1360 5747202421 10741 0ustar jbin#define d6_width 24 #define d6_height 36 static unsigned char d6_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xf0, 0x09, 0x00, 0xf8, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x05, 0x00, 0xf0, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xd0, 0xf9, 0xff, 0xcf, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0x09, 0x00, 0xc8, 0x05, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d7.xbm100644 153 7 1360 5747202422 10743 0ustar jbin#define d7_width 24 #define d7_height 36 static unsigned char d7_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0x0f, 0x00, 0xc8, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d8.xbm100644 153 7 1360 5747202423 10745 0ustar jbin#define d8_width 24 #define d8_height 36 static unsigned char d8_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xd0, 0x09, 0x00, 0xc8, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf9, 0xff, 0xcf, 0x05, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xd0, 0xf9, 0xff, 0xcf, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0x09, 0x00, 0xc8, 0x05, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/d9.xbm100644 153 7 1360 5747202424 10747 0ustar jbin#define d9_width 24 #define d9_height 36 static unsigned char d9_bits[] = { 0xff, 0xff, 0xff, 0x03, 0x00, 0xe0, 0x05, 0x00, 0xd0, 0x09, 0x00, 0xc8, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf1, 0xff, 0xc7, 0xf9, 0xff, 0xcf, 0x05, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0x07, 0x00, 0xd0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0x0f, 0x00, 0xc8, 0x07, 0x00, 0xd0, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xonix-1.4/eater.xpm100644 153 7 163 5751362647 11542 0ustar jbin/* XPM */ static char * eater_xpm[] = { "4 4 2 1", " c goldenrod", ". c yellow", " .. ", "....", "....", " .. "}; xonix-1.4/empty.xpm100644 153 7 2360 6017332025 11600 0ustar jbin/* XPM */ static char * empty_xpm[] = { "32 32 3 1", " c green yellow", ". c forest green", "X c lime green", " ...............................", "........... ....................", "......................X.........", "................................", ".....X............ .............", "....X...........................", "................................", ".........X......................", "............................... ", "................................", "................................", ".................X......X.......", "........................X.......", "........................X.......", "..........X.....................", "... ............................", "................................", "................................", "................................", "............ ......X............", "...............................X", "...X............................", "................................", "................................", "........................... ....", ".............X..................", "................................", ". ..........X...................", "...........X....................", "................................", "...X..................X.....X...", "...X............................"}; xonix-1.4/filled.xpm100644 153 7 2352 6017332025 11702 0ustar jbin/* XPM */ static char * filled_xpm[] = { "32 32 3 1", " c green yellow", ". c brown", "X c lime green", " ...............................", "........... ....................", "......................X.........", "................................", ".....X............ .............", "....X...........................", "................................", ".........X......................", "............................... ", "................................", "................................", ".................X......X.......", "........................X.......", "........................X.......", "..........X.....................", "... ............................", "................................", "................................", "................................", "............ ......X............", "...............................X", "...X............................", "................................", "................................", "........................... ....", ".............X..................", "................................", ". ..........X...................", "...........X....................", "................................", "...X..................X.....X...", "...X............................"}; xonix-1.4/flyer.xpm100644 153 7 315 5751362650 11554 0ustar jbin/* XPM */ static char * flyer_xpm[] = { "8 8 3 1", " c forest green", ". g4 yellow c tomato", "X c black", " .. ", " .XX. ", " ...... ", " .X..X. ", " ...... ", " ..XX.. ", " .... ", " .XX. "}; xonix-1.4/mac.c100644 153 7 217654 6024011037 10671 0ustar jbin/* Hey emacs, this is -*- Mode: C++; tab-width: 4 -*- */ #ifdef USE_MAC /* * mac.c * * Macintosh interface for the xonix game * * mac.c,v 1.18 1995/09/08 09:51:27 j Exp */ /* * Copyright (c) 1995 * Torsten Schoenitz * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ------------------------------------------------------------------------ */ /* Die #include-Statements binden die Interface-Dateien der benoetigten */ /* Manager in den Quelltext ein. */ /* ------------------------------------------------------------------------ */ #include "xonix.h" #include /* Wegen der Zufaelligkeiten */ #include #include #include #include /* ------------------------------------------------------------------------ */ /* Resource-IDs. */ /* ------------------------------------------------------------------------ */ #define BASE_RES_ID 400 /* Basis-Ressource-ID */ #define rMenuBar BASE_RES_ID /* MBAR-Resource. */ #define rPrefs BASE_RES_ID /* Preferences */ #define rAboutDialog BASE_RES_ID /* "Ueber xonix..."-Dialog */ #define rEndOfGameDialog BASE_RES_ID+2 /* Spielende-Dialog */ #define rNoRamDialog BASE_RES_ID+3 /* Speicher reicht nicht */ #define rKeyPrefsDialog BASE_RES_ID+4 /* Tastenbelegung */ #define rHallOfFameDialog BASE_RES_ID+5 /* HighScore-Dialog */ #define rCongratulation BASE_RES_ID+6 /* Gratulation und Namen-Eingabe*/ #define rWinnersList BASE_RES_ID+7 /* HighScore-Liste */ #define rHints1 BASE_RES_ID+8 /* Tips & Hinweise 1 */ #define rHints2 BASE_RES_ID+9 /* Tips & Hinweise 2 */ #define rBackgroundInfo BASE_RES_ID+10 /* HintergrŸndiges */ /* Menu - IDs */ #define mApple BASE_RES_ID /* "Apple"-Menue */ #define mFile BASE_RES_ID+1 /* "Ablage"-Menue */ #define mEdit BASE_RES_ID+2 /* "Bearbeiten"-Menue */ #define mPrefs BASE_RES_ID+3 /* "Einstellungen"-Menue */ #define mInfos BASE_RES_ID+4 /* "Infos"-Menue */ /* "Apple"-Menuepunkte. */ #define iAbout 1 /* "Ueber xonix...". */ /* "Ablage"-Menuepunkte. */ #define iNew 1 /* "Neu". */ #define iOpen 2 /* "Oeffnen..". */ #define iClose 4 /* "Schliessen". */ #define iSave 5 /* "Sichern". */ #define iSaveAs 6 /* "Sichern unter...". */ #define iPageSetup 7 /* "Seitenformat...". */ #define iPrint 9 /* "Drucken...". */ #define iQuit 11 /* "Beenden". */ /* "Bearbeiten"-Menuepunkte. */ #define iUndo 1 /* "Widerrufen". */ #define iCut 3 /* "Ausschneiden". */ #define iCopy 4 /* "Kopieren". */ #define iPaste 5 /* "Einsetzen". */ #define iClear 6 /* "Loeschen". */ #define iClipBoard 8 /* "Zwischenablage zeigen". */ /* "Einstellungen"-Menuepunkte. */ #define iKeyPrefs 1 /* "Tastenbelegung". */ #define iSound 2 /* "Sound EIN" bzw. "Sound AUS" */ #define iPictures 3 /* "Bilder EIN" / "Bilder AUS" */ #define iShowHighScore 4 /* "Zeige HighScore" */ #define iResetHighScore 5 /* "Lšsche HighScore" */ /* "Infos"-Menueunkte. */ #define iHints 1 /* "Tips & Hinweise". */ #define iBackgroundInfo 2 /* "HintergŸndiges". */ /* Dialog-Items */ #define iMyName 3 /* Name zum Eintragen in HOF */ #define iWinnerName 4 /* Item-Nr. 1.Platz in HOF */ /* PICT-Ressourcen */ #define rScoreLabel BASE_RES_ID+6 /* Label fuer Punkte-Anzeige */ #define rLevelLabel BASE_RES_ID+7 /* Label fuer Level-Anzeige */ #define rPercentLabel BASE_RES_ID+8 /* Label fuer Fuellstand-Anzeige*/ #define rPlayerLabel BASE_RES_ID+9 /* Label fuer Player-Anzeige */ #define rDigit0 BASE_RES_ID+10 /* Die Digits der 7-Segment- */ #define rDigit1 rDigit0+1 /* Anzeige */ #define rDigit2 rDigit0+2 #define rDigit3 rDigit0+3 #define rDigit4 rDigit0+4 #define rDigit5 rDigit0+5 #define rDigit6 rDigit0+6 #define rDigit7 rDigit0+7 #define rDigit8 rDigit0+8 #define rDigit9 rDigit0+9 /* ppat-Ressourcen */ #define rEmptyPattern BASE_RES_ID /* Pattern fŸr EMPTY */ #define rFilledPattern BASE_RES_ID+1 /* Pattern fŸr FILLED */ #define rRunnerPattern BASE_RES_ID+2 /* Pattern fŸr RUNNER */ #define rFlyerPattern BASE_RES_ID+3 /* Pattern fŸr FLYER */ #define rEaterPattern BASE_RES_ID+4 /* Pattern fŸr EATER */ #define rWayPattern BASE_RES_ID+5 /* Pattern fŸr WAY */ #define rStatusPattern BASE_RES_ID+20 /* Pattern fŸr Statusanzeige */ /* CICN-Ressourcen */ #define rRunnerIcon BASE_RES_ID+2 #define rFlyerIcon BASE_RES_ID+3 #define rRunnerIconPlain BASE_RES_ID+4 /* snd-Ressourcen */ #define rEndOfGameSound BASE_RES_ID #define rRunnerDieSound BASE_RES_ID+1 /* STR-Ressourcen */ #define rHighScore BASE_RES_ID+200 #define rDefaultHighScore BASE_RES_ID+230 /* STR#-Ressourcen */ #define STRING_LIST BASE_RES_ID #define PREF_STRING_INDEX 1 /* KBRS-Ressourcen */ #define rKeyboardPrefs BASE_RES_ID #define HILITE_DELAY 8L #define PICTURES_OFFSET 0 #define HIGHSCORE_ITEMS 10 #define NO_PICTURES_OFFSET 10 #define MAX_PIXEL_DEPTH 8 #define NIL_POINTER 0L #define NO_FLAGS 0L #define VISIBLE TRUE #define INVISIBLE FALSE #define NO_GOAWAY TRUE #define MOVE_TO_FRONT (WindowPtr) -1L #define STATUS_BORDER_WIDTH 5 #define STATUS_BORDER_HEIGHT 2 #define DIGIT_SPACE 2 #define CR_CHAR 0x0d #define ENTER_CHAR 0x03 #define TAB_CHAR 0x09 #define ESC_CHAR 0x1b #define LEFT_CHAR 0x1c #define RIGHT_CHAR 0x1d #define UP_CHAR 0x1e #define DOWN_CHAR 0x1f #define OK_BUTTON 1 #define CANCEL_BUTTON 2 #define ENDE_BUTTON 2 #define NOCHMAL_BUTTON 1 #define WEITER_BUTTON 1 #define KEY_UP_ITEM 3 #define KEY_RIGHT_ITEM 4 #define KEY_DOWN_ITEM 5 #define KEY_LEFT_ITEM 6 #define SOUND_ITEM 7 #define PICTURES_ITEM 8 /* ------------------------------------------------------------------------ */ /* Deklaration der globalen Variablen. */ /* ------------------------------------------------------------------------ */ EventRecord gEvent; /* Die Variable gEvent enthaelt */ /* den aktuellen EventRecord */ /* (Informationen ueber den auf-*/ /* getretenen Event). */ Boolean gGotEvent, /* Wenn ein neuer Event vor- */ /* liegt wird gGotEvent auf */ /* TRUE gesetzt. */ gSoundOn; /* Wir machen den Ton */ MenuHandle gAppleMenu; char gKeyUp, /* Taste "hoch" */ gKeyDown, /* Taste "runter" */ gKeyRight, /* Taste "rechts" */ gKeyLeft, /* Taste "links" */ gKeyPause; /* Taste "Chef kommt !" */ GWorldPtr gMyGWorld; /* Offscreen-Area */ WindowPtr gTheCWindow; /* Das Window fuer alles */ Rect gWorldRect, /* Offscreen-Bereich */ gLevelLabelRect, /* Labels in der Statusanzeige */ gPercentLabelRect, gPlayerLabelRect, gScoreLabelRect; PicHandle gDigits[10]; /* Die Digits der 7-Segment- */ /* Anzeige */ PicHandle gLevelLabel, /* Labels der Statusanzeige */ gPercentLabel, gPlayerLabel, gScoreLabel; int gDigitWidth, /* Fuer das Arrangieren der */ gDigitHeight; /* Statusanzeige noetig */ PixPatHandle gFilledPat, /* Pattern fŸr FILLED */ gEmptyPat, /* Pattern fŸr EMPTY */ gRunnerPat, gFlyerPat, gEaterPat, gWayPat, gStatusPat; CIconHandle gFlyerIcon, gRunnerIcon; int gPatternOffset; /* Zum Wechsel fŸr Patterns */ short gActiveItem; /* Aktiviertes Tastenfeld */ hgScoreEntry gHighScoreEntry[10]; /* HighScoreListe */ short gApplRefNum; /* Referenz-Nr. Resource-Fork */ /* von MacXonix selbst */ short gPrefsRefNum; /* Selbiges fuer Prefs-File */ /* ------------------------------------------------------------------------ */ /* Forward-Declarations. */ /* ------------------------------------------------------------------------ */ void Set_WindowEnv (WindowPtr theWindow); void Set_DrawingEnv (WindowPtr theWindow); void InitStatusArea (void); void InitMyWindow (void); void InitKeyBoard (void); void InitStatusDisplay (void); void InitFigures (void); void DrawStatusBackground (void); void EndOfGameSound (void); Boolean Do_KeyPrefs (void); void DrawCompleteInside (void); void LoadFiguresPattern (void); void GetKeyString (Str255 myString, char myChar); void ShowWinnersList (void); void ResetWinnersList (void); void ShowHints (void); short ShowMessage (short dialogID, short endItem1, short endItem2); void InitPreferences (void); short OpenPrefsFile (void); /* ------------------------------------------------------------------------ */ /* MakeGWorld erzeugt das Offscreen-Area fuer das "hintergruendige" Zeichnen*/ /* bevor der Bildschirm die Neuigkeiten erfaehrt. */ /* ------------------------------------------------------------------------ */ void MakeGWorld (void) { GDHandle oldGD; GWorldPtr oldGW; QDErr errorCode; SetRect (&gWorldRect, 0, 0, FIELD_WIDTH, FIELD_HEIGHT + 2 * STATUS_BORDER_HEIGHT + gDigitHeight); GetGWorld (&oldGW, &oldGD); errorCode = NewGWorld (&gMyGWorld, MAX_PIXEL_DEPTH, &gWorldRect, NIL_POINTER, NIL_POINTER, NO_FLAGS); if (errorCode != noErr) { ExitXonix (1); } LockPixels (gMyGWorld -> portPixMap); SetGWorld (gMyGWorld, NIL_POINTER); DrawCompleteInside (); DrawCompleteBorder (); DrawStatusBackground (); SetGWorld (oldGW, oldGD); UnlockPixels (gMyGWorld -> portPixMap); } /* ------------------------------------------------------------------------ */ /* Do_DragWindow ermoeglicht das Verschieben des Fensters. */ /* ------------------------------------------------------------------------ */ void Do_DragWindow (WindowPtr theWindow) { if (theWindow != FrontWindow ()) SelectWindow (theWindow); SetPort (theWindow); DragWindow (theWindow, gEvent.where, &qd.screenBits.bounds); } /* ------------------------------------------------------------------------ */ /* Is_DAWindow ueberprueft, ob ein Fenster zu einem Schreibtischprogramm */ /* gehoert. Diese Funktion wird fuer die Kompatibilitaet zu System 6 + */ /* Finder in bezug auf DAs benoetigt. */ /* ------------------------------------------------------------------------ */ short Is_DAWindow (WindowPtr theWindow) { short daRefNum; daRefNum = ((WindowPeek) theWindow) -> windowKind; if (daRefNum < 0) /* Wenn windowKind des */ /* WindowRecords negativ */ return daRefNum; /* ist, dann gehoert das */ /* Fenster zu einem DA. */ else return 0; } /* ------------------------------------------------------------------------ */ /* Do_Close wird aufgerufen, wenn der Benutzer das aktuelle (das vordere) */ /* Fenster schliessen will. */ /* ------------------------------------------------------------------------ */ Boolean Do_Close (void) { short itemHit, daRefNum; WindowPtr theWindow; Str255 title; theWindow = FrontWindow (); /* Wenn das vordere Fenster zu */ /* einem Schreibtischprogramm */ daRefNum = Is_DAWindow (theWindow); /* gehoert und das Programm */ /* unter System 6 im Finder */ /* laeuft, sollte das DA beendet*/ if (daRefNum) /* werden, indem CloseDeskAcc */ /* aufgerufen wird. */ { /* Dies ist aus Kompatbilitaets-*/ /* gruenden in das Programm auf-*/ /* genommen worden. */ CloseDeskAcc (daRefNum); /* Wenn xonix unter Multifinder */ /* bzw. System 7 laeuft, ueber- */ /* nimmt der DA-Handler die Kon-*/ /* trolle, wenn ein DA vorne ist*/ } else { HideWindow (gTheCWindow); /* Fenster wegblenden */ } gRun = FALSE; /* keine Animation mehr */ return true; } /* ------------------------------------------------------------------------ */ /* Do_CloseWindow reagiert auf einen Klick in die Close-Box des Fensters. */ /* ------------------------------------------------------------------------ */ void Do_CloseWindow (WindowPtr theWindow) { if (TrackGoAway (theWindow, gEvent.where)) Do_Close (); } /* ------------------------------------------------------------------------ */ /* Do_AppleMenu reagiert auf die Auswahl eines Menuepunktes aus dem "Apple"-*/ /* Menue, indem das ausgewaehlte Schreibtischprogramm gestartet wird oder */ /* der "ueber xonix..."-Dialog erzeugt wird. */ /* ------------------------------------------------------------------------ */ void Do_AppleMenu (short menuItem) { short daRefNum; Str255 daName; switch (menuItem) { case iAbout: /* "Ueber xonix..."-Menuepunkt. */ ShowMessage (rAboutDialog, OK_BUTTON, OK_BUTTON); break; default: /* Alle anderen Menue punkte */ /* sind DAs. Hole den DA-Namen */ GetItem (GetMHandle (mApple), menuItem, daName); daRefNum = OpenDeskAcc (daName); /* Oeffne das DA */ break; } } /* ------------------------------------------------------------------------ */ /* Do_Quit reagiert auf die Auswahl des "Beenden"-Menuepunktes, indem alle */ /* geoeffneten Fenster geschlossen werden und das Terminationskriterium */ /* gesetzt wird. */ /* ------------------------------------------------------------------------ */ void Do_Quit (void) { gQuit = true; /* Ich will hier raus !!! */ if (gTheCWindow) CloseWindow (gTheCWindow); Do_Close (); /* Das vordere Fenster schlies- */ /* sen. */ } /* ------------------------------------------------------------------------ */ /* Do_FileMenu koordiniert die Reaktion auf die Auswahl eines Menuepunktes */ /* aus dem "Ablage"-Menue. */ /* ------------------------------------------------------------------------ */ void Do_FileMenu (short menuItem) { switch (menuItem) { case iNew: /* "Neu". */ Do_New (); break; case iOpen: /* "Oeffnen...". */ break; case iClose: /* "Schliessen". */ Do_Close (); break; case iSave: /* "Sichern". */ break; case iSaveAs: /* "Sichern unter...". */ break; case iQuit: /* "Beenden". */ Do_Quit (); break; } } /* ------------------------------------------------------------------------ */ /* Do_PrefsMenu verwaltet den MenŸpunkt "Einstellungen" */ /* ------------------------------------------------------------------------ */ void Do_PrefsMenu (short menuItem) { switch (menuItem) { case iKeyPrefs: /* "Tastenbelegung". */ if ((Do_KeyPrefs ()) == TRUE) /* Neustart notwendig ? */ { Do_Close(); Do_New(); } break; case iSound: if (gSoundOn == TRUE) /* Sound ist ein und mu§ aus- */ { /* geschaltet werden */ gSoundOn = FALSE; } else { gSoundOn = TRUE; } break; case iPictures: if (gPatternOffset == PICTURES_OFFSET) /* Bilder verwendet */ { gPatternOffset = NO_PICTURES_OFFSET; } else { gPatternOffset = PICTURES_OFFSET; } LoadFiguresPattern (); Do_Close (); Do_New (); break; case iResetHighScore: ResetWinnersList (); case iShowHighScore: ShowWinnersList (); break; } } /* ------------------------------------------------------------------------ */ /* Do_InfoMenu verwaltet den MenŸpunkt "Infos" */ /* ------------------------------------------------------------------------ */ void Do_InfoMenu (short menuItem) { switch (menuItem) { case iHints: ShowHints (); break; case iBackgroundInfo: ShowMessage (rBackgroundInfo, OK_BUTTON, OK_BUTTON); break; } } /* ------------------------------------------------------------------------ */ /* Do_MenuCommand entscheidet anhand der Menu-ID des Menues, zu dem der */ /* ausgewaehlte Menuepunkt gehoert, welche Routine aufgerufen wird. */ /* ------------------------------------------------------------------------ */ void Do_MenuCommand (long choice) { short menuID, menuItem; /* Das Hi-Word des Ergebniswertes von MenuSelect oder MenuKey (der */ /* choice) enthaelt die Menu-ID des Menues, zu dem der ausgewaehlte */ /* Menuepunkt gehoert. Das Lo-Word beinhaltet die Menuepunktnummer des */ /* ausgewaehlten Menuepunktes. */ menuID = HiWord (choice); menuItem = LoWord (choice); switch (menuID) { case mApple: /* "Apple". */ Do_AppleMenu (menuItem); break; case mFile: /* "Ablage". */ Do_FileMenu (menuItem); break; case mEdit: /* "Bearbeiten". */ SystemEdit (menuItem -1); /* Kompatibilitaet zu DA`s unter*/ break; /* System 6.x + Finder. */ case mPrefs: /* "Einstellungen" */ Do_PrefsMenu (menuItem); break; case mInfos: /* "Infos" */ Do_InfoMenu (menuItem); break; } HiliteMenu (0); /* Hervorhebung des ausgew. */ /* Menuepunktes aufheben. */ } /* ------------------------------------------------------------------------ */ /* Adjust_Menus wird aufgerufen, bevor der Benutzer einen Menuepunkt aus- */ /* waehlen kann. Diese Funktion sorgt dafuer, dass dem Benutzer nur die */ /* Menuepunkte zur Verfuegung stehen, die in der aktuellen Programmsituation*/ /* verwendet werden koennen. */ /* ------------------------------------------------------------------------ */ void Adjust_Menus (void) { MenuHandle theMenu; WindowPtr theWindow; /* "Ablage"-Menuepunkte*/ theMenu = GetMHandle (mFile); /* Handle auf Menue holen. */ DisableItem (theMenu, iOpen); DisableItem (theMenu, iSave); DisableItem (theMenu, iSaveAs); if (gRun == FALSE) /* Es laeuft noch nix */ { EnableItem (theMenu, iNew); /* aktiviere Menuepunkte */ /* "Neu" und "Oeffnen...". */ DisableItem (theMenu, iClose); } else { DisableItem (theMenu, iNew); /* Ansonsten deaktivieren */ EnableItem (theMenu, iClose); } if (Is_DAWindow (FrontWindow ())) /* Vorderes Fenster DA ? */ { DisableItem (theMenu, iNew); /* Saemtliche Menuepunkte des */ /* "Ablage"-Menues */ DisableItem (theMenu, iOpen); /* deaktivieren (System 6.x + */ /* Finder). */ EnableItem (theMenu, iClose); /* Nur "Schliessen" aktiv */ /* (zum Beenden des DAs). */ DisableItem (theMenu, iSave); DisableItem (theMenu, iSaveAs); } theMenu = GetMHandle (mPrefs); /* Handle auf Voreinst.-Menue */ if (gSoundOn) /* Es zwitschert schon */ { SetItem (theMenu, iSound, "\pSound AUS"); } else { SetItem (theMenu, iSound, "\pSound EIN"); } if (gPatternOffset == PICTURES_OFFSET) /* Bilder werden verwendet */ { SetItem (theMenu, iPictures, "\pBilder AUS"); } else { SetItem (theMenu, iPictures, "\pBilder EIN"); } } /* ------------------------------------------------------------------------ */ /* Do_MouseDown entscheidet anhand des Ergebniswertes von FindWindow, */ /* welche Aktionsroutine aufgerufen wird. */ /* ------------------------------------------------------------------------ */ void Do_MouseDown (void) { short part; WindowPtr theWindow; /* FindWindow untersucht die Position des Mausklicks und stellt fest, in*/ /* welchem Teil des Bildschirms die Koordinaten liegen. */ part = FindWindow (gEvent.where, &theWindow); switch (part) { case inSysWindow: /* Fenster eines DA`s */ SystemClick (&gEvent, theWindow); /* Kompatibilitaet zu */ /* System 6.x + Finder. */ break; case inDrag: /* Fenster verschieben */ Do_DragWindow (theWindow); break; case inGoAway: /* Fenster schliessen. */ Do_CloseWindow (theWindow); break; case inMenuBar: /* Menueleiste geklickt. */ Adjust_Menus (); /* Verfuegbare Menuepunkte */ /* aktivieren, nichtver- */ /* fuegbare deaktivieren. */ Do_MenuCommand (MenuSelect (gEvent.where)); /* MenuSelect laesst den */ /* Benutzer einen Menuepunkt*/ /* auswaehlen. */ break; } } /* ------------------------------------------------------------------------ */ /* Do_KeyDown ueberprueft, ob es sich bei dem KeyDown-Event um einen Menue- */ /* kurzbefehl handelt (Befehlstaste + normale Taste). */ /* ------------------------------------------------------------------------ */ void Do_KeyDown (void) { char key; /* Das modifiers-Feld des EventRecords enthaelt die Information, ob bei */ /* Betaetigung der Taste die Befehlstaste gedrueckt war. Die vordefi- */ /* nierte Maske cmdKey kann verwendet werden, um das entsprechende Bit */ /* des modifiers-Feldes auszumaskieren. */ if (gEvent.modifiers & cmdKey) { key = gEvent.message & charCodeMask; /* ASCII-Code aus dem */ /* message-Feld des */ /* EventRecords. */ Adjust_Menus (); /* Verfuegbare Menuepunkte */ /* aktivieren, nichtver- */ /* fuegbare deaktivieren. */ Do_MenuCommand (MenuKey (key)); /* Menukey sucht den Menue- */ /* punkt mit dem gesuchten */ /* Menuekurzbefehl. */ } key = gEvent.message & charCodeMask; if (key == gKeyLeft) { gMyRunner.dx = - RATIO; gMyRunner.dy = 0; } else if (key == gKeyRight) { gMyRunner.dx = RATIO; gMyRunner.dy = 0; } else if (key == gKeyUp) { gMyRunner.dy = - RATIO; gMyRunner.dx = 0; } else if (key == gKeyDown) { gMyRunner.dy = RATIO; gMyRunner.dx = 0; } else if (key == gKeyPause) { if (gRun == TRUE) { gRun = FALSE; HideWindow (gTheCWindow); } else { gRun = TRUE; ShowWindow (gTheCWindow); } } } /* ------------------------------------------------------------------------ */ /* Set_DrawingEnv macht das aktuelle Window zur Zeichenumgebung */ /* ------------------------------------------------------------------------ */ void Set_DrawingEnv (WindowPtr theWindow) { SetPort (theWindow); } /* ------------------------------------------------------------------------ */ /* Set_WindowEnv setzt den Koordinatensystemursprung wieder auf die ur- */ /* spruengliche Position (0,0) zurueck und sorgt dafuer, dass die Clipping- */ /* Region den gesamten Fensterinhalt (inlusive Scrollbars) beschreibt. */ /* ------------------------------------------------------------------------ */ void Set_WindowEnv (WindowPtr theWindow) { SetPort (theWindow); SetOrigin (0, 0); ClipRect (&theWindow->portRect); } /* ------------------------------------------------------------------------ */ /* Do_Update reagiert auf einen Update-Event, indem der Zeichenbereich auf */ /* den neuzuzeichnenden Bereich beschraenkt und die gesamte Grafik gezeich- */ /* net wird. */ /* ------------------------------------------------------------------------ */ void Do_Update (void) { WindowPtr theWindow; GWorldEntry (); theWindow = (WindowPtr) gEvent.message; /* Das Universalfeld message */ /* verweist auf das neuzuzeich- */ /* nende Fenster. */ Set_WindowEnv (theWindow); /* Koordinatensystem, Clipping- */ /* Region auf "Normalzustand". */ BeginUpdate (theWindow); /* Die Visible-Region (visRgn) */ /* wird auf den neuzuzeichnenden*/ /* Bereich eingeschraenkt. */ Set_DrawingEnv (theWindow); /* Zeichenbereich einschraenken,*/ /* Koordinatensystemursprung */ /* verschieben. */ Set_WindowEnv (theWindow); /* Koordinatensystem, Clipping- */ /* Region auf "Normalzustand". */ GWorldExit (); EndUpdate (theWindow); /* Visible-Region wird wieder */ /* auf die urspruengliche Form */ /* zurueckgesetzt. */ } /* ------------------------------------------------------------------------ */ /* Do_Activate reagiert auf einen Activate-Event, indem das Fenster an den */ /* neuen Aktivierungszustand (aktiv oder inaktiv) angepasst wird. */ /* ------------------------------------------------------------------------ */ void Do_Activate (void) { WindowPtr theWindow; theWindow = (WindowPtr) gEvent.message; /* Das Universalfeld message */ /* verweist auf das betroffene */ /* Fenster. */ SetPort (theWindow); if (gEvent.modifiers & activeFlag) /* Activate-/ Deactivate-Event ?*/ { /* Activate-Event.*/ SetCursor (&qd.arrow); /* Der normale Pfeilcursor. */ } else { /* DeActivate-Event.*/ } } /* ------------------------------------------------------------------------ */ /* Do_Event entscheidet anhand des Event-Typs, welche Event-Behandlungs- */ /* routine aufgerufen wird. */ /* ------------------------------------------------------------------------ */ void Do_Event (void) { switch (gEvent.what) { case mouseDown: /* MouseDown-Event. */ Do_MouseDown (); break; case keyDown: /* KeyDown-Event. */ case autoKey: Do_KeyDown (); break; case updateEvt: /* Update-Event. */ Do_Update (); break; case activateEvt: /* Activate-Event. */ Do_Activate (); break; } } /* ------------------------------------------------------------------------ */ /* Init_ToolBox initialisiert die benoetigten ToolBox-Manager. */ /* ------------------------------------------------------------------------ */ void Init_ToolBox (void) { InitGraf ((Ptr) &qd.thePort); /* QuickDraw. */ InitFonts (); /* Font-Manager. */ InitWindows (); /* Window-Manager. */ InitMenus (); /* Menu-Manager. */ TEInit (); /* TextEdit. */ InitDialogs (NULL); /* Dialog-Manager. */ } /* ------------------------------------------------------------------------ */ /* Make_Menus laedt und installiert die Menueleiste. */ /* ------------------------------------------------------------------------ */ void Make_Menus (void) { Handle menuBar; menuBar = GetNewMBar (rMenuBar); SetMenuBar (menuBar); gAppleMenu = GetMHandle (mApple); AddResMenu (gAppleMenu, 'DRVR'); DrawMenuBar(); } /* ------------------------------------------------------------------------ */ /* Initialize setzt die globalen Variablen auf ihre Ausgangswerte und */ /* koordiniert den weiteren Initialisierungsprozess. */ /* ------------------------------------------------------------------------ */ void Initialize (void) { gQuit = false; /* Terminationskriterium. */ Init_ToolBox (); /* Initialisiere QuickDraw, */ /* Window-Manager etc. */ Make_Menus (); /* Erzeuge Menueleiste. */ SetCursor (&qd.arrow); /* Der normale Pfeilkursor */ InitStatusArea (); /* Initialisiere Statusfeld */ InitPreferences (); /* Initialisierung Tasten, */ /* Bild-/Tonverwendung, */ /* HighScore-Tabelle */ InitStatusDisplay (); /* Initialisierung Statusanzeige*/ InitFigures (); /* Initialisierung der Spiel- */ /* elemente */ MakeGWorld (); /* Offscreen-Area anlegen */ InitMyWindow (); /* Anlegen Spielfenster */ Do_New (); /* Starte neues Spiel */ } /* ------------------------------------------------------------------------ */ /* InitStatusArea legt das Verwaltungsfeld an */ /* ------------------------------------------------------------------------ */ void InitStatusArea (void) { int i; i = H_STEPS * V_STEPS; /* Groesse der Spielflaeche */ gMyStatusArea = NewPtr (i); /* Statusfeld anfordern */ if (gMyStatusArea == NIL_POINTER) /* Es reicht nicht aus !! */ { ExitXonix (1); } } /* ------------------------------------------------------------------------ */ /* InitMyWindow legt das Hauptwindow fuer das Spiel an */ /* ------------------------------------------------------------------------ */ void InitMyWindow (void) { Rect r; SetRect (&r, WINDOW_START_X, WINDOW_START_Y, WINDOW_START_X + FIELD_WIDTH, WINDOW_START_Y + FIELD_HEIGHT + 2 * STATUS_BORDER_HEIGHT + gDigitHeight); gTheCWindow = NewCWindow (NIL_POINTER, &r, "\pXonix", VISIBLE, noGrowDocProc, MOVE_TO_FRONT, NO_GOAWAY, NIL_POINTER); SetPort (gTheCWindow); /* Spielfeld-Window anlegen */ } /* ------------------------------------------------------------------------ */ /* InitKeyBoard legt die Default-Einstellung der Tasten fest */ /* ------------------------------------------------------------------------ */ void InitKeyBoard (void) { kbPrefsHandle myKbHandle; myKbHandle = (kbPrefsHandle) Get1Resource ('KBRS', rKeyboardPrefs); gKeyUp = (**myKbHandle).upKey; gKeyDown = (**myKbHandle).downKey; gKeyRight = (**myKbHandle).rightKey; gKeyLeft = (**myKbHandle).leftKey; gKeyPause = (**myKbHandle).pauseKey; } /* ------------------------------------------------------------------------ */ /* InitPreferences liest das Preferences-File aus dem entsprechenden */ /* Systemordner und initialisiert damit die globalen Variablen fŸr */ /* Sound- und Bildverwendung, Tastaturbelegung bzw. die HighScore-Tabelle */ /* Wird kein File gefunden, wird ein neues File mit Defaultwerten erzeugt. */ /* ------------------------------------------------------------------------ */ void InitPreferences (void) { gApplRefNum = CurResFile (); gPrefsRefNum = OpenPrefsFile (); UseResFile (gPrefsRefNum); InitKeyBoard (); UseResFile (gApplRefNum); } /* ------------------------------------------------------------------------ */ /* InitStatusDisplay initialisiert alle Elemente des Statusdisplays */ /* ------------------------------------------------------------------------ */ void InitStatusDisplay (void) { int i, space; int levelLabelWidth, percentLabelWidth, playerLabelWidth, scoreLabelWidth; int labelHeight; for (i = 0; i < 10; i ++) /* Pict-Ressourcen laden */ { gDigits[i] = GetPicture (rDigit0 + i); } gLevelLabel = GetPicture (rLevelLabel); gPercentLabel = GetPicture (rPercentLabel); gPlayerLabel = GetPicture (rPlayerLabel); gScoreLabel = GetPicture (rScoreLabel); gDigitWidth = (**(gDigits[0])).picFrame.right - (**(gDigits[0])).picFrame.left; gDigitHeight = (**(gDigits[0])).picFrame.bottom - (**(gDigits[0])).picFrame.top; levelLabelWidth = (**(gLevelLabel)).picFrame.right - (**(gLevelLabel)).picFrame.left; percentLabelWidth = (**(gPercentLabel)).picFrame.right - (**(gPercentLabel)).picFrame.left; playerLabelWidth = (**(gPlayerLabel)).picFrame.right - (**(gPlayerLabel)).picFrame.left; scoreLabelWidth = (**(gScoreLabel)).picFrame.right - (**(gScoreLabel)).picFrame.left; labelHeight = (**(gLevelLabel)).picFrame.bottom - (**(gLevelLabel)).picFrame.top; /* Pict-Ressourcen sind geladen, nun kann arrangiert werden */ space = FIELD_WIDTH - levelLabelWidth - 2 * gDigitWidth - DIGIT_SPACE - percentLabelWidth - 2 * gDigitWidth - DIGIT_SPACE - playerLabelWidth - 2 * gDigitWidth - DIGIT_SPACE - scoreLabelWidth - 6 * gDigitWidth - 5 * DIGIT_SPACE - 2 * STATUS_BORDER_WIDTH; space /= 3; /* 4 Anzeigen sind es, also 3 Zwischenraeume */ SetRect (&gLevelLabelRect, STATUS_BORDER_WIDTH, FIELD_HEIGHT + STATUS_BORDER_HEIGHT, STATUS_BORDER_WIDTH + levelLabelWidth, FIELD_HEIGHT + STATUS_BORDER_HEIGHT + labelHeight); SetRect (&gPercentLabelRect, STATUS_BORDER_WIDTH + levelLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space, FIELD_HEIGHT + STATUS_BORDER_HEIGHT, STATUS_BORDER_WIDTH + levelLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + percentLabelWidth, FIELD_HEIGHT + STATUS_BORDER_HEIGHT + labelHeight); SetRect (&gPlayerLabelRect, STATUS_BORDER_WIDTH + levelLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + percentLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space, FIELD_HEIGHT + STATUS_BORDER_HEIGHT, STATUS_BORDER_WIDTH + levelLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + percentLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + playerLabelWidth, FIELD_HEIGHT + STATUS_BORDER_HEIGHT + labelHeight); SetRect (&gScoreLabelRect, STATUS_BORDER_WIDTH + levelLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + percentLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + playerLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space, FIELD_HEIGHT + STATUS_BORDER_HEIGHT, STATUS_BORDER_WIDTH + levelLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + percentLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + playerLabelWidth + 2 * gDigitWidth + DIGIT_SPACE + space + scoreLabelWidth, FIELD_HEIGHT + STATUS_BORDER_HEIGHT + labelHeight); } /* ------------------------------------------------------------------------ */ /* CopyDefaultHighScoreList kopiert die String-Resourcen der Applikation in */ /* das Preferences-File */ /* ------------------------------------------------------------------------ */ void CopyDefaultHighScoreList (short fileRefNum) { StringHandle myStringHandle; short resID; ResType resType; Str255 resName; short resAttributes; short i; for (i = 0; i < HIGHSCORE_ITEMS * 3; i ++) { UseResFile (gApplRefNum); myStringHandle = (StringHandle) Get1Resource ('STR ', rDefaultHighScore + i); if (myStringHandle) { GetResInfo (myStringHandle, &resID, &resType, resName); resAttributes = GetResAttrs (myStringHandle); DetachResource (myStringHandle); UseResFile (fileRefNum); AddResource (myStringHandle, 'STR ', rHighScore + i, resName); SetResAttrs (myStringHandle, resAttributes); ChangedResource (myStringHandle); WriteResource (myStringHandle); ReleaseResource (myStringHandle); } } } /* ------------------------------------------------------------------------ */ /* CopyDefaultKeyboardPrefs kopiert die Tastaturbelegungs-Resource in das */ /* uebergebene Resource-File */ /* ------------------------------------------------------------------------ */ void CopyDefaultKeyboardPrefs (short fileRefNum) { kbPrefsHandle myKbHandle; short resID; ResType resType; Str255 resName; short resAttributes; UseResFile (gApplRefNum); myKbHandle = (kbPrefsHandle) Get1Resource ('KBRS', rKeyboardPrefs); if (myKbHandle) { GetResInfo (myKbHandle, &resID, &resType, resName); resAttributes = GetResAttrs (myKbHandle); DetachResource (myKbHandle); UseResFile (fileRefNum); AddResource (myKbHandle, 'KBRS', rKeyboardPrefs, resName); SetResAttrs (myKbHandle, resAttributes); ChangedResource (myKbHandle); WriteResource (myKbHandle); ReleaseResource (myKbHandle); } } /* ------------------------------------------------------------------------ */ /* CreateNewPrefsFile erzeugt bei Nichtvorhandensein eines Preferences- */ /* Files ein Solches */ /* ------------------------------------------------------------------------ */ short CreateNewPrefsFile (FSSpec prefFSSpec) { short fileRefNum; Handle appHandle; short resID; ResType resType; Str255 resName; short resAttributes; FSpCreateResFile (&prefFSSpec, 'RSED', 'rsrc', iuSystemScript); fileRefNum = FSpOpenResFile (&prefFSSpec, fsCurPerm); CopyDefaultHighScoreList (fileRefNum); CopyDefaultKeyboardPrefs (fileRefNum); UseResFile (gApplRefNum); return fileRefNum; } /* ------------------------------------------------------------------------ */ /* OpenPrefsFile oeffnet das Preferences-File */ /* ------------------------------------------------------------------------ */ short OpenPrefsFile (void) { short fileRefNum; short volRef; long dirID; FSSpec prefFSSpec; Str255 prefFileName; GetIndString (prefFileName, STRING_LIST, PREF_STRING_INDEX); FindFolder (kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, &volRef, &dirID); FSMakeFSSpec (volRef, dirID, prefFileName, &prefFSSpec); fileRefNum = FSpOpenResFile (&prefFSSpec, fsCurPerm); if (fileRefNum == -1) fileRefNum = CreateNewPrefsFile (prefFSSpec); return fileRefNum; } /* ------------------------------------------------------------------------ */ /* LoadFiguresPattern laedt die Pattern aller Figuren */ /* ------------------------------------------------------------------------ */ void LoadFiguresPattern (void) { gFilledPat = GetPixPat (rFilledPattern + gPatternOffset); gEmptyPat = GetPixPat (rEmptyPattern + gPatternOffset); gRunnerPat = GetPixPat (rRunnerPattern + gPatternOffset); gFlyerPat = GetPixPat (rFlyerPattern + gPatternOffset); gEaterPat = GetPixPat (rEaterPattern + gPatternOffset); gWayPat = GetPixPat (rWayPattern + gPatternOffset); if (gPatternOffset == PICTURES_OFFSET) { gRunnerIcon = GetCIcon (rRunnerIcon); } else { gRunnerIcon = GetCIcon (rRunnerIconPlain); } } /* ------------------------------------------------------------------------ */ /* InitFigures initialisiert die Spielelemente (Farbzuweisung, Pattern usw.)*/ /* ------------------------------------------------------------------------ */ void InitFigures (void) { gPatternOffset = NO_PICTURES_OFFSET; gStatusPat = GetPixPat (rStatusPattern); gFlyerIcon = GetCIcon (rFlyerIcon); LoadFiguresPattern (); gSoundOn = TRUE; } /* ------------------------------------------------------------------------ */ /* DrawRunnerToGWorld zeichnet den Runner an der aktuellen Position in */ /* GWorld */ /* ------------------------------------------------------------------------ */ void DrawRunnerToGWorld (void) { Rect r; r.top = gMyRunner.y * EATER_SIZE; r.bottom = r.top + gMyRunner.sy; r.left = gMyRunner.x * EATER_SIZE; r.right = r.left + gMyRunner.sx; PlotCIcon (&r, gRunnerIcon); } /* ------------------------------------------------------------------------ */ /* DrawWayToGWorld zeichnet die Runner-Spur an der aktuellen Position */ /* in GWorld */ /* ------------------------------------------------------------------------ */ void DrawWayToGWorld (void) { Rect r; r.top = gMyRunner.y * EATER_SIZE; r.bottom = r.top + gMyRunner.sy; r.left = gMyRunner.x * EATER_SIZE; r.right = r.left + gMyRunner.sx; FillCRect (&r, gWayPat); } /* ------------------------------------------------------------------------ */ /* DrawEmptyToGWorld zeichnet ein freies Feld (Runner-Size) in GWorld */ /* ------------------------------------------------------------------------ */ void DrawEmptyToGWorld (int xPos, int yPos) { Rect r; r.top = yPos * EATER_SIZE; r.bottom = r.top + RUNNER_SIZE; r.left = xPos * EATER_SIZE; r.right = r.left + RUNNER_SIZE; FillCRect (&r, gEmptyPat); } /* ------------------------------------------------------------------------ */ /* DrawFlyerToGWorld zeichnet einen Flyer in GWorld */ /* ------------------------------------------------------------------------ */ void DrawFlyerToGWorld (int xPos, int yPos) { Rect r; r.top = yPos * EATER_SIZE; r.bottom = r.top + FLYER_SIZE; r.left = xPos * EATER_SIZE; r.right = r.left + FLYER_SIZE; if (gPatternOffset == PICTURES_OFFSET) { PlotCIcon (&r, gFlyerIcon); } else { FillCRect (&r, gFlyerPat); } } /* ------------------------------------------------------------------------ */ /* DrawEaterToGWorld zeichnet einen Eater in GWorld */ /* ------------------------------------------------------------------------ */ void DrawEaterToGWorld (int xPos, int yPos) { Rect r; r.top = yPos * EATER_SIZE; r.bottom = r.top + EATER_SIZE; r.left = xPos * EATER_SIZE; r.right = r.left + EATER_SIZE; FillCRect (&r, gEaterPat); } /* ------------------------------------------------------------------------ */ /* DrawFilledToGWorld zeichnet ein Randfeld in Groesse eines Runners in */ /* GWorld */ /* ------------------------------------------------------------------------ */ void DrawFilledToGWorld (int xPos, int yPos) { Rect r; r.top = yPos * EATER_SIZE; r.bottom = r.top + RUNNER_SIZE; r.left = xPos * EATER_SIZE; r.right = r.left + RUNNER_SIZE; FillCRect (&r, gFilledPat); } /* ------------------------------------------------------------------------ */ /* DrawSmallFilledToGWorld zeichnet ein gefuelltes Feld in Groesse eines */ /* Eaters nach GWorld */ /* ------------------------------------------------------------------------ */ void DrawSmallFilledToGWorld (int xPos, int yPos) { Rect r; r.top = yPos * EATER_SIZE; r.bottom = r.top + EATER_SIZE; r.left = xPos * EATER_SIZE; r.right = r.left + EATER_SIZE; FillCRect (&r, gFilledPat); } /* ------------------------------------------------------------------------ */ /* DrawCompleteBorder zeichnet den gesamten Rahmen um das Spielfeld neu */ /* ------------------------------------------------------------------------ */ void DrawCompleteBorder (void) { int i; for (i = 0; i < H_STEPS; i += RATIO) { DrawFilledToGWorld (i, 0); DrawFilledToGWorld (i, V_STEPS - RATIO); } for (i = RATIO; i < V_STEPS - RATIO; i += RATIO) { DrawFilledToGWorld (0, i); DrawFilledToGWorld (H_STEPS - RATIO, i); } } /* ------------------------------------------------------------------------ */ /* DrawCompleteInside zeichnet das Innere des Spielfelds neu */ /* ------------------------------------------------------------------------ */ void DrawCompleteInside (void) { Rect r; r.top = RATIO * EATER_SIZE; r.bottom = (V_STEPS - RATIO) * EATER_SIZE; r.left = RATIO * EATER_SIZE; r.right = (H_STEPS - RATIO) * EATER_SIZE; FillCRect (&r, gEmptyPat); } /* ------------------------------------------------------------------------ */ /* DrawStatusBackground zeichnet den Hintergrund der Statusanzeige */ /* ------------------------------------------------------------------------ */ void DrawStatusBackground (void) { Rect r; PicHandle Ph; r.top = FIELD_HEIGHT; r.bottom = r.top + 2 * STATUS_BORDER_HEIGHT + gDigitHeight; r.left = 0; r.right = FIELD_WIDTH; FillCRect (&r, gStatusPat); DrawPicture (gLevelLabel, &gLevelLabelRect); DrawPicture (gPercentLabel, &gPercentLabelRect); DrawPicture (gPlayerLabel, &gPlayerLabelRect); DrawPicture (gScoreLabel, &gScoreLabelRect); } /* ------------------------------------------------------------------------ */ /* Draw2DigitsToGWorld zeichnet eine zweistellige Ziffer in das ueber- */ /* gebene Rechteck */ /* ------------------------------------------------------------------------ */ void Draw2DigitsToGWorld (int num, Rect *r) { int value; value = num / 10; r -> left = r -> right + DIGIT_SPACE; r -> right = r -> left + gDigitWidth; r -> bottom = r -> top + gDigitHeight; DrawPicture (gDigits[value], r); value = num % 10; r -> left += gDigitWidth + DIGIT_SPACE; r -> right += gDigitWidth + DIGIT_SPACE; DrawPicture (gDigits[value], r); } /* ------------------------------------------------------------------------ */ /* ScorePercentage zeigt den aktuellen Fuellstand in Prozent an */ /* ------------------------------------------------------------------------ */ void ScorePercentage (int num) { Rect r; r = gPercentLabelRect; Draw2DigitsToGWorld (num, &r); return; } /* ------------------------------------------------------------------------ */ /* ScoreLevel zeigt das aktuelle Level an */ /* ------------------------------------------------------------------------ */ void ScoreLevel (int num) { Rect r; r = gLevelLabelRect; Draw2DigitsToGWorld (num, &r); return; } /* ------------------------------------------------------------------------ */ /* ScoreRunner zeigt die Anzahl der verbliebenen Runner an */ /* ------------------------------------------------------------------------ */ void ScoreRunner (int num) { Rect r; r = gPlayerLabelRect; Draw2DigitsToGWorld (num, &r); return; } /* ------------------------------------------------------------------------ */ /* ScorePoints zeigt die aktuelle Punktzahl an */ /* ------------------------------------------------------------------------ */ void ScorePoints (unsigned int points) { Rect r; r = gScoreLabelRect; Draw2DigitsToGWorld ((points / 10000) % 100, &r); Draw2DigitsToGWorld ((points % 10000) / 100, &r); Draw2DigitsToGWorld ((points % 10000) % 100, &r); } /* ---------------------------------------------------------------------------- */ /* Die folgenden kleinen Routinen unterstŸtzen die Arbeit mit Dialog-Items */ /* ---------------------------------------------------------------------------- */ /* Hole Text eines Dialog-Items */ static void GetDText(DialogPtr dlg, short item, Str255 str) { short type; Handle hitem; Rect box; GetDItem(dlg, item, &type, &hitem, &box); GetIText(hitem, str); } /* Setze Text eines Dialog-Items */ static void SetDText(DialogPtr dlg, short item, const Str255 str) { short type; Handle hitem; Rect box; GetDItem(dlg, item, &type, &hitem, &box); SetIText(hitem, str); } /* Hole numerischen Wert eines Dialog-Items */ static long GetDNum(DialogPtr dlg, short item) { long num; Str255 str; GetDText(dlg, item, str); StringToNum(str, &num); return(num); } /* Setze numerischen Wert eines Dialog-Items */ static void SetDNum(DialogPtr dlg, short item, long num) { Str255 str; NumToString(num, str); SetDText(dlg, item, str); } /* Hole ein ControlHandle fŸr ein Item */ static ControlHandle GetDControl(DialogPtr dlg, short item) { short type; Handle hitem; Rect box; GetDItem(dlg, item, &type, &hitem, &box); return((ControlHandle) hitem); } static void SetItemValue (DialogPtr dlg, short itemNo, short value) { short itemType; Handle item; Rect box; GetDItem (dlg, itemNo, &itemType, &item, &box); SetCtlValue ((ControlHandle) item, value); } /* ------------------------------------------------------------------------ */ /* ShowHints zeigt den "Tips & Hinweise"-Dialog */ /* ------------------------------------------------------------------------ */ void ShowHints (void) { if (ShowMessage (rHints1, ENDE_BUTTON, WEITER_BUTTON) == WEITER_BUTTON) { ShowMessage (rHints2, OK_BUTTON, OK_BUTTON); } } /* ------------------------------------------------------------------------ */ /* CheckHighScore ueberprueft, ob die aktuelle Punktzahl fuer einen Rang */ /* unter den ersten 10 ausreicht */ /* ------------------------------------------------------------------------ */ Boolean CheckHighScore (void) { StringHandle myStringHandle; int lastHighScore; UseResFile (gPrefsRefNum); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + 2 * HIGHSCORE_ITEMS - 1); if (myStringHandle) StringToNum (*myStringHandle, &lastHighScore); UseResFile (gApplRefNum); if (lastHighScore < gHighScore) { return TRUE; } else { return FALSE; } } /* ------------------------------------------------------------------------ */ /* SetHighScoreLine setzt die Dialogelemente der Ÿbergebenen Platznummer */ /* ------------------------------------------------------------------------ */ void SetHighScoreLine (short number, DialogPtr theDialog) { StringHandle myStringHandle; myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + number + 2 * HIGHSCORE_ITEMS); if (myStringHandle) SetDText (theDialog, iWinnerName + number + 2 * HIGHSCORE_ITEMS, *myStringHandle); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + number + HIGHSCORE_ITEMS); if (myStringHandle) SetDText (theDialog, iWinnerName + number + HIGHSCORE_ITEMS, *myStringHandle); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + number); if (myStringHandle) SetDText (theDialog, iWinnerName + number, *myStringHandle); } /* ------------------------------------------------------------------------ */ /* DeleteHighScoreEntry lšscht den Eintrag mit der Ÿbergebenen Nummer */ /* ------------------------------------------------------------------------ */ void DeleteHighScoreEntry (short number) { StringHandle myStringHandle; myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + number - 1); if (myStringHandle) RmveResource (myStringHandle); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + number + HIGHSCORE_ITEMS - 1); if (myStringHandle) RmveResource (myStringHandle); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + number + 2 * HIGHSCORE_ITEMS - 1); if (myStringHandle) RmveResource (myStringHandle); } /* ------------------------------------------------------------------------ */ /* ShowWinnersList zeigt die "Hall of Fame" */ /* ------------------------------------------------------------------------ */ void ShowWinnersList (void) { DialogPtr theDialog; short itemHit, i; theDialog = GetNewDialog (rWinnersList, NULL, (WindowPtr) -1); UseResFile (gPrefsRefNum); for (i = 0; i < HIGHSCORE_ITEMS; i ++) { SetHighScoreLine (i, theDialog); } UseResFile (gApplRefNum); ShowWindow (theDialog); do { ModalDialog (NULL, &itemHit); } while (itemHit != OK_BUTTON); DisposeDialog (theDialog); } /* ------------------------------------------------------------------------ */ /* ResetWinnersList lšscht alle Eintraege in der "Hall of Fame" und gene- */ /* riert 10 Standard-Eintraege */ /* ------------------------------------------------------------------------ */ void ResetWinnersList (void) { StringHandle myStringHandle; int i; UseResFile (gPrefsRefNum); for (i = 0; i < HIGHSCORE_ITEMS; i ++) { DeleteHighScoreEntry (i + 1); } CopyDefaultHighScoreList (gPrefsRefNum); UseResFile (gApplRefNum); } /* ------------------------------------------------------------------------ */ /* ModifyWinnersList modifiziert die STR - Ressourcen der "Hall of Fame" */ /* und traegt den neuen Namen ein */ /* ------------------------------------------------------------------------ */ void ModifyWinnersList (Str255 newName, int newPoints) { StringHandle myStringHandle, myNameHandle, myPointsHandle, myLevelHandle; int i, points; Str255 myPointsString, myLevelString; UseResFile (gPrefsRefNum); DeleteHighScoreEntry (HIGHSCORE_ITEMS); for (i = HIGHSCORE_ITEMS - 2, points = newPoints - 1; (i >= 0) && (points < newPoints); i --) { myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + HIGHSCORE_ITEMS + i); StringToNum (*myStringHandle, &points); if (points < newPoints) { SetResInfo (myStringHandle, rHighScore + HIGHSCORE_ITEMS + i + 1, NULL); WriteResource (myStringHandle); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + i); SetResInfo (myStringHandle, rHighScore + i + 1, NULL); WriteResource (myStringHandle); myStringHandle = (StringHandle) Get1Resource ('STR ', rHighScore + 2 * HIGHSCORE_ITEMS + i); SetResInfo (myStringHandle, rHighScore + i + 1 + 2 * HIGHSCORE_ITEMS, NULL); WriteResource (myStringHandle); } } if ((i == -1) && (points < newPoints)) i ++; else i += 2; myNameHandle = NewString (newName); if (myNameHandle) { memcpy (*myNameHandle, newName, (*newName) + 1); AddResource (myNameHandle, 'STR ', rHighScore + i, NULL); WriteResource (myNameHandle); } NumToString ((long) newPoints, myPointsString); myPointsHandle = NewString (myPointsString); if (myPointsHandle) { memcpy (*myPointsHandle, myPointsString, (*myPointsString) + 1); AddResource (myPointsHandle, 'STR ', rHighScore + HIGHSCORE_ITEMS + i, NULL); WriteResource (myPointsHandle); } NumToString ((long) gLevel, myLevelString); myLevelHandle = NewString (myLevelString); if (myLevelHandle) { memcpy (*myLevelHandle, myLevelString, (*myLevelString) + 1); AddResource (myLevelHandle, 'STR ', rHighScore + 2 * HIGHSCORE_ITEMS + i, NULL); WriteResource (myLevelHandle); } if (myPointsHandle) DetachResource (myPointsHandle); if (myNameHandle) DetachResource (myNameHandle); if (myStringHandle) DetachResource (myStringHandle); if (myLevelHandle) DetachResource (myLevelHandle); UseResFile (gApplRefNum); return; } /* ------------------------------------------------------------------------ */ /* InsertToHallOfFame zeigt den HallOfFame-Dialog und trŠgt den Namen des */ /* Spielers an der entsprechenden Stelle ein */ /* ------------------------------------------------------------------------ */ Boolean InsertToHallOfFame (void) { short itemHit, i; DialogPtr theDialog; Str255 myName, myPoints; StringHandle myStringHandle, myNameHandle, myPointsHandle; int HighScore; EndOfGameSound (); theDialog = GetNewDialog (rCongratulation, NULL, (WindowPtr) -1); FlushEvents (everyEvent, 0); SelIText (theDialog, iMyName, 0, 32767); do { ModalDialog (NULL, &itemHit); } while (itemHit != OK_BUTTON); GetDText (theDialog, iMyName, myName); DisposeDialog (theDialog); ModifyWinnersList (myName, gHighScore); theDialog = GetNewDialog (rHallOfFameDialog, NULL, (WindowPtr) -1); UseResFile (gPrefsRefNum); for (i = 0; i < HIGHSCORE_ITEMS; i ++) { SetHighScoreLine (i, theDialog); } UseResFile (gApplRefNum); ShowWindow (theDialog); do { ModalDialog (NULL, &itemHit); } while ((itemHit != ENDE_BUTTON) && (itemHit != NOCHMAL_BUTTON)); DisposeDialog (theDialog); if (itemHit == ENDE_BUTTON) return TRUE; else return FALSE; } /* ------------------------------------------------------------------------ */ /* GameOverDialog zeigt ein Dialog-Window und liefert TRUE zurueck, wenn der*/ /* OK-Button gedrueckt wurde. Wurde der Nochmal-Button gedrŸckt, erfolgt */ /* die RŸckkehr mit FALSE zurŸck. */ /* ------------------------------------------------------------------------ */ Boolean GameOverDialog (void) { EndOfGameSound (); if (ShowMessage (rEndOfGameDialog, ENDE_BUTTON, NOCHMAL_BUTTON) == ENDE_BUTTON) return TRUE; else return FALSE; } /* ------------------------------------------------------------------------ */ /* SetKeyItem gibt im aktivierten Item den text aus und setzt die neue */ /* Tastenzuordnung */ /* ------------------------------------------------------------------------ */ void SetKeyItem (DialogPtr theDialog, char theChar, Str255 text) { SetDText (theDialog, gActiveItem, text); SelIText (theDialog, gActiveItem, 0, 32767); switch (gActiveItem) { case KEY_UP_ITEM: gKeyUp = theChar; break; case KEY_DOWN_ITEM: gKeyDown = theChar; break; case KEY_LEFT_ITEM: gKeyLeft = theChar; break; case KEY_RIGHT_ITEM: gKeyRight = theChar; break; } } /* ------------------------------------------------------------------------ */ /* RefModalFilter Ÿbernimmt die Sonderbehandlung von Funktionstasten bei */ /* Eingabe der gewŸnschten Tastenbelegung */ /* ------------------------------------------------------------------------ */ static pascal Boolean RefModalFilter(DialogPtr theDialog, EventRecord *theEvent, short *theItem) { unsigned char theChar; Boolean returnFlag; long finalTicks; Str255 myString; returnFlag = FALSE; switch (theEvent -> what) { case keyDown: case autoKey: theChar = (theEvent -> message) & charCodeMask; switch (theChar) { case CR_CHAR: /* Carriage Return */ case ENTER_CHAR: /* Enter */ *theItem = OK_BUTTON; returnFlag = TRUE; HiliteControl (GetDControl (theDialog, OK_BUTTON), OK_BUTTON); Delay (HILITE_DELAY, &finalTicks); HiliteControl (GetDControl (theDialog, OK_BUTTON), 0); break; case ESC_CHAR: /* ESC */ *theItem = CANCEL_BUTTON; returnFlag = TRUE; HiliteControl (GetDControl (theDialog, CANCEL_BUTTON), CANCEL_BUTTON); Delay (HILITE_DELAY, &finalTicks); HiliteControl (GetDControl (theDialog, CANCEL_BUTTON), 0); break; case UP_CHAR: /* UpArrow */ case RIGHT_CHAR: /* RightArrow */ case DOWN_CHAR: /* DownArrow */ case LEFT_CHAR: /* LeftArrow */ GetKeyString (myString, theChar); SetKeyItem (theDialog, theChar, myString); returnFlag = TRUE; break; default: SelIText (theDialog, gActiveItem, 0, 32767); if (theChar != TAB_CHAR) /* TAB wird nicht genutzt */ { switch (gActiveItem) { case KEY_UP_ITEM: gKeyUp = theChar; break; case KEY_DOWN_ITEM: gKeyDown = theChar; break; case KEY_LEFT_ITEM: gKeyLeft = theChar; break; case KEY_RIGHT_ITEM: gKeyRight = theChar; break; } } break; } default: break; } return returnFlag; } /* ------------------------------------------------------------------------ */ /* GetKeyString wandelt den uebergebenen char-Code in einen entsprechenden */ /* Textstring (mit Uebersetzung der Zeichen unter 0x20) */ /* ------------------------------------------------------------------------ */ void GetKeyString (Str255 myString, char myChar) { int i; StringHandle myStringHandle; if (isgraph (myChar)) /* "normales Zeichen" */ { *myString = 1; *(myString + 1) = myChar; } else if (iscntrl (myChar)) /* Steuerzeichen */ { myStringHandle = (StringHandle) Get1Resource ('STR ', BASE_RES_ID+myChar); if (myStringHandle) { for (i = 0; i <= **myStringHandle; i ++) { *(myString + i) = *(*myStringHandle + i); } } } } /* ------------------------------------------------------------------------ */ /* SetCurrentKeyStrings traegt die aktuellen Tastenbezeichnungen in die */ /* jeweiligen Dialog-Items ein */ /* ------------------------------------------------------------------------ */ void SetCurrentKeyStrings (DialogPtr theDialog) { Str255 myString; GetKeyString (myString, gKeyUp); SetDText (theDialog, KEY_UP_ITEM, myString); GetKeyString (myString, gKeyDown); SetDText (theDialog, KEY_DOWN_ITEM, myString); GetKeyString (myString, gKeyLeft); SetDText (theDialog, KEY_LEFT_ITEM, myString); GetKeyString (myString, gKeyRight); SetDText (theDialog, KEY_RIGHT_ITEM, myString); } /* ------------------------------------------------------------------------ */ /* Do_KeyPrefs erledigt die Einstellung der Steuertasten fŸr die Bewegungen */ /* des Runners sowie Sound- und Darstellungsumschaltung. Ist ein Spielneu- */ /* start notwendig, wird TRUE zurueckgegeben */ /* ------------------------------------------------------------------------ */ Boolean Do_KeyPrefs (void) { short itemHit; DialogPtr theDialog; int itemType; Rect itemRect; Handle itemHandle; char leftBack, rightBack, upBack, downBack; Boolean picturesBack, soundBack; kbPrefsHandle myKbHandle; leftBack = gKeyLeft; rightBack = gKeyRight; upBack = gKeyUp; downBack = gKeyDown; picturesBack = gPatternOffset; soundBack = gSoundOn; theDialog = GetNewDialog (rKeyPrefsDialog, NULL, MOVE_TO_FRONT); SetCurrentKeyStrings (theDialog); SetItemValue (theDialog, SOUND_ITEM, gSoundOn); if (gPatternOffset == PICTURES_OFFSET) SetItemValue (theDialog, PICTURES_ITEM, 1); else SetItemValue (theDialog, PICTURES_ITEM, 0); gActiveItem = KEY_UP_ITEM; SelIText (theDialog, gActiveItem, 0, 32767); do { ModalDialog (RefModalFilter, &itemHit); switch (itemHit) { case KEY_UP_ITEM: case KEY_RIGHT_ITEM: case KEY_DOWN_ITEM: case KEY_LEFT_ITEM: gActiveItem = itemHit; SelIText (theDialog, itemHit, 0, 32767); break; case SOUND_ITEM: gSoundOn = 1 - gSoundOn; SetItemValue (theDialog, SOUND_ITEM, gSoundOn); break; case PICTURES_ITEM: if (gPatternOffset == PICTURES_OFFSET) { gPatternOffset = NO_PICTURES_OFFSET; SetItemValue (theDialog, PICTURES_ITEM, 1); } else { gPatternOffset = PICTURES_OFFSET; SetItemValue (theDialog, PICTURES_ITEM, 0); } LoadFiguresPattern (); break; } } while ((itemHit != CANCEL_BUTTON) && (itemHit != OK_BUTTON)); if (itemHit == CANCEL_BUTTON) /* Evtl. Aenderungen verwerfen */ { gKeyLeft = leftBack; gKeyRight = rightBack; gKeyUp = upBack; gKeyDown = downBack; gPatternOffset = picturesBack; gSoundOn = soundBack; } UseResFile (gPrefsRefNum); myKbHandle = (kbPrefsHandle) Get1Resource ('KBRS', rKeyboardPrefs); (**myKbHandle).upKey = gKeyUp; (**myKbHandle).downKey = gKeyDown; (**myKbHandle).rightKey = gKeyRight; (**myKbHandle).leftKey = gKeyLeft; (**myKbHandle).pauseKey = gKeyPause; ChangedResource (myKbHandle); WriteResource (myKbHandle); UseResFile (gApplRefNum); DisposeDialog (theDialog); if (picturesBack == gPatternOffset) /* "Bilder" nicht geaendert */ return FALSE; else return TRUE; } /* ------------------------------------------------------------------------ */ /* ShowMessage zeigt einen modalen Dialog entsprechend der uebergebenen */ /* Resource-ID und liefert die Item-Nr. des aktivierten Items zum Beenden */ /* ------------------------------------------------------------------------ */ short ShowMessage (short dialogID, short endItem1, short endItem2) { short itemHit; DialogPtr theDialog; theDialog = GetNewDialog (dialogID, NULL, (WindowPtr) -1); do { ModalDialog (NULL, &itemHit); } while ((itemHit != endItem1) && (itemHit != endItem2)); DisposeDialog (theDialog); return itemHit; } /* ------------------------------------------------------------------------ */ /* RunnerDieSound spielt einen Sound, wenn ein Runner geopfert wurde */ /* ------------------------------------------------------------------------ */ void RunnerDieSound (void) { Handle soundHandle; if (gSoundOn && (soundHandle = GetResource ('snd ', rRunnerDieSound))) SndPlay (0L, soundHandle, FALSE); } /* ------------------------------------------------------------------------ */ /* EndOfGameSound spielt einen Sound, wenn alle Runner verspielt wurden */ /* ------------------------------------------------------------------------ */ void EndOfGameSound (void) { Handle soundHandle; if (gSoundOn && (soundHandle = GetResource ('snd ', rEndOfGameSound))) SndPlay (0L, soundHandle, FALSE); } /* ------------------------------------------------------------------------ */ /* Das Hauptprogramm beinhaltet die Main-Event-Loop, welche solange laeuft, */ /* bis der Benutzer das Fenster schliesst und dadurch das Terminations- */ /* kriterium gesetzt wird. */ /* ------------------------------------------------------------------------ */ void main (void) { Initialize (); /* Initialisierung. */ while (!gQuit) /* Main-Event-Loop. */ { if (gRun) /* Laeuft ein Spiel? */ Animate (); /* Alle Figuren bewegen */ gGotEvent = WaitNextEvent (everyEvent, /* Wir nehmen jeden Event. */ &gEvent, /* Hier steht hinterher */ /* der Event drin. */ 3, /* 2 Ticks fuer Hinter- */ /* grundapplikationen. */ NULL); /* Noch keine Mouse-Region */ /* (MouseMoved-Events). */ if (gGotEvent) /* Liegt ein Event vor? */ Do_Event (); /* Sorge fuer Abarbeitung */ if (gEndOfGame == TRUE) /* QUIT gedrŸckt oder Player*/ { /* sind alle */ if (CheckHighScore () == TRUE) /* Unter den ersten 10 ? */ { gQuit = InsertToHallOfFame (); /* Eintragen in Hall Of Fame*/ } else { gQuit = GameOverDialog (); /* Es hat nicht gereicht */ } if (gQuit == FALSE) { Do_New (); /* Versuchen wir«s nochmal */ } } } } /* ------------------------------------------------------------------------ */ /* ExitXonix beendet Xonix und gibt gegebenenfalls eine notwendige Message */ /* aus */ /* ------------------------------------------------------------------------ */ void ExitXonix (int status) { switch (status) { case 1: /* Speicher reicht nicht */ ShowMessage (rNoRamDialog, OK_BUTTON, OK_BUTTON); break; default: break; } if (gMyStatusArea) DisposePtr (gMyStatusArea); if (gMyGWorld) DisposePtr (gMyGWorld); ExitToShell (); } #endif /* USE_MAC */ xonix-1.4/patchlevel.h100644 153 7 53 6026013550 12150 0ustar jbin#define VERSION "1995/09/14 11:52:08 1.4" xonix-1.4/runner.xpm100644 153 7 336 5750654253 11751 0ustar jbin/* XPM */ static char * runner_xpm[] = { "8 8 5 1", " c gold", ". c sienna", "X c yellow", "o c orange", "O c dark violet", " .... ", " XX ", ".ooXoo..", ".oo ooX.", ".XXX XX.", ".XOOOO .", " XXX ", " .... "}; xonix-1.4/stack.c100644 153 7 17313 6024011040 11176 0ustar jbin/* Hey emacs, this is -*- Mode: C++; tab-width: 4 -*- */ /* * simple Point stack * * stack.c,v 1.6 1995/09/08 09:51:28 j Exp */ /* * Copyright (c) 1995 * Alfredo Herrera Hernandez * Torsten Schoenitz * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "xonix.h" #include "stack.h" #define INIT_SIZE (1024) /* ------------------------------------------------------------------------ */ /* InitMyPoints legt einen Speicherbereich mit der gewuenschten Groesse an */ /* ------------------------------------------------------------------------ */ myPoint *InitMyPoints (int size) { return ((myPoint *) malloc (size * sizeof (myPoint))); } /* ------------------------------------------------------------------------ */ /* InitMySegments legt einen Speicherbereich mit der gewuenschten Groesse */ /* an */ /* ------------------------------------------------------------------------ */ mySegment *InitMySegments (int size) { return ((mySegment *) malloc (size * sizeof (mySegment))); } /* ------------------------------------------------------------------------ */ /* InitStack initialisiert die Stackverwaltung fuer myPoints */ /* ------------------------------------------------------------------------ */ stack *InitStack (void) { stack *s; if ((s = (stack *) malloc (sizeof (stack))) == NULL) return NULL; if ((s -> bottom = InitMyPoints (INIT_SIZE)) == NULL) return NULL; s -> size = INIT_SIZE; s -> counter = 0; return s; } /* ------------------------------------------------------------------------ */ /* InitSegmentStack initialisiert die Stackverwaltung fuer mySegments */ /* ------------------------------------------------------------------------ */ segStack *InitSegmentStack (void) { segStack *s; if ((s = (segStack *) malloc (sizeof (segStack))) == NULL) return NULL; if ((s -> bottom = InitMySegments (INIT_SIZE)) == NULL) return NULL; s -> size = INIT_SIZE; s -> counter = 0; return s; } /* ------------------------------------------------------------------------ */ /* DeinitMyPoints gibt die Stackelemente wieder frei */ /* ------------------------------------------------------------------------ */ int DeinitMyPoints (myPoint *p) { free (p); return 1; } /* ------------------------------------------------------------------------ */ /* DeinitMySegments gibt die Stackelemente wieder frei */ /* ------------------------------------------------------------------------ */ int DeinitMySegments (mySegment *p) { free (p); return 1; } /* ------------------------------------------------------------------------ */ /* DeinitStack gibt den Stack wieder frei */ /* ------------------------------------------------------------------------ */ int DeinitStack (stack *s) { if (s == NULL) return 0; DeinitMyPoints (s -> bottom); free (s); return 1; } /* ------------------------------------------------------------------------ */ /* DeinitSegmentStack gibt den Stack wieder frei */ /* ------------------------------------------------------------------------ */ int DeinitSegmentStack (segStack *s) { if (s == NULL) return 0; DeinitMySegments (s -> bottom); free (s); return 1; } /* ------------------------------------------------------------------------ */ /* ReallocMyPoints fordert Speicher fuer size Stackelemente an */ /* ------------------------------------------------------------------------ */ myPoint *ReallocMyPoints (myPoint *p, int size) { return ((myPoint *) realloc (p, size * sizeof (myPoint))); } /* ------------------------------------------------------------------------ */ /* ReallocMySegments fordert Speicher fuer size Stackelemente an */ /* ------------------------------------------------------------------------ */ mySegment *ReallocMySegments (mySegment *p, int size) { return ((mySegment *) realloc (p, size * sizeof (mySegment))); } /* ------------------------------------------------------------------------ */ /* Push packt ein Element auf den Stack */ /* ------------------------------------------------------------------------ */ int Push (stack *s, int x, int y) { if (s -> size == s -> counter) { if ((s -> bottom = ReallocMyPoints (s -> bottom, s -> size + 0x1000)) == NULL) return 0; s -> size += 0x1000; } (s -> bottom + s -> counter) -> h = x; (s -> bottom + s -> counter) -> v = y; s -> counter ++; return 1; } /* ------------------------------------------------------------------------ */ /* PushSeg packt ein Segment auf den Stack */ /* ------------------------------------------------------------------------ */ int PushSeg (segStack *s, int y, int xl, int xr, int dy) { if (s -> size == s -> counter) { if ((s -> bottom = ReallocMySegments (s -> bottom, s -> size + 0x1000)) == NULL) return 0; s -> size += 0x1000; } if ((y + dy >= RATIO) && (y + dy <= V_STEPS - RATIO)) { (s -> bottom + s -> counter) -> y = y; (s -> bottom + s -> counter) -> xl = xl; (s -> bottom + s -> counter) -> xr = xr; (s -> bottom + s -> counter) -> dy = dy; s -> counter ++; } return 1; } /* ------------------------------------------------------------------------ */ /* Pop liefert das oberste Element aus dem Stack */ /* ------------------------------------------------------------------------ */ int Pop (stack *s, myPoint *p) { if (s -> counter) s -> counter --; else return 0; if (s -> size > (s -> counter + 0x1000)) { if ((s -> bottom = ReallocMyPoints (s -> bottom, s -> size - 0x1000)) == NULL) return 0; s -> size -= 0x1000; } *p = *(s -> bottom + s -> counter); return 1; } /* ------------------------------------------------------------------------ */ /* PopSeg liefert das oberste Segment aus dem Stack */ /* ------------------------------------------------------------------------ */ int PopSeg (segStack *s, mySegment *p) { if (s -> counter) s -> counter --; else return 0; if (s -> size > (s -> counter + 0x1000)) { if ((s -> bottom = ReallocMySegments (s -> bottom, s -> size - 0x1000)) == NULL) return 0; s -> size -= 0x1000; } (s -> bottom + s -> counter) -> y += (s -> bottom + s -> counter) -> dy; *p = *(s -> bottom + s -> counter); return 1; } xonix-1.4/stack.h100644 153 7 4342 6020320467 11175 0ustar jbin/* Hey emacs, this is -*- Mode: C++; tab-width: 4 -*- */ /* * simple Point stack * * stack.h,v 1.6 1995/08/28 10:57:59 j Exp */ /* * Copyright (c) 1995 * Alfredo Herrera Hernandez * Torsten Schoenitz * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef STACK_H #define STACK_H typedef struct { myPoint *bottom; int size; int counter; } stack; typedef struct { mySegment *bottom; int size; int counter; } segStack; /* ------------------------------------------------------------------------ */ /* Funktionen */ /* ------------------------------------------------------------------------ */ extern stack *InitStack (); extern int DeinitStack (stack *s); extern int Push (stack *s, int x, int y); extern int Pop (stack *s, myPoint *p); extern segStack *InitSegmentStack (); extern int DeinitSegmentStack (segStack *s); extern int PushSeg (segStack *s, int y, int xl, int xr, int dy); extern int PopSeg (segStack *s, mySegment *p); #endif /* STACK_H */ xonix-1.4/way.xpm100644 153 7 2377 5750654316 11267 0ustar jbin/* XPM */ static char * way_xpm[] = { "32 32 4 1", " c goldenrod", ". c forest green", "X c green yellow", "o c lime green", " ... .. . ... . ... .. . . ..", " .. .......X... ................", "..... . .. . .. ....o.........", ".. ................... ... .. ..", ". ...o.. . ... .X . . ..... ..", "....o...... .. . ... ..... ...", " . ...... . ... ..... . .....", "..... o.... . .. . ........", ".... ........ . .. ..... ......X", ".. .... . . .. . .......... ..", "... .. .. .... . ... ... ...", " . .. . .... .... .o. ... ", "..... ..... .. .. .. o.... . ", " ... ..... . . . .......o.......", " ..... .. o . . . . ............", ". .X . .. ... ... . .... . . ", ".... ...... ... .... . . ..... ", " . . ..... . ... ... .. ... ", "...... .. ... .. .... .....", "..... .....X ....o. .. ... ...", " . . . . . . ..... . . ..... o", "... .. .... .. .. ...... . . .", "... . .. . ........... ...... ..", "... .. ... . .. ... ........", " .... .. . . . .... ... .X....", ".. ... .....o .......... .. ..", ".. ... ...... ...... ..........", " X... .. .. o... . .. ..... ", "...... ....o...... . .... . ....", ". . . ..... ... ........ .. ..", "...o. .............. .o..... ...", "...o...... .... ................"}; xonix-1.4/x11.c100644 153 7 75415 6026014113 10517 0ustar jbin/* * xonix game * * X11 interface functions * * x11.c,v 1.53 1995/09/14 11:55:55 j Exp */ /* * Copyright (c) 1995 * Joerg Wunsch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef USE_X11 #include #include #include #include #include #include #include #include #define POINTS_DIGITS 6 /* number of digits in score display */ #if !defined(__unix) && (defined(__unix__) || defined(unix)) # define __unix /* not all compilers do this */ #endif #ifdef __unix #define MAXSCORES 10 /* number of entries in high score table */ #define PATH_HIGHSCORE XONIXDIR "/scores" #define PATH_TEMPSCORE XONIXDIR "/score_tmp" #if defined(__unix) && !defined PATH_RMAIL #define PATH_RMAIL "rmail" /* rely on the $PATH */ #endif #include #include #include #include #include #include #endif #include "xonix.xbm" #include "xonix_mask.xbm" #include "d0.xbm" #include "d1.xbm" #include "d2.xbm" #include "d3.xbm" #include "d4.xbm" #include "d5.xbm" #include "d6.xbm" #include "d7.xbm" #include "d8.xbm" #include "d9.xbm" #include "colon.xbm" #include "flyer.xpm" #include "runner.xpm" #include "eater.xpm" #include "empty.xpm" #include "way.xpm" #include "filled.xpm" #include #if USE_XAW_3D #include #include #include #include #include #include #include #include #else /* standard Xaw */ #include #include #include #include #include #include #include #include #endif /* USE_XAW_3D */ #include "patchlevel.h" #include "xonix.h" #define ApplicationClassName "Xonix" #define trans_table \ "WM_PROTOCOLS: GlobalProtoHandler()\n" \ "Left: Left()\n" \ "Right: Right()\n" \ "Up: Up()\n" \ "Down: Down()\n" \ "Q: Quit()\n" \ "Escape: Quit()\n" \ ": Pause()\n" \ "P: Pause()\n" \ ": Continue()\n" #define about_msg \ " The game of xonix\n" \ "\n" \ " Copyright \251 1995 by\n" \ "Torsten Sch\366nitz, J\366rg Wunsch, Alfredo Herrera Hern\341ndez\n" \ "\n" \ " version info:\n" \ VERSION typedef struct AppResources { int time_step; } AppResources; typedef struct CallbackData { Widget w; int button_number; } CallbackData; typedef struct Dims { Dimension width, height; } Dims; #define Offset(field) (XtOffsetOf(AppResources, field)) static XtResource xonix_resources[] = { {"timeStep", "TimeStep", XtRInt, sizeof(int), Offset(time_step), XtRImmediate, (XtPointer) STEP_TIME}, }; static Window win; static Visual *vis; static int screenno; static int depth; static Screen *screen; static Colormap cmap; static int winx, winy; static AppResources resources; static int exiting = 0; /* exported */ Display *dpy; Window canv; Dimension sizex, sizey; static GC default_gc, empty_gc; static Pixmap runner_pm, flyer_pm, eater_pm, filled_pm, empty_pm, way_pm; static Dims empty_dims, filled_dims, way_dims; static const EventMask evmask = ExposureMask; static Atom delwin; /* the delete window atom */ static Widget toplevel; /* the top level widget */ static Widget container; /* form widget containing everything */ static Widget drawarea; /* our Canvas */ static Widget statusarea; /* form for status display */ /* percentage display */ static Widget st_percentage, st_perc_label, st_perc_d10, st_perc_d1; /* level display */ static Widget st_level, st_lev_label, st_lev_d10, st_lev_d1; /* runner display */ static Widget st_runner, st_run_label, st_run_d10, st_run_d1; /* time display */ static Widget st_score, st_score_label; static Widget st_points[POINTS_DIGITS]; /* game menu */ static Widget game_button, game_menu, game_about, game_l1, game_quit; /* game over shell */ static Widget gameover_shell = (Widget)0; static int gameover_pending = 0; /* score widget */ static Widget score_shell = (Widget)0; static void timeout(XtPointer client_data, XtIntervalId *timer); static void DoAbout(void); static void QuitCallback(Widget, XtPointer, XtPointer); static void AboutCallback(Widget, XtPointer, XtPointer); static XtAppContext app; static XtIntervalId gTimer = (XtIntervalId) 0; /* action handling */ static void GlobalProtoHandler(Widget, XEvent *, String *, Cardinal *); static void Left(Widget, XEvent *, String *, Cardinal *); static void Right(Widget, XEvent *, String *, Cardinal *); static void Up(Widget, XEvent *, String *, Cardinal *); static void Down(Widget, XEvent *, String *, Cardinal *); static void Quit(Widget, XEvent *, String *, Cardinal *); static void Pause(Widget, XEvent *, String *, Cardinal *); static void Continue(Widget, XEvent *, String *, Cardinal *); static void DrawWayElementToGWorld (int xPos, int yPos); static XtActionsRec actions[] = { {"GlobalProtoHandler", GlobalProtoHandler}, {"Left", Left}, {"Right", Right}, {"Up", Up}, {"Down", Down}, {"Quit", Quit}, {"Pause", Pause}, {"Continue", Continue} }; /* our 7-segment display */ static unsigned char *digit_bits[] = { d0_bits, d1_bits, d2_bits, d3_bits, d4_bits, d5_bits, d6_bits, d7_bits, d8_bits, d9_bits }; static Pixmap digit_pms[10]; static void GlobalProtoHandler(Widget w, XEvent *xev, String *p, Cardinal *n) { if(xev->xclient.data.l[0] == delwin) { if(w == toplevel) ExitXonix(0); else XtPopdown(w); } } static void Left(Widget w, XEvent *xev, String *p, Cardinal *n) { gMyRunner.dx = - RATIO; gMyRunner.dy = 0; } static void Right(Widget w, XEvent *xev, String *p, Cardinal *n) { gMyRunner.dx = RATIO; gMyRunner.dy = 0; } static void Up(Widget w, XEvent *xev, String *p, Cardinal *n) { gMyRunner.dy = - RATIO; gMyRunner.dx = 0; } static void Down(Widget w, XEvent *xev, String *p, Cardinal *n) { gMyRunner.dy = RATIO; gMyRunner.dx = 0; } static void Quit(Widget w, XEvent *xev, String *p, Cardinal *n) { exiting++; /* do not ask back */ ExitXonix(0); } static void Pause(Widget w, XEvent *xev, String *p, Cardinal *n) { if(xev->type == UnmapNotify) { gPause = True; if(gRun) { XtRemoveTimeOut(gTimer); gTimer = (XtIntervalId) 0; } } else { (void)XIconifyWindow (dpy, XtWindow(toplevel), screenno); /* will come here soon again (UnmapNotify) */ } } static void Continue(Widget w, XEvent *xev, String *p, Cardinal *n) { if(gPause) { gPause = False; if(gTimer == 0) gTimer = XtAppAddTimeOut(app, resources.time_step, timeout, 0); } } static void XonixEventHandler(Widget w, /* canvas */ XtPointer cd, XEvent *event, Boolean *cont) { XExposeEvent *exp = (XExposeEvent *)event; int x0, y0, x1, y1, i, j; int exposed = 0; /* first, redraw the requested large areas */ do { switch(event->type) { case Expose: exposed++; x0 = (((exp->x + EATER_SIZE - 1) / EATER_SIZE) - 1) & ~1; y0 = (((exp->y + EATER_SIZE - 1) / EATER_SIZE) - 1) & ~1; if(x0 < 0) x0 = 0; if(y0 < 0) y0 = 0; x1 = ((exp->x + exp->width + EATER_SIZE - 1) / EATER_SIZE) | 1; y1 = ((exp->y + exp->height + EATER_SIZE - 1) / EATER_SIZE) | 1; for(j = y0; j < y1; j += 2) for(i = x0; i < x1; i += 2) { unsigned char c = *(gMyStatusArea + (j * H_STEPS) + i); if((c & FILLED) || (c & BORDER) || (c & EATER)) DrawFilledToGWorld(i, j); else if(c & FLYER) DrawFlyerToGWorld(i, j); else if(c & WAY) DrawWayElementToGWorld(i, j); else if(c & RUNNER) DrawRunnerToGWorld(); else DrawEmptyToGWorld(i, j); } break; default: /* nothing else notify */ break; } } while(True == XCheckWindowEvent(dpy, canv, evmask, event)); /* * finally, if we have been exposed, redraw all flyers; this * is way easier than to care for their sub-micros in the loop * above */ if(exposed) for(i = 0; i < gEaterCount; i ++) DrawEaterToGWorld (gEater[i].x, gEater[i].y); *cont = True; /* the event handler will not be removed */ } void x11_init(int argc, char **argv) { XGCValues v; XColor c, c1; Cursor cursor; Pixmap cursor_pm, cursor_mask_pm, colon; XColor cursor_fg, cursor_bg; Arg wargs[4]; XtTranslations ttab; int i; Dimension width, height; XpmAttributes xpm_attr; toplevel = XtVaAppInitialize(&app, /* application context */ ApplicationClassName, /* class */ NULL, 0, /* options */ &argc, argv, NULL, /* fallback resources */ NULL); XtAppAddActions(app, actions, XtNumber(actions)); XtGetApplicationResources(toplevel, (XtPointer) &resources, xonix_resources, XtNumber(xonix_resources), NULL, (Cardinal) 0); container = XtVaCreateManagedWidget("container", formWidgetClass, toplevel, NULL); game_menu= XtVaCreatePopupShell("game_menu", simpleMenuWidgetClass, container, NULL); game_button = XtVaCreateManagedWidget("game_button", menuButtonWidgetClass, container, XtNmenuName, "game_menu", NULL); game_about = XtVaCreateManagedWidget("about", smeBSBObjectClass, game_menu, NULL); game_l1 = XtVaCreateManagedWidget("game_l1", smeLineObjectClass, game_menu, NULL); game_quit = XtVaCreateManagedWidget("quit", smeBSBObjectClass, game_menu, NULL); XtAddCallback(game_quit, XtNcallback, QuitCallback, NULL); XtAddCallback(game_about, XtNcallback, AboutCallback, NULL); drawarea = XtVaCreateManagedWidget("canvas", coreWidgetClass, container, XtNfromVert, (XtPointer)game_button, XtNwidth, (sizex = FIELD_WIDTH), XtNheight, (sizey = FIELD_HEIGHT), NULL); statusarea = XtVaCreateManagedWidget("status", formWidgetClass, container, XtNfromVert, (XtPointer)drawarea, NULL); st_level = XtVaCreateManagedWidget("level", formWidgetClass, statusarea, NULL); st_lev_label = XtVaCreateManagedWidget("lev_label", labelWidgetClass, st_level, NULL); st_lev_d10 = XtVaCreateManagedWidget("lev_d10", labelWidgetClass, st_level, XtNfromHoriz, (XtPointer)st_lev_label, XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); st_lev_d1 = XtVaCreateManagedWidget("lev_d1", labelWidgetClass, st_level, XtNfromHoriz, (XtPointer)st_lev_d10, XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); st_percentage = XtVaCreateManagedWidget("percentage", formWidgetClass, statusarea, XtNfromHoriz, (XtPointer)st_level, NULL); st_perc_label = XtVaCreateManagedWidget("perc_label", labelWidgetClass, st_percentage, NULL); st_perc_d10 = XtVaCreateManagedWidget("perc_d10", labelWidgetClass, st_percentage, XtNfromHoriz, (XtPointer)st_perc_label, XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); st_perc_d1 = XtVaCreateManagedWidget("perc_d1", labelWidgetClass, st_percentage, XtNfromHoriz, (XtPointer)st_perc_d10, XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); st_runner = XtVaCreateManagedWidget("runner", formWidgetClass, statusarea, XtNfromHoriz, (XtPointer)st_percentage, NULL); st_run_label = XtVaCreateManagedWidget("run_label", labelWidgetClass, st_runner, NULL); st_run_d10 = XtVaCreateManagedWidget("run_d10", labelWidgetClass, st_runner, XtNfromHoriz, (XtPointer)st_run_label, XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); st_run_d1 = XtVaCreateManagedWidget("run_d1", labelWidgetClass, st_runner, XtNfromHoriz, (XtPointer)st_run_d10, XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); st_score = XtVaCreateManagedWidget("time", formWidgetClass, statusarea, XtNfromHoriz, (XtPointer)st_runner, NULL); st_score_label = XtVaCreateManagedWidget("time_label", labelWidgetClass, st_score, NULL); for(i = POINTS_DIGITS - 1; i >= 0; i--) { char WName[20]; sprintf(WName, "st_points%d", i + 1); st_points[i] = XtVaCreateManagedWidget(WName, labelWidgetClass, st_score, XtNfromHoriz, (XtPointer)(i == POINTS_DIGITS-1? st_score_label: st_points[i + 1]), XtNwidth, (XtPointer)d0_width, XtNheight, (XtPointer)d0_height, NULL); } XtRealizeWidget(toplevel); dpy = XtDisplay(toplevel); screenno = DefaultScreen(dpy); screen = DefaultScreenOfDisplay(dpy); vis = DefaultVisual(dpy, screenno); depth = DefaultDepth(dpy, screenno); cmap = DefaultColormap(dpy, screenno); if(depth < 4) XtAppError(app, "Depth too small, need at least 4"); win = XtWindow(toplevel); delwin = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, win, &delwin, 1); i = 0; XtSetArg(wargs[i], XtNwidth, (XtPointer)&width); i++; XtSetArg(wargs[i], XtNheight, (XtPointer)&height); i++; XtGetValues(toplevel, wargs, i); i = 0; XtSetArg(wargs[i], XtNminWidth, (XtPointer)(unsigned)width); i++; XtSetArg(wargs[i], XtNmaxWidth, (XtPointer)(unsigned)width); i++; XtSetArg(wargs[i], XtNminHeight, (XtPointer)(unsigned)height); i++; XtSetArg(wargs[i], XtNmaxHeight, (XtPointer)(unsigned)height); i++; XtSetValues(toplevel, wargs, i); ttab = XtParseTranslationTable(trans_table); XtOverrideTranslations(toplevel, ttab); XtOverrideTranslations(container, ttab); canv = XtWindow(drawarea); XtAddEventHandler(drawarea, evmask, True, XonixEventHandler, 0 /* client data or data transfer */); XAllocNamedColor (dpy, cmap, "cadet blue", &c1, &cursor_fg); XAllocNamedColor (dpy, cmap, "white", &c1, &cursor_bg); cursor_pm = XCreateBitmapFromData(dpy, canv, xonix_bits, xonix_width, xonix_height); cursor_mask_pm = XCreateBitmapFromData(dpy, canv, xonix_mask_bits, xonix_mask_width, xonix_mask_height); cursor = XCreatePixmapCursor(dpy, cursor_pm, cursor_mask_pm, &cursor_fg, &cursor_bg, xonix_mask_width/2, xonix_mask_height/2); XDefineCursor(dpy, canv, cursor); XtSetArg(wargs[0], XtNiconPixmap, (XtPointer)cursor_pm); XtSetValues(toplevel, wargs, 1); for(i = 0; i < 10; i++) { digit_pms[i] = XCreateBitmapFromData(dpy, XtWindow(statusarea), digit_bits[i], /* assume all digits are same size */ d0_width, d0_height); } colon = XCreateBitmapFromData(dpy, XtWindow(statusarea), colon_bits, colon_width, colon_height); XtSetArg(wargs[0], XtNbitmap, (XtPointer)colon); default_gc = DefaultGC(dpy, screenno); #define InitPM(item) \ (void)XpmCreatePixmapFromData(dpy, canv, item##_xpm, \ &item##_pm, NULL, &xpm_attr); xpm_attr.valuemask = XpmSize; InitPM(filled); filled_dims.width = xpm_attr.width; filled_dims.height = xpm_attr.height; InitPM(empty); empty_dims.width = xpm_attr.width; empty_dims.height = xpm_attr.height; InitPM(way); way_dims.width = xpm_attr.width; way_dims.height = xpm_attr.height; InitPM(runner); InitPM(flyer); InitPM(eater); v.function = GXcopy; v.fill_style = FillTiled; v.tile = empty_pm; empty_gc = XCreateGC(dpy, canv, GCTile|GCFillStyle, &v); gMyStatusArea = (char *)malloc(H_STEPS * V_STEPS); if(gMyStatusArea == 0) XtAppError(app, "No space for status area"); Do_New(); if(gTimer == 0) gTimer = XtAppAddTimeOut(app, resources.time_step, timeout, 0); } void x11_eventloop(void) { XtAppMainLoop(app); } void DrawRunnerToGWorld (void) { XCopyArea(dpy, runner_pm, canv, default_gc, 0, 0, gMyRunner.sx, gMyRunner.sy, gMyRunner.x * EATER_SIZE, gMyRunner.y * EATER_SIZE); } void DrawWayToGWorld (void) { XCopyArea(dpy, way_pm, canv, default_gc, (gMyRunner.x * EATER_SIZE) % way_dims.width, (gMyRunner.y * EATER_SIZE) % way_dims.height, gMyRunner.sx, gMyRunner.sy, gMyRunner.x * EATER_SIZE, gMyRunner.y * EATER_SIZE); } static void DrawWayElementToGWorld (int xPos, int yPos) { XCopyArea(dpy, way_pm, canv, default_gc, (xPos * EATER_SIZE) % way_dims.width, (yPos * EATER_SIZE) % way_dims.height, RUNNER_SIZE, RUNNER_SIZE, xPos * EATER_SIZE, yPos * EATER_SIZE); } void DrawEmptyToGWorld (int xPos, int yPos) { XCopyArea(dpy, empty_pm, canv, default_gc, (xPos * EATER_SIZE) % empty_dims.width, (yPos * EATER_SIZE) % empty_dims.height, RUNNER_SIZE, RUNNER_SIZE, xPos * EATER_SIZE, yPos * EATER_SIZE); } void DrawFlyerToGWorld (int xPos, int yPos) { XCopyArea(dpy, flyer_pm, canv, default_gc, 0, 0, RUNNER_SIZE, RUNNER_SIZE, xPos * EATER_SIZE, yPos * EATER_SIZE); } void DrawEaterToGWorld (int xPos, int yPos) { XCopyArea(dpy, eater_pm, canv, default_gc, 0, 0, EATER_SIZE, EATER_SIZE, xPos * EATER_SIZE, yPos * EATER_SIZE); } void DrawFilledToGWorld (int xPos, int yPos) { XCopyArea(dpy, filled_pm, canv, default_gc, (xPos * EATER_SIZE) % filled_dims.width, (yPos * EATER_SIZE) % filled_dims.height, RUNNER_SIZE, RUNNER_SIZE, xPos * EATER_SIZE, yPos * EATER_SIZE); } void DrawSmallFilledToGWorld (int xPos, int yPos) { XCopyArea(dpy, filled_pm, canv, default_gc, (xPos * EATER_SIZE) % way_dims.width, (yPos * EATER_SIZE) % way_dims.height, EATER_SIZE, EATER_SIZE, xPos * EATER_SIZE, yPos * EATER_SIZE); } void DrawCompleteBorder (void) { int i; for (i = 0; i < H_STEPS; i += RATIO) { DrawFilledToGWorld (i, 0); DrawFilledToGWorld (i, V_STEPS - RATIO); } for (i = RATIO; i < V_STEPS - RATIO; i += RATIO) { DrawFilledToGWorld (0, i); DrawFilledToGWorld (H_STEPS - RATIO, i); } } void DrawCompleteInside (void) { XFillRectangle(dpy, canv, empty_gc, RATIO * EATER_SIZE, RATIO * EATER_SIZE, (H_STEPS - 2 * RATIO) * EATER_SIZE, (V_STEPS - 2 * RATIO) * EATER_SIZE); } static void timeout(XtPointer client_data, XtIntervalId *timer) { if(gQuit) ExitXonix(0); if(gRun && !gPause) { Animate(); XSync(dpy, False); gTimer = XtAppAddTimeOut(app, resources.time_step, timeout, 0); } } static void DrawDigit(Widget w, int num) { Arg wargs[1]; if(num < 0 || num > 9) XtAppError(app, "Unreasonable value in DrawDigit()"); XtSetArg(wargs[0], XtNbitmap, (XtPointer)digit_pms[num]); XtSetValues(w, wargs, 1); } void ScorePercentage(int num) { if(num > 99) num = 99; /* sanity */ DrawDigit(st_perc_d10, num / 10); DrawDigit(st_perc_d1, num % 10); } void ScoreLevel(int num) { if(num > 99) num = 99; /* sanity */ DrawDigit(st_lev_d10, num / 10); DrawDigit(st_lev_d1, num % 10); } void ScoreRunner(int num) { if(num > 99) num = 99; /* sanity */ DrawDigit(st_run_d10, num / 10); DrawDigit(st_run_d1, num % 10); } static void PopdownGameOver(Widget w, XtPointer client_data, XtPointer call_data) { CallbackData *cb = (CallbackData *)client_data; XtPopdown(cb->w); switch(cb->button_number) { case 0: /* quit "i know" */ gQuit = True; break; case 1: /* goon "once more" */ exiting = 0; gQuit = False; gRun = False; gPause = False; Do_New(); break; } /* make sure, the quit will be notified */ XtRemoveTimeOut(gTimer); gTimer = XtAppAddTimeOut(app, resources.time_step, timeout, 0); } static void PopdownGeneric(Widget w, XtPointer client_data, XtPointer call_data) { XtPopdown((Widget)client_data); XtDestroyWidget((Widget)client_data); if(gameover_pending > 1) XtPopupSpringLoaded(gameover_shell); gameover_pending = 0; } static void QuitCallback(Widget w, XtPointer client_data, XtPointer call_data) { ExitXonix(0); } static void AboutCallback(Widget w, XtPointer client_data, XtPointer call_data) { DoAbout(); } static void DoAbout(void) { static Widget about = (Widget)0; Widget box, msg, done; Arg wargs[2]; int i; Cardinal x, y; about = XtVaCreatePopupShell("about_shell", transientShellWidgetClass, toplevel, NULL); box = XtVaCreateManagedWidget("about_box", boxWidgetClass, about, XtNorientation, (XtPointer)XtorientVertical, NULL); msg = XtVaCreateManagedWidget("about_msg", labelWidgetClass, box, XtNlabel, about_msg, NULL); done = XtVaCreateManagedWidget("about_done", commandWidgetClass, box, NULL); XtAddCallback(done, XtNcallback, PopdownGeneric, (XtPointer)about); i = 0; XtSetArg(wargs[i], XtNx, (XtPointer)&x); i++; XtSetArg(wargs[i], XtNy, (XtPointer)&y); i++; XtGetValues(toplevel, wargs, i); i = 0; XtSetArg(wargs[i], XtNx, (XtPointer)(x + 10)); i++; XtSetArg(wargs[i], XtNy, (XtPointer)(y + 10)); i++; XtSetValues(about, wargs, i); gameover_pending = 1; XtPopupSpringLoaded(about); } void ScorePoints (int points) { int i; for(i = 0; i < POINTS_DIGITS; i++) { DrawDigit(st_points[i], points % 10); points /= 10; } } #ifdef __unix struct score_rec { unsigned score, level; char login[11], full[65]; time_t tstamp; }; static int compare(const void *a, const void *b) { const struct score_rec *ra = (struct score_rec *)a; const struct score_rec *rb = (struct score_rec *)b; return ra->score - rb->score; } #endif /* __unix */ void DisplayHighScore(void) { #ifdef __unix /* * global high score file handling, non-unix (but X11) systems will * have to provide their own hooks here */ FILE *high; struct passwd *pw; char *fullname = 0, *cp; struct score_rec score_rec[MAXSCORES]; int i, numentries = 0; char tempname[sizeof(PATH_TEMPSCORE) + 15]; char hugestring[MAXSCORES * 100]; Widget box1, box2, msg, headl, done, area; Arg wargs[2]; Cardinal x, y; if((pw = getpwuid(getuid())) == 0) { fprintf(stderr, "xonix: Who are you?\n"); endpwent(); return; } endpwent(); if(strlen(pw->pw_gecos)) { /* replace & by login ID */ if((cp = strchr(pw->pw_gecos, '&'))) { fullname = (char *)malloc(strlen(pw->pw_gecos) + strlen(pw->pw_name) + 1); memset(fullname, 0, strlen(pw->pw_gecos) + strlen(pw->pw_name) + 1); strncpy(fullname, pw->pw_gecos, cp - pw->pw_gecos); strcat(fullname, pw->pw_name); strcat(fullname, cp + 1); /* see if first char of login ID needs to be capitalized */ cp = &fullname[cp - pw->pw_gecos]; *cp = toupper(*cp); } else fullname = strdup(pw->pw_gecos); if((cp = strchr(fullname, ','))) *cp = 0; /* remove trailing garbage */ } else fullname = strdup("(No name)"); /* the strdup() allows to free() it */ /* try opening high score file, and read it */ if((high = fopen(PATH_HIGHSCORE, "r"))) { for(i = 0; i < 10; i++) { char line[100]; if(fgets(line, 100, high) == NULL) break; if(sscanf(line, " %u %u%*[\t]%10[^\t]%*[\t]%64[^\t] %ld", &score_rec[i].score, &score_rec[i].level, score_rec[i].login, score_rec[i].full, &score_rec[i].tstamp) != 5) break; /* mangled entry */ } numentries = i; fclose(high); } if(numentries) qsort(score_rec, numentries, sizeof(struct score_rec), compare); /* make sure the new list will be world-readable */ (void)umask(umask(0) & ~0644); sprintf(tempname, "%s.%d", PATH_TEMPSCORE, (int)getpid()); if((high = fopen(tempname, "w")) == NULL) { fprintf(stderr, "xonix: cannot rewrite high score file\n"); free(fullname); gameover_pending = 0; return; } if(numentries >= MAXSCORES && gHighScore < score_rec[0].score) { /* sorry, not among top ten */ fclose(high); (void)unlink(tempname); free(fullname); gameover_pending = 0; return; } for(i = 0; i < numentries; i++) { /* look where to put entry */ if(score_rec[i].score > gHighScore) break; } #ifdef SEND_MAIL if(numentries > 0 && gHighScore > score_rec[numentries - 1].score && strcmp(pw->pw_name, score_rec[numentries - 1].login) != 0) { /* we have got a new champion, warn the old one (:-) */ FILE *mail; char cmd[200]; char tbuf[20]; struct score_rec *sp = &score_rec[numentries - 1]; struct tm *tm; strncpy(cmd, PATH_RMAIL, 200); strncat(cmd, " \"", 200 - 2 - strlen(cmd)); strncat(cmd, sp->login, 200 - strlen(sp->login) - strlen(cmd)); strncat(cmd, "\"", 200 - 1 - strlen(cmd)); tm = localtime(&sp->tstamp); strftime(tbuf, 20, "%d-%b-%y", tm); if((mail = popen(cmd, "w")) != NULL) { fprintf(mail, "To: %s (%s)\n" "Subject: Lost xonix championship\n\n" "Your previously held first rank in the local xonix score\n" "table (%u points, level %u, dated %s) has been\n" "vanished today by me with %u points.\n\n" "\t\tpitying you\t%s (%s)\n", sp->login, sp->full, sp->score, sp->level, tbuf, gHighScore, pw->pw_name, fullname); (void)pclose(mail); } } #endif /* SEND_MAIL */ if(numentries >= MAXSCORES) { i--; if(i > 0) /* we must shift something */ memmove(&score_rec[0], &score_rec[1], i * sizeof(struct score_rec)); } else { if(numentries > i) /* we must shift something */ memmove(&score_rec[i + 1], &score_rec[i], (numentries - i) * sizeof(struct score_rec)); numentries++; } score_rec[i].score = gHighScore; score_rec[i].level = gLevel; memset(score_rec[i].login, 0, 11); strncpy(score_rec[i].login, pw->pw_name, 10); memset(score_rec[i].full, 0, 65); strncpy(score_rec[i].full, fullname, 64); score_rec[i].tstamp = time(NULL); free(fullname); for(i = 0; i < numentries; i++) (void)fprintf(high, "%u\t%u\t%s\t%s\t%ld\n", score_rec[i].score, score_rec[i].level, score_rec[i].login, score_rec[i].full, score_rec[i].tstamp); fclose(high); if(rename(tempname, PATH_HIGHSCORE)) fprintf(stderr, "xonix: cannot install new highscore file\n"); /* create hugestring for highscore label */ hugestring[0] = 0; for(i = 0; i < numentries; i++) { struct score_rec *sp = &score_rec[numentries - i - 1]; struct tm *tm; char tbuf[20]; char line[100]; tm = localtime(&sp->tstamp); strftime(tbuf, 20, "%d-%b-%y", tm); sprintf(line, "%5u %5u %s %-10.10s %-.64s\n", sp->score, sp->level, tbuf, sp->login, sp->full); strcat(hugestring, line); } score_shell = XtVaCreatePopupShell("score_shell", transientShellWidgetClass, toplevel, NULL); box1 = XtVaCreateManagedWidget("score_box", boxWidgetClass, score_shell, XtNorientation, (XtPointer)XtorientVertical, NULL); box2 = XtVaCreateManagedWidget("score_box", boxWidgetClass, box1, XtNorientation, (XtPointer)XtorientVertical, NULL); msg = XtVaCreateManagedWidget("score_msg", labelWidgetClass, box2, NULL); headl = XtVaCreateManagedWidget("score_headl", labelWidgetClass, box2, NULL); area = XtVaCreateManagedWidget("score_area", labelWidgetClass, box2, XtNlabel, (XtPointer)hugestring, NULL); done = XtVaCreateManagedWidget("score_done", commandWidgetClass, box1, NULL); XtAddCallback(done, XtNcallback, PopdownGeneric, (XtPointer)score_shell); i = 0; XtSetArg(wargs[i], XtNx, (XtPointer)&x); i++; XtSetArg(wargs[i], XtNy, (XtPointer)&y); i++; XtGetValues(toplevel, wargs, i); i = 0; XtSetArg(wargs[i], XtNx, (XtPointer)(x + 10)); i++; XtSetArg(wargs[i], XtNy, (XtPointer)(y + 100)); i++; XtSetValues(score_shell, wargs, i); gameover_pending = 1; XtPopupSpringLoaded(score_shell); #else /* ! __unix */ gameover_pending = 0; #endif /* __unix */ } void ExitXonix(int status) { static CallbackData cb_iknow, cb_goon; Arg wargs[2]; int i; Cardinal x, y; /* game over dialog */ Widget box, msg, buttonbox, iknow, goon; if(status == 0 && !exiting) { if(gameover_shell == 0) { gameover_shell = XtVaCreatePopupShell("gameover_shell", transientShellWidgetClass, toplevel, NULL); box = XtVaCreateManagedWidget("gameover_box", boxWidgetClass, gameover_shell, XtNorientation, (XtPointer)XtorientVertical, NULL); msg = XtVaCreateManagedWidget("gameover_msg", labelWidgetClass, box, NULL); buttonbox = XtVaCreateManagedWidget("gameover_buttonbox", boxWidgetClass, box, NULL); iknow = XtVaCreateManagedWidget("gameover_iknow", commandWidgetClass, buttonbox, NULL); goon = XtVaCreateManagedWidget("gameover_goon", commandWidgetClass, buttonbox, NULL); XtInstallAllAccelerators(gameover_shell, toplevel); XtInstallAllAccelerators(gameover_shell, gameover_shell); XtInstallAllAccelerators(toplevel, toplevel); XtInstallAllAccelerators(toplevel, gameover_shell); cb_iknow.w = cb_goon.w = gameover_shell; cb_iknow.button_number = 0; cb_goon.button_number = 1; XtAddCallback(iknow, XtNcallback, PopdownGameOver, (XtPointer)&cb_iknow); XtAddCallback(goon, XtNcallback, PopdownGameOver, (XtPointer)&cb_goon); } exiting++; i = 0; XtSetArg(wargs[i], XtNx, (XtPointer)&x); i++; XtSetArg(wargs[i], XtNy, (XtPointer)&y); i++; XtGetValues(toplevel, wargs, i); i = 0; XtSetArg(wargs[i], XtNx, (XtPointer)(x + 10)); i++; XtSetArg(wargs[i], XtNy, (XtPointer)(y + 10)); i++; XtSetValues(gameover_shell, wargs, i); if(!gameover_pending++) XtPopupSpringLoaded(gameover_shell); } else exit(status); } int main(int argc, char **argv) { x11_init(argc, argv); x11_eventloop(); /* NOTREACHED */ return 1; } #endif /* USE_X11 */ xonix-1.4/xonix.c100644 153 7 123726 6026013552 11300 0ustar jbin/* Hey emacs, this is -*- Mode: C++; tab-width: 4 -*- */ /* ------------------------------------------------------------------------ */ /* NAME */ /* xonix.c */ /* */ /* BESCHREIBUNG */ /* xonix ist ein Spielprogramm, dessen Idee aus den Anfangszeiten der */ /* DOSEN stammt. Es wurde auf Basis von framework erstellt. */ /* ------------------------------------------------------------------------ */ /* * Copyright (c) 1995 * Torsten Schoenitz * Joerg Wunsch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* xonix.c,v 1.51 1995/09/14 11:52:10 j Exp */ #include /* Wegen der Zufaelligkeiten */ #include #include #include "xonix.h" #include "stack.h" #define AKT_STATUS (*(gMyStatusArea+H_STEPS*gMyRunner.y+gMyRunner.x)) /* ------------------------------------------------------------------------ */ /* Deklaration der globalen Variablen. */ /* ------------------------------------------------------------------------ */ Boolean gQuit, /* Wenn gQuit auf true gesetzt */ /* wird, terminiert die */ /* Applikation. */ gRun, /* Ist gRun auf true gesetzt */ /* laeuft das Spiel, sonst sind */ /* Einstellungen usw. moeglich */ gPause, /* Spiel unterbrochen */ gEndOfGame; /* Runner sind alle */ int gPlayer; /* Soviele Runner kann ich */ /* verheizen */ int gLevel; /* Es geht mit Level 1 los */ int gFlyerCount; /* Anzahl der Flieger */ int gFillCount; /* Anzahl gefuellter Flaechen- */ /* stuecke (Runner-Groesse) */ Player gFlyer[MAX_FLYER]; /* Alle Flieger */ int gEaterCount; /* Anzahl der Fresser */ Player gEater[MAX_EATER]; /* Alle Fresser */ Player gMyRunner; /* Spielfigur */ Ptr gMyStatusArea; /* Status-Area */ unsigned gHighScore; /* Punktestand */ int gLoops; /* Schleifenzaehler im Animate */ /* ------------------------------------------------------------------------ */ /* Forward-Declarations. */ /* ------------------------------------------------------------------------ */ void Do_New (void); void NewFlyer (void); void NewRunner (void); void NewEater (void); void NewPlayRoom (void); void GetNewPlayer (void); void CheckStatus (void); void DrawCompleteBorder (void); void ResetGlobals (void); void SetPlayerToStatus (int xPos, int yPos, unsigned char figur); Boolean HorizontalBounceCheck (int x, int y, int size, unsigned char *bouncePartner); Boolean VerticalBounceCheck (int x, int y, int size, unsigned char *bouncePartner); /* ------------------------------------------------------------------------ */ /* Do_New startet ein komplett neues Spiel */ /* ------------------------------------------------------------------------ */ void Do_New (void) { ResetGlobals (); /* Frisch an's Werk */ NewPlayRoom (); /* Neue Spielwiese anlegen */ gRun = TRUE; /* ... und ab gehts */ #ifdef USE_MAC if (gTheCWindow) /* das Window ist doch da ? */ ShowWindow (gTheCWindow); #endif return; } /* ------------------------------------------------------------------------ */ /* ResetGlobals setzt alle spielbestimmenden Globalen in den Ausgangs- */ /* zustand */ /* ------------------------------------------------------------------------ */ void ResetGlobals (void) { gFlyerCount = 0; gFillCount = 0; gEaterCount = 0; gLevel = 1; gPlayer = 5; gPause = FALSE; gEndOfGame = FALSE; gHighScore = 0; gLoops = 0; } /* ------------------------------------------------------------------------ */ /* TestFree kontrolliert, ob die uebergebene Position eine freie Position */ /* ist. In diesem Fall wird TRUE zurueckgegeben. Beim ersten Auftreten */ /* eines unfreien Platzes erfolgt die Rueckkehr mit FALSE. */ /* ------------------------------------------------------------------------ */ Boolean TestFree (int xPos, int yPos) { int i, j; for (i = 0; i < RATIO; i ++) for (j = 0; j < RATIO; j ++) if (*(gMyStatusArea + (yPos + i) * H_STEPS + (xPos + j)) != EMPTY) { return FALSE; } return TRUE; } /* ------------------------------------------------------------------------ */ /* RandomPosition errechnet eine zufaellige Position fuer einen neuen Flyer.*/ /* ------------------------------------------------------------------------ */ myPoint RandomPosition (void) { myPoint newPosition; srand ((unsigned int) time (0)); /* Zufallsgenerator initialis. */ newPosition.h = ((unsigned) rand () % ((H_STEPS / RATIO) - 4) + 2) * RATIO; newPosition.v = ((unsigned) rand () % ((V_STEPS / RATIO) - 4) + 2) * RATIO; return newPosition; } /* ------------------------------------------------------------------------ */ /* NewRunner erzeugt einen neuen Runner an der Ausgangsposition links oben */ /* im Rahmenbereich und traegt ihn in das Statusfeld ein */ /* ------------------------------------------------------------------------ */ void NewRunner (void) { gLoops = 0; gMyRunner.x = 0; gMyRunner.y = 0; gMyRunner.sx = RUNNER_SIZE; gMyRunner.sy = RUNNER_SIZE; gMyRunner.dx = 0; gMyRunner.dy = 0; SetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) RUNNER); ScoreRunner (gPlayer); return; } /* ------------------------------------------------------------------------ */ /* NewEater erzeugt einen neuen Fresser im Rahmenbereich und traegt ihn in */ /* das Statusfeld ein */ /* ------------------------------------------------------------------------ */ void NewEater (void) { if (gEaterCount < MAX_EATER) { gEater[gEaterCount].sx = EATER_SIZE; gEater[gEaterCount].sy = EATER_SIZE; gEater[gEaterCount].dx = 1; gEater[gEaterCount].dy = 1; switch (gEaterCount % 4) /* Anfangsrichtung der Fresser */ { case 0: gEater[gEaterCount].x = H_STEPS - RATIO; gEater[gEaterCount].y = V_STEPS - RATIO - 1 - gEaterCount * 4; break; case 1: gEater[gEaterCount].x = H_STEPS - RATIO - gEaterCount * 4; gEater[gEaterCount].y = V_STEPS - RATIO; gEater[gEaterCount].dy *= -1; break; case 2: gEater[gEaterCount].x = H_STEPS - RATIO - gEaterCount * 4; gEater[gEaterCount].y = 0; gEater[gEaterCount].dx *= -1; break; case 3: gEater[gEaterCount].x = 0; gEater[gEaterCount].y = V_STEPS - RATIO; gEater[gEaterCount].dx *= -1; gEater[gEaterCount].dy *= -1; break; } /* Fresser in Statusfeld eintragen */ *(gMyStatusArea + gEater[gEaterCount].y * H_STEPS + gEater[gEaterCount].x) |= (unsigned char) EATER; gEaterCount ++; } return; } /* ------------------------------------------------------------------------ */ /* ResetStatus erzeugt einen definierten Anfangszustand im StatusArea */ /* ------------------------------------------------------------------------ */ void ResetStatus (void) { int i, j, k; i = H_STEPS * V_STEPS; /* Also z.B. 150 x 100 */ j = H_STEPS * RATIO + RATIO; /* Beginn EMPTY-Bereich */ k = H_STEPS - (2 * RATIO); /* Breite EMPTY-Bereiches */ memset (gMyStatusArea, (char) FILLED, i); /* erstmal ist alles Rahmen */ memset (gMyStatusArea + j, (char) EMPTY, k); /* Eine Zeile mit Rand */ for (i = 1; i < V_STEPS - 2 * RATIO; i ++) { memcpy (gMyStatusArea + j + (i * H_STEPS), gMyStatusArea + j, k); /* Erste EMPTY-Zeile auf */ /* alle anderen kopieren */ } } /* ------------------------------------------------------------------------ */ /* SetPlayerToStatus traegt den Status der uebergebenen Spielfigur (Runner, */ /* Flyer oder Way) an der uebergebenen Position in das Statusfeld ein. */ /* ------------------------------------------------------------------------ */ void SetPlayerToStatus (int xPos, int yPos, unsigned char figur) { int i, j; for (i = 0; i < RATIO; i ++) for (j = 0; j < RATIO; j ++) *(gMyStatusArea + (yPos + i) * H_STEPS + (xPos + j)) |= figur; return; } /* ------------------------------------------------------------------------ */ /* UnsetPlayerToStatus loescht den Status der uebergebenen Spielfigur */ /* (Runner, Flyer oder Way) an der uebergebenen Position aus dem Statusfeld.*/ /* ------------------------------------------------------------------------ */ void UnsetPlayerToStatus (int xPos, int yPos, unsigned char figur) { int i, j; for (i = 0; i < RATIO; i ++) for (j = 0; j < RATIO; j ++) *(gMyStatusArea + (yPos + i) * H_STEPS + (xPos + j)) &= ~figur; return; } /* ------------------------------------------------------------------------ */ /* ChangeToFilled wechselt den Status von TESTFILLED zu FILLED */ /* ------------------------------------------------------------------------ */ void ChangeToFilled (int xPos, int yPos) { int i, j; for (i = 0; i < RATIO; i ++) for (j = 0; j < RATIO; j ++) { *(gMyStatusArea + (yPos + i) * H_STEPS + (xPos + j)) &= ~((unsigned char) TESTFILLED); *(gMyStatusArea + (yPos + i) * H_STEPS + (xPos + j)) |= (unsigned char) FILLED; } } /* ------------------------------------------------------------------------ */ /* SetEaterToStatus traegt einen Eater an der uebergebenen Position in das */ /* Statusfeld ein */ /* ------------------------------------------------------------------------ */ void SetEaterToStatus (int xPos, int yPos) { *(gMyStatusArea + (yPos * H_STEPS) + xPos) |= (unsigned char) EATER; } /* ------------------------------------------------------------------------ */ /* UnsetEaterToStatus loescht einen Eater an der uebergebenen Position aus */ /* dem Statusfeld */ /* ------------------------------------------------------------------------ */ void UnsetEaterToStatus (int xPos, int yPos) { *(gMyStatusArea + (yPos * H_STEPS) + xPos) &= ~((unsigned char) EATER); } /* ------------------------------------------------------------------------ */ /* ClearWay loescht die Spur des Runners */ /* ------------------------------------------------------------------------ */ void ClearWay (void) { int i, j; for (i = 0; i < V_STEPS; i += RATIO) for (j = 0; j < H_STEPS; j += RATIO) { if (*(gMyStatusArea + (i * H_STEPS) + j) == (unsigned char) WAY) { UnsetPlayerToStatus (j, i, (unsigned char) WAY); DrawEmptyToGWorld (j, i); } } } /* ------------------------------------------------------------------------ */ /* FillWay fuellt die Spur des Runners */ /* ------------------------------------------------------------------------ */ void FillWay (void) { int i, j; for (i = 0; i < V_STEPS; i += RATIO) for (j = 0; j < H_STEPS; j += RATIO) { if (*(gMyStatusArea + (i * H_STEPS) + j) == (unsigned char) WAY) { UnsetPlayerToStatus (j, i, (unsigned char) WAY); SetPlayerToStatus (j, i, (unsigned char) FILLED); DrawFilledToGWorld (j, i); gFillCount ++; } } } /* ------------------------------------------------------------------------ */ /* NewFlyer erzeugt einen neuen Flyer an einer zufaelligen Position und */ /* uebergibt ihn der Spielverwaltung */ /* ------------------------------------------------------------------------ */ void NewFlyer (void) { myPoint flyerStartPoint; if (gFlyerCount < MAX_FLYER) { do { flyerStartPoint = RandomPosition (); /* Zufaellige Startposition*/ } while (!(TestFree (flyerStartPoint.h, flyerStartPoint.v))); gFlyer[gFlyerCount].x = flyerStartPoint.h; gFlyer[gFlyerCount].y = flyerStartPoint.v; gFlyer[gFlyerCount].sx = FLYER_SIZE; gFlyer[gFlyerCount].sy = FLYER_SIZE; gFlyer[gFlyerCount].dx = FLYER_STEP; gFlyer[gFlyerCount].dy = FLYER_STEP; switch (gFlyerCount % 4) /* Anfangsrichtung festlegen */ { case 1: gFlyer[gFlyerCount].dx *= -1; break; case 2: gFlyer[gFlyerCount].dy *= -1; break; case 3: gFlyer[gFlyerCount].dx *= -1; gFlyer[gFlyerCount].dy *= -1; break; default: break; } SetPlayerToStatus (gFlyer[gFlyerCount].x, gFlyer[gFlyerCount].y, (unsigned char) FLYER); gFlyerCount ++; /* Hallo, wieder einer mehr !!! */ } return; } /* ------------------------------------------------------------------------ */ /* NewPlayRoom erzeugt eine komplett leere Spielumgebung mit Rand und */ /* leerem Innenraum sowie die dem Level entsprechende Anzahl an Stoeren- */ /* frieden */ /* ------------------------------------------------------------------------ */ void NewPlayRoom (void) { int i; GWorldEntry (); ResetStatus (); DrawCompleteInside (); DrawCompleteBorder (); ScorePercentage (0); ScorePoints (gHighScore); ScoreLevel (gLevel); for (i = 0, gFlyerCount = 0; i < gLevel + 1; i ++) { NewFlyer (); } NewRunner (); gFillCount = 0; for (i = 0, gEaterCount = 0; i < gLevel / 5 + 1; i ++) { NewEater (); } GWorldExit (); } /* ------------------------------------------------------------------------ */ /* NewLevel schaltet auf das naechste Level und fordert eine neue Spiel- */ /* flaeche an */ /* ------------------------------------------------------------------------ */ void NewLevel (void) { gHighScore += gLevel * LEVEL_BONUS_FACTOR; ScorePoints (gHighScore); gLevel ++; if (gLevel % 2 == 1) { gPlayer ++; /* Einen Runner als Bonus */ } NewPlayRoom (); /* Eine neue Spielwiese muss her*/ return; } /* ------------------------------------------------------------------------ */ /* SetRunner setzt die Schrittweite eines Runners; wird beim Tastendruck */ /* gerufen */ /* ------------------------------------------------------------------------ */ void SetRunner (int x, int y) { gMyRunner.dx = x; gMyRunner.dy = y; } /* ------------------------------------------------------------------------ */ /* SetOldRect setzt das Refresh-Rect eines Players auf die aktuelle Posi- */ /* tion */ /* ------------------------------------------------------------------------ */ void SetOldRect (Player *pl) { pl -> rr.top = (pl -> y) * EATER_SIZE; pl -> rr.bottom = (pl -> rr.top) + (pl -> sy); pl -> rr.left = (pl -> x) * EATER_SIZE; pl -> rr.right = (pl -> rr.left) + (pl -> sx); } /* ------------------------------------------------------------------------ */ /* SetUnionRect setzt das Refresh-Rect eines Players auf das gemeinsame */ /* Rechteck aus dem bisherigen Refresh-Rect und der aktuellen Position */ /* ------------------------------------------------------------------------ */ void SetUnionRect (Player *pl) { int x, y; x = (pl -> x) * EATER_SIZE; y = (pl -> y) * EATER_SIZE; pl -> rr.top = (pl -> rr.top) < y ? pl -> rr.top : y; pl -> rr.bottom = (pl -> rr.bottom) > (y + (pl -> sy)) ? pl -> rr.bottom : (y + (pl -> sy)); pl -> rr.left = (pl -> rr.left) < x ? pl -> rr.left : x; pl -> rr.right = (pl -> rr.right) > (x + (pl -> sx)) ? pl -> rr.right : (x + (pl -> sx)); } /* ------------------------------------------------------------------------ */ /* FindStartPoints sucht zwei mšgliche Startpunkte fuer das Fuellen */ /* ------------------------------------------------------------------------ */ void FindStartPoints (int *x1Start, int *y1Start, int *x2Start, int *y2Start) { if (gMyRunner.dx) /* horizontale Bewegung */ { if (gMyRunner.y >= (2 * RATIO)) { if (*(gMyStatusArea + gMyRunner.x - gMyRunner.dx + ((gMyRunner.y - RATIO) * H_STEPS)) == (unsigned char) EMPTY) { *x1Start = gMyRunner.x - gMyRunner.dx; *y1Start = gMyRunner.y - RATIO; } } if (gMyRunner.y < V_STEPS - (2 * RATIO)) { if (*(gMyStatusArea + gMyRunner.x - gMyRunner.dx + ((gMyRunner.y + RATIO) * H_STEPS)) == (unsigned char) EMPTY) { *x2Start = gMyRunner.x - gMyRunner.dx; *y2Start = gMyRunner.y + RATIO; } } } else if (gMyRunner.dy) /* vertikale Bewegung */ { if (gMyRunner.x >= (2 * RATIO)) { if (*(gMyStatusArea + gMyRunner.x - RATIO + ((gMyRunner.y - gMyRunner.dy) * H_STEPS)) == (unsigned char) EMPTY) { *x1Start = gMyRunner.x - RATIO; *y1Start = gMyRunner.y - gMyRunner.dy; } } if (gMyRunner.x < H_STEPS - (2 * RATIO)) { if (*(gMyStatusArea + gMyRunner.x + RATIO + ((gMyRunner.y - gMyRunner.dy) * H_STEPS)) == (unsigned char) EMPTY) { *x2Start = gMyRunner.x + RATIO; *y2Start = gMyRunner.y - gMyRunner.dy; } } } return; } /* ------------------------------------------------------------------------ */ /* FillUp fuellt den Bereich beginnend beim uebergebenen Startpunkt und */ /* liefert TRUE zurueck, wenn kein Flieger im Wege war (sonst FALSE) */ /* ------------------------------------------------------------------------ */ Boolean FillUp (int xStart, int yStart) { stack *fillStack; myPoint pt; Boolean runFlag; unsigned char nb; int i, j; if ((fillStack = InitStack ()) == NIL_POINTER) /* Ich bekomme nicht, */ { /* was ich will !!! */ ExitXonix (1); } Push (fillStack, xStart, yStart); /* Startpunkt in den Stack */ runFlag = TRUE; while ((Pop (fillStack, &pt)) && (runFlag == TRUE)) { SetPlayerToStatus (pt.h, pt.v, (unsigned char) TESTFILLED); if (pt.v >= (2 * RATIO)) /* oberen Nachbar testen */ { nb = *(gMyStatusArea + pt.h + (H_STEPS * (pt.v - RATIO))); if (nb == (unsigned char) EMPTY) { Push (fillStack, pt.h, pt.v - RATIO); } else if (nb == (unsigned char) FLYER) { runFlag = FALSE; } } if (pt.v < (V_STEPS - (2 * RATIO))) /* unteren Nachbar testen */ { nb = *(gMyStatusArea + pt.h + (H_STEPS * (pt.v + RATIO))); if (nb == (unsigned char) EMPTY) { Push (fillStack, pt.h, pt.v + RATIO); } else if (nb == (unsigned char) FLYER) { runFlag = FALSE; } } if (pt.h >= (2 * RATIO)) /* linken Nachbar testen */ { nb = *(gMyStatusArea + (pt.h - RATIO) + (H_STEPS * pt.v)); if (nb == (unsigned char) EMPTY) { Push (fillStack, pt.h - RATIO, pt.v); } else if (nb == (unsigned char) FLYER) { runFlag = FALSE; } } if (pt.h < (H_STEPS - (2 * RATIO))) /* rechten Nachbar testen */ { nb = *(gMyStatusArea + (pt.h + RATIO) + (H_STEPS * pt.v)); if (nb == (unsigned char) EMPTY) { Push (fillStack, pt.h + RATIO, pt.v); } else if (nb == (unsigned char) FLYER) { runFlag = FALSE; } } } if (runFlag) { for (i = RATIO; i <= V_STEPS - RATIO; i += RATIO) for (j = RATIO; j <= H_STEPS - RATIO; j += RATIO) { if (*(gMyStatusArea + (i * H_STEPS) + j) == (unsigned char) TESTFILLED) { ChangeToFilled (j, i); DrawFilledToGWorld (j, i); gFillCount ++; } } } else { for (i = RATIO; i <= V_STEPS - RATIO; i += RATIO) for (j = RATIO; j <= H_STEPS - RATIO; j += RATIO) { UnsetPlayerToStatus (j, i, (unsigned char) TESTFILLED); } } DeinitStack (fillStack); return runFlag; } /* ------------------------------------------------------------------------ */ /* SeedFillUp fuellt einen Bereich segmentweise beginnend beim uebergebenen */ /* Startpunkt und liefert TRUE zurueck, wenn kein Flieger im Wege war */ /* (sonst FALSE) */ /* ------------------------------------------------------------------------ */ Boolean SeedFillUp (int xStart, int yStart, Boolean wayToFill) { segStack *fillStack; mySegment sg; Boolean runFlag; int l, x1, x2, dy; unsigned char ov, av, nv, wv; int i, j, m, n; if ((fillStack = InitSegmentStack ()) == NIL_POINTER) /* Ich bekomme nicht, */ { /* was ich will !!! */ ExitXonix(1); } runFlag = TRUE; nv = (unsigned char) TESTFILLED; wv = (unsigned char) WAY; ov = *(gMyStatusArea + yStart * H_STEPS + xStart); PushSeg (fillStack, yStart, xStart, xStart, RATIO); PushSeg (fillStack, yStart + RATIO, xStart, xStart, -RATIO); while ((PopSeg (fillStack, &sg)) && (runFlag == TRUE)) { for (xStart = sg.xl; xStart >= RATIO && (av = *(gMyStatusArea + H_STEPS * sg.y + xStart)) == ov; xStart -= RATIO) { /* SetPlayerToStatus (xStart, sg.y, nv); */ /* Eigentlich reicht auch eine Markierung ! */ *(gMyStatusArea + H_STEPS * sg.y + xStart) |= nv; } if (av == (unsigned char) FLYER) runFlag = FALSE; if (xStart >= sg.xl) goto skip; l = xStart + RATIO; if (l < sg.xl) PushSeg (fillStack, sg.y, l, sg.xl - RATIO, -sg.dy); xStart = sg.xl + RATIO; do { for (; xStart <= H_STEPS - RATIO && (av = *(gMyStatusArea + H_STEPS * sg.y + xStart)) == ov; xStart += RATIO) { /* SetPlayerToStatus (xStart, sg.y, nv); */ /* Eigentlich reicht auch eine Markierung ! */ *(gMyStatusArea + H_STEPS * sg.y + xStart) |= nv; } if (av == (unsigned char) FLYER) runFlag = FALSE; PushSeg (fillStack, sg.y, l, xStart - RATIO, sg.dy); if (xStart > sg.xr + RATIO) PushSeg (fillStack, sg.y, sg.xr + RATIO, xStart - RATIO, -sg.dy); skip: for (xStart += RATIO; xStart <= sg.xr && *(gMyStatusArea + H_STEPS * sg.y + xStart) != ov; xStart += RATIO); l = xStart; } while (xStart <= sg.xr); } if ((runFlag) && (!wayToFill)) { for (i = RATIO; i <= V_STEPS - RATIO; i += RATIO) for (j = RATIO; j <= H_STEPS - RATIO; j += RATIO) { if (*(gMyStatusArea + (i * H_STEPS) + j) == nv) { /* ChangeToFilled (j, i); */ *(gMyStatusArea + H_STEPS * i + j) &= ~nv; for (m = 0; m < RATIO; m ++) for (n = 0; n < RATIO; n ++) *(gMyStatusArea + (i + m) * H_STEPS + j + n) |= (unsigned char) FILLED; DrawFilledToGWorld (j, i); gFillCount ++; } } } else if ((!runFlag) && (!wayToFill)) { for (i = RATIO; i <= V_STEPS - RATIO; i += RATIO) for (j = RATIO; j <= H_STEPS - RATIO; j += RATIO) { /* UnsetPlayerToStatus (j, i, nv); */ /* Eigentlich reicht auch eine Markierung ! */ *(gMyStatusArea + H_STEPS * i + j) &= ~nv; } } else if ((runFlag) && (wayToFill)) { for (i = RATIO; i <= V_STEPS - RATIO; i += RATIO) for (j = RATIO; j <= H_STEPS - RATIO; j += RATIO) { if (*(gMyStatusArea + (i * H_STEPS) + j) & (nv | wv)) { for (m = 0; m < RATIO; m ++) for (n = 0; n < RATIO; n ++) { *(gMyStatusArea + (i + m) * H_STEPS + j + n) &= ~(nv | wv); *(gMyStatusArea + (i + m) * H_STEPS + j + n) |= (unsigned char) FILLED; } DrawFilledToGWorld (j, i); gFillCount ++; } } } else if ((!runFlag) && (wayToFill)) { for (i = RATIO; i <= V_STEPS - RATIO; i += RATIO) for (j = RATIO; j <= H_STEPS - RATIO; j += RATIO) { if (*(gMyStatusArea + (i * H_STEPS) + j) == wv) { for (m = 0; m < RATIO; m ++) for (n = 0; n < RATIO; n ++) { *(gMyStatusArea + (i + m) * H_STEPS + j + n) &= ~wv; *(gMyStatusArea + (i + m) * H_STEPS + j + n) |= (unsigned char) FILLED; } DrawFilledToGWorld (j, i); gFillCount ++; } else { for (m = 0; m < RATIO; m ++) for (n = 0; n < RATIO; n ++) { *(gMyStatusArea + (i + m) * H_STEPS + j + n) &= ~nv; } } } } DeinitSegmentStack (fillStack); return runFlag; } /* ------------------------------------------------------------------------ */ /* NewRunnerPosition berechnet die neue Position der Spielfigur, zeichnet */ /* die Schleifspur und gibt im Falle eines Bummses den bouncePartner */ /* zurueck (ansonsten EMPTY) */ /* ------------------------------------------------------------------------ */ unsigned char NewRunnerPosition (void) { int i, j; Boolean bounced; unsigned char bouncePartner; GWorldEntry (); bounced = FALSE; SetOldRect (&gMyRunner); if (gMyRunner.dx < 0) /* nach links */ { if (gMyRunner.x == 0) gMyRunner.dx = 0; else bounced = VerticalBounceCheck (gMyRunner.x - 1, gMyRunner.y, RATIO, &bouncePartner) && ((AKT_STATUS & (unsigned char) FILLED) != (unsigned char) FILLED); } else if (gMyRunner.dx > 0) /* nach rechts */ { if (gMyRunner.x == H_STEPS - RATIO) gMyRunner.dx = 0; else bounced = VerticalBounceCheck (gMyRunner.x + RATIO, gMyRunner.y, RATIO, &bouncePartner) && ((AKT_STATUS & (unsigned char) FILLED) != (unsigned char) FILLED); } else if (gMyRunner.dy < 0) /* nach oben */ { if (gMyRunner.y == 0) gMyRunner.dy = 0; else bounced = HorizontalBounceCheck (gMyRunner.x, gMyRunner.y - 1, RATIO, &bouncePartner) && ((AKT_STATUS & (unsigned char) FILLED) != (unsigned char) FILLED); } else if (gMyRunner.dy > 0) /* nach unten */ { if (gMyRunner.y == V_STEPS - RATIO) gMyRunner.dy = 0; else bounced = HorizontalBounceCheck (gMyRunner.x, gMyRunner.y + RATIO, RATIO, &bouncePartner) && ((AKT_STATUS & (unsigned char) FILLED) != (unsigned char) FILLED); } if (bounced == TRUE) /* irgendwas liegt im Weg */ { switch (bouncePartner) { case (unsigned char) FILLED: /* Geschafft */ if ((AKT_STATUS & (WAY + FILLED)) == (unsigned char) EMPTY) { UnsetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) RUNNER); SetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) WAY); DrawWayToGWorld (); gMyRunner.x += gMyRunner.dx; gMyRunner.y += gMyRunner.dy; SetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) RUNNER); DrawRunnerToGWorld (); } else { bouncePartner = (unsigned char) EMPTY; } break; case (unsigned char) WAY: /* Pech gehabt ! */ break; case (unsigned char) FLYER: /* Boing ! */ break; } } else /* Hinterlasse eine Spur */ { UnsetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) RUNNER); if (TestFree (gMyRunner.x, gMyRunner.y)) { SetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) WAY); DrawWayToGWorld (); } else { DrawFilledToGWorld (gMyRunner.x, gMyRunner.y); } gMyRunner.x += gMyRunner.dx; /* Auf zur naechsten Position */ gMyRunner.y += gMyRunner.dy; SetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) RUNNER); DrawRunnerToGWorld (); bouncePartner = (unsigned char) EMPTY; } SetUnionRect (&gMyRunner); GWorldExitRunner(); return bouncePartner; } /* ------------------------------------------------------------------------ */ /* FillNewArea fuellt den abgegrenzten Bereich, in dem keine Flieger herum- */ /* geistern */ /* ------------------------------------------------------------------------ */ void FillNewArea (void) { int x1, y1, x2, y2; int percent, oldFillCount; Boolean wayToFill; double bonusFactor; GWorldEntry (); FindStartPoints (&x1, &y1, &x2, &y2); /* Wo geht die Fuellerei los ? */ wayToFill = TRUE; oldFillCount = gFillCount; if ((x1 >= RATIO) && (x1 < H_STEPS - RATIO) && (y1 >= RATIO) && (y1 < V_STEPS - RATIO)) { SeedFillUp (x1, y1, wayToFill); /* Fuelle erste Region */ wayToFill = FALSE; } if ((x2 >= RATIO) && (x2 < H_STEPS - RATIO) && (y2 >= RATIO) && (y2 < V_STEPS - RATIO)) { SeedFillUp (x2, y2, wayToFill); /* Fuelle zweite Region */ wayToFill = FALSE; } if (wayToFill == TRUE) FillWay (); /* Fuelle wenigstens die Spur */ gMyRunner.dx = 0; /* Hier wird gestoppt */ gMyRunner.dy = 0; percent = (gFillCount * 100) / ((H_STEPS / RATIO - 2) * (V_STEPS / RATIO - 2)); ScorePercentage (percent); gHighScore += (gFillCount - oldFillCount) * gLevel * LOOP_FACTOR / gLoops; ScorePoints (gHighScore); gLoops = 0; GWorldExit (); return; } /* ------------------------------------------------------------------------ */ /* NewEaterPosition setzt die Fresser auf die naechste Position und kon- */ /* trolliert evtl. moegliche Knabber-Angriffe auf die Spielfigur. Wurde die */ /* Spielfigur angeknabbert, wird TRUE zurueckgegeben. */ /* ------------------------------------------------------------------------ */ Boolean NewEaterPosition (void) { int i, j; int nextX, nextY; Boolean hbFlag, vbFlag, returnFlag; unsigned char bouncePartner; GWorldEntry (); returnFlag = FALSE; hbFlag = FALSE; vbFlag = FALSE; for (i = 0; i < gEaterCount; i ++) { nextX = gEater[i].x + gEater[i].dx; nextY = gEater[i].y + gEater[i].dy; if ((nextX >= 0) && (nextX < H_STEPS)) /* Alles bleibt im Rahmen */ { if ((bouncePartner = *(gMyStatusArea + gEater[i].y * H_STEPS + nextX)) != (unsigned char) FILLED) /* Bumm !!! */ { if ((bouncePartner & (unsigned char) RUNNER) == (unsigned char) RUNNER) /* Aetsch ! */ { returnFlag = TRUE; } hbFlag = TRUE; gEater[i].dx *= -1; } } else /* Hier darf keiner 'raus */ { hbFlag = TRUE; gEater[i].dx *= -1; /* Wende !!! */ } if ((nextY >= 0) && (nextY < V_STEPS)) /* Alles bleibt im Rahmen */ { if ((bouncePartner = *(gMyStatusArea + nextY * H_STEPS + gEater[i].x)) != (unsigned char) FILLED) /* Bumm ! */ { if ((bouncePartner & (unsigned char) RUNNER) == (unsigned char) RUNNER) /* Aetsch ! */ { returnFlag = TRUE; } vbFlag = TRUE; gEater[i].dy *= -1; } } else /* Hier darf keiner 'raus */ { vbFlag = TRUE; gEater[i].dy *= -1; /* Wende !!! */ } if ((vbFlag == FALSE) && (hbFlag == FALSE)) /* evtl. nur diagonal */ { if ((bouncePartner = *(gMyStatusArea + nextY * H_STEPS + nextX)) != (unsigned char) FILLED) /* Bumm ! */ { gEater[i].dx *= -1; gEater[i].dy *= -1; if ((bouncePartner & (unsigned char) RUNNER) == (unsigned char) RUNNER) /* Aetsch ! */ { returnFlag = TRUE; } } } } /* Alle Anstoessigkeiten sind abgeklaert, nun mal los ! */ for (i = 0; i < gEaterCount; i ++) { SetOldRect (&(gEater[i])); DrawSmallFilledToGWorld (gEater[i].x, gEater[i].y); UnsetEaterToStatus (gEater[i].x, gEater[i].y); gEater[i].x += gEater[i].dx; gEater[i].y += gEater[i].dy; SetEaterToStatus (gEater[i].x, gEater[i].y); DrawEaterToGWorld (gEater[i].x, gEater[i].y); SetUnionRect (&(gEater[i])); } GWorldExitEater (); return returnFlag; } /* ------------------------------------------------------------------------ */ /* CheckPercentage liefert TRUE, wenn der Schwellwert des Fuellstands */ /* ueberschritten wird */ /* ------------------------------------------------------------------------ */ Boolean CheckPercentage (void) { int percent; percent = (gFillCount * 100) / ((H_STEPS / RATIO - 2) * (V_STEPS / RATIO - 2)); if (percent >= PERCENT_THRESHOLD) return TRUE; else return FALSE; } /* ------------------------------------------------------------------------ */ /* GetNewPlayer setzt die Spielfigur wieder an den Ausgangspunkt zurueck */ /* und kassiert dafuer ein Leben */ /* ------------------------------------------------------------------------ */ void GetNewPlayer (void) { GWorldEntry(); UnsetPlayerToStatus (gMyRunner.x, gMyRunner.y, (unsigned char) RUNNER); if (TestFree (gMyRunner.x, gMyRunner.y)) DrawEmptyToGWorld (gMyRunner.x, gMyRunner.y); else DrawFilledToGWorld (gMyRunner.x, gMyRunner.y); DrawCompleteBorder (); ClearWay (); if (!(-- gPlayer)) { gRun = FALSE; gQuit = TRUE; gEndOfGame = TRUE; #ifndef USE_MAC /* mac does it inside the main loop */ DisplayHighScore(); #endif } else { NewRunner (); BELL (); } GWorldExit(); return; } /* ------------------------------------------------------------------------ */ /* HorizontalBounceCheck testet ab der uebergebenen Position ueber die */ /* Breite von size, ob der Bereich unbelegt (EMPTY) ist. Andernfalls wird */ /* TRUE zurueckgegeben, um zu signalisieren, dass es gebummst hat. */ /* ------------------------------------------------------------------------ */ Boolean HorizontalBounceCheck (int x, int y, int size, unsigned char *bouncePartner) { int i; for (i = 0; i < size; i ++) { if ((*bouncePartner = *(gMyStatusArea + (y * H_STEPS) + (i + x))) != (char) EMPTY) { return TRUE; } } return FALSE; } /* ------------------------------------------------------------------------ */ /* VerticalBounceCheck testet ab der uebergebenen Position ueber die Hoehe */ /* von size, ob der Bereich unbelegt (EMPTY) ist. Andernfalls wird TRUE */ /* zurueckgegeben, um zu signalisieren, dass es gebummst hat. */ /* ------------------------------------------------------------------------ */ Boolean VerticalBounceCheck (int x, int y, int size, unsigned char *bouncePartner) { int i; for (i = 0; i < size; i ++) { if ((*bouncePartner = *(gMyStatusArea + ((i + y) * H_STEPS) + x)) != (char) EMPTY) { return TRUE; } } return FALSE; } /* ------------------------------------------------------------------------ */ /* NewFlyerPosition berechnet die naechste Position der Flieger und zeich- */ /* net sie entsprechend. */ /* ------------------------------------------------------------------------ */ Boolean NewFlyerPosition (void) { int i, j; unsigned char bouncePartner; Boolean returnFlag, vbFlag, hbFlag; GWorldEntry (); returnFlag = FALSE; vbFlag = FALSE; hbFlag = FALSE; for (i = 0; i < gFlyerCount; i ++) { vbFlag = VerticalBounceCheck (gFlyer[i].x + gFlyer[i].dx, gFlyer[i].y, RATIO, &bouncePartner); if (vbFlag == TRUE) { gFlyer[i].dx *= -1; if ((bouncePartner == ((unsigned char) WAY)) || (bouncePartner == ((unsigned char) RUNNER))) returnFlag = TRUE; if (HorizontalBounceCheck (gFlyer[i].x + gFlyer[i].dx, gFlyer[i].y + gFlyer[i].dy, 1, &bouncePartner) == TRUE) gFlyer[i].dy *= -1; if ((bouncePartner == ((unsigned char) WAY)) || (bouncePartner == ((unsigned char) RUNNER))) returnFlag = TRUE; } hbFlag = HorizontalBounceCheck (gFlyer[i].x, gFlyer[i].y + gFlyer[i].dy, RATIO, &bouncePartner); if (hbFlag == TRUE) { gFlyer[i].dy *= -1; if ((bouncePartner == ((unsigned char) WAY)) || (bouncePartner == ((unsigned char) RUNNER))) returnFlag = TRUE; if (HorizontalBounceCheck (gFlyer[i].x + gFlyer[i].dx, gFlyer[i].y + gFlyer[i].dy, 1, &bouncePartner) == TRUE) gFlyer[i].dx *= -1; if ((bouncePartner == ((unsigned char) WAY)) || (bouncePartner == ((unsigned char) RUNNER))) returnFlag = TRUE; } if ((vbFlag == FALSE) && (hbFlag == FALSE)) /* evtl. nur diagonal ? */ { if (HorizontalBounceCheck (gFlyer[i].x + gFlyer[i].dx, gFlyer[i].y + gFlyer[i].dy, 1, &bouncePartner) == TRUE) { gFlyer[i].dx *= -1; gFlyer[i].dy *= -1; if ((bouncePartner == ((unsigned char) WAY)) || (bouncePartner == ((unsigned char) RUNNER))) returnFlag = TRUE; } } } /* Anstoessiges ist geklaert, jetzt geht es zur Sache */ for (i = 0; (i < gFlyerCount) && (returnFlag == FALSE); i ++) { SetOldRect (&(gFlyer[i])); DrawEmptyToGWorld (gFlyer[i].x, gFlyer[i].y); UnsetPlayerToStatus (gFlyer[i].x, gFlyer[i].y, (unsigned char) FLYER); gFlyer[i].x += gFlyer[i].dx; gFlyer[i].y += gFlyer[i].dy; SetPlayerToStatus (gFlyer[i].x, gFlyer[i].y, (unsigned char) FLYER); DrawFlyerToGWorld (gFlyer[i].x, gFlyer[i].y); SetUnionRect (&(gFlyer[i])); } GWorldExitFlyer (); return returnFlag; } /* ------------------------------------------------------------------------ */ /* Animate laesst alle Figuren auf ihre neuen Positionen wechseln und auf */ /* evtl. Kollisionen bzw. Fuellerfordernisse ueberpruefen */ /* ------------------------------------------------------------------------ */ void Animate (void) { switch (NewRunnerPosition ()) { case (unsigned char) FILLED: /* Abgrenzung geschaffen */ FillNewArea (); if (CheckPercentage () == TRUE) { NewLevel (); /* Schwelle Fuellstand erreicht */ } break; case (unsigned char) WAY: /* Eigene Spur erwischt */ GetNewPlayer (); break; default: if (NewEaterPosition () == TRUE)/* Spielfigur von Fresser "ange-*/ { /* knabbert" */ GetNewPlayer (); } else if (NewFlyerPosition () == TRUE) /* Spur der Spielfigur von*/ { /* Flieger getroffen */ GetNewPlayer (); } break; } if(gRun && !gPause) { gLoops ++; } } xonix-1.4/xonix.h100644 153 7 25230 6024011042 11242 0ustar jbin/* Hey emacs, make this use -*- Mode: C++; tab-width: 4 -*- */ #ifndef XONIX_H #define XONIX_H /* * xonix global definitions * * xonix.h,v 1.39 1995/09/08 09:51:30 j Exp */ /* * Copyright (c) 1995 * Torsten Schoenitz * Joerg Wunsch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef USE_X11 #include /* Boolean et al. */ #include #endif #ifdef USE_MAC #include /* Basistypendeklarationen. */ #include #include /* Interface-Datei zu den QuickDraw-Datenstruk- */ /* turen und Routinen. */ #include /* Wegen der hintergruendigen GWorld-Geschichten*/ #include /* Interface-Datei des Font-Managers (wird vom */ /* Window-Manager benoetigt). */ #include /* Interface-Datei des Window-Managers (hier */ /* wird u.a. GetNewWindow deklariert). */ #include /* Interface-Datei zu den Routinen und Daten- */ /* strukturen des Event-Managers. */ #include /* ToolBox-Utilities (z.B. HiWord, LoWord). */ #include /* Interface-Datei des Menu-Managers. */ #include /* Desk-Manager (Kompatibilitaet zu System 6.x +*/ /* Finder in bezug auf Schreibtischprogramme). */ #include /* Interface-Datei des TextEdit-Managers (wird */ /* vom Dialog-Manager verwendet). */ #include /* Interface-Datei des Dialog-Managers. */ #include /* Einsprungadressen bzw. Datenstrukturen von */ /* SFGetFile und SFPutFile. */ #endif /* USE_MAC */ /* Typedefs.*/ struct point { short h, v; }; typedef struct point myPoint; struct rectangle { short top, left, bottom, right; }; typedef struct rectangle myRect; #ifdef USE_MAC struct keyboardPrefs { char leftKey, rightKey, upKey, downKey, pauseKey; }; typedef struct keyboardPrefs kbPrefs, *kbPrefsPtr, **kbPrefsHandle; struct highScoreEntry { Str255 name; int score; int level; }; typedef struct highScoreEntry hgScoreEntry, *hgScoreEntryPtr, **hgScoreEntryHandle; #endif /* USE_MAC */ struct Player { int x, y; /* Koordinaten der Figur */ int sx, sy; /* Groesse der Figur */ int dx, dy; /* Schrittweite der Figur */ myRect rr; /* Redraw-Rechteck */ }; typedef struct Player Player; struct Segment { int y; int xl; int xr; int dy; }; typedef struct Segment mySegment; enum attribute { EMPTY = 0x00, /* Ungefuellt */ WAY = 0x01, /* Spur des Runners */ TESTFILLED = 0x02, /* Probefuellung */ FILLED = 0x04, /* Endgueltig gefuellt */ BORDER = 0x08, /* Rahmen */ RUNNER = 0x80, /* Spielfigur */ FLYER = 0x40, /* Flieger */ EATER = 0x20 /* Fresser */ }; /* Andere Konstanten. */ /* Die Spieldimensionen werden durch die "Fresser"-Groesse bestimmt. */ /* H_STEPS und V_STEPS sollten multipliziert mit EATER_SIZE jeweils */ /* etwa 600 bzw. 400 ergeben */ #define EATER_SIZE 4 /* Groesse der "Fresser" */ #define RATIO 2 /* Faktor von Eater zu Runner */ #define H_STEPS 150 /* Horizontal moegl. Positionen */ #define V_STEPS 100 /* Vertikal moegl. Positionen */ #define PERCENT_THRESHOLD 75 /* Fuellstand - Schwelle */ #define LEVEL_BONUS_FACTOR 100.0 /* Bonus fuer geschafftes Level */ #define LOOP_FACTOR 10.0 /* Faktor fuer Punktberechnung */ #define EATER_STEP 1 /* Schrittweite der "Fresser"*/ #define FLYER_SIZE RATIO*EATER_SIZE /* Groesse der "Flieger" */ #define FLYER_STEP RATIO /* Schrittweite der "Flieger"*/ #define RUNNER_SIZE RATIO*EATER_SIZE /* Groesse der Spielfigur */ #define RUNNER_STEP RATIO /* Schrittweite der Spielfig.*/ #define FIELD_WIDTH H_STEPS*EATER_SIZE /* Breite des Spielfeldes */ #define FIELD_HEIGHT V_STEPS*EATER_SIZE /* Hoehe des Spielfeldes */ #define WINDOW_START_X 20 #define WINDOW_START_Y 40 #define MAX_FLYER 10 #define MAX_EATER 4 #ifdef USE_X11 typedef unsigned char * Ptr; #define NIL_POINTER NULL #define STEP_TIME 50 /* Schrittweite in ms */ #define BELL() XBell(dpy, 50) #endif #ifdef USE_MAC #define KEY char #define BELL() RunnerDieSound() #endif /* ------------------------------------------------------------------------ */ /* Deklaration der globalen Variablen. */ /* ------------------------------------------------------------------------ */ extern Boolean gQuit, /* Wenn gQuit auf true gesetzt */ /* wird, terminiert die Appli- */ /* kation. */ gRun, /* Ist gRun auf true gesetzt, */ /* laeuft das Spiel, sonst sind */ /* Einstellungen usw. moeglich */ gPause, /* Spiel unterbrochen */ gEndOfGame; /* Runner sind alle */ extern int gFlyerCount; /* Anzahl der Flieger */ extern Player gFlyer[MAX_FLYER]; /* Alle Flieger */ extern int gEaterCount; /* Anzahl der Fresser */ extern Player gEater[MAX_EATER]; /* Alle Fresser */ extern Player gMyRunner; /* Spielfigur */ extern Ptr gMyStatusArea; /* Status-Area */ extern unsigned gHighScore; /* Punktestand */ extern int gLevel; /* Es geht mit Level 1 los */ #ifdef USE_MAC extern GWorldPtr gMyGWorld; /* Offscreen-Area */ extern WindowPtr gTheCWindow; /* Das Window fuer alles */ extern Rect gWorldRect; #endif /* USE_MAC */ #ifdef USE_X11 extern Display *dpy; #endif /* USE_X11 */ /* ------------------------------------------------------------------------ */ /* Funktionen */ /* ------------------------------------------------------------------------ */ extern void Animate (void); extern void Do_Event (void); extern void DrawRunnerToGWorld (void); extern void DrawWayToGWorld (void); extern void DrawEmptyToGWorld (int xPos, int yPos); extern void DrawFlyerToGWorld (int xPos, int yPos); extern void DrawEaterToGWorld (int xPos, int yPos); extern void DrawFilledToGWorld (int xPos, int yPos); extern void DrawSmallFilledToGWorld (int xPos, int yPos); extern void DrawCompleteBorder (void); extern void SetRunner (int x, int y); extern void ClearWay (void); extern Boolean FillUp (int x, int y); extern void ExitXonix (int number); extern void ScorePercentage (int num); extern void ScoreLevel (int num); extern void ScoreRunner (int num); extern void ShowHighScore (void); #ifdef USE_MAC #define NIL_POINTER 0L #define GWorldEntry() \ GDHandle oldGD; \ GWorldPtr oldGW; \ GetGWorld (&oldGW, &oldGD); \ LockPixels (gMyGWorld -> portPixMap); \ SetGWorld (gMyGWorld, NIL_POINTER) #define GWorldExit() \ SetGWorld (oldGW, oldGD); \ SetPort (gTheCWindow); \ CopyBits ((BitMap*)*gMyGWorld -> portPixMap, &gTheCWindow -> portBits, \ &gWorldRect, \ &gWorldRect, srcCopy, 0L); \ UnlockPixels (gMyGWorld -> portPixMap) #define GWorldExitFlyer() \ SetGWorld (oldGW, oldGD); \ SetPort (gTheCWindow); \ for (i = 0; i < gFlyerCount; i ++) \ CopyBits ((BitMap*)*gMyGWorld -> portPixMap, &gTheCWindow -> portBits, \ &gFlyer[i].rr, \ &gFlyer[i].rr, srcCopy, 0L); \ UnlockPixels (gMyGWorld -> portPixMap) #define GWorldExitEater() \ SetGWorld (oldGW, oldGD); \ SetPort (gTheCWindow); \ for (i = 0; i < gEaterCount; i ++) \ CopyBits ((BitMap*)*gMyGWorld -> portPixMap, &gTheCWindow -> portBits, \ &gEater[i].rr, \ &gEater[i].rr, srcCopy, 0L); \ UnlockPixels (gMyGWorld -> portPixMap) #define GWorldExitRunner() \ SetGWorld (oldGW, oldGD); \ SetPort (gTheCWindow); \ CopyBits ((BitMap*)*gMyGWorld -> portPixMap, &gTheCWindow -> portBits, \ &gMyRunner.rr, \ &gMyRunner.rr, srcCopy, 0L); \ UnlockPixels (gMyGWorld -> portPixMap) #endif /* USE_MAC */ #ifdef USE_X11 #define GWorldEntry() #define GWorldExit() #define GWorldExitFlyer() #define GWorldExitEater() #define GWorldExitRunner() #endif /* USE_X11 */ #ifdef __FreeBSD__ #define rand() random() #define srand(x) srandom(x) #endif /* __FreeBSD */ #endif /* XONIX_H */ xonix-1.4/xonix.man100644 153 7 13045 6020320473 11576 0ustar jbin.\" .\" Copyright (c) 1995 .\" Joerg Wunsch .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" xonix.man -- man page for the xonix game .\" .\" xonix.man,v 1.7 1995/08/28 10:58:03 j Exp .\" .TH XONIX 6 .SH NAME xonix \- a game .SH SYNOPSIS .B xonix [ .I \-toolkitoption \&.\|.\|. ] .SH DESCRIPTION The \fIxonix\fP application consists of a playing area and a status display below. The status display shows the current values for level, filled area (in percent), number of players (lifes), and elapsed time. The playing area has several regions. The brown region (initially only the border) is ``filled region'', where the player can move, starting from the top left corner. Beware of the bouncing yellow eater(s) that do also move across filled regions however, if they hit the player, a life will go away. The flyers can only bounce across the green (so-called empty) area in the middle. The purpose of the game is to move the player across the empty region (whereby it leaves his way in a brown color to show where it came along), and finally cut off a piece of unfilled region by moving him back to some filled region. If the player itself or the (unfilled yet) way will be hit by a flyer, a life will be lost again. Once the player's way reached another part of filled region, the way and all adjacent unfilled regions where there is no flyer in will be filled in turn. One level has completed as soon as 75 % of the originally unfilled area have been filled this way. Every level, there will be one flyer more. Every second level, an additional player will be granted. Every fifth level, an additional eater will be fired off. The default keys to move the player around are the arrow keys. This can be changed in the app-defaults file, however, as well as the timeout between single steps (defaulting to 50 ms equal 20 moves per second). The default keys to immediately quit the game are `Q' and `Escape'. Hitting `P' or iconizing the window with the window manager will pause the game; de-iconizing will continue it. On Posix-compliant systems, there is also a high-score file, \fB$PROJECTROOT/\fP\fIlib/X11/xonix/scores\fP. It records the top ten xonix players for that machine. As a special compile-time option, a mail is sent to the previous xonix score leader when he's lost his first rank. .SH WIDGETS \fIXonix\fP uses the X Toolkit and the Athena Widget Set. Below is the widget structure of the \fIxonix\fP application. Indentation indicates hierarchical structure. The widget class name is given first, followed by the widget instance name. .sp .nf Xonix xonix VendorShellExt shellext Form container MenuButton game_button Canvas canvas Form status Form level Label lev_label Label lev_d10 Label lev_d1 Form percentage Label perc_label Label perc_d10 Label perc_d1 Form runner Label run_label Label run_d10 Label run_d1 Form time Label time_label Label mins_d10 Label mins_d1 Label time_colon Label secs_d10 Label secs_d1 SimpleMenu game_menu SmeBSB about SmeLine game_l1 SmeBSB quit TransientShell about_shell VendorShellExt shellext Box about_box Label about_msg Command about_done TransientShell gameover_shell VendorShellExt shellext Box gameover_box Label gameover_msg Box gameover_buttonbox Command gameover_iknow Command gameover_goon .fi .SH OPTIONS All the standard toolkit options apply. It's not particularly useful to attempt forcing any geometry however. .SH AUTHORS The original \fIxonix\fP game has been seen somewhere on an old PC/XT clone. This is a reimplementation from scratch, done by .if t Torsten Sch\(:onitz .if n Torsten Schoenitz starting the project on a Macintosh. The X11 support has been written by .if t J\(:org Wunsch .if n Joerg Wunsch with the pleasant help by .if t Alfredo Herrera Hern\('andez. .if n Alfredo Herrera Hernandez. .SH BUGS Source code comments are still mostly in German. Some files require the unusal tab width of 4 in order to be displayed correctly. It should be possible to pass some parameters from the command line as well (e.g. the time step value), which is currently only possible by the back-door via the \fI-xrm\fP toolkit option. Mail any suggestions to . xonix-1.4/xonix.xbm100644 153 7 1311 5746747600 11605 0ustar jbin#define xonix_width 25 #define xonix_height 25 static unsigned char xonix_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x3e, 0x00, 0xf8, 0x00, 0x66, 0x00, 0xcc, 0x00, 0x8a, 0x00, 0xa2, 0x00, 0x10, 0x83, 0x11, 0x00, 0x20, 0x7c, 0x08, 0x00, 0x20, 0x00, 0x08, 0x00, 0x40, 0xc6, 0x04, 0x00, 0x40, 0xc6, 0x04, 0x00, 0xc0, 0x00, 0x06, 0x00, 0x80, 0x29, 0x03, 0x00, 0x00, 0x93, 0x01, 0x00, 0x00, 0x82, 0x00, 0x00, 0x80, 0x39, 0x03, 0x00, 0xc0, 0x7c, 0x06, 0x00, 0x60, 0xc6, 0x0c, 0x00, 0x30, 0x00, 0x18, 0x00, 0x18, 0xfe, 0x30, 0x00, 0xec, 0x83, 0x6f, 0x00, 0x14, 0x00, 0x50, 0x00, 0x0e, 0x00, 0xe0, 0x00, 0x06, 0x00, 0xc0, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}; xonix-1.4/xonix_mask.xbm100644 153 7 1330 5746747601 12622 0ustar jbin#define xonix_mask_width 25 #define xonix_mask_height 25 static unsigned char xonix_mask_bits[] = { 0x0e, 0x00, 0xe0, 0x00, 0x7f, 0x00, 0xfc, 0x01, 0xff, 0x00, 0xfe, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0xc7, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xf8, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0xc0, 0xff, 0x07, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0xff, 0x00, 0xfe, 0xff, 0xff, 0x00, 0xff, 0xc7, 0xff, 0x01, 0x3f, 0x00, 0xf8, 0x01, 0x1f, 0x00, 0xf0, 0x01, 0x0f, 0x00, 0xe0, 0x01, 0x0e, 0x00, 0xe0, 0x00};