home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 5 / amigaformatcd05.iso / screenplay / shareware / mastermind / source / mastermind.c next >
C/C++ Source or Header  |  1996-08-13  |  39KB  |  1,457 lines

  1. /* 
  2.    MasterMind.c © Kamran Karimi.
  3.    Written with SAS/C 6.50 on an A1200. 
  4. */
  5. #include "misc.h"
  6.  
  7.  
  8. #define ConstMaxColors 16
  9. #define ConstMaxColumns 16
  10.  
  11. UWORD Private,Pens[] = {0xFFFF};
  12. UBYTE PubName[] = "MasterMind";
  13. struct TagItem MyTags[]  = { {SA_Pens,(ULONG)Pens},
  14.                              {SA_PubName,(ULONG)PubName},
  15.                              {SA_DisplayID,DEFAULT_MONITOR_ID | HIRES_KEY},
  16.                              {SA_Overscan,OSCAN_TEXT},
  17.                              {SA_AutoScroll,TRUE},
  18.                              {TAG_END,NULL} };
  19.  
  20. ULONG NormalMaxColumns = 9,NormalMaxRows;
  21. ULONG MaxColumns = 9,MinColumns = 1;
  22. ULONG MaxColors = 12,MinColors = 2;
  23. LONG NumColors = 6,PrevNumColors;
  24. LONG NumColumns = 4,PrevNumColumns;
  25. LONG NumRows = 0,PrevNumRows;
  26. LONG MaxRows,MaxNoLaceRows,MinRows = 1;
  27.  
  28. ULONG GID,ShouldClear = FALSE;
  29. APTR IAddress;
  30. ULONG OS,ForcePal = FALSE,Public = TRUE,UseLace = TRUE;
  31.  
  32. UBYTE AllocatedColor[ConstMaxColors]; /* 4 reserved colors */
  33. UBYTE Cheated[ConstMaxColumns];
  34.  
  35. ULONG Blacks,Whites,MemAlloc1 = FALSE,MemAlloc2 = FALSE;
  36. ULONG SelectedColor,LowRow,PrevLowRow,NumCheated,FastClean = FALSE;
  37. ULONG CurrentRow = 1,Added = FALSE,Lace = FALSE,Pal;  
  38. USHORT X,Y;/* for Result Borders */
  39.  
  40. struct Remember *ColorRem = NULL,*BoardRem =NULL;
  41.  
  42. VOID Error(ULONG Err),MyMessage(int Mes),CompResBorder(VOID);
  43. VOID ClearBoard(VOID),UpDateAcceptGadget(LONG Where),CheckBounds(VOID);
  44. VOID DrawCircles(LONG Whites,LONG Blacks),GoUp(VOID),ComputeResults(VOID);
  45. VOID GetRandColors(VOID),ProcessBoardGadget(struct Gadget *GadAddr);
  46. VOID ClickOtherColorGads(LONG ID),FillMyColorGadgets(VOID),MyOpenLibs(int);
  47. VOID DrawMyGadgets(VOID),DoConfiguration(VOID),MyEvent(LONG event);
  48. VOID FreeMyGadgets(struct Remember *MyStructRem,struct Gadget *GadToDo);
  49. VOID StartNewGame(VOID),OpenAll(VOID),FreeResources(VOID),WaitForUser(VOID);
  50. int AllocMyGadgets(LONG GadgetNum,struct Remember *MyStructRem,
  51.                                                      struct Gadget *GadToDo);
  52. VOID OpenDragableColor(VOID),CloseDragableColor(VOID);
  53. VOID HandleDragableColor(VOID),GetNewVals(VOID),CleanClean(VOID);
  54. ULONG Permute(ULONG,ULONG);
  55. VOID Cheat(VOID),GetArgs(int,char **);
  56. LONG CheckNoRep(VOID),CheckAllSelected(VOID);
  57. VOID CompatibleSetOPen(struct RastPort *rp,ULONG Color);
  58. ULONG CompatibleGetAPen(struct RastPort *rp),CloseScr(VOID);
  59. VOID CompatibleLoadRGB(struct ViewPort *vp);
  60.  
  61.  
  62. main(int argc,char *argv[])
  63. {
  64.  int done = FALSE,ConfigDone = 0;
  65.  struct Gadget *CurGad;
  66.  
  67.  IconBase = NULL;
  68.  MyOpenLibs(argc);
  69.  
  70.  OS = ((struct Library *)IntuitionBase)->lib_Version;
  71.  if(((struct Library *)GfxBase)->lib_Version >= 36)
  72.   if(GfxBase->ChipRevBits0 & GFXF_HR_DENISE) 
  73.    if(GfxBase->ChipRevBits0 & GFXF_HR_AGNUS) ForcePal = TRUE;
  74.  GetArgs(argc,argv);
  75.  if(OS < 36) UseLace = TRUE;
  76.  if(ForcePal) Pal = TRUE;
  77.  else Pal = (GfxBase->DisplayFlags & PAL);
  78.  if(OS >= 36) MaxColumns = 12;
  79.  NormalMaxRows  = (Pal) ? 24 : 18;
  80.  if(OS >= 36) MaxRows = 99;
  81.  else MaxRows = NormalMaxRows;
  82.  MaxNoLaceRows = (Pal) ? 11 : 8;
  83.  if(!NumRows) NumRows = (Pal) ? 10 : 8;
  84.  NewScr.Height = (Pal) ? 256 : 200;
  85.  MyNewWindow.Height = NewScr.Height;
  86.  if(!Public) MyTags[1].ti_Tag = TAG_IGNORE; 
  87.  
  88.  ((struct StringInfo *)CMGadget.SpecialInfo)->LongInt = NumColumns;
  89.  ((struct StringInfo *)CRGadget.SpecialInfo)->LongInt = NumColors;
  90.  ((struct StringInfo *)RWGadget.SpecialInfo)->LongInt = NumRows;
  91.  PrevNumRows = NumRows;
  92.  PrevNumColumns = NumColumns;
  93.  PrevNumColors = NumColors;
  94.  GetNewVals();
  95.  StartNewGame();
  96.               
  97.  while (done == FALSE)
  98.  {
  99.   WaitForUser(); 
  100.   if ((GID >= 100) && (GID < 116))  
  101.   {
  102.    ClickOtherColorGads(GID);
  103.    MyMessage(Colorize);
  104.    CurGad = (struct Gadget *)IAddress;
  105.    if(CurGad->Flags & GFLG_SELECTED)
  106.     SelectedColor = GID - 96; /* colors start with 4 */
  107.    else SelectedColor = 0;
  108.   }
  109.   if((GID <= NumColumns) && (GID > 0)) ProcessBoardGadget(IAddress);
  110.   switch(GID)
  111.   {
  112.    case 0:
  113.              break;
  114.    case 300:
  115.              if(!CheckAllSelected())
  116.              {
  117.               if(CheckNoRep())
  118.               {
  119.                MyMessage(NoRep);
  120.                break;
  121.               }
  122.               else
  123.               {
  124.                ComputeResults();
  125.                if(Blacks == NumColumns) 
  126.                {
  127.                 MyEvent(UserWon);
  128.                 MyMessage(ChooseCol);
  129.                 StartNewGame(); 
  130.                 break;
  131.                }
  132.                if(CurrentRow != NumRows) 
  133.                {
  134.                 MyMessage(AfterDone);
  135.                 CurrentRow++;
  136.                 GoUp();
  137.                }
  138.                else 
  139.                {
  140.                 NewGadget.GadgetText = &NewText;
  141.                 RefreshGList(&NewGadget,MyWindow,NULL,1);
  142.                 MyEvent(GameDone);
  143.                 MyMessage(ChooseCol);
  144.                 StartNewGame(); 
  145.                }
  146.               }
  147.              }
  148.              else MyMessage(FillFirst);  
  149.              break;
  150.  
  151.    case 500: Cheat();
  152.              break;
  153.  
  154.    case 501:
  155.              if((OS >= 36) && Public)
  156.              {
  157.               Private = PubScreenStatus(MyScreen,PSNF_PRIVATE);
  158.               if(Private & 0x0001) done = TRUE;
  159.               else MyMessage(Visitors);
  160.              }
  161.              else done = TRUE;
  162.              break;
  163.  
  164.    case 502: 
  165.              if(NewGadget.GadgetText == &AbortText)
  166.              {
  167.               NewGadget.GadgetText = &NewText;
  168.               RefreshGList(&NewGadget,MyWindow,NULL,1);
  169.               MyEvent(GameDone);
  170.               MyMessage(ChooseCol);
  171.               StartNewGame(); 
  172.              }
  173.              else 
  174.              {
  175.               MyMessage(ChooseCol);
  176.               StartNewGame();
  177.              }
  178.              break;
  179.  
  180.    case 503:
  181.              if(ConfigDone)  
  182.              {
  183.               RemoveGList(MyWindow,&RWGadget,3);
  184.               GetNewVals();
  185.               StartNewGame();
  186.              }
  187.              else  
  188.              {
  189.               if(ColorWindow && (ColorWindow != MyWindow)) 
  190.                CloseDragableColor();
  191.               DoConfiguration();
  192.               MyMessage(ChangeConf);
  193.              }
  194.              ConfigDone = ~ConfigDone;
  195.              break;
  196.  
  197.    case 1000: 
  198.              NumColumns = ((struct StringInfo *)CMGadget.SpecialInfo)->LongInt;
  199.              break; 
  200.  
  201.    case 1001: 
  202.              NumColors = ((struct StringInfo *)CRGadget.SpecialInfo)->LongInt;
  203.              break;
  204.  
  205.    case 1002: 
  206.              NumRows = ((struct StringInfo *)RWGadget.SpecialInfo)->LongInt;
  207.              break;
  208.   }
  209.  }
  210.  FreeResources();
  211.  exit(0);
  212. }
  213.  
  214.  
  215. VOID FreeResources(VOID)
  216. {
  217.  if(MemAlloc1)
  218.  {
  219.   RemoveGList(MyWindow,&BoardGadget,NumColumns);
  220.   FreeMyGadgets(BoardRem,&BoardGadget);
  221.  }
  222.  if(MemAlloc2)
  223.  {
  224.   RemoveGList(ColorWindow,&ColorGadget,NumColors);
  225.   FreeMyGadgets(ColorRem,&ColorGadget);
  226.  }
  227.  if(Added) RemoveGList(MyWindow,&ConfiGadget,5);
  228.  if(ColorWindow && (ColorWindow != MyWindow)) CloseWindow(ColorWindow);
  229.  if(MyWindow) CloseWindow(MyWindow);
  230.  if(MyScreen) CloseScreen(MyScreen);
  231.  if(GfxBase) CloseLibrary((struct Library *)GfxBase);
  232.  if(IconBase) CloseLibrary(IconBase);
  233.  if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  234. }
  235.  
  236.  
  237. VOID WaitForUser(VOID)
  238. {
  239.  struct MsgPort *Port;
  240.  struct IntuiMessage *msg;
  241.  UWORD code;
  242.  ULONG class,RecMask;
  243.  ULONG ColorMask = 1L << (ColorWindow->UserPort)->mp_SigBit;
  244.  ULONG MainMask = 1L << (MyWindow->UserPort)->mp_SigBit;
  245.  
  246. #ifdef DEBUG
  247.  printf("ColorWin = %lx    MyWin = %lx\n",ColorWindow,MyWindow);
  248.  printf("ColorMask = %08lx    MainMask = %08lx\n",ColorMask,MainMask);
  249. #endif
  250.  RecMask = Wait(ColorMask | MainMask);
  251.  if(RecMask & ColorMask) Port = ColorWindow->UserPort;
  252.  else Port = MyWindow->UserPort;
  253.  msg = (struct IntuiMessage *)GetMsg(Port);
  254.  GID = 0;
  255.  class = msg->Class;
  256.  switch(class)
  257.  {
  258.     case IDCMP_GADGETUP: 
  259.                         IAddress = (msg->IAddress);
  260.                         GID = ((struct Gadget *)IAddress)->GadgetID;
  261.                         while(msg)
  262.                         {
  263.                          ReplyMsg((struct Message *)msg);
  264.                          msg = (struct IntuiMessage *)GetMsg(Port);
  265.                         }
  266.                         break;
  267.     case IDCMP_MOUSEBUTTONS:
  268.                         code = msg->Code;
  269.                         while(msg)
  270.                         {
  271.                          ReplyMsg((struct Message *)msg);
  272.                          msg = (struct IntuiMessage *)GetMsg(Port);
  273.                         }
  274.                         if(code == MENUUP)
  275.                          if(ConfiGadget.GadgetText != &DoneText) 
  276.                           HandleDragableColor();
  277.                         break;
  278.  }
  279. }
  280.  
  281.  
  282. VOID HandleDragableColor(VOID)
  283. {
  284.  if(ColorWindow == MyWindow) OpenDragableColor();
  285.  else CloseDragableColor();
  286. }
  287.  
  288.  
  289. VOID CloseDragableColor(VOID)
  290. {
  291.  int count;
  292.  struct Gadget *CurrGad;
  293.  
  294.  if((ColorWindow == NULL) || (ColorWindow == MyWindow)) return;
  295.  RemoveGList(ColorWindow,&ColorGadget,NumColors);
  296.  CloseWindow(ColorWindow);
  297.  ColorWindow = MyWindow;
  298.  ColorGadget.LeftEdge = MyScreen->Width - 350;
  299.  ColorGadget.TopEdge = MyScreen->Height - 16;  
  300.  CurrGad = ColorGadget.NextGadget;
  301.  for(count = 1;count < NumColors;count++)
  302.  {
  303.   CurrGad->LeftEdge = ColorGadget.LeftEdge - count * 25;
  304.   CurrGad->TopEdge = ColorGadget.TopEdge;
  305.   CurrGad = CurrGad->NextGadget;
  306.  } 
  307.  AddGList(MyWindow,&ColorGadget,~0,NumColors,NULL);
  308.  DrawBorder(ColorWindow->RPort,&ColBorder[3],
  309.              MyScreen->Width - NumColors * 25 - 328,ColorGadget.TopEdge - 2);
  310.  FillMyColorGadgets();
  311.  RefreshGList(&ColorGadget,MyWindow,NULL,NumColors); 
  312. }
  313.  
  314.  
  315. VOID OpenDragableColor(VOID)
  316. {
  317.  int count;
  318.  SHORT Left,Width;
  319.  struct Gadget *CurrGad;
  320.  
  321.  if((ColorWindow != MyWindow) && (ColorWindow != NULL)) return;
  322.  RemoveGList(MyWindow,&ColorGadget,NumColors);
  323.  SetAPen(MyWindow->RPort,0);
  324.  CompatibleSetOPen(MyWindow->RPort,0);
  325.  RectFill(MyWindow->RPort,2,MyScreen->Height - 22,
  326.                              ColorGadget.LeftEdge + 30,MyScreen->Height);
  327.  NewColorWindow.Width = NumColors * 25 + 40;  
  328.  if(MyScreen->MouseY > 50)
  329.    NewColorWindow.TopEdge = MyScreen->MouseY - 35; 
  330.  else 
  331.   NewColorWindow.TopEdge = MyScreen->MouseY;
  332.   
  333.   NewColorWindow.LeftEdge = (MyScreen->MouseX) - (NewColorWindow.Width/2);
  334.   Left = NewColorWindow.LeftEdge;
  335.   Width = NewColorWindow.Width;
  336.   if(Left + Width >= MyScreen->Width) 
  337.    NewColorWindow.LeftEdge = MyScreen->Width - Width;
  338.   if(Left <= MyScreen->LeftEdge)
  339.    NewColorWindow.LeftEdge = MyScreen->LeftEdge;
  340.   
  341.  ColorGadget.LeftEdge = NewColorWindow.Width - 40;
  342.  ColorGadget.TopEdge = 16;
  343.  CurrGad = ColorGadget.NextGadget;
  344.  for(count = 1;count < NumColors;count++)
  345.  {
  346.   CurrGad->LeftEdge = ColorGadget.LeftEdge - count * 25;
  347.   CurrGad->TopEdge = ColorGadget.TopEdge;
  348.   CurrGad = CurrGad->NextGadget;
  349.  } 
  350.  NewColorWindow.Screen = MyScreen; 
  351.  if((ColorWindow = OpenWindow(&NewColorWindow)) == NULL) Error(NoWindow);
  352.  AddGList(ColorWindow,&ColorGadget,~0,NumColors,NULL);
  353.  DrawBorder(ColorWindow->RPort,&ColBorder[3],22,14);
  354.  FillMyColorGadgets();
  355.  RefreshGList(&ColorGadget,ColorWindow,NULL,NumColors);
  356.  
  357. VOID Error(ULONG Err)
  358. {
  359.  FreeResources();
  360.  exit(Err);
  361. }
  362.  
  363. VOID CompatibleSetOPen(struct RastPort *rp,ULONG Color)
  364. {
  365.  if(OS >= 39) SetOutlinePen(rp,Color);
  366.  else SetOPen(rp,(UBYTE)Color);
  367. }
  368.  
  369. ULONG CompatibleGetAPen(struct RastPort *rp)
  370. {
  371.  return((OS >= 39) ? GetAPen(rp) : rp->FgPen);
  372. }
  373.  
  374. VOID CompatibleLoadRGB(struct ViewPort *vp)
  375. {
  376.  if(OS >= 39) LoadRGB32(vp,CMap32Bit); 
  377.  else LoadRGB4(vp,CMap4Bit,16);
  378. }
  379.  
  380. VOID MyMessage(int Mes)
  381. {
  382.  LONG y,Color; 
  383.  
  384.  strcpy(Row1,Messages[Mes]);
  385.  strcpy(Row2,Messages[Mes + 1]);
  386.  strcpy(Row3,Messages[Mes + 2]);
  387.  y = (Pal) ? 89 : 65;
  388.  Color = 1;
  389.  if(Mes == UserWon) Color = 4;
  390.  else if(Mes == GameDone) Color = 7; 
  391.  if(Mes >= NoAvailMem)
  392.  {
  393.   Color = 8;
  394.   DisplayBeep(MyScreen);
  395.  }
  396.  row1Text.FrontPen = row2Text.FrontPen = row3Text.FrontPen = Color;
  397.  PrintIText(MyWindow->RPort,&row3Text,MyScreen->Width - 180,y);
  398. }
  399.  
  400.  
  401. VOID Cheat(VOID)
  402. {
  403.  struct IntuiMessage *msg;
  404.  LONG CheatCol,Column,XMin,YMin,XMax,YMax,cnt;
  405.  struct Gadget *CurGad;
  406.  struct MD *md;
  407.  
  408.  RemoveGList(MyWindow,&BoardGadget,NumColumns);
  409.  RemoveGList(ColorWindow,&ColorGadget,NumColors);
  410.  OffGadget(&AcceptGadget,MyWindow,NULL);
  411.  OffGadget(&CheatGadget,MyWindow,NULL);
  412.  OffGadget(&NewGadget,MyWindow,NULL);
  413.  CheatCol = (ULONG)(rand() % NumColumns);
  414.  while(Cheated[CheatCol + 4] == TRUE) CheatCol = (CheatCol + 1) % NumColumns;
  415.  NumCheated++;
  416.  Cheated[CheatCol + 4] = TRUE;
  417.  MyMessage(CheatMe);
  418.  MyResWindow.LeftEdge = CheatGadget.LeftEdge;
  419.  MyResWindow.TopEdge = CheatGadget.TopEdge - 100;
  420.  MyResWindow.Screen = MyScreen;
  421.  MyResWindow.Width = 100;
  422.  MyResWindow.Title = "Naughty!";
  423.  if((ResWindow = OpenWindow(&MyResWindow)) == NULL) Error(NoWindow);
  424.  CurGad = &BoardGadget;
  425.  for(Column = 0;Column < CheatCol;Column++) CurGad = CurGad->NextGadget;
  426.  DrawImage(ResWindow->RPort,&MyImage, 33,15);
  427.  XMin = 33 + 9;
  428.  YMin = 20;
  429.  XMax = XMin + 14;
  430.  YMax = YMin + 8;
  431.  md = CurGad->UserData;
  432.  SetAPen(ResWindow->RPort,md->RandomColor);
  433.  CompatibleSetOPen(ResWindow->RPort,md->RandomColor);
  434.  RectFill(ResWindow->RPort,XMin,YMin,XMax,YMax);
  435.  WaitPort(ResWindow->UserPort);
  436.  msg = (struct IntuiMessage *)GetMsg(ResWindow->UserPort);
  437.  while(msg)
  438.  {
  439.   ReplyMsg((struct Message *)msg);
  440.   msg = (struct IntuiMessage *)GetMsg(ResWindow->UserPort);
  441.  }
  442.  CloseWindow(ResWindow);
  443.  CurGad = &ColorGadget;
  444.  for(cnt = 0;cnt < md->RandomColor - 4;cnt++) CurGad = CurGad->NextGadget;
  445.  CheatSign.BackPen = md->RandomColor;
  446.  XMin = CurGad->LeftEdge + 6;
  447.  YMin = CurGad->TopEdge + 1;
  448.  PrintIText(ColorWindow->RPort,&CheatSign,XMin,YMin);
  449.  UpDateAcceptGadget(1);
  450.  OnGadget(&AcceptGadget,MyWindow,NULL);
  451.  XMin = CheatGadget.LeftEdge - 2;
  452.  YMin = CheatGadget.TopEdge - 2;
  453.  XMax = NewGadget.LeftEdge + NewGadget.Width + 2;
  454.  YMax = YMin + NewGadget.Height + 1;
  455.  SetAPen(MyWindow->RPort,0);
  456.  CompatibleSetOPen(MyWindow->RPort,0);
  457.  if(NumCheated < NumColumns) OnGadget(&CheatGadget,MyWindow,NULL);
  458.  else OffGadget(&CheatGadget,MyWindow,NULL);
  459.  RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  460.  SetAPen(MyWindow->RPort,SelectedColor);
  461.  CompatibleSetOPen(MyWindow->RPort,SelectedColor);
  462.  OnGadget(&NewGadget,MyWindow,NULL);
  463.  RefreshGList(&CheatGadget,MyWindow,NULL,1);
  464.  AddGList(MyWindow,&BoardGadget,~0,NumColumns,NULL);
  465.  AddGList(ColorWindow,&ColorGadget,~0,NumColors,NULL);
  466. }
  467.  
  468. VOID CompResBorder(VOID)
  469. {
  470.  ULONG BigX,BigY,XMin,YMin,XMax,YMax,count;
  471.  
  472.  Y =  19;
  473.  X =  ((NumColumns / 2) + (NumColumns % 2)) * 15; 
  474.  
  475.  ResLines1[1] = Y;
  476.  ResLines1[4] = X + 1;
  477.  
  478.  ResLines2[1] = Y - 1;
  479.  ResLines2[2] = X + 1;
  480.  ResLines2[3] = Y - 1;
  481.  ResLines2[4] = X + 1;
  482.  
  483.  ResLines3[1] = Y - 2;
  484.  ResLines3[4] = X;
  485.  
  486.  ResLines4[1] = Y;
  487.  ResLines4[2] = X + 2;
  488.  ResLines4[3] = Y;
  489.  ResLines4[4] = X + 2; 
  490.  BigX = X + NumColumns * 33 + 13;
  491.  BigY = LowRow - ((NumRows - 1) * 19 + 5);
  492.  SetAPen(MyWindow->RPort,2);
  493.  Move(MyWindow->RPort,2,LowRow + 23);
  494.  Draw(MyWindow->RPort,2,BigY);
  495.  Draw(MyWindow->RPort,BigX,BigY);
  496.  SetAPen(MyWindow->RPort,1);
  497.  Draw(MyWindow->RPort,BigX,LowRow + 23);
  498.  Draw(MyWindow->RPort,2,LowRow + 23);
  499.  SetAPen(MyWindow->RPort,3); 
  500.  RectFill(MyWindow->RPort,3,BigY + 1,BigX - 1,LowRow + 22);
  501.  
  502.  SetAPen(MyWindow->RPort,0);
  503.  for(count = 0;count < NumRows;count++)
  504.  {
  505.   XMin = 9;
  506.   YMin = LowRow - count * 19;
  507.   XMax = XMin + X - 1;
  508.   YMax = YMin + Y - 2;
  509.   RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  510.  }
  511.  
  512. ULONG Permute(ULONG arg1,ULONG arg2)
  513. {
  514.  ULONG count,val = 1;
  515.  
  516.  arg2 = arg1 - arg2;
  517.  for(count = arg2 + 1;count <= arg1;count++)
  518.  {
  519.   val =  val * count;
  520.   if(val > MaxRows) break;
  521.  }
  522.  return(val);
  523. }
  524.  
  525.  
  526. VOID CheckBounds(VOID)
  527. {
  528.  ULONG Perm;
  529.  
  530.  if(NumColumns < MinColumns) NumColumns = MinColumns;
  531.  else if(NumColumns > MaxColumns) NumColumns = MaxColumns;
  532.  if(NumColors < MinColors) NumColors = MinColors;
  533.  else if(NumColors > MaxColors) NumColors = MaxColors;
  534.  if(NumRows < MinRows) NumRows = MinRows;
  535.  else if(NumRows > MaxRows) NumRows = MaxRows;
  536.  if(NumColors < NumColumns) NumColors = NumColumns;
  537.  Perm = Permute(NumColors,NumColumns) - 1;
  538.  if(NumRows > Perm) NumRows = Perm;
  539. }
  540.  
  541.  
  542. ULONG CloseScr(VOID)
  543. {
  544.  ULONG Success = TRUE;
  545.  
  546.  if(MyScreen)
  547.  {
  548.   if((OS >= 36) && Public)
  549.   {
  550.    Private = PubScreenStatus(MyScreen,PSNF_PRIVATE);
  551.    if(!(Private & 0x0001)) 
  552.    { 
  553.     Success = FALSE; 
  554.     MyMessage(Visitors); 
  555.    }
  556.   }
  557.   if(Success)
  558.   {
  559.    if(MemAlloc1 && MyWindow)
  560.    {
  561.     RemoveGList(MyWindow,&BoardGadget,NumColumns);
  562.     FreeMyGadgets(BoardRem,&BoardGadget);
  563.     MemAlloc1 = FALSE;
  564.    }
  565.    if(MemAlloc2 && ColorWindow)
  566.    {
  567.     RemoveGList(ColorWindow,&ColorGadget,NumColors);
  568.     FreeMyGadgets(ColorRem,&ColorGadget);
  569.     MemAlloc2 = FALSE;
  570.    } 
  571.    if(Added) { RemoveGList(MyWindow,&ConfiGadget,4); Added = FALSE; }
  572.    if(MyWindow) { CloseWindow(MyWindow); ColorWindow = MyWindow = NULL; }
  573.    if(MyScreen) { CloseScreen(MyScreen); MyScreen = NULL; }
  574.   }
  575.  }
  576.  return(Success);
  577. }
  578.  
  579.  
  580. VOID GetNewVals(VOID)
  581. {
  582.  ULONG ShouldChange = FALSE;
  583.  UWORD OW,OH,OM;
  584.  
  585.  NumColumns = ((struct StringInfo *)CMGadget.SpecialInfo)->LongInt;
  586.  NumColors = ((struct StringInfo *)CRGadget.SpecialInfo)->LongInt;
  587.  NumRows = ((struct StringInfo *)RWGadget.SpecialInfo)->LongInt;
  588.  CheckBounds();
  589.  OW = NewScr.Width;
  590.  OH = NewScr.Height;
  591.  OM = NewScr.ViewModes;
  592.  NewScr.DefaultTitle = NormalScrTitle;
  593.  if(NumColumns > NormalMaxColumns)
  594.  {
  595.   NewScr.Width = 640 + (NumColumns - NormalMaxColumns) * 35 + 9;
  596.   NewScr.DefaultTitle = ExtraScrTitle;
  597.  }
  598.  else NewScr.Width = 640; 
  599.  if(UseLace)
  600.  {
  601.   if(NumRows > MaxNoLaceRows)
  602.   {
  603.    NewScr.ViewModes |= LACE;
  604.    MyTags[2].ti_Data |= HIRESLACE_KEY;    
  605.    NewScr.Height = (Pal) ? 512 : 400;
  606.   } 
  607.   else
  608.   {
  609.    NewScr.ViewModes &= ~LACE;
  610.    MyTags[2].ti_Data &= ~HIRESLACE_KEY;
  611.    MyTags[2].ti_Data |= HIRES_KEY;  
  612.    NewScr.Height = (Pal) ? 256 : 200;
  613.   }
  614.   if(NumRows > NormalMaxRows) 
  615.   {
  616.    NewScr.Height += (NumRows - NormalMaxRows) * 20;
  617.    NewScr.DefaultTitle = ExtraScrTitle;
  618.   }
  619.  }
  620.  else
  621.  {
  622.   if(NumRows > MaxNoLaceRows) 
  623.   {
  624.    NewScr.Height = ((Pal) ? 256 : 200) + (NumRows - MaxNoLaceRows) * 20;
  625.    NewScr.DefaultTitle = ExtraScrTitle;  
  626.   }
  627.   else  
  628.   {
  629.    NewScr.Height = (Pal) ? 256 : 200;
  630.    NewScr.DefaultTitle = NormalScrTitle;
  631.   }
  632.  }
  633.  MyNewWindow.Height = NewScr.Height;
  634.  MyNewWindow.Width = NewScr.Width;
  635.  ShouldChange = 
  636.    ((OW != NewScr.Width) || (OH != NewScr.Height) || (OM != NewScr.ViewModes));
  637.  if(ShouldChange || !MyScreen)
  638.  {
  639.   if(CloseScr()) 
  640.   {
  641.    ShouldClear = FALSE;
  642.    AcceptGadget.LeftEdge = 1;
  643.    OpenAll();
  644.    MyMessage(ChooseCol);
  645.   } 
  646.   else
  647.   {
  648.    NumColors = PrevNumColors;
  649.    NumColumns = PrevNumColumns;
  650.    NumRows = PrevNumRows;
  651.    MyNewWindow.Width = NewScr.Width = OW;
  652.    MyNewWindow.Height = NewScr.Height = OH;
  653.    NewScr.ViewModes = OM;
  654.    if(MyScreen) MyMessage(Visitors);
  655.   }
  656.  }
  657.  else MyMessage(ChooseCol); 
  658. #ifdef DEBUG
  659.   printf("Width = %d   Height = %d\n",NewScr.Width,NewScr.Height);
  660. #endif
  661. }
  662.  
  663.  
  664. VOID ClearBoard(VOID)
  665. {
  666.  ULONG BigX,BigY,x,y;
  667.  
  668.  SetAPen(MyWindow->RPort,0);
  669.  CompatibleSetOPen(MyWindow->RPort,0);
  670.  RectFill(MyWindow->RPort,2,MyScreen->Height - 22,
  671.                                           MyScreen->Width,MyScreen->Height);
  672.  if(!ShouldClear)
  673.  {
  674.   ShouldClear = TRUE;
  675.   FastClean = FALSE;
  676.  }
  677.  else
  678.  {
  679.   BigX = X + PrevNumColumns * 33 + 13;
  680.   BigY = PrevLowRow - ((PrevNumRows - 1) * 19 + 5);
  681.   if((PrevNumColumns == NumColumns) && (PrevNumRows == NumRows))
  682.   {
  683.    CleanClean();
  684.    FastClean = TRUE;
  685.   }
  686.   else
  687.   { 
  688.    FastClean = FALSE;
  689.    RectFill(MyWindow->RPort,2,BigY,BigX + 1,PrevLowRow + 23);
  690.   }
  691.   x = ConfiGadget.LeftEdge - 2;
  692.   y = ConfiGadget.TopEdge - 2;
  693.   RectFill(MyWindow->RPort,x,y,x + ConfiGadget.Width + 2,
  694.                                                  y + ConfiGadget.Height + 2);
  695.  }
  696. }
  697.  
  698.  
  699. VOID UpDateAcceptGadget(LONG Where)
  700. {
  701.  ULONG XMin,YMin,XMax,YMax,OldAPen;
  702.  
  703.  if(!Where) RemoveGList(MyWindow,&AcceptGadget,1);
  704.  XMin = AcceptGadget.LeftEdge - 1;
  705.  YMin = AcceptGadget.TopEdge - 1;
  706.  XMax = XMin + 64;
  707.  YMax = YMin + 13;
  708.  OldAPen = CompatibleGetAPen(MyWindow->RPort);
  709.  SetAPen(MyWindow->RPort,0);
  710.  CompatibleSetOPen(MyWindow->RPort,0);
  711.  RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  712.  SetAPen(MyWindow->RPort,OldAPen);
  713.  if(!Where)  
  714.  {
  715.   AcceptGadget.TopEdge -= 19;
  716.   AddGList(MyWindow,&AcceptGadget,~0,1,NULL);
  717.   RefreshGList(&AcceptGadget,MyWindow,NULL,1);
  718.  }
  719. }
  720.  
  721.  
  722. VOID DrawCircles(LONG Whites,LONG Blacks)
  723.  ULONG CoOrd1,CoOrd2,count,count2,Elements;
  724.  struct Image *CurrImage;
  725.  
  726.  CoOrd1 = BoardGadget.LeftEdge;
  727.  CoOrd2 = BoardGadget.TopEdge;
  728.  count = 0;
  729.  Elements = Whites;
  730.  CurrImage = &WCircle; 
  731.  for(count2 = 0;count2 < 2;count2++)
  732.  {
  733.   while(Elements > 0)
  734.   {
  735.    DrawImage(MyWindow->RPort,CurrImage,CoOrd1 - 12,CoOrd2 + 4 );   
  736.    switch(count % 2)
  737.    {
  738.     case 0: CoOrd2 += 6;
  739.             break;
  740.  
  741.     case 1: CoOrd1 -= 12;
  742.             CoOrd2 -= 6;
  743.             break;
  744.    } 
  745.    count++;
  746.    Elements--;
  747.   }
  748.   Elements = Blacks;
  749.   CurrImage = &BCircle;
  750.  }
  751. }
  752.  
  753.  
  754. LONG CheckAllSelected(VOID)
  755. {
  756.  struct Gadget *CurGad;
  757.  struct MD *md;
  758.  int count;
  759.  
  760.  CurGad = &BoardGadget;
  761.  for(count = 1;count <= NumColumns;count++)
  762.  {
  763.   md = (struct MD *)CurGad->UserData;
  764.   if(md->GuessedColor == 0) return(1);
  765.   CurGad = CurGad->NextGadget;
  766.  }
  767.  return(0);
  768.  
  769.  
  770. LONG CheckNoRep(VOID)
  771. {
  772.  LONG count,count2;
  773.  struct Gadget *CurGad,*CurGad2; 
  774.  struct MD *md,*md2;
  775.  
  776.  CurGad = &BoardGadget;
  777.  for(count = 0;count < NumColumns;count++)
  778.  {
  779.   CurGad2 = CurGad->NextGadget;
  780.   for(count2 = count + 1;count2 <= NumColumns; count2++)
  781.   {
  782.    md = (struct MD *)CurGad->UserData;
  783.    md2 = (struct MD *)CurGad2->UserData;
  784.    CurGad2 = CurGad2->NextGadget;
  785.    if((md->GuessedColor == md2->GuessedColor) && 
  786.                                     (md->GuessedColor != 0)) return(RepFound);
  787.   }
  788.   CurGad = CurGad->NextGadget;
  789.  }
  790.  return(0);
  791. }
  792.  
  793.  
  794. VOID GoUp(VOID)
  795. {
  796.  int count;
  797.  struct Gadget *CurGad;
  798.  struct MD *md;
  799.  
  800.  RemoveGList(MyWindow,&BoardGadget,NumColumns);
  801.  CurGad = &BoardGadget;
  802.  for(count = 1;count <= NumColumns;count++)
  803.  {
  804.   CurGad->TopEdge -=  19;
  805.   md = (struct MD *)CurGad->UserData;
  806.   md->GuessedColor = 0;
  807.   CurGad = CurGad->NextGadget;
  808.  }
  809.  AddGList(MyWindow,&BoardGadget,~0,NumColumns,NULL);
  810.  RefreshGList(&BoardGadget,MyWindow,NULL,NumColumns);
  811.  UpDateAcceptGadget(0);
  812. }
  813.  
  814.  
  815. VOID ComputeResults(VOID)
  816. {
  817.  LONG count,count2,XMin,YMin,XMax,YMax;
  818.  struct MD *md,*md2;
  819.  struct Gadget *CurGad,*CurGad2;
  820.  
  821.  Blacks = Whites = 0;
  822.  CurGad = &BoardGadget;
  823.  
  824.  if(NewGadget.GadgetText != &AbortText)
  825.  {
  826.   NewGadget.GadgetText = &AbortText;
  827.   RefreshGList(&NewGadget,MyWindow,NULL,1);
  828.   OffGadget(&ConfiGadget,MyWindow,NULL);
  829.   OffGadget(&QuitGadget,MyWindow,NULL);
  830.   XMin = CheatGadget.LeftEdge - 2;
  831.   YMin = CheatGadget.TopEdge - 2;
  832.   XMax = XMin + CheatGadget.Width + 4;
  833.   YMax = YMin + CheatGadget.Height + 4;
  834.   SetAPen(MyWindow->RPort,0);
  835.   CompatibleSetOPen(MyWindow->RPort,0);
  836.   RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  837.   if((NumColumns == 1) || (NumColumns == NumColors))
  838.    OffGadget(&CheatGadget,MyWindow,NULL);
  839.   else OnGadget(&CheatGadget,MyWindow,NULL);
  840.   SetAPen(MyWindow->RPort,SelectedColor); 
  841.   CompatibleSetOPen(MyWindow->RPort,SelectedColor);
  842.  }
  843.  for(count = 1;count <= NumColumns; count++) /* first the blacks */
  844.  {
  845.   md = (struct MD *)CurGad->UserData;
  846.   if(md->RandomColor == md->GuessedColor) 
  847.   {
  848.    md->GuessedColor = 0;
  849.    Blacks++;
  850.   }
  851.   CurGad = CurGad->NextGadget;
  852.  }
  853.  
  854.  CurGad = &BoardGadget;
  855.  for(count = 1;count <= NumColumns;count++)
  856.  {
  857.   md = (struct MD *)CurGad->UserData;
  858.   CurGad2 = &BoardGadget;
  859.   for(count2 = 1; count2 <= NumColumns;count2++)
  860.   {
  861.    md2 = (struct MD *)CurGad2->UserData;
  862.    if(md->RandomColor == md2->GuessedColor) 
  863.    {
  864.     md2->GuessedColor = 0;
  865.     Whites++;
  866.     break;
  867.    }
  868.    CurGad2 = CurGad2->NextGadget;
  869.   }
  870.   CurGad = CurGad->NextGadget;
  871.  }
  872.  CurGad = &BoardGadget;
  873.  for(count = 1;count <= NumColumns;count++)
  874.  {
  875.   md = (struct MD *)CurGad->UserData;
  876.   md->GuessedColor = 0;
  877.   CurGad = CurGad->NextGadget;
  878.  }
  879.  DrawCircles(Whites,Blacks);
  880. #ifdef DEBUG
  881.  printf("whites = %ld  Blacks = %ld\n",Whites,Blacks);
  882. #endif
  883. }
  884.  
  885. VOID GetRandColors(VOID)
  886. {
  887.  ULONG count,Color;
  888.  ULONG Secs,Mics;
  889.  struct Gadget *CurGad;
  890.  struct MD *md;
  891.  
  892. #ifdef DEBUG
  893.  printf("Total Colors = %ld\n",NumColors);
  894.  printf("Columns = %d\n",NumColumns);
  895.  printf("Rows = %ld\n",NumRows);
  896. #endif
  897.  
  898.  CurGad = &BoardGadget;
  899.  CurrentTime(&Secs,&Mics);
  900.  srand(Secs + Mics);
  901.  for(count = 1;count <= NumColumns;count++)
  902.  {
  903.   Color = (ULONG)(rand() % NumColors);
  904.   while(AllocatedColor[Color + 4] == TRUE) 
  905.                                        Color = (Color + 1) % NumColors;
  906.   md = (struct MD *)CurGad->UserData;
  907.   md->RandomColor = Color + 4;
  908.   md->GuessedColor = 0;
  909.   AllocatedColor[Color + 4] = TRUE;
  910.   CurGad = CurGad->NextGadget;
  911. #ifdef DEBUG
  912.   printf("Color No. %ld = %ld\n",count,Color);
  913. #endif
  914.  } 
  915.  
  916.  
  917. VOID ProcessBoardGadget(struct Gadget *GadAddr)
  918. {
  919.  LONG XMin,YMin,XMax,YMax;
  920.  struct MD *md;
  921.  
  922.  XMin = GadAddr->LeftEdge + 9;
  923.  YMin = GadAddr->TopEdge + 5;
  924.  XMax = XMin + 14;
  925.  YMax = YMin + 8;
  926.  SetAPen(MyWindow->RPort,SelectedColor);
  927.  CompatibleSetOPen(MyWindow->RPort,SelectedColor);
  928.  RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  929.  if(SelectedColor > 3)
  930.  {
  931.   md = (struct MD *)GadAddr->UserData;
  932.   md->GuessedColor = SelectedColor;
  933.   MyMessage(RepColoring);
  934.  }
  935. }
  936.  
  937. VOID CleanClean(VOID)
  938. {
  939.  ULONG XMin,XMax,YMin,YMax,ResYMin,count1,count2;
  940.  
  941.  YMin = LowRow + 5;
  942.  YMax = YMin + 8;
  943.  SetAPen(MyWindow->RPort,0);
  944.  CompatibleSetOPen(MyWindow->RPort,0);
  945.  for(count1 = 1; count1 <= NumRows; count1++)
  946.  {
  947.   ResYMin = LowRow + 2 - (count1 - 1) * 19;
  948.   RectFill(MyWindow->RPort,10,ResYMin,7 + X - 1,ResYMin + 13);
  949.   XMin = X + 9 + 9;
  950.   XMax = XMin + 14;
  951.   for(count2 = 1;count2 <= NumColumns; count2++)
  952.   {
  953.    RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  954.    XMin = XMin + BoardGadget.Width;
  955.    XMax = XMin + 14;
  956.   }
  957.   YMin = YMin - 19;
  958.   YMax = YMin + 8;
  959.  }
  960. }
  961.  
  962.  
  963. VOID ClickOtherColorGads(LONG ID)
  964. {
  965.  int count;
  966.  struct Gadget *CurGad = &ColorGadget;
  967.  
  968.  for(count = 0;count < NumColors;count++)
  969.  { 
  970.   if((CurGad->Flags & GFLG_SELECTED) && (CurGad->GadgetID != ID))
  971.   {
  972.    CurGad->Flags &= ~GFLG_SELECTED;  
  973.    break;
  974.   }
  975.   CurGad = CurGad->NextGadget;
  976.  }
  977.  RefreshGList(&ColorGadget,ColorWindow,NULL,NumColors);
  978. }
  979.  
  980.  
  981. VOID FillMyColorGadgets(VOID)
  982. {
  983.  LONG count,count2,XMin,YMin,XMax,YMax,Color;
  984.  struct Gadget *CurGad = &ColorGadget,*CurGad2;
  985.  
  986.  for(count = 4;count < NumColors + 4;count++)
  987.  {
  988.   SetAPen(ColorWindow->RPort,count);
  989.   CompatibleSetOPen(ColorWindow->RPort,count);
  990.   XMin = CurGad->LeftEdge;
  991.   YMin = CurGad->TopEdge;
  992.   XMax = XMin + CurGad->Width - 1;
  993.   YMax = YMin + CurGad->Height - 1;
  994.   RectFill(ColorWindow->RPort,XMin,YMin,XMax,YMax);
  995.   CurGad2 = &BoardGadget;
  996.   for(count2 = 0;count2 < NumColumns;count2++)
  997.   {
  998.    Color = ((struct MD *)(CurGad2->UserData))->RandomColor;
  999.    if((Cheated[count2 + 4] == TRUE) && (Color == count))
  1000.    { 
  1001.     CheatSign.BackPen = count;
  1002.     XMin = CurGad->LeftEdge + 6;
  1003.     YMin = CurGad->TopEdge + 1;
  1004.     PrintIText(ColorWindow->RPort,&CheatSign,XMin,YMin);
  1005.    }
  1006.    CurGad2 = CurGad2->NextGadget;
  1007.   }
  1008.   CurGad = CurGad->NextGadget;
  1009.  }
  1010. }
  1011.  
  1012.  
  1013. VOID DrawMyGadgets(VOID)
  1014. {
  1015.  int Column,Row;
  1016.  
  1017.  if(FastClean) return;
  1018.  CompResBorder();
  1019.  for(Row = 0;Row < NumRows;Row++)
  1020.  {
  1021.   DrawBorder(MyWindow->RPort,&ResBorder[3],7,LowRow - Row * 19);
  1022.   for(Column = 0;Column < NumColumns;Column++)
  1023.    DrawImage(MyWindow->RPort,&MyImage,(X + 9 + Column * 33),
  1024.                                                           LowRow - Row * 19);
  1025.  }
  1026. }
  1027.  
  1028.  
  1029. /* This routine dynamically allocates gadgets. Total gadget number equals 
  1030.    the ones allocated here plus the gadget whose pointer is in GadTodo.
  1031.    total = [GadgetNum -1] (allocated here) + [1] (GadToDo)
  1032. */
  1033.  
  1034. int AllocMyGadgets(LONG GadgetNum,struct Remember *MyStructRem,
  1035.                                                       struct Gadget *GadToDo)
  1036. {
  1037.  struct Gadget *PrevGadget,*NewGad;
  1038.  struct MD *Mymd;
  1039.  int count;
  1040.   
  1041.  if(GadToDo == &BoardGadget) GadToDo->LeftEdge = X + 9;
  1042.  GadToDo->Flags &= ~GFLG_SELECTED;
  1043.  PrevGadget = GadToDo;
  1044.  for(count = 1; count < GadgetNum; count++) 
  1045.  {
  1046.   NewGad = AllocRemember(&MyStructRem,sizeof(struct Gadget),MEMF_ANY);
  1047.   if(NewGad == NULL) 
  1048.   {
  1049.    FreeMyGadgets(MyStructRem,GadToDo);
  1050.    return(FALSE);
  1051.   }
  1052.   CopyMem(GadToDo,NewGad,sizeof(struct Gadget));
  1053.   NewGad->GadgetID = PrevGadget->GadgetID + 1;
  1054.   if(GadToDo == &BoardGadget)
  1055.   {
  1056.    NewGad->LeftEdge = PrevGadget->LeftEdge + GadToDo->Width;
  1057.    Mymd = AllocRemember(&MyStructRem,sizeof(struct MD),MEMF_ANY|MEMF_CLEAR);
  1058.    if(Mymd == NULL) 
  1059.    {
  1060.     FreeMyGadgets(MyStructRem,GadToDo);
  1061.     return(FALSE);
  1062.    }
  1063.    NewGad->UserData = Mymd;
  1064.   }
  1065.   else if(GadToDo == &ColorGadget)
  1066.    NewGad->LeftEdge = PrevGadget->LeftEdge - GadToDo->Width - 5; 
  1067.   PrevGadget->NextGadget = NewGad;
  1068.   PrevGadget = NewGad;
  1069.  }
  1070.  NewGad->NextGadget = NULL;
  1071.  return(TRUE);
  1072. }
  1073.  
  1074. VOID FreeMyGadgets(struct Remember *MyStructRem,struct Gadget *GadToDo)
  1075. {
  1076.  FreeRemember(&MyStructRem,TRUE);
  1077.  MyStructRem = NULL;
  1078.  GadToDo->NextGadget = NULL;
  1079. }
  1080.  
  1081.  
  1082. VOID DoConfiguration(VOID)
  1083. {
  1084.  LONG y1;
  1085.  
  1086.  y1 = (Pal) ? 111 : 90;
  1087.  
  1088.  PrevNumColors = NumColors;
  1089.  PrevNumRows = NumRows;
  1090.  PrevNumColumns = NumColumns;
  1091.  PrevLowRow = LowRow;
  1092.  
  1093.  if(MemAlloc1)
  1094.  {
  1095.   RemoveGList(MyWindow,&BoardGadget,NumColumns);
  1096.   FreeMyGadgets(BoardRem,&BoardGadget);
  1097.  }
  1098.  if(MemAlloc2)
  1099.  {
  1100.   RemoveGList(ColorWindow,&ColorGadget,NumColors);
  1101.   FreeMyGadgets(ColorRem,&ColorGadget);
  1102.  }
  1103.  MemAlloc1 = MemAlloc2 = FALSE;
  1104.  ConfiGadget.GadgetText = &DoneText;
  1105.  RefreshGList(&ConfiGadget,MyWindow,NULL,1);
  1106.  OffGadget(&NewGadget,MyWindow,NULL);
  1107.  OffGadget(&QuitGadget,MyWindow,NULL);
  1108.  OffGadget(&AcceptGadget,MyWindow,NULL);
  1109.  OffGadget(&CheatGadget,MyWindow,NULL);
  1110.  CRGadget.GadgetRender = &ConfBorder[3];
  1111.  CMGadget.GadgetRender = &ConfBorder[3];
  1112.  RWGadget.GadgetRender = &ConfBorder[3];
  1113.  BigConfBorder[0].FrontPen = 2;
  1114.  BigConfBorder[1].FrontPen = 1;
  1115.  DrawBorder(MyWindow->RPort,&BigConfBorder[1],
  1116.                              MyScreen->Width - 182,MyScreen->Height - y1 - 1);
  1117.  AddGList(MyWindow,&RWGadget,~0,3,NULL);
  1118.  RefreshGList(&RWGadget,MyWindow,NULL,3);
  1119. }  
  1120.  
  1121.  
  1122. VOID MyEvent(LONG event)
  1123. {
  1124.  struct IntuiMessage *msg;
  1125.  LONG Column,XMin,YMin,XMax,YMax;
  1126.  ULONG class;
  1127.  struct Gadget *CurGad;
  1128.  struct MD *md;
  1129.  
  1130.  RemoveGList(MyWindow,&BoardGadget,NumColumns);
  1131.  RemoveGList(ColorWindow,&ColorGadget,NumColors);
  1132.  OffGadget(&CheatGadget,MyWindow,NULL);
  1133.  OffGadget(&AcceptGadget,MyWindow,NULL);
  1134.  if(event == UserWon) 
  1135.  {
  1136.   MyMessage(UserWon);
  1137.   NewGadget.GadgetText = &OKText;
  1138.   RefreshGList(&NewGadget,MyWindow,NULL,1);
  1139.   do
  1140.   {    
  1141.    WaitPort(MyWindow->UserPort);
  1142.    msg = (struct IntuiMessage *)GetMsg(MyWindow->UserPort);
  1143.    class = msg->Class;
  1144.    while(msg)
  1145.    {
  1146.     ReplyMsg((struct Message *)msg);
  1147.     msg = (struct IntuiMessage *)GetMsg(MyWindow->UserPort);
  1148.    }
  1149.   }while(class != IDCMP_GADGETUP);
  1150.   NewGadget.GadgetText = &NewText;
  1151.   RefreshGList(&NewGadget,MyWindow,NULL,1);
  1152.  }
  1153.  if(event == GameDone)
  1154.  { 
  1155.   MyMessage(GameDone);
  1156.   OffGadget(&NewGadget,MyWindow,NULL);
  1157.   MyResWindow.Width = NumColumns * 33 + 13 + 40;
  1158.   MyResWindow.LeftEdge = NewGadget.LeftEdge - MyResWindow.Width + 100;
  1159.   MyResWindow.TopEdge = NewGadget.TopEdge - 100;
  1160.   MyResWindow.Screen = MyScreen;
  1161.   MyResWindow.Title = "Solution";
  1162.   if((ResWindow = OpenWindow(&MyResWindow)) == NULL) Error(NoWindow);
  1163.   CurGad = &BoardGadget;
  1164.   for(Column = 0;Column < NumColumns;Column++)
  1165.   {
  1166.    DrawImage(ResWindow->RPort,&MyImage, 25 + Column * 33,15);
  1167.    XMin = 25 + Column * 33 + 9;
  1168.    YMin = 20;
  1169.    XMax = XMin + 14;
  1170.    YMax = YMin + 8;
  1171.    md = CurGad->UserData;
  1172.    SetAPen(ResWindow->RPort,md->RandomColor);
  1173.    CompatibleSetOPen(ResWindow->RPort,md->RandomColor);
  1174.    RectFill(ResWindow->RPort,XMin,YMin,XMax,YMax);
  1175.    CurGad = CurGad->NextGadget;
  1176.   } 
  1177.   WaitPort(ResWindow->UserPort);
  1178.   msg = (struct IntuiMessage *)GetMsg(ResWindow->UserPort);
  1179.   while(msg)
  1180.   {
  1181.    ReplyMsg((struct Message *)msg);
  1182.    msg = (struct IntuiMessage *)GetMsg(ResWindow->UserPort);
  1183.   }
  1184.   CloseWindow(ResWindow);
  1185.  }
  1186. }
  1187.  
  1188.  
  1189. VOID StartNewGame(VOID)
  1190. {
  1191.  
  1192.  LONG y1,count,XMin,YMin,XMax,YMax,X2;
  1193.  
  1194.  y1 = (Pal) ? 111 : 90;
  1195.  
  1196.  SelectedColor = 0; 
  1197.  if(MemAlloc1)
  1198.  {
  1199.   RemoveGList(MyWindow,&BoardGadget,NumColumns);
  1200.   FreeMyGadgets(BoardRem,&BoardGadget);
  1201.  }
  1202.  if(MemAlloc2)
  1203.  {
  1204.   RemoveGList(ColorWindow,&ColorGadget,NumColors);
  1205.   FreeMyGadgets(ColorRem,&ColorGadget);
  1206.  }
  1207.  for(count = 0;count < (MaxColors + 4);count++) AllocatedColor[count] = FALSE;
  1208.  for(count = 0;count < (MaxColumns + 4);count++) Cheated[count] = FALSE;
  1209.  NumCheated = 0;
  1210.  CurrentRow = 1;
  1211.  LowRow = MyScreen->Height - 24 - (MyScreen->Height - (NumRows * 19)) / 2;
  1212.  BoardGadget.TopEdge = LowRow;
  1213.  OffGadget(&CheatGadget,MyWindow,NULL); 
  1214.  OnGadget(&NewGadget,MyWindow,NULL);
  1215.  OnGadget(&QuitGadget,MyWindow,NULL);
  1216.  OnGadget(&AcceptGadget,MyWindow,NULL);
  1217.  OnGadget(&ConfiGadget,MyWindow,NULL);
  1218.  UpDateAcceptGadget(1);
  1219.  ClearBoard();
  1220.  X2 = NumColors * (20 + 5) + 7;  
  1221.  CoLines1[4] = X2;
  1222.  CoLines2[2] = X2 - 1;
  1223.  CoLines2[4] = X2 - 1;
  1224.  CoLines3[4] = X2 - 1;
  1225.  CoLines4[2] = X2;
  1226.  CoLines4[4] = X2;
  1227.  
  1228.  if(ColorWindow == MyWindow)
  1229.   DrawBorder(ColorWindow->RPort,&ColBorder[3],
  1230.             MyScreen->Width - NumColors * 25 - 328,ColorGadget.TopEdge - 2); 
  1231.  else
  1232.   DrawBorder(ColorWindow->RPort,&ColBorder[3],22,14);
  1233.  DrawMyGadgets(); 
  1234.  MemAlloc1 = (AllocMyGadgets(NumColumns,BoardRem,&BoardGadget)) ? TRUE:FALSE;
  1235.  MemAlloc2 = (AllocMyGadgets(NumColors,ColorRem,&ColorGadget)) ? TRUE:FALSE;
  1236.  if(!MemAlloc1 || !MemAlloc2)
  1237.  {
  1238.   MyMessage(NoAvailMem);
  1239.   Delay(300);
  1240.   FreeResources();
  1241.   exit(20);
  1242.  } 
  1243.  GetRandColors();
  1244.  AddGList(MyWindow,&BoardGadget,~0,NumColumns,NULL);
  1245.  
  1246.  AddGList(ColorWindow,&ColorGadget,~0,NumColors,NULL);
  1247.  
  1248.  FillMyColorGadgets(); 
  1249.  
  1250.  RefreshGList(&BoardGadget,MyWindow,NULL,NumColumns);
  1251.  RefreshGList(&ColorGadget,ColorWindow,NULL,NumColors);
  1252.  
  1253.  sprintf(crbuf,"%d",NumColors);
  1254.  sprintf(cmbuf,"%d",NumColumns);
  1255.  sprintf(rwbuf,"%d",NumRows);
  1256.  ((struct StringInfo *)CMGadget.SpecialInfo)->LongInt = NumColumns;
  1257.  ((struct StringInfo *)CRGadget.SpecialInfo)->LongInt = NumColors;
  1258.  ((struct StringInfo *)RWGadget.SpecialInfo)->LongInt = NumRows;
  1259.  XMin = CMGadget.LeftEdge - 4;
  1260.  YMin = CMGadget.TopEdge - 4;
  1261.  XMax = RWGadget.LeftEdge + RWGadget.Width + 2;
  1262.  YMax = RWGadget.TopEdge + RWGadget.Height + 2;
  1263.  SetAPen(MyWindow->RPort,0);
  1264.  CompatibleSetOPen(MyWindow->RPort,0);
  1265.  RectFill(MyWindow->RPort,XMin,YMin,XMax,YMax);
  1266.  BigConfBorder[0].FrontPen = 1;
  1267.  BigConfBorder[1].FrontPen = 2;
  1268.  DrawBorder(MyWindow->RPort,&BigConfBorder[1],
  1269.                             MyScreen->Width - 182,MyScreen->Height - y1 - 1);
  1270.  CRGadget.GadgetRender = NULL;
  1271.  CMGadget.GadgetRender = NULL;
  1272.  RWGadget.GadgetRender = NULL;
  1273.  AddGList(MyWindow,&RWGadget,~0,3,NULL);
  1274.  RefreshGList(&RWGadget,MyWindow,NULL,3);
  1275.  RemoveGList(MyWindow,&RWGadget,3);
  1276.  AcceptGadget.LeftEdge = BoardGadget.LeftEdge + NumColumns * 33  + 9;
  1277.  AcceptGadget.TopEdge = LowRow - (CurrentRow - 1) * 19 + 4;
  1278.  RefreshGList(&AcceptGadget,MyWindow,NULL,1);
  1279.  NewGadget.GadgetText = &NewText;
  1280.  RefreshGList(&NewGadget,MyWindow,NULL,2);
  1281.  RefreshGList(&CheatGadget,MyWindow,NULL,2);
  1282.  ConfiGadget.GadgetText = &ConfigText;
  1283.  RefreshGList(&ConfiGadget,MyWindow,NULL,1);
  1284.  PrevNumColors = NumColors;
  1285.  PrevNumRows = NumRows;
  1286.  PrevNumColumns = NumColumns;
  1287.  PrevLowRow = LowRow;
  1288. }
  1289.  
  1290.  
  1291. VOID MyOpenLibs(int Argc)
  1292. {
  1293.  if((IntuitionBase = (struct IntuitionBase *)
  1294.         OpenLibrary("intuition.library",0)) == NULL) Error(NoIntuition);
  1295.  
  1296.  if((GfxBase = (struct GfxBase *)
  1297.         OpenLibrary("graphics.library",0)) == NULL) Error(NoGraphics);
  1298.  
  1299.  if(!Argc)
  1300.   if((IconBase = OpenLibrary("icon.library",33)) == NULL) Error(NoIcon);
  1301. }
  1302.  
  1303.  
  1304. VOID OpenAll(VOID)
  1305. {
  1306.  LONG y,y1;
  1307.  
  1308.  y = (Pal) ? 86 : 62;
  1309.  y1 = (Pal) ? 111 : 90;
  1310.  
  1311.  if(OS >= 36)
  1312.  {
  1313.   if(ForcePal) MyTags[2].ti_Data |= PAL_MONITOR_ID;
  1314.   if((MyScreen = OpenScreenTagList(&NewScr,MyTags)) == NULL) Error(NoScreen); 
  1315.  }
  1316.  
  1317.  else if((MyScreen = OpenScreen(&NewScr)) == NULL) Error(NoScreen);
  1318.  MyNewWindow.Screen = MyScreen;
  1319.  if((MyWindow = OpenWindow(&MyNewWindow)) == NULL) Error(NoWindow);
  1320.  ColorWindow = MyWindow;
  1321.  
  1322.  CompatibleLoadRGB(&(MyScreen->ViewPort));
  1323.  
  1324.  ColorGadget.LeftEdge = MyScreen->Width - 350;
  1325.  ColorGadget.TopEdge = MyScreen->Height - 16;
  1326.  
  1327.  QuitGadget.LeftEdge = MyScreen->Width - 90;
  1328.  QuitGadget.TopEdge = MyScreen->Height - 15;
  1329.  
  1330.  NewGadget.LeftEdge = MyScreen->Width - 190;
  1331.  NewGadget.TopEdge = MyScreen->Height  - 15;
  1332.  
  1333.  CheatGadget.LeftEdge = MyScreen->Width - 290;
  1334.  CheatGadget.TopEdge = MyScreen->Height - 15;
  1335.  
  1336.  ConfiGadget.LeftEdge = MyScreen->Width - 135;
  1337.  ConfiGadget.TopEdge = MyScreen->Height - (y1 - 48);
  1338.   
  1339.  DrawImage(MyWindow->RPort,&LogoImage,MyScreen->Width - 184, 20);
  1340.  
  1341.  PrintIText(MyWindow->RPort,&rwText,
  1342.                 MyScreen->Width - 183,MyScreen->Height - y1 + 2);
  1343.  
  1344.  BigConfBorder[0].FrontPen = 1;
  1345.  BigConfBorder[1].FrontPen = 2;
  1346.  DrawBorder(MyWindow->RPort,&BigConfBorder[1],
  1347.                             MyScreen->Width - 182,MyScreen->Height - y1 - 1);
  1348.  
  1349.  DrawBorder(MyWindow->RPort,&MessBorder[3],
  1350.                                MyScreen->Width - 180,y);
  1351.  
  1352.  CRGadget.LeftEdge = CMGadget.LeftEdge =
  1353.                               RWGadget.LeftEdge = MyScreen->Width - 90;
  1354.  
  1355.  CMGadget.TopEdge = MyScreen->Height - y1;
  1356.  CRGadget.TopEdge = CMGadget.TopEdge + 15;
  1357.  RWGadget.TopEdge = CRGadget.TopEdge + 16;
  1358.  
  1359.  AddGList(MyWindow,&ConfiGadget,~0,5,NULL);
  1360.  Added = TRUE;
  1361.  if((OS >= 36) && Public)
  1362.  {
  1363.   Private = PubScreenStatus(MyScreen,0);
  1364.   if (!(Private & 0x0001)) Error(NoPub);
  1365.  }
  1366. }
  1367.  
  1368.  
  1369. VOID GetArgs(int argc,char *argv[])
  1370. {
  1371.  int Temp,count;
  1372.  struct WBStartup *WBMessage;
  1373.  struct WBArg *WBarg;
  1374.  struct DiskObject *DiskObj;
  1375.  char **ToolArray,*tt;
  1376.  
  1377.  if((argc == 2) && !strcmp(argv[1],"?"))
  1378.  {
  1379.   printf("\n MasterMind.  © Kamran Karimi\n");
  1380.   printf("\nUSAGE: %s [(c|C)#] [(g|G)#] [(t|T)#] [m|M)] [e|E] [n|N]\n",
  1381.                                                                    argv[0]);
  1382.   printf("         c : Guess among this many 'C'olors\n\
  1383.          g : 'G'uess this many Colors\n\
  1384.          t : In atmost this many 'T'ries\n\
  1385.          m : Use a custo'M' screen (not public)\n\
  1386.          e : Don't use interlace ('E'yes at 'E'ase!)\n\
  1387.          n : Don't force a PAL screen (for 'N'TSC users)\n");
  1388.   exit(0);
  1389.  }
  1390.  if(argc > 1)
  1391.  {
  1392.   for(count = 1;count < argc;count++)
  1393.   {
  1394.    Temp = atoi(argv[count] + 1);
  1395.    switch (argv[count][0])
  1396.    {
  1397.     case 'g':
  1398.     case 'G':
  1399.              if(Temp > 0) NumColumns = Temp;
  1400.              break;
  1401.     case 'c':
  1402.     case 'C':
  1403.              if(Temp > 0) NumColors = Temp;
  1404.              break; 
  1405.     case 't':
  1406.     case 'T':
  1407.              if(Temp > 0) NumRows = Temp;
  1408.              break;
  1409.     case 'm':
  1410.     case 'M':
  1411.              Public = FALSE;
  1412.              break;
  1413.     case 'e':
  1414.     case 'E':
  1415.              UseLace = FALSE;
  1416.              break;       
  1417.     case 'n':
  1418.     case 'N':
  1419.              ForcePal = FALSE;
  1420.              break;        
  1421.    }
  1422.   }
  1423.  }
  1424.  
  1425.  if(!argc)
  1426.  {
  1427.   WBMessage = (struct WBStartup *)argv;
  1428.   WBarg = WBMessage->sm_ArgList;
  1429.   DiskObj = GetDiskObject(WBarg->wa_Name);
  1430.   ToolArray = (char **)DiskObj->do_ToolTypes; 
  1431.   if(tt = (char *)FindToolType(ToolArray,"COLORS")) 
  1432.   {
  1433.    Temp = atoi(tt);
  1434.    if(Temp > 0) NumColors = Temp;
  1435.   }
  1436.   if(tt = (char *)FindToolType(ToolArray,"GUESS")) 
  1437.   {
  1438.    Temp = atoi(tt);
  1439.    if(Temp > 0) NumColumns = Temp;
  1440.   }
  1441.   if(tt = (char *)FindToolType(ToolArray,"TRIES")) 
  1442.   {
  1443.    Temp = atoi(tt);
  1444.    if(Temp > 0) NumRows = Temp;
  1445.   }
  1446.   if(tt = (char *)FindToolType(ToolArray,"CUSTOMSCREEN")) Public = FALSE;
  1447.   if(tt = (char *)FindToolType(ToolArray,"NOINTERLACE")) UseLace = FALSE;
  1448.   if(tt = (char *)FindToolType(ToolArray,"NOPAL")) ForcePal = FALSE;
  1449.   FreeDiskObject(DiskObj);
  1450.  }
  1451. }
  1452.