home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 138.lha / Cycle / cycles.c < prev    next >
C/C++ Source or Header  |  1986-11-20  |  7KB  |  224 lines

  1. /*
  2.  * main cycles program ..wait for messages to com in and
  3.  *do "the right thing"
  4.  */
  5. #include <intuition/intuition.h>
  6. #include <exec/memory.h>
  7. #include <devices/timer.h>
  8. #include <libraries/dos.h>
  9. #include "cycles.h"
  10. #ifdef AZTEC_C
  11. extern long  Enable_Abort;
  12. #endif
  13. extern BYTE   scr_image[];
  14.  
  15. long xdir[]   = { 0, 1, 0,-1};  /* up,right,down,left */
  16. long ydir[]   = {-1, 0, 1, 0};  /* up,right,down,left */
  17. long TIME     = 6;
  18. long PLAYERS  = 2;
  19. long GAMES    = 0;
  20. long scores[MAX_COLOURS];
  21.  
  22. IMAGE   scr_data;             /* screen image data                      */
  23. LIST    cycle_list;           /* list of current cycles                 */
  24. TIMEREQ *tr;                  /* timer ExtIO request structure          */
  25. PORT    *sPort;               /* server port                            */
  26. PORT    *tPort;               /* timer port                             */
  27. long     num_players = 0;     /* how many players are there             */
  28. long     num_waiting = 0;     /* how many are waiting for new game      */
  29. long     num_alive   = 0;     /* number of cycles that are still moving */
  30.  
  31. extern struct Window *war_window;  /* our window c/w close gadget */
  32.  
  33. main(argc,argv)
  34. long argc; char **argv;
  35. {
  36.   ORDER   *msg;               /* order from client                      */
  37.   CYCLE   *cycle;             /* current cycle structure                */
  38.   long portsig,closesig;      /* signal bits for our ports              */
  39.   long signals;               /* reserved signals                       */
  40.   long used_colours = 0;      /* bitmask showing which colours are used */
  41.   long i;                     /* misc.                                  */
  42.   long games_played;
  43.  
  44. #ifdef AZTEC_C
  45.   Enable_Abort = 0;
  46. #endif
  47.   /* initialize screen data structures, will tell clients the shape
  48.    * of the screen by providing a pointer to this data
  49.    */
  50.   scr_data.x     = X_SIZE;
  51.   scr_data.y     = Y_SIZE;
  52.   scr_data.buf   = scr_image;
  53.   tr             = 0;
  54.   games_played   = 0;
  55.  
  56.   for(i=1; i<argc; i++) {
  57.     switch(argv[i][0]) {
  58.       case 't':  TIME = atoi(argv[i] + 1);
  59.                  break;
  60.       case 'p':  PLAYERS = atoi(argv[i] + 1);
  61.                  if (PLAYERS < 2) PLAYERS = 2;
  62.                  break;
  63.       case 'g':  GAMES = atoi(argv[i] + 1);
  64.                  break;
  65.       }
  66.     }
  67.   sPort = CreatePort("Cycle Server",0L);
  68.   if (!sPort) {
  69.     printf("Error, can't open server port\n");
  70.     terminate();
  71.     }
  72.   tr = Timer_Open(UNIT_MICROHZ,sPort);
  73.   if (!tr) terminate();
  74.   /* open up custom screen etc... */
  75.   if (g_init()) terminate();
  76.  
  77.   draw_scores();
  78.  
  79.   /* do setup */
  80.   g_restart();
  81.  
  82.   portsig  = (1<<(sPort->mp_SigBit));
  83.   closesig = (1<< war_window->UserPort->mp_SigBit);
  84.  
  85.   srand(time(0)); /* seed the random number generator */
  86.   NewList(&cycle_list);
  87.   Timer_Post(tr, TIME / 1000,(TIME % 1000) * 1000);
  88.  
  89.   for(;;) {
  90.     /* wait for either a time event or a client */
  91.     signals = Wait(closesig | portsig | SIGBREAKF_CTRL_C);
  92.  
  93.     if (signals & portsig) {
  94.       while(msg = (ORDER *)GetMsg(sPort)) {
  95.         if ((TIMEREQ *)msg == tr) { /* time request reply */
  96.           if (num_alive) move_cycles(&cycle_list);
  97.             Timer_Post(tr,
  98.                   TIME * num_alive / 1000,           /* seconds */
  99.                   ((num_alive * TIME) % 1000) * 1000 /* micros  */
  100.                   );
  101.           continue;
  102.         }
  103.         cycle = msg->cycle;
  104.  
  105.         if (!cycle) {
  106.           for (i=0; i<8; i++)
  107.             if ((~used_colours) & (1<<i)) break;
  108.           if (i == MAX_COLOURS) {
  109.             printf("Error, no colours left for the new cycle\n");
  110.             msg->status = STATUS_REMOVED;
  111.             ReplyMsg(msg);
  112.             continue;
  113.           }
  114.           cycle = AllocMem(sizeof(CYCLE),MEMF_PUBLIC);
  115.           if (!cycle) {
  116.             printf("Error, can't get memory for new cycle\n");
  117.             msg->status = STATUS_REMOVED;
  118.             ReplyMsg(msg);
  119.             continue;
  120.           }
  121.           AddHead(&cycle_list, &cycle->node);
  122.           num_players++;
  123.           msg->cycle        = cycle;
  124.           msg->table        = &scr_data;
  125.           cycle->status     = STATUS_LOSER;
  126.           cycle->dir        = DIR_RIGHT;
  127.           cycle->x          = rand() % (X_SIZE - 10) + 5;
  128.           cycle->y          = rand() % (Y_SIZE - 10) + 5;
  129.           cycle->colour     = i;
  130.           cycle->msg        = NULL;
  131.           used_colours     |= (1<<i);
  132.           scores[i]         = 0;
  133.         }
  134.         switch(msg->order) {
  135.           case ORD_DIRECTION:
  136.               if (cycle->status < STATUS_DEAD) {
  137.                 cycle->dir    = msg->dir;
  138.                 cycle->status = STATUS_GOT_MOVE;
  139.                 cycle->msg    = msg;
  140.               }
  141.               else {
  142.                 msg->status = cycle->status;
  143.                 ReplyMsg(msg);
  144.               }
  145.               continue;
  146.           case ORD_AWAIT:
  147.               if (cycle->status < STATUS_DEAD) /* still alive */
  148.                 num_alive--;
  149.               cycle->msg    = msg;
  150.               cycle->status = STATUS_AWAITING;
  151.               num_waiting++;
  152.               if (num_waiting == num_players) {
  153.                 if (GAMES > 0 && games_played >= GAMES)
  154.                   terminate();
  155.                 else if (num_players >= PLAYERS) {
  156.                   g_restart();
  157.                   restart_cycles(&cycle_list);
  158.                   games_played++;
  159.                 }
  160.               }
  161.               continue;
  162.  
  163.           case ORD_RETIRE:
  164.               Remove(cycle);
  165.               if (cycle->status < STATUS_DEAD) /* still alive */
  166.                 num_alive--;
  167.               FreeMem(cycle,sizeof(CYCLE));
  168.               num_players--;
  169.               used_colours   &= ~(1<<cycle->colour);
  170.               msg->status     = STATUS_REMOVED;
  171.               ReplyMsg(msg);
  172.               continue;
  173.  
  174.           default:
  175.               printf("Got an invalid request, Ignoring\n");
  176.               ReplyMsg(msg);
  177.               continue;
  178.         }
  179.       }
  180.     }
  181.     if (signals & SIGBREAKF_CTRL_C || signals & closesig)
  182.       terminate();
  183.   }
  184. }
  185.  
  186. terminate()
  187. {
  188.   ORDER *msg;
  189.  
  190.   free_cycles(&cycle_list);
  191.  
  192.   if (tr) {
  193.     WaitIO(tr);
  194.     tr->tr_node.io_Message.mn_ReplyPort = 0L;
  195.     Timer_Close(tr);
  196.   }
  197.   /* inform all players that are still active that we are shutting down */
  198.   while (num_players) {
  199.     WaitPort(sPort);
  200.     while(msg = (ORDER *)GetMsg(sPort)) {
  201.       msg->status = STATUS_REMOVED;
  202.       /* if a new player tries to join, don't      */
  203.       /* decrement the coiunt the actual structure */
  204.       /* has already been free so don't look at it */
  205.       if (msg->cycle) num_players--;
  206.       ReplyMsg(msg);
  207.     }
  208.   }
  209.   g_finish();
  210.   /* here we clear out the Port before deleting it, it is important to
  211.    * Forbid() first so that no new messages arrive at the port between
  212.    * the time we last look at it and the time it is DeletePort'ed
  213.    */
  214.  
  215.   Forbid();
  216.   while(msg = (ORDER *)GetMsg(sPort)) {
  217.     msg->status = STATUS_REMOVED;
  218.     ReplyMsg(msg);
  219.   }
  220.   DeletePort(sPort);
  221.   Permit();
  222.   exit(0);
  223. }
  224.