home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / wbgames / tripppin / source / event.c < prev    next >
C/C++ Source or Header  |  1977-12-31  |  8KB  |  384 lines

  1. /* this handles player mouse input in the game Trippin. */
  2.  
  3. #include <exec/memory.h>
  4. #include <intuition/intuition.h>
  5. #include <graphics/sprite.h>
  6. #include "trip.h"
  7.  
  8.  
  9. #define SIGBREAKF_CTRL_C   bit(SIGBREAKB_CTRL_C)
  10.  
  11.  
  12.  
  13. #define THINKDELAY 200
  14. #define ANTTIME    27
  15. #define BLINKTIME  75
  16.  
  17. /* THINKDELAY is the minimum time in 300ths of a second for which we should
  18. say "thinking" before we make a machine move (it embarasses the users when we
  19. move before they finish letting go of the mouse button, with them low
  20. difficulty levels).  ANTTIME is the minimum duration of each frame of the
  21. animation of the ants, if any.  The ants can't animate any faster than ten
  22. per second (reliably) without opening the timer device ... but that's fast
  23. enough and setting up a tiny vblank interrupt is less trouble than opening
  24. the timer.  BLINKTIME is the time between toggling the X markers on or off. */
  25.  
  26.  
  27.  
  28. adr IntuitionBase;
  29.  
  30.  
  31. import void LiftBob(), DropBob(), DragBob(), Play(), DrawSquare(), Die(),
  32.         Win2Square();
  33.  
  34. import piece oo, bb, *turn;
  35.  
  36. import bool notadrill, thinking, abort_think, DoMenu();
  37.  
  38. import bool won, lace;
  39.  
  40. import short sigdone, suggx, suggy, thinkx, thinky, depth, thite;
  41.  
  42. import ushort *osprat, *bsprat, *nuth;
  43.  
  44. import struct SimpleSprite ox, bx;
  45.  
  46. import struct Task *child;
  47.  
  48. import struct Window *win;
  49.  
  50. import struct ViewPort *vp;
  51.  
  52.  
  53.  
  54. /* image data created with GetImage */
  55.  
  56. private UWORD ant0[26] = {
  57.     0x5280, 0x6300,
  58.     0x5298, 0x6318,
  59.     0x0000, 0x0018,
  60.     0x0018, 0x0000,
  61.     0xc000, 0x0000,
  62.     0x0000, 0xc000,
  63.     0xc018, 0xc018,
  64.     0x0000, 0x0018,
  65.     0x0018, 0x0000,
  66.     0xc000, 0x0000,
  67.     0x0000, 0xc000,
  68.     0xca50, 0xc630,
  69.     0x0a50, 0x0630
  70. };
  71.  
  72.  
  73. private UWORD ant1[26] = {
  74.     0x2520, 0x8428,
  75.     0x2520, 0x4630,
  76.     0xc018, 0xc000,
  77.     0x0000, 0x0000,
  78.     0x0000, 0x0000,
  79.     0xc018, 0x0018,
  80.     0x0000, 0xc018,
  81.     0xc018, 0xc000,
  82.     0x0000, 0x0000,
  83.     0x0000, 0x0000,
  84.     0xc018, 0x0018,
  85.     0x2520, 0x6310,
  86.     0x2520, 0xa308
  87. };
  88.  
  89.  
  90. private UWORD ant2[26] = {
  91.     0x0a50, 0x0c60,
  92.     0xca50, 0x0c60,
  93.     0x0000, 0xc000,
  94.     0xc000, 0xc000,
  95.     0x0018, 0x0018,
  96.     0x0000, 0x0018,
  97.     0xc018, 0x0000,
  98.     0x0000, 0xc000,
  99.     0xc000, 0xc000,
  100.     0x0018, 0x0018,
  101.     0x0000, 0x0018,
  102.     0x5298, 0x3180,
  103.     0x5280, 0x3180
  104. };
  105.  
  106.  
  107. private UWORD ant3[26] = {
  108.     0x14a0, 0x18c0,
  109.     0x14a0, 0x18c0,
  110.     0xc000, 0x0000,
  111.     0x0018, 0xc018,
  112.     0xc000, 0xc018,
  113.     0x0018, 0x0000,
  114.     0x0000, 0x0000,
  115.     0xc000, 0x0000,
  116.     0x0018, 0xc018,
  117.     0xc000, 0xc018,
  118.     0x0018, 0x0000,
  119.     0x2940, 0x18c0,
  120.     0x2940, 0x18c0
  121. };
  122.  
  123.  
  124. private UWORD ant4[26] = {
  125.     0x2940, 0x3180,
  126.     0x2940, 0x3180,
  127.     0x0018, 0x0018,
  128.     0xc000, 0x0018,
  129.     0x0018, 0xc000,
  130.     0xc000, 0xc000,
  131.     0x0000, 0x0000,
  132.     0x0018, 0x0018,
  133.     0xc000, 0x0018,
  134.     0x0018, 0xc000,
  135.     0xc000, 0xc000,
  136.     0x14a0, 0x0c60,
  137.     0x14a0, 0x0c60
  138. };
  139.  
  140.  
  141.  
  142. piece *grabee;
  143.  
  144.  
  145. long startedthinking = 0, antsmoved, blinked = 0;
  146.  
  147.  
  148. private ushort sprum = -1, antnum, *sproint = null;    /* points to chip ram */
  149.  
  150.  
  151. private struct SimpleSprite suggestion = {
  152.     &ant0[0] /* sproint */, 13, 0, 0, -1
  153. };
  154.  
  155.  
  156.  
  157. void Ding()
  158. {
  159.     DisplayBeep(win->WScreen);
  160. }
  161.  
  162.  
  163.  
  164. long Now()    /* returns time since game started measured in 300ths of sec */
  165. {
  166.     static long starts = 0, startm = 0;
  167.     long ss, mm;
  168.     CurrentTime(&ss, &mm);
  169.     if (!starts) {
  170.     starts = ss;
  171.     startm = mm;
  172.     return 0;
  173.     }
  174.     return 300 * (ss - starts) + (mm - startm) / 3333;
  175. }
  176.  
  177.  
  178.  
  179. void KillAnts()
  180. {
  181.     if (~sprum)
  182.     FreeSprite((long) sprum);
  183.     if (sproint)
  184.     FreeMem(sproint, 64L);
  185.     sproint = null;
  186.     sprum = -1;
  187. }
  188.  
  189.  
  190.  
  191. private short spx, spy;
  192.  
  193. private void AnimAnts()
  194. {
  195.     ushort *new;
  196.     long now = Now(), offf = 9L + thite + win->TopEdge + 8 * lace, blate;
  197.     bool stifle = (win->Flags & MENUSTATE) || !(win->Flags & WINDOWACTIVE);
  198.     short hi = stifle ? 1 : 9;
  199.  
  200.     if (ox.x == bx.x && ox.y == bx.y)
  201.     blate = BLINKTIME << 1;
  202.     else if (ox.height > 1)
  203.     blate = 3 * BLINKTIME;
  204.     else blate = BLINKTIME;
  205.     if (stifle || now - blinked >= blate) {
  206.     blinked = now;
  207.     if (blate == (BLINKTIME << 1) && !won) {
  208.         if (ox.height == 1)
  209.         ox.height = hi, bx.height = 1;
  210.         else
  211.         ox.height = 1, bx.height = hi;
  212.     } else if (ox.height == 1 && !won)
  213.         ox.height = bx.height = hi;
  214.     else ox.height = bx.height = 1;
  215.     ((long *) osprat)[10] = ((long *) bsprat)[10] = ((long *) nuth)[2] = 0;
  216.     ChangeSprite(vp, &ox, ox.height == 1 ? nuth : osprat);
  217.     ChangeSprite(vp, &bx, bx.height == 1 ? nuth : bsprat);
  218.     }
  219.     MoveSprite(vp, &ox, oo.goalx * (SQIZE << 1) + 12L + win->LeftEdge,
  220.             oo.goaly * (SQIZE << lace) + offf);
  221.     MoveSprite(vp, &bx, bb.goalx * (SQIZE << 1) + 12L + win->LeftEdge,
  222.             bb.goaly * (SQIZE << lace) + offf);
  223.     /* MoveSprite them repeatedly to follow window / viewport movement */
  224.  
  225.     if (!~sprum)
  226.     return;
  227.     /* Should we wait for the video beam to be well placed?     NAAAAH... */
  228.     if (now - antsmoved >= ANTTIME) {
  229.     antsmoved = now;
  230.     if (++antnum > 4)
  231.         antnum = 0;
  232.     switch (antnum) {
  233.         case 0:  new = &ant0[0]; break;
  234.         case 1:  new = &ant1[0]; break;
  235.         case 2:  new = &ant2[0]; break;
  236.         case 3:  new = &ant3[0]; break;
  237.         case 4:  new = &ant4[0];
  238.     }
  239.     if (stifle)
  240.         setmem(sproint + 2, 52, 0);        /* invisible */
  241.     else
  242.         movmem(new, sproint + 2, 52);
  243.     }
  244.     MoveSprite(vp, &suggestion, spx * (SQIZE << 1) + 10L + win->LeftEdge,
  245.         spy * (SQIZE << lace) + 7L + thite + win->TopEdge + 6 * lace);
  246. }
  247.  
  248.  
  249.  
  250. void MakeAnts(x, y) short x, y;
  251. {
  252.     struct SimpleSprite placeholder;
  253.     long cum;
  254.     bool gotsp1;
  255.  
  256.     KillAnts();
  257.     placeholder = suggestion;
  258.     gotsp1 = GetSprite(&placeholder, 1L) != -1;      /* reserve this sprite */
  259.     if (~(sprum = GetSprite(&suggestion, -1L)))
  260.     if (!(sproint = AllocCPZ(64))) {
  261.         FreeSprite((long) sprum);
  262.         sprum = -1;
  263.     }
  264.     if (gotsp1)
  265.     FreeSprite(1L);
  266.     if (sprum < 0)
  267.     return;
  268.     ChangeSprite(vp, &suggestion, sproint);
  269.     spx = x; spy = y;
  270.     antnum = 0;
  271.     cum = 17 + ((sprum << 1) & ~3);
  272.     SetRGB4(vp, cum, 0L, 0L, 15L);        /* blue */
  273.     SetRGB4(vp, cum + 1, 0L, 15L, 0L);        /* green */
  274.     SetRGB4(vp, cum + 2, 15L, 0L, 0L);        /* red */
  275.     antsmoved = 0;
  276.     AnimAnts();
  277. }
  278.  
  279.  
  280.  
  281. void PickUpToken(m) struct IntuiMessage *m;
  282. {
  283.     piece *ogre = grabee;
  284.     short xxx, yyy;
  285.  
  286.     Win2Square(m->MouseX, m->MouseY, &xxx, &yyy);
  287.     if (xxx == oo.x && yyy == oo.y)
  288.     grabee = &oo;
  289.     else if (xxx == bb.x && yyy == bb.y)
  290.     grabee = &bb;
  291.     else grabee = null;
  292.     if (won)
  293.     grabee = null;
  294.     if (grabee != ogre) {
  295.     if (ogre) /* probably not */
  296.         DropBob(ogre);
  297.     if (grabee) {
  298.         if (grabee != turn || grabee->machine) {    /* not your turn! */
  299.         grabee = null;
  300.         Ding();
  301.         } else {
  302.         LiftBob(grabee);
  303.         DrawSquare(grabee->x, grabee->y);    /* erase old image */
  304.         DragBob(grabee, m->MouseX, m->MouseY);
  305.         }
  306.     }
  307.     }
  308. }
  309.  
  310.  
  311.  
  312. void SetTokenDown(m) struct IntuiMessage *m;
  313. {
  314.     short xx, yy;
  315.     Win2Square(m->MouseX, m->MouseY, &xx, &yy);
  316.     if (!TryMove(grabee, xx, yy))
  317.     Ding();                    /* illegal move */
  318.     DropBob(grabee);
  319.     grabee = null;
  320. }
  321.  
  322.  
  323.  
  324. void Play()
  325. {
  326.     struct IntuiMessage *orig, m;
  327.     long sigmund, mask;
  328.     bool machineready = false;
  329.  
  330.     mask = bit(win->UserPort->mp_SigBit) | bit(sigdone) | bit(sigtof)
  331.         | SIGBREAKF_CTRL_C;
  332.     for (;;) {        /* intuition event loop */
  333.     sigmund = Wait(mask);
  334.     while (orig = (adr) GetMsg(win->UserPort)) {
  335.         m = *orig;
  336.         ReplyMsg(orig);
  337.         if (m.Class == CLOSEWINDOW)    {    /* quit the game! */
  338.         abort_think = true;
  339.         return;
  340.         } else if (m.Class == MOUSEBUTTONS) {
  341.         if (m.Code == SELECTDOWN)
  342.             PickUpToken(&m);
  343.         else if (m.Code == SELECTUP && grabee)
  344.             SetTokenDown(&m);
  345.         } else if (m.Class == MOUSEMOVE) {
  346.         if (m.Qualifier & IEQUALIFIER_LEFTBUTTON && grabee)
  347.             DragBob(grabee, m.MouseX, m.MouseY);
  348.         } else {                    /* MENUPICK */
  349.         if (grabee) /* probably not */
  350.             DropBob(grabee);
  351.         grabee = null;
  352.         if (DoMenu(ITEMNUM(m.Code)))
  353.             return;
  354.         }
  355.     }
  356.     AnimAnts();
  357.     if (sigmund & bit(sigdone)) {
  358.         if (!abort_think && !won) {
  359.         if (notadrill) {
  360.             machineready = true;
  361.             abort_think = false;
  362.         } else {
  363.             suggx = thinkx;
  364.             suggy = thinky;
  365.             depth++;
  366.             if (depth <= 12) {
  367.             startedthinking = Now();
  368.             thinking = true;
  369.             Signal(child, bit(sigthink));    /* resume, deeper */
  370.             }
  371.         }
  372.         } else abort_think = false;
  373.     }
  374.     if (machineready && Now() - startedthinking >= THINKDELAY) {
  375.         machineready = false;
  376.         MachineMove();
  377.     }
  378.     if (sigmund & SIGBREAKF_CTRL_C) {
  379.         abort_think = true;
  380.         return;
  381.     }
  382.     }
  383. }
  384.