/*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. * * %sccs.include.redist.c% */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char sccsid[] = "@(#)xneko.c 5.2 (Berkeley) 05/22/91"; #endif /* not lint */ /*-------------------------------------------------------------- * * xneko - X11 G- * * Original Writer: Masayuki Koba * Programmed by Masayuki Koba, 1990 * *-------------------------------------------------------------- * *!!Introduction: * *!!!!K\@(#)xneko.c 5.2m%0%i%`$O Macintosh $N05/22/919%/%"%/%;%5%j!< "neko" $N *!!F0:n$r X11 $G%^%M$?$b$N$G$9!# * *!!!!Macintosh "neko" $N=(0o$J05/22/916%$%s$K7I0U$rI=$7$D$D!"$3$N *!!@(#)xneko.c 5.2m%0%i%`$r3'$5$s$KJ{$2$^$9!# * *-------------------------------------------------------------- * *!!Special Thanks to * * toshi-w !D!!Macintosh neko $N>R2p:\!&2~NI$O *!!<+M3$K9T$C$F2<$5$$!# * *!!!!$J$*!"86:nc32$dITMx1W$K$D$$$F$$$C$5$$@UG$$r;}$A$^$;$s!# * *-------------------------------------------------------------- * *!!Bugs: * *!!!!!J#1!KX11 $N .Xdefaults $N@_Dj$r$^$k$C$-$jL5;k$7$F$$$^$9!# * *!!!!!J#2!KG-$NF0:n$,;~4V$HF14|$7$F$$$k$?$a!"%^%&%9$N0\F0>pJs *!!!!!!!!$r%]!<%j%s%0$7$F$$$^$9!#=>$C$F!"%^%&%9$,A4$/F0:n$7$F *!!!!!!!!$$$J$$;~$OL5BL$J%^%&%9:BI8FI$_uBV$r@(#) xneko.c 5.2@(#)' *!!!!!!!!70/$7$F!"%"%$%3%s2=$5$l$F$$$k;~$O40A4$K%$s%HBT$A *!!!!!!!!$K$J$k$h$&$K=q$-JQ$($J$1$l$P$J$j$^$;$s!# ($=$s$J$3$H!" *!!!!!!!!$G$-$k$N$+$J$!!#X10 $G$O$G$-$^$7$?$,!#) * *!!!!!J#4!K%j%5%$%:8e$N%&%#%s5.2&$,6KC<$K>.$5$/$J$C$?;~$NF0:n *!!!!!!!!$OJ]>Z$G$-$^$;$s!# * *!!!!!J#5!KK\Mh$J$i$P3NJ]$7$?%&%#%s5.2&$d Pixmap $O@(#)xneko.c 5.2m%0%i%` *!!!!!!!!=*N;;~$K2rJ|$9$kI,MW$,$"$j$^$9$,!"K\@(#)xneko.c 5.2m%0%i%`$O$=$N *!!!!!!!!$X$s$r%5%\$C$F$*$j!"Hs>o$K$*9T57$,0-$/$J$C$F$$$^$9!# *!!!!!!!!IaDL$O exit() ;~$K%7%9s.xneko.c`$,M>J,$J%j%=!<%9$r2rJ|$7$F *!!!!!!!!$/$l$^$9$,!"#O#S$K/usr/home/csrg/sccs/games/xneko/SCCS/s.xneko.c0$,$"$k>l9g$O xneko $r2?EY$b5/ *!!!!!!!!F0$9$k$H!"$=$N$&$A%9%o82WNN0h$,ITB-$7$F$7$^$&$3$H$K *!!!!!!!!$J$k$+$b$7$l$^$;$s!# * *!!!!!J#6!K;~4V$KF14|$7$FI,$:IA2h=hM}$ruBV *!!!!!!!!$G$b Idle 90 !A 95% $H$J$j!"%7%9s.xneko.c`#C#P#U$r 5 !A 10% *!!!!!!!!Dx>CHq$7$^$9!#!Jxtachos $GD4$Y$^$7$?!#!K * *-------------------------------------------------------------- * *!!System (Machine): * *!!!!K\@(#)xneko.c 5.2m%0%i%`$NF0:n$r3NG'$7$?%7%9s.xneko.c`9=@.$O0J2<$NDL$j!# * * !&NWS-1750!"NWS-1720 (NEWS)!"NWP-512D * !!NEWS-OS 3.2a (UNIX 4.3BSD)!"X11 Release 2 * * !&NWS-1750!"NWS-1720 (NEWS)!"NWP-512D * !!NEWS-OS 3.3 (UNIX 4.3BSD)!"X11 Release 3 * * !&Sun 3!"X11 Release 4 * * !&LUNA!"X11 Release 3 * * !&DECstation 3100!"ULTRIX!"X11 * *--------------------------------------------------------------*/ #include #include #include #include #include #include #include #ifndef lint static char rcsid[] = "$Header: /afs/athena.mit.edu/user/j/jik/sipbsrc/src/xneko/RCS/xneko.c,v 1.2 90/09/01 23:40:01 jik Exp $"; static char WriterMessage[] = "xneko: Programmed by Masayuki Koba, 1990"; #endif /* * X11 G- 0C10/14/12^129W13:03:18!%$%k0lMw!' * * "icon.xbm" !D!!%"%$%3%s * "cursor.xbm" !D!!%+!<%=%k * "cursor_mask.xbm" !D!!%+!<%=%k!J%^%9%/!K * * "space.xbm" !D!!%9%Z!<%9 * * "mati2.xbm" !D!!BT$A#2 * "jare2.xbm" !D!!$8$c$l#2 * "kaki1.xbm" !D!!A_$-#1 * "kaki2.xbm" !D!!A_$-#2 * "mati3.xbm" !D!!BT$A#3!J$"$/$S!K * "sleep1.xbm" !D!!?2$k#1 * "sleep2.xbm" !D!!?2$k#2 * * "awake.xbm" !D!!L\3P$a * * "up1.xbm" !D!!>e#1 * "up2.xbm" !D!!>e#2 * "down1.xbm" !D!!2<#1 * "down2.xbm" !D!!2<#2 * "left1.xbm" !D!!:8#1 * "left2.xbm" !D!!:8#2 * "right1.xbm" !D!!1 * "right2.xbm" !D!!1 * "upleft1.xbm" !D!!:8>e#1 * "upleft2.xbm" !D!!:8>e#2 * "upright1.xbm" !D!!1&>e#1 * "upright2.xbm" !D!!1&>e#2 * "dwleft1.xbm" !D!!:82<#1 * "dwleft2.xbm" !D!!:82<#2 * "dwright1.xbm" !D!!1&2<#1 * "dwright2.xbm" !D!!1&2<#2 * * "utogi1.xbm" !D!!>eKa$.#1 * "utogi2.xbm" !D!!>eKa$.#2 * "dtogi1.xbm" !D!!2uBVDj?t */ #define NEKO_STOP 0 /* N)$A;_$^$C$? */ #define NEKO_JARE 1 /* 4i$r@v$C$F$$$k */ #define NEKO_KAKI 2 /* F,$rA_$$$F$$$k */ #define NEKO_AKUBI 3 /* $"$/$S$r$7$F$$$k */ #define NEKO_SLEEP 4 /* ?2$F$7$^$C$? */ #define NEKO_AWAKE 5 /* L\$,3P$a$? */ #define NEKO_U_MOVE 6 /* >e$K0\F0Cf */ #define NEKO_D_MOVE 7 /* 2<$K0\F0Cf */ #define NEKO_L_MOVE 8 /* :8$K0\F0Cf */ #define NEKO_R_MOVE 9 /* 1&$K0\F0Cf */ #define NEKO_UL_MOVE 10 /* :8>e$K0\F0Cf */ #define NEKO_UR_MOVE 11 /* 1&>e$K0\F0Cf */ #define NEKO_DL_MOVE 12 /* :82<$K0\F0Cf */ #define NEKO_DR_MOVE 13 /* 1&2<$K0\F0Cf */ #define NEKO_U_TOGI 14 /* >e$NJI$r0z$CA_$$$F$$$k */ #define NEKO_D_TOGI 15 /* 2<$NJI$r0z$CA_$$$F$$$k */ #define NEKO_L_TOGI 16 /* :8$NJI$r0z$CA_$$$F$$$k */ #define NEKO_R_TOGI 17 /* 1&$NJI$r0z$CA_$$$F$$$k */ /* G-$N%"%K%a!<%7%g%s7+$jJV$72s?t */ #define NEKO_STOP_TIME 4 #define NEKO_JARE_TIME 10 #define NEKO_KAKI_TIME 4 #define NEKO_AKUBI_TIME 3 #define NEKO_AWAKE_TIME 3 #define NEKO_TOGI_TIME 10 #define PI_PER8 ((double)3.1415926535/(double)8) #define DIRNAMELEN 255 /* * %0%m!>N */ Display *theDisplay; int theScreen; unsigned int theDepth; unsigned long theBlackPixel; unsigned long theWhitePixel; Window theWindow; Cursor theCursor; static unsigned int WindowWidth; static unsigned int WindowHeight; static int WindowPointX; static int WindowPointY; static unsigned int BorderWidth = DEFAULT_BORDER; long IntervalTime = INTERVAL; int EventState; /* %$s%H=hM}MQ >uBVJQ?t */ int NekoTickCount; /* G-F0:n%+%&%s%? */ int NekoStateCount; /* G-F10l>uBV%+%&%s%? */ int NekoState; /* G-$N>uBV */ int MouseX; /* %^%&%9#X:BI8 */ int MouseY; /* %^%&%9#Y:BI8 */ int PrevMouseX = 0; /* D>A0$N%^%&%9#X:BI8 */ int PrevMouseY = 0; /* D>A0$N%^%&%9#Y:BI8 */ int NekoX; /* G-#X:BI8 */ int NekoY; /* G-#Y:BI8 */ int NekoMoveDx; /* G-0\F05wN%#X */ int NekoMoveDy; /* G-0\F05wN%#Y */ int NekoLastX; /* G-:G=*IA2h#X:BI8 */ int NekoLastY; /* G-:G=*IA2h#Y:BI8 */ GC NekoLastGC; /* G-:G=*IA2h GC */ double NekoSpeed = (double)NEKO_SPEED; double SinPiPer8Times3; /* sin( #3&P!?#8 ) */ double SinPiPer8; /* sin( &P!?#8 ) */ Pixmap SpaceXbm; Pixmap Mati2Xbm; Pixmap Jare2Xbm; Pixmap Kaki1Xbm; Pixmap Kaki2Xbm; Pixmap Mati3Xbm; Pixmap Sleep1Xbm; Pixmap Sleep2Xbm; Pixmap AwakeXbm; Pixmap Up1Xbm; Pixmap Up2Xbm; Pixmap Down1Xbm; Pixmap Down2Xbm; Pixmap Left1Xbm; Pixmap Left2Xbm; Pixmap Right1Xbm; Pixmap Right2Xbm; Pixmap UpLeft1Xbm; Pixmap UpLeft2Xbm; Pixmap UpRight1Xbm; Pixmap UpRight2Xbm; Pixmap DownLeft1Xbm; Pixmap DownLeft2Xbm; Pixmap DownRight1Xbm; Pixmap DownRight2Xbm; Pixmap UpTogi1Xbm; Pixmap UpTogi2Xbm; Pixmap DownTogi1Xbm; Pixmap DownTogi2Xbm; Pixmap LeftTogi1Xbm; Pixmap LeftTogi2Xbm; Pixmap RightTogi1Xbm; Pixmap RightTogi2Xbm; GC SpaceGC; GC Mati2GC; GC Jare2GC; GC Kaki1GC; GC Kaki2GC; GC Mati3GC; GC Sleep1GC; GC Sleep2GC; GC AwakeGC; GC Up1GC; GC Up2GC; GC Down1GC; GC Down2GC; GC Left1GC; GC Left2GC; GC Right1GC; GC Right2GC; GC UpLeft1GC; GC UpLeft2GC; GC UpRight1GC; GC UpRight2GC; GC DownLeft1GC; GC DownLeft2GC; GC DownRight1GC; GC DownRight2GC; GC UpTogi1GC; GC UpTogi2GC; GC DownTogi1GC; GC DownTogi2GC; GC LeftTogi1GC; GC LeftTogi2GC; GC RightTogi1GC; GC RightTogi2GC; typedef struct { GC *GCCreatePtr; Pixmap *BitmapCreatePtr; char *PixelPattern; unsigned int PixelWidth; unsigned int PixelHeight; } BitmapGCData; BitmapGCData BitmapGCDataTable[] = { { &SpaceGC, &SpaceXbm, space_bits, space_width, space_height }, { &Mati2GC, &Mati2Xbm, mati2_bits, mati2_width, mati2_height }, { &Jare2GC, &Jare2Xbm, jare2_bits, jare2_width, jare2_height }, { &Kaki1GC, &Kaki1Xbm, kaki1_bits, kaki1_width, kaki1_height }, { &Kaki2GC, &Kaki2Xbm, kaki2_bits, kaki2_width, kaki2_height }, { &Mati3GC, &Mati3Xbm, mati3_bits, mati3_width, mati3_height }, { &Sleep1GC, &Sleep1Xbm, sleep1_bits, sleep1_width, sleep1_height }, { &Sleep2GC, &Sleep2Xbm, sleep2_bits, sleep2_width, sleep2_height }, { &AwakeGC, &AwakeXbm, awake_bits, awake_width, awake_height }, { &Up1GC, &Up1Xbm, up1_bits, up1_width, up1_height }, { &Up2GC, &Up2Xbm, up2_bits, up2_width, up2_height }, { &Down1GC, &Down1Xbm, down1_bits, down1_width, down1_height }, { &Down2GC, &Down2Xbm, down2_bits, down2_width, down2_height }, { &Left1GC, &Left1Xbm, left1_bits, left1_width, left1_height }, { &Left2GC, &Left2Xbm, left2_bits, left2_width, left2_height }, { &Right1GC, &Right1Xbm, right1_bits, right1_width, right1_height }, { &Right2GC, &Right2Xbm, right2_bits, right2_width, right2_height }, { &UpLeft1GC, &UpLeft1Xbm, upleft1_bits, upleft1_width, upleft1_height }, { &UpLeft2GC, &UpLeft2Xbm, upleft2_bits, upleft2_width, upleft2_height }, { &UpRight1GC, &UpRight1Xbm, upright1_bits, upright1_width, upright1_height }, { &UpRight2GC, &UpRight2Xbm, upright2_bits, upright2_width, upright2_height }, { &DownLeft1GC, &DownLeft1Xbm, dwleft1_bits, dwleft1_width, dwleft1_height }, { &DownLeft2GC, &DownLeft2Xbm, dwleft2_bits, dwleft2_width, dwleft2_height }, { &DownRight1GC, &DownRight1Xbm, dwright1_bits, dwright1_width, dwright1_height }, { &DownRight2GC, &DownRight2Xbm, dwright2_bits, dwright2_width, dwright2_height }, { &UpTogi1GC, &UpTogi1Xbm, utogi1_bits, utogi1_width, utogi1_height }, { &UpTogi2GC, &UpTogi2Xbm, utogi2_bits, utogi2_width, utogi2_height }, { &DownTogi1GC, &DownTogi1Xbm, dtogi1_bits, dtogi1_width, dtogi1_height }, { &DownTogi2GC, &DownTogi2Xbm, dtogi2_bits, dtogi2_width, dtogi2_height }, { &LeftTogi1GC, &LeftTogi1Xbm, ltogi1_bits, ltogi1_width, ltogi1_height }, { &LeftTogi2GC, &LeftTogi2Xbm, ltogi2_bits, ltogi2_width, ltogi2_height }, { &RightTogi1GC, &RightTogi1Xbm, rtogi1_bits, rtogi1_width, rtogi1_height }, { &RightTogi2GC, &RightTogi2Xbm, rtogi2_bits, rtogi2_width, rtogi2_height }, { NULL, NULL, NULL, NULL, NULL } }; typedef struct { GC *TickEvenGCPtr; GC *TickOddGCPtr; } Animation; Animation AnimationPattern[] = { { &Mati2GC, &Mati2GC }, /* NekoState == NEKO_STOP */ { &Jare2GC, &Mati2GC }, /* NekoState == NEKO_JARE */ { &Kaki1GC, &Kaki2GC }, /* NekoState == NEKO_KAKI */ { &Mati3GC, &Mati3GC }, /* NekoState == NEKO_AKUBI */ { &Sleep1GC, &Sleep2GC }, /* NekoState == NEKO_SLEEP */ { &AwakeGC, &AwakeGC }, /* NekoState == NEKO_AWAKE */ { &Up1GC, &Up2GC } , /* NekoState == NEKO_U_MOVE */ { &Down1GC, &Down2GC }, /* NekoState == NEKO_D_MOVE */ { &Left1GC, &Left2GC }, /* NekoState == NEKO_L_MOVE */ { &Right1GC, &Right2GC }, /* NekoState == NEKO_R_MOVE */ { &UpLeft1GC, &UpLeft2GC }, /* NekoState == NEKO_UL_MOVE */ { &UpRight1GC, &UpRight2GC }, /* NekoState == NEKO_UR_MOVE */ { &DownLeft1GC, &DownLeft2GC }, /* NekoState == NEKO_DL_MOVE */ { &DownRight1GC, &DownRight2GC }, /* NekoState == NEKO_DR_MOVE */ { &UpTogi1GC, &UpTogi2GC }, /* NekoState == NEKO_U_TOGI */ { &DownTogi1GC, &DownTogi2GC }, /* NekoState == NEKO_D_TOGI */ { &LeftTogi1GC, &LeftTogi2GC }, /* NekoState == NEKO_L_TOGI */ { &RightTogi1GC, &RightTogi2GC }, /* NekoState == NEKO_R_TOGI */ }; /*-------------------------------------------------------------- * * 0C10/14/12^504W%G!<%?!&GC =i4|2= * *--------------------------------------------------------------*/ void InitBitmapAndGCs() { BitmapGCData *BitmapGCDataTablePtr; XGCValues theGCValues; theGCValues.function = GXcopy; theGCValues.foreground = BlackPixel( theDisplay, theScreen ); theGCValues.background = WhitePixel( theDisplay, theScreen ); theGCValues.fill_style = FillTiled; for ( BitmapGCDataTablePtr = BitmapGCDataTable; BitmapGCDataTablePtr->GCCreatePtr != NULL; BitmapGCDataTablePtr++ ) { *(BitmapGCDataTablePtr->BitmapCreatePtr) = XCreatePixmapFromBitmapData( theDisplay, RootWindow( theDisplay, theScreen ), BitmapGCDataTablePtr->PixelPattern, BitmapGCDataTablePtr->PixelWidth, BitmapGCDataTablePtr->PixelHeight, BlackPixel( theDisplay, theScreen ), WhitePixel( theDisplay, theScreen ), DefaultDepth( theDisplay, theScreen ) ); theGCValues.tile = *(BitmapGCDataTablePtr->BitmapCreatePtr); *(BitmapGCDataTablePtr->GCCreatePtr) = XCreateGC( theDisplay, theWindow, GCFunction | GCForeground | GCBackground | GCTile | GCFillStyle, &theGCValues ); } XFlush( theDisplay ); } /*-------------------------------------------------------------- * * %9%/%j!<%s4D6-=i4|2= * *--------------------------------------------------------------*/ void InitScreen( DisplayName, theGeometry, TitleName, iconicState ) char *DisplayName; char *theGeometry; char *TitleName; Bool iconicState; { int GeometryStatus; XSetWindowAttributes theWindowAttributes; XSizeHints theSizeHints; unsigned long theWindowMask; Pixmap theIconPixmap; Pixmap theCursorSource; Pixmap theCursorMask; XWMHints theWMHints; Window theRoot; Colormap theColormap; XColor theWhiteColor, theBlackColor, theExactColor; if ( ( theDisplay = XOpenDisplay( DisplayName ) ) == NULL ) { fprintf( stderr, "%s: Can't open display", ProgramName ); if ( DisplayName != NULL ) { fprintf( stderr, " %s.\n", DisplayName ); } else { fprintf( stderr, ".\n" ); } exit( 1 ); } theScreen = DefaultScreen( theDisplay ); theDepth = DefaultDepth( theDisplay, theScreen ); theBlackPixel = BlackPixel( theDisplay, theScreen ); theWhitePixel = WhitePixel( theDisplay, theScreen ); GeometryStatus = XParseGeometry( theGeometry, &WindowPointX, &WindowPointY, &WindowWidth, &WindowHeight ); if ( !( GeometryStatus & XValue ) ) { WindowPointX = DEFAULT_WIN_X; } if ( !( GeometryStatus & YValue ) ) { WindowPointY = DEFAULT_WIN_Y; } if ( !( GeometryStatus & WidthValue ) ) { WindowWidth = WINDOW_WIDTH; } if ( !( GeometryStatus & HeightValue ) ) { WindowHeight = WINDOW_HEIGHT; } theCursorSource = XCreateBitmapFromData( theDisplay, RootWindow( theDisplay, theScreen ), cursor_bits, cursor_width, cursor_height ); theCursorMask = XCreateBitmapFromData( theDisplay, RootWindow( theDisplay, theScreen ), cursor_mask_bits, cursor_mask_width, cursor_mask_height ); theColormap = DefaultColormap( theDisplay, theScreen ); if ( !XAllocNamedColor( theDisplay, theColormap, "white", &theWhiteColor, &theExactColor ) ) { fprintf( stderr, "%s: Can't XAllocNamedColor( \"white\" ).\n", ProgramName ); exit( 1 ); } if ( !XAllocNamedColor( theDisplay, theColormap, "black", &theBlackColor, &theExactColor ) ) { fprintf( stderr, "%s: Can't XAllocNamedColor( \"black\" ).\n", ProgramName ); exit( 1 ); } theCursor = XCreatePixmapCursor( theDisplay, theCursorSource, theCursorMask, &theBlackColor, &theWhiteColor, cursor_x_hot, cursor_y_hot ); theWindowAttributes.border_pixel = theBlackPixel; theWindowAttributes.background_pixel = theWhitePixel; theWindowAttributes.cursor = theCursor; theWindowAttributes.override_redirect = False; theWindowMask = CWBackPixel | CWBorderPixel | CWCursor | CWOverrideRedirect; theWindow = XCreateWindow( theDisplay, RootWindow( theDisplay, theScreen ), WindowPointX, WindowPointY, WindowWidth, WindowHeight, BorderWidth, theDepth, InputOutput, CopyFromParent, theWindowMask, &theWindowAttributes ); theIconPixmap = XCreateBitmapFromData( theDisplay, theWindow, icon_bits, icon_width, icon_height ); theWMHints.icon_pixmap = theIconPixmap; if ( iconicState ) { theWMHints.initial_state = IconicState; } else { theWMHints.initial_state = NormalState; } theWMHints.flags = IconPixmapHint | StateHint; XSetWMHints( theDisplay, theWindow, &theWMHints ); theSizeHints.flags = PPosition | PSize; theSizeHints.x = WindowPointX; theSizeHints.y = WindowPointY; theSizeHints.width = WindowWidth; theSizeHints.height = WindowHeight; XSetNormalHints( theDisplay, theWindow, &theSizeHints ); if ( strlen( TitleName ) >= 1 ) { XStoreName( theDisplay, theWindow, TitleName ); XSetIconName( theDisplay, theWindow, TitleName ); } else { XStoreName( theDisplay, theWindow, ProgramName ); XSetIconName( theDisplay, theWindow, ProgramName ); } XMapWindow( theDisplay, theWindow ); XFlush( theDisplay ); XGetGeometry( theDisplay, theWindow, &theRoot, &WindowPointX, &WindowPointY, &WindowWidth, &WindowHeight, &BorderWidth, &theDepth ); InitBitmapAndGCs(); XSelectInput( theDisplay, theWindow, EVENT_MASK1 ); XFlush( theDisplay ); } /*-------------------------------------------------------------- * * %$%s%?!= MAX_TICK ) { NekoTickCount = 0; } if ( NekoTickCount % 2 == 0 ) { if ( NekoStateCount < MAX_TICK ) { NekoStateCount++; } } } /*-------------------------------------------------------------- * * G->uBV@_Dj * *--------------------------------------------------------------*/ void SetNekoState( SetValue ) int SetValue; { NekoTickCount = 0; NekoStateCount = 0; NekoState = SetValue; #ifdef DEBUG switch ( NekoState ) { case NEKO_STOP: case NEKO_JARE: case NEKO_KAKI: case NEKO_AKUBI: case NEKO_SLEEP: case NEKO_U_TOGI: case NEKO_D_TOGI: case NEKO_L_TOGI: case NEKO_R_TOGI: NekoMoveDx = NekoMoveDy = 0; break; default: break; } #endif } /*-------------------------------------------------------------- * * G-IA2h=hM} * *--------------------------------------------------------------*/ void DrawNeko( x, y, DrawGC ) int x; int y; GC DrawGC; { if ( ( x != NekoLastX || y != NekoLastY ) && ( EventState != DEBUG_LIST ) ) { XFillRectangle( theDisplay, theWindow, SpaceGC, NekoLastX, NekoLastY, BITMAP_WIDTH, BITMAP_HEIGHT ); } XSetTSOrigin( theDisplay, DrawGC, x, y ); XFillRectangle( theDisplay, theWindow, DrawGC, x, y, BITMAP_WIDTH, BITMAP_HEIGHT ); XFlush( theDisplay ); NekoLastX = x; NekoLastY = y; NekoLastGC = DrawGC; } /*-------------------------------------------------------------- * * G-:FIA2h=hM} * *--------------------------------------------------------------*/ void RedrawNeko() { XFillRectangle( theDisplay, theWindow, NekoLastGC, NekoLastX, NekoLastY, BITMAP_WIDTH, BITMAP_HEIGHT ); XFlush( theDisplay ); } /*-------------------------------------------------------------- * * G-0\F0J}K!7hDj * *--------------------------------------------------------------*/ void NekoDirection() { int NewState; double LargeX, LargeY; double Length; double SinTheta; if ( NekoMoveDx == 0 && NekoMoveDy == 0 ) { NewState = NEKO_STOP; } else { LargeX = (double)NekoMoveDx; LargeY = (double)(-NekoMoveDy); Length = sqrt( LargeX * LargeX + LargeY * LargeY ); SinTheta = LargeY / Length; if ( NekoMoveDx > 0 ) { if ( SinTheta > SinPiPer8Times3 ) { NewState = NEKO_U_MOVE; } else if ( ( SinTheta <= SinPiPer8Times3 ) && ( SinTheta > SinPiPer8 ) ) { NewState = NEKO_UR_MOVE; } else if ( ( SinTheta <= SinPiPer8 ) && ( SinTheta > -( SinPiPer8 ) ) ) { NewState = NEKO_R_MOVE; } else if ( ( SinTheta <= -( SinPiPer8 ) ) && ( SinTheta > -( SinPiPer8Times3 ) ) ) { NewState = NEKO_DR_MOVE; } else { NewState = NEKO_D_MOVE; } } else { if ( SinTheta > SinPiPer8Times3 ) { NewState = NEKO_U_MOVE; } else if ( ( SinTheta <= SinPiPer8Times3 ) && ( SinTheta > SinPiPer8 ) ) { NewState = NEKO_UL_MOVE; } else if ( ( SinTheta <= SinPiPer8 ) && ( SinTheta > -( SinPiPer8 ) ) ) { NewState = NEKO_L_MOVE; } else if ( ( SinTheta <= -( SinPiPer8 ) ) && ( SinTheta > -( SinPiPer8Times3 ) ) ) { NewState = NEKO_DL_MOVE; } else { NewState = NEKO_D_MOVE; } } } if ( NekoState != NewState ) { SetNekoState( NewState ); } } /*-------------------------------------------------------------- * * G-JI$V$D$+$jH=Dj * *--------------------------------------------------------------*/ Bool IsWindowOver() { Bool ReturnValue = False; if ( NekoY <= 0 ) { NekoY = 0; ReturnValue = True; } else if ( NekoY >= WindowHeight - BITMAP_HEIGHT ) { NekoY = WindowHeight - BITMAP_HEIGHT; ReturnValue = True; } if ( NekoX <= 0 ) { NekoX = 0; ReturnValue = True; } else if ( NekoX >= WindowWidth - BITMAP_WIDTH ) { NekoX = WindowWidth - BITMAP_WIDTH; ReturnValue = True; } return( ReturnValue ); } /*-------------------------------------------------------------- * * G-0\F0>u67H=Dj * *--------------------------------------------------------------*/ Bool IsNekoDontMove() { if ( NekoX == NekoLastX && NekoY == NekoLastY ) { return( True ); } else { return( False ); } } /*-------------------------------------------------------------- * * G-0\F03+;OH=Dj * *--------------------------------------------------------------*/ Bool IsNekoMoveStart() { #ifndef DEBUG if ( ( PrevMouseX >= MouseX - IDLE_SPACE && PrevMouseX <= MouseX + IDLE_SPACE ) && ( PrevMouseY >= MouseY - IDLE_SPACE && PrevMouseY <= MouseY + IDLE_SPACE ) ) { return( False ); } else { return( True ); } #else if ( NekoMoveDx == 0 && NekoMoveDy == 0 ) { return( False ); } else { return( True ); } #endif } /*-------------------------------------------------------------- * * G-0\F0 dx, dy 7W;; * *--------------------------------------------------------------*/ void CalcDxDy() { Window QueryRoot, QueryChild; int AbsoluteX, AbsoluteY; int RelativeX, RelativeY; unsigned int ModKeyMask; double LargeX, LargeY; double DoubleLength, Length; XQueryPointer( theDisplay, theWindow, &QueryRoot, &QueryChild, &AbsoluteX, &AbsoluteY, &RelativeX, &RelativeY, &ModKeyMask ); PrevMouseX = MouseX; PrevMouseY = MouseY; MouseX = RelativeX; MouseY = RelativeY; LargeX = (double)( MouseX - NekoX - BITMAP_WIDTH / 2 ); LargeY = (double)( MouseY - NekoY - BITMAP_HEIGHT ); DoubleLength = LargeX * LargeX + LargeY * LargeY; if ( DoubleLength != (double)0 ) { Length = sqrt( DoubleLength ); if ( Length <= NekoSpeed ) { NekoMoveDx = (int)LargeX; NekoMoveDy = (int)LargeY; } else { NekoMoveDx = (int)( ( NekoSpeed * LargeX ) / Length ); NekoMoveDy = (int)( ( NekoSpeed * LargeY ) / Length ); } } else { NekoMoveDx = NekoMoveDy = 0; } } /*-------------------------------------------------------------- * * F0:n2r@OG-IA2h=hM} * *--------------------------------------------------------------*/ void NekoThinkDraw() { #ifndef DEBUG CalcDxDy(); #endif if ( NekoState != NEKO_SLEEP ) { DrawNeko( NekoX, NekoY, NekoTickCount % 2 == 0 ? *(AnimationPattern[ NekoState ].TickEvenGCPtr) : *(AnimationPattern[ NekoState ].TickOddGCPtr) ); } else { DrawNeko( NekoX, NekoY, NekoTickCount % 8 <= 3 ? *(AnimationPattern[ NekoState ].TickEvenGCPtr) : *(AnimationPattern[ NekoState ].TickOddGCPtr) ); } TickCount(); switch ( NekoState ) { case NEKO_STOP: if ( IsNekoMoveStart() ) { SetNekoState( NEKO_AWAKE ); break; } if ( NekoStateCount < NEKO_STOP_TIME ) { break; } if ( NekoMoveDx < 0 && NekoX <= 0 ) { SetNekoState( NEKO_L_TOGI ); } else if ( NekoMoveDx > 0 && NekoX >= WindowWidth - BITMAP_WIDTH ) { SetNekoState( NEKO_R_TOGI ); } else if ( NekoMoveDy < 0 && NekoY <= 0 ) { SetNekoState( NEKO_U_TOGI ); } else if ( NekoMoveDy > 0 && NekoY >= WindowHeight - BITMAP_HEIGHT ) { SetNekoState( NEKO_D_TOGI ); } else { SetNekoState( NEKO_JARE ); } break; case NEKO_JARE: if ( IsNekoMoveStart() ) { SetNekoState( NEKO_AWAKE ); break; } if ( NekoStateCount < NEKO_JARE_TIME ) { break; } SetNekoState( NEKO_KAKI ); break; case NEKO_KAKI: if ( IsNekoMoveStart() ) { SetNekoState( NEKO_AWAKE ); break; } if ( NekoStateCount < NEKO_KAKI_TIME ) { break; } SetNekoState( NEKO_AKUBI ); break; case NEKO_AKUBI: if ( IsNekoMoveStart() ) { SetNekoState( NEKO_AWAKE ); break; } if ( NekoStateCount < NEKO_AKUBI_TIME ) { break; } SetNekoState( NEKO_SLEEP ); break; case NEKO_SLEEP: if ( IsNekoMoveStart() ) { SetNekoState( NEKO_AWAKE ); break; } break; case NEKO_AWAKE: if ( NekoStateCount < NEKO_AWAKE_TIME ) { break; } NekoDirection(); /* G-$,F0$/8~$-$r5a$a$k */ break; case NEKO_U_MOVE: case NEKO_D_MOVE: case NEKO_L_MOVE: case NEKO_R_MOVE: case NEKO_UL_MOVE: case NEKO_UR_MOVE: case NEKO_DL_MOVE: case NEKO_DR_MOVE: NekoX += NekoMoveDx; NekoY += NekoMoveDy; NekoDirection(); if ( IsWindowOver() ) { if ( IsNekoDontMove() ) { SetNekoState( NEKO_STOP ); } } break; case NEKO_U_TOGI: case NEKO_D_TOGI: case NEKO_L_TOGI: case NEKO_R_TOGI: if ( IsNekoMoveStart() ) { SetNekoState( NEKO_AWAKE ); break; } if ( NekoStateCount < NEKO_TOGI_TIME ) { break; } SetNekoState( NEKO_KAKI ); break; default: /* Internal Error */ SetNekoState( NEKO_STOP ); break; } Interval(); } #ifdef DEBUG /*-------------------------------------------------------------- * * %-%c%i%/%?!<0lMwI=<(!J05/22/91P11500MQ!K * *--------------------------------------------------------------*/ void DisplayCharacters() { int Index; int x, y; for ( Index = 0, x = 0, y = 0; BitmapGCDataTable[ Index ].GCCreatePtr != NULL; Index++ ) { DrawNeko( x, y, *(BitmapGCDataTable[ Index ].GCCreatePtr) ); XFlush( theDisplay ); x += BITMAP_WIDTH; if ( x > WindowWidth - BITMAP_WIDTH ) { x = 0; y += BITMAP_HEIGHT; if ( y > WindowHeight - BITMAP_HEIGHT) { break; } } } } #endif /* DEBUG */ /*-------------------------------------------------------------- * * %-!<%$s%H=hM} * *--------------------------------------------------------------*/ Bool ProcessKeyPress( theKeyEvent ) XKeyEvent *theKeyEvent; { int Length; int theKeyBufferMaxLen = AVAIL_KEYBUF; char theKeyBuffer[ AVAIL_KEYBUF + 1 ]; KeySym theKeySym; XComposeStatus theComposeStatus; Bool ReturnState; ReturnState = True; Length = XLookupString( theKeyEvent, theKeyBuffer, theKeyBufferMaxLen, &theKeySym, &theComposeStatus ); if ( Length > 0 ) { switch ( theKeyBuffer[ 0 ] ) { case 'q': case 'Q': if ( theKeyEvent->state & Mod1Mask ) { /* META (Alt) %-!< */ ReturnState = False; } break; default: break; } } #ifdef DEBUG if ( EventState == DEBUG_MOVE ) { switch ( theKeySym ) { case XK_KP_1: NekoMoveDx = -(int)( NekoSpeed / sqrt( (double)2 ) ); NekoMoveDy = -NekoMoveDx; break; case XK_KP_2: NekoMoveDx = 0; NekoMoveDy = (int)NekoSpeed; break; case XK_KP_3: NekoMoveDx = (int)( NekoSpeed / sqrt( (double)2 ) ); NekoMoveDy = NekoMoveDx; break; case XK_KP_4: NekoMoveDx = -(int)NekoSpeed; NekoMoveDy = 0; break; case XK_KP_5: NekoMoveDx = 0; NekoMoveDy = 0; break; case XK_KP_6: NekoMoveDx = (int)NekoSpeed; NekoMoveDy = 0; break; case XK_KP_7: NekoMoveDx = -(int)( NekoSpeed / sqrt( (double)2 ) ); NekoMoveDy = NekoMoveDx; break; case XK_KP_8: NekoMoveDx = 0; NekoMoveDy = -(int)NekoSpeed; break; case XK_KP_9: NekoMoveDx = (int)( NekoSpeed / sqrt( (double)2 ) ); NekoMoveDy = -NekoMoveDx; break; } } #endif return( ReturnState ); } /*-------------------------------------------------------------- * * G-0LCVD4@0 * *--------------------------------------------------------------*/ void NekoAdjust() { if ( NekoX < 0 ) { NekoX = 0; } else if ( NekoX > WindowWidth - BITMAP_WIDTH ) { NekoX = WindowWidth - BITMAP_WIDTH; } if ( NekoY < 0 ) { NekoY = 0; } else if ( NekoY > WindowHeight - BITMAP_HEIGHT ) { NekoY = WindowHeight - BITMAP_HEIGHT; } } /*-------------------------------------------------------------- * * %$s%H=hM} * *--------------------------------------------------------------*/ Bool ProcessEvent() { XEvent theEvent; Bool ContinueState = True; switch ( EventState ) { case NORMAL_STATE: while ( XCheckMaskEvent( theDisplay, EVENT_MASK1, &theEvent ) ) { switch ( theEvent.type ) { case ConfigureNotify: WindowWidth = theEvent.xconfigure.width; WindowHeight = theEvent.xconfigure.height; WindowPointX = theEvent.xconfigure.x; WindowPointY = theEvent.xconfigure.y; BorderWidth = theEvent.xconfigure.border_width; NekoAdjust(); break; case Expose: if ( theEvent.xexpose.count == 0 ) { RedrawNeko(); } break; case MapNotify: RedrawNeko(); break; case KeyPress: ContinueState = ProcessKeyPress( &theEvent.xkey ); if ( !ContinueState ) { return( ContinueState ); } break; default: /* Unknown Event */ break; } } break; #ifdef DEBUG case DEBUG_LIST: XNextEvent( theDisplay, &theEvent ); switch ( theEvent.type ) { case ConfigureNotify: WindowWidth = theEvent.xconfigure.width; WindowHeight = theEvent.xconfigure.height; WindowPointX = theEvent.xconfigure.x; WindowPointY = theEvent.xconfigure.y; BorderWidth = theEvent.xconfigure.border_width; break; case Expose: if ( theEvent.xexpose.count == 0 ) { DisplayCharacters(); } break; case MapNotify: DisplayCharacters(); break; case KeyPress: ContinueState = ProcessKeyPress( &theEvent ); break; default: /* Unknown Event */ break; } break; case DEBUG_MOVE: while ( XCheckMaskEvent( theDisplay, EVENT_MASK1, &theEvent ) ) { switch ( theEvent.type ) { case ConfigureNotify: WindowWidth = theEvent.xconfigure.width; WindowHeight = theEvent.xconfigure.height; WindowPointX = theEvent.xconfigure.x; WindowPointY = theEvent.xconfigure.y; BorderWidth = theEvent.xconfigure.border_width; NekoAdjust(); break; case Expose: if ( theEvent.xexpose.count == 0 ) { RedrawNeko(); } break; case MapNotify: RedrawNeko(); break; case KeyPress: ContinueState = ProcessKeyPress( &theEvent ); if ( !ContinueState ) { return( ContinueState ); } break; default: /* Unknown Event */ break; } } break; #endif default: /* Internal Error */ break; } return( ContinueState ); } /*-------------------------------------------------------------- * * G-=hM} * *--------------------------------------------------------------*/ void ProcessNeko() { struct itimerval Value; /* 4D6-$N=i4|2= */ EventState = NORMAL_STATE; /* G-$N=i4|2= */ NekoX = ( WindowWidth - BITMAP_WIDTH / 2 ) / 2; NekoY = ( WindowHeight - BITMAP_HEIGHT / 2 ) / 2; NekoLastX = NekoX; NekoLastY = NekoY; SetNekoState( NEKO_STOP ); /* %?%$%^!<@_Dj */ timerclear( &Value.it_interval ); timerclear( &Value.it_value ); Value.it_interval.tv_usec = IntervalTime; Value.it_value.tv_usec = IntervalTime; setitimer( ITIMER_REAL, &Value, 0 ); /* %a%$%s=hM} */ do { NekoThinkDraw(); } while ( ProcessEvent() ); } #ifdef DEBUG /*-------------------------------------------------------------- * * G-0lMw!J05/22/91P14460MQ!K * *--------------------------------------------------------------*/ void NekoList() { EventState = DEBUG_LIST; fprintf( stderr, "\n" ); fprintf( stderr, "G-0lMw$rI=<($7$^$9!#(Quit !D Alt-Q)\n" ); fprintf( stderr, "\n" ); XSelectInput( theDisplay, theWindow, EVENT_MASK2 ); while ( ProcessEvent() ); } /*-------------------------------------------------------------- * * G-0\F0s.xneko.c9%H!J05/22/91P14670MQ!K * *--------------------------------------------------------------*/ void NekoMoveTest() { struct itimerval Value; /* 4D6-$N=i4|2= */ EventState = DEBUG_MOVE; /* G-$N=i4|2= */ NekoX = ( WindowWidth - BITMAP_WIDTH / 2 ) / 2; NekoY = ( WindowHeight - BITMAP_HEIGHT / 2 ) / 2; NekoLastX = NekoX; NekoLastY = NekoY; SetNekoState( NEKO_STOP ); /* %?%$%^!<@_Dj */ timerclear( &Value.it_interval ); timerclear( &Value.it_value ); Value.it_interval.tv_usec = IntervalTime; Value.it_value.tv_usec = IntervalTime; setitimer( ITIMER_REAL, &Value, 0 ); /* %a%$%s=hM} */ fprintf( stderr, "\n" ); fprintf( stderr, "G-$N0\F0s.xneko.c9%H$r9T$$$^$9!#(Quit !D Alt-Q)\n" ); fprintf( stderr, "\n" ); fprintf( stderr, "\t%-!e$Ns.xneko.cs%-!<$GG-$r0\F0$5$;$F2<$5$$!#\n" ); fprintf( stderr, "\t(M-8z$J%-!<$O#1!A#9$G$9!#)\n" ); fprintf( stderr, "\n" ); do { NekoThinkDraw(); } while ( ProcessEvent() ); } /*-------------------------------------------------------------- * * %a%K%e!<=hM}!J05/22/91P15170MQ!K * *--------------------------------------------------------------*/ void ProcessDebugMenu() { int UserSelectNo = 0; char UserAnswer[ BUFSIZ ]; fprintf( stderr, "\n" ); fprintf( stderr, "!Zxneko 05/22/91P15280%a%K%e!= 1 && UserSelectNo <= 2 ) ) { fprintf( stderr, "\n" ); fprintf( stderr, "\t1)!!G-%-%c%i%/%?!<0lMwI=<(\n" ); fprintf( stderr, "\t2)!!G-0\F0s.xneko.c9%H\n" ); fprintf( stderr, "\n" ); fprintf( stderr, "Select: " ); fgets( UserAnswer, sizeof( UserAnswer ), stdin ); UserSelectNo = atoi( UserAnswer ); if ( !( UserSelectNo >= 1 && UserSelectNo <= 2 ) ) { fprintf( stderr, "\n" ); fprintf( stderr, "@5$7$$HV9f$rA*Br$7$F2<$5$$!#\n" ); } } switch ( UserSelectNo ) { case 1: /* G-%-%c%i%/%?!<0lMwI=<( */ NekoList(); break; case 2: /* G-0\F0s.xneko.c9%H */ NekoMoveTest(); break; default: /* Internal Error */ break; } fprintf( stderr, "s.xneko.c9%H=*N;!#\n" ); fprintf( stderr, "\n" ); } #endif /* DEBUG */ /*-------------------------------------------------------------- * * SIGALRM %7%0%J%k=hM} * *--------------------------------------------------------------*/ void NullFunction() { /* No Operation */ } /*-------------------------------------------------------------- * * Usage * *--------------------------------------------------------------*/ void Usage() { fprintf( stderr, "Usage: %s [-display ] [-geometry ] \\\n", ProgramName ); fprintf( stderr, " [-title ] [-name <title>] [-iconic] \\\n" ); fprintf( stderr, " [-speed <speed>] [-time <time>] [-help]\n" ); } /*-------------------------------------------------------------- * * #Xi%a!<%?I>2A * *--------------------------------------------------------------*/ Bool GetArguments( argc, argv, theDisplayName, theGeometry, theTitle, NekoSpeed, IntervalTime ) int argc; char *argv[]; char *theDisplayName; char *theGeometry; char *theTitle; double *NekoSpeed; long *IntervalTime; { int ArgCounter; Bool iconicState; theDisplayName[ 0 ] = '\0'; theGeometry[ 0 ] = '\0'; theTitle[ 0 ] = '\0'; iconicState = False; for ( ArgCounter = 0; ArgCounter < argc; ArgCounter++ ) { if ( strncmp( argv[ ArgCounter ], "-h", 2 ) == 0 ) { Usage(); exit( 0 ); } else if ( strcmp( argv[ ArgCounter ], "-display" ) == 0 ) { ArgCounter++; if ( ArgCounter < argc ) { strcpy( theDisplayName, argv[ ArgCounter ] ); } else { fprintf( stderr, "%s: -display option error.\n", ProgramName ); exit( 1 ); } } else if ( strncmp( argv[ ArgCounter ], "-geom", 5 ) == 0 ) { ArgCounter++; if ( ArgCounter < argc ) { strcpy( theGeometry, argv[ ArgCounter ] ); } else { fprintf( stderr, "%s: -geometry option error.\n", ProgramName ); exit( 1 ); } } else if ( ( strcmp( argv[ ArgCounter ], "-title" ) == 0 ) || ( strcmp( argv[ ArgCounter ], "-name" ) == 0 ) ) { ArgCounter++; if ( ArgCounter < argc ) { strcpy( theTitle, argv[ ArgCounter ] ); } else { fprintf( stderr, "%s: -title option error.\n", ProgramName ); exit( 1 ); } } else if ( strcmp( argv[ ArgCounter ], "-iconic" ) == 0 ) { iconicState = True; } else if ( strcmp( argv[ ArgCounter ], "-speed" ) == 0 ) { ArgCounter++; if ( ArgCounter < argc ) { *NekoSpeed = atof( argv[ ArgCounter ] ); } else { fprintf( stderr, "%s: -speed option error.\n", ProgramName ); exit( 1 ); } } else if ( strcmp( argv[ ArgCounter ], "-time" ) == 0 ) { ArgCounter++; if ( ArgCounter < argc ) { *IntervalTime = atol( argv[ ArgCounter ] ); } else { fprintf( stderr, "%s: -time option error.\n", ProgramName ); exit( 1 ); } } else { fprintf( stderr, "%s: Unknown option \"%s\".\n", ProgramName, argv[ ArgCounter ] ); Usage(); exit( 1 ); } } if ( strlen( theDisplayName ) < 1 ) { theDisplayName = NULL; } if ( strlen( theGeometry ) < 1 ) { theGeometry = NULL; } return( iconicState ); } /*-------------------------------------------------------------- * * %a%$%s4X?t * *--------------------------------------------------------------*/ int main( argc, argv ) int argc; char *argv[]; { Bool iconicState; char theDisplayName[ DIRNAMELEN ]; char theGeometry[ DIRNAMELEN ]; char theTitle[ DIRNAMELEN ]; ProgramName = argv[ 0 ]; argc--; argv++; iconicState = GetArguments( argc, argv, theDisplayName, theGeometry, theTitle, &NekoSpeed, &IntervalTime ); InitScreen( theDisplayName, theGeometry, theTitle, iconicState ); signal( SIGALRM, NullFunction ); SinPiPer8Times3 = sin( PI_PER8 * (double)3 ); SinPiPer8 = sin( PI_PER8 ); #ifndef DEBUG ProcessNeko(); #else ProcessDebugMenu(); #endif exit( 0 ); }