home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d886 / goalkeeper.lha / GoalKeeper / Sources / main.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  20KB  |  692 lines

  1.  
  2. /* GOALKEEPER V1.0  19-oct-92 Camiel Rouweler */
  3.  
  4. #include <intuition/intuition.h>
  5. #include <dos/dosextens.h>
  6. #include <exec/memory.h>
  7.  
  8. #define MODE_OLDFILE 1005L  /* saves us from including dos.h */
  9. #define MODE_NEWFILE 1006L
  10.  
  11. /* data for a played match */
  12. struct GameData
  13. {
  14.    UBYTE  TeamA[12], TeamB[12];  /* Team names */
  15.    ULONG  pl1_score, pl2_score;  /* goals scored */
  16. };
  17.  
  18. /* data for one player entry */
  19. struct PlayerData
  20. {
  21.    UBYTE  pl_num; /* remember after sorting which player he was */
  22.    UBYTE  pl_name[12];  /* name */
  23.    UWORD  gw, gd, gl;   /* wins, draws and losses */
  24.    ULONG  gf, ga; /* goals for and against */
  25. };
  26.  
  27. /* complete datastructure */
  28. struct DataSeg
  29. {
  30.    UBYTE  pl_entered;   /* number of players, should always be 8 */
  31.    UBYTE  games_played; /* matches played, starts with 0, maximum = 8 */
  32.    struct GameData  LastResults[8]; /* results of last matches */
  33.    struct PlayerData  Player[8]; /* data of all entered players */
  34. };
  35.  
  36. struct DataSeg  Data =
  37. {
  38.    8, 0, /* 8 players, no matches played */
  39.    "", "", 0, 0,  /* as I said, no matches played */
  40.    "", "", 0, 0,
  41.    "", "", 0, 0,
  42.    "", "", 0, 0,
  43.    "", "", 0, 0,
  44.    "", "", 0, 0,
  45.    "", "", 0, 0,
  46.    "", "", 0, 0,
  47.    0, "Player 1", 0, 0, 0, 0, 0, /* player ID, name and scores */
  48.    1, "Player 2", 0, 0, 0, 0, 0,
  49.    2, "Player 3", 0, 0, 0, 0, 0,
  50.    3, "Player 4", 0, 0, 0, 0, 0,
  51.    4, "Player 5", 0, 0, 0, 0, 0,
  52.    5, "Player 6", 0, 0, 0, 0, 0,
  53.    6, "Player 7", 0, 0, 0, 0, 0,
  54.    7, "Player 8", 0, 0, 0, 0, 0
  55. };
  56.  
  57. #define DATASEGSIZE sizeof(struct DataSeg)
  58. #define DISPLAYSIZE 8   /* number of entries on display, do not change! */
  59. #define PREFSSIZE sizeof(struct Preferences)
  60.  
  61. struct IntuitionBase  *IntuitionBase;  /* normal declarations */
  62. struct Window *Window;
  63. struct RastPort  *RPort;
  64. struct IntuiMessage *message;
  65. void  *AllocMem();
  66. struct Filehandle  *F;
  67. UBYTE  FN[] = "Soccer.data"; /* file name for data file */
  68. struct FileLock  *lock;
  69. void  *Open();
  70. void  *OpenLibrary();
  71. BOOL  GetResult();
  72. BOOL  LoadData();
  73. BOOL  SaveData();
  74. UBYTE  WinPoints = 2;
  75. /* points for a win, can be set to three for these people in the UK, who
  76.    always should make things different */
  77. UBYTE  light, dark;  /* pen numbers of the dark and light pen */
  78.  
  79. /* Use normal font even if user has set some strange Preferences */
  80. struct TextAttr  Style =
  81. {  (UBYTE *)"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };
  82.  
  83. /* All IntuiText structures I need */
  84. struct IntuiText
  85. Notsaved_text = {  0, 1, JAM2, 10, 10, &Style,
  86.    (UBYTE *)"New results not yet saved", NULL },
  87. NSYes_text =  {  0, 1, JAM2, 5, 3, &Style, (UBYTE *)"Quit", NULL },
  88. NSNo_text =   {  0, 1, JAM2, 5, 3, &Style, (UBYTE *)"Save", NULL },
  89. SVText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Save", NULL },
  90. QTText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Quit", NULL },
  91. USText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Enter result", NULL },
  92. EuroText =    {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Winning = 2p", NULL },
  93. UKText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Winning = 3p", NULL },
  94. SUText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)" Results", NULL },
  95. SSText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)" Tables", NULL },
  96. SxText =      {  1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Show", NULL },
  97. SHeaderText = {  1, 0, JAM2, 0, 0, &Style,
  98.    (UBYTE *)"Player name   P   W   D   L  PTS   GF -  GA", NULL },
  99. RHeaderText = {  1, 0, JAM2, 0, 0, &Style,
  100.    (UBYTE *)"Team A         Team B      Scores          ", NULL },
  101. ResLine =     {  1, 0, JAM2, 0, 0, &Style,
  102.    (UBYTE *)"                                           ", NULL };
  103.  
  104. /* defines define positions of certain text elements in strings */
  105. #define plname_pos 0
  106. #define gp_pos 14
  107. #define gw_pos 18
  108. #define gd_pos 22
  109. #define gl_pos 26
  110. #define pt_pos 31
  111. #define gf_pos 36
  112. #define line2_pos    38
  113. #define ga_pos       42
  114. #define pl1name_pos   0
  115. #define vs_pos       12
  116. #define pl2name_pos  15
  117. #define pl1score_pos 29
  118. #define line_pos     31
  119. #define pl2score_pos 35
  120.  
  121.  
  122. /* All Border structures I need */
  123. WORD  BigPairs2a[] =
  124. {  -1, 81, -1, -1, 350, -1 };
  125. WORD  BigPairs2[] =
  126. {  350, 0, 350, 82, -1, 82 };
  127.  
  128. WORD  BigPairsa[] =
  129. {  0, 12, 349, 12, 349, 1, 349, 81, 0, 81   };
  130. WORD  BigPairs[] =
  131. {  348, 13, 0, 13, 0, 80, 0, 0, 349, 0 };
  132.  
  133. struct Border  BigBorder2a =
  134. {  -3, -3, 2, 0, JAM1, 3, BigPairs2a, NULL  };
  135. struct Border  BigBorder2 =
  136. {  -3, -3, 1, 0, JAM1, 3, BigPairs2, &BigBorder2a  };
  137.  
  138. struct Border  BigBordera =
  139. {  -3, -3, 2, 0, JAM1, 5, BigPairsa, &BigBorder2  };
  140. struct Border  BigBorder =
  141. {  -3, -3, 1, 0, JAM1, 5, BigPairs, &BigBordera  };
  142.  
  143. WORD  GadgetPairs3[] =
  144. {  84, 1, 84, 13, 0, 13   };
  145. WORD  GadgetPairs3a[] =
  146. {  0, 12, 0, 0, 84, 0   };
  147.  
  148. struct Border  GadgetBorder3a =
  149. {  0, 0, 2, 0, JAM1, 3, GadgetPairs3a, NULL  };
  150. struct Border  GadgetBorder3 =
  151. {  0, 0, 1, 0, JAM1, 3, GadgetPairs3, &GadgetBorder3a  };
  152.  
  153. struct Border  GadgetBorder3ainv =
  154. {  0, 0, 1, 0, JAM1, 3, GadgetPairs3a, NULL  };
  155. struct Border  GadgetBorder3inv =
  156. {  0, 0, 2, 0, JAM1, 3, GadgetPairs3, &GadgetBorder3ainv  };
  157.  
  158.  
  159. WORD  GadgetPairs2[] =
  160. {  108, 1, 108, 13, 0, 13   };
  161. WORD  GadgetPairs2a[] =
  162. {  0, 12, 0, 0, 108, 0   };
  163.  
  164. struct Border  GadgetBorder2a =
  165. {  0, 0, 2, 0, JAM1, 3, GadgetPairs2a, NULL  };
  166. struct Border  GadgetBorder2 =
  167. {  0, 0, 1, 0, JAM1, 3, GadgetPairs2, &GadgetBorder2a  };
  168.  
  169. WORD  GadgetPairs1[] =
  170. {  44, 1, 44, 13, 0, 13   };
  171. WORD  GadgetPairs1a[] =
  172. {  0, 12, 0, 0, 44, 0   };
  173.  
  174. struct Border  GadgetBorder1a =
  175. {  0, 0, 2, 0, JAM1, 3, GadgetPairs1a, NULL  };
  176. struct Border  GadgetBorder1 =
  177. {  0, 0, 1, 0, JAM1, 3, GadgetPairs1, &GadgetBorder1a  };
  178.  
  179. /* Borders in file res.c */
  180. extern struct Border  squarebox, squareboxa;
  181. extern struct Border  ResBorder, ResBordera;
  182. extern struct Border  IntBorder, IntBordera;
  183. extern struct Border  RGadgetBorder3, RGadgetBorder3a;
  184. extern struct Border  OKBox, OKBoxa;
  185.  
  186. /* GadgetID-defines */
  187. #define g_SS 11
  188. #define g_SU 10
  189. #define g_SC 6
  190. #define g_US 5
  191. #define g_QT 1
  192. #define g_SV 2
  193.  
  194. /* Gadget structures */
  195.  
  196. /* 'Tables' */
  197. struct Gadget  SSGadget =
  198. {
  199.    NULL, 198, 20, 85, 14, GADGHNONE, GADGIMMEDIATE,
  200.    BOOLGADGET, (APTR)&GadgetBorder3inv, NULL, &SSText, NULL, NULL, g_SS, NULL
  201. };
  202.  
  203. /* 'Results' */
  204. struct Gadget  SUGadget =
  205. {
  206.    &SSGadget, 48, 20, 85, 14, GADGHNONE, GADGIMMEDIATE,
  207.    BOOLGADGET, (APTR)&GadgetBorder3, NULL, &SUText, NULL, NULL, g_SU, NULL
  208. };
  209.  
  210. /* 'winpoints = x' */
  211. struct Gadget  SCGadget =
  212. {
  213.    &SUGadget, 137, 140, 109, 14, GADGHCOMP, GADGIMMEDIATE, BOOLGADGET,
  214.    (APTR)&GadgetBorder2, NULL, &EuroText, NULL, NULL, g_SC, NULL
  215. };
  216.  
  217. /* 'Enter result' */
  218. struct Gadget  USGadget =
  219. {
  220.    &SCGadget, 17, 140, 109, 14, GADGHCOMP, RELVERIFY, BOOLGADGET,
  221.    (APTR)&GadgetBorder2, NULL, &USText, NULL, NULL, g_US, NULL
  222. };
  223.  
  224. /* 'Quit' */
  225. struct Gadget  QTGadget =
  226. {
  227.    &USGadget, 321, 140, 45, 14, GADGHCOMP, RELVERIFY, BOOLGADGET,
  228.    (APTR)&GadgetBorder1, NULL, &QTText, NULL, NULL, g_QT, NULL
  229. };
  230.  
  231. /* 'Save' */
  232. struct Gadget  SVGadget =
  233. {
  234.    &QTGadget, 264, 140, 45, 14, GADGHCOMP, RELVERIFY, BOOLGADGET,
  235.    (APTR)&GadgetBorder1, NULL, &SVText, NULL, NULL, g_SV, NULL
  236. };
  237.  
  238. /* NewWindow structure for main window */
  239. struct NewWindow NewWindow =
  240. {
  241.    100, 20, 384, 160, -1, -1,
  242.    GADGETDOWN | GADGETUP,
  243.    WINDOWDEPTH | WINDOWDRAG | SMART_REFRESH | ACTIVATE,
  244.    &SVGadget, NULL, (UBYTE *)"Goalkeeper v1.0 - by Camiel Rouweler",
  245.    NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN,
  246. };
  247.  
  248. int  main()
  249. {
  250.    ULONG  MessageClass; /* all for receiving IntuiMessages */
  251.    UWORD  code, GadgetNr;
  252.    struct Gadget *GadgetPtr;
  253.    struct Message  *GetMsg();
  254.    /* show what?           how many points for a win? */
  255.    BOOL  g_SU_sel = FALSE, Euro_selected = TRUE;
  256.    BOOL  Data_saved = TRUE; /* data was not changed since last save operation */
  257.    struct Preferences  *PrefsPtr;
  258.    UWORD  col1, col2, r, g, b;
  259.  
  260.    IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L);
  261.  
  262.    PrefsPtr = (struct Preferences *) AllocMem(PREFSSIZE, MEMF_PUBLIC);
  263.    /* Open Preferences structure to find out how colour settings are */
  264.    if (PrefsPtr)
  265.    {
  266.       GetPrefs(PrefsPtr, PREFSSIZE);
  267.       col1 = PrefsPtr->color1;
  268.       col2 = PrefsPtr->color2;
  269.       r = (col1 & 0x0f00) / 256;
  270.       g = (col1 & 0x00f0) /16;
  271.       b = col1 & 0x000f;
  272.       col1 = r + g + b;
  273.       r = (col2 & 0x0f00) / 256;
  274.       g = (col2 & 0x00f0) /16;
  275.       b = col2 & 0x000f;
  276.       col2 = r + g + b;
  277.       FreeMem(PrefsPtr, PREFSSIZE);
  278.       if (col1 > col2)
  279.       {
  280.          /* colour2 is darker than colour1 */
  281.          light = 1;
  282.          dark = 2;
  283.       }
  284.       else
  285.       {
  286.          /* colour1 is darker than colour2 */
  287.          light = 2;
  288.          dark = 1;
  289.       }
  290.       /* Adjust colours in Border structures for a nice 2.0 look, even in 1.3
  291.          independently from Preferences-settings */
  292.       GadgetBorder1.FrontPen = dark;
  293.       GadgetBorder1a.FrontPen = light;
  294.       GadgetBorder2.FrontPen = dark;
  295.       GadgetBorder2a.FrontPen = light;
  296.       GadgetBorder3.FrontPen = dark;
  297.       GadgetBorder3a.FrontPen = light;
  298.       GadgetBorder3inv.FrontPen = light;
  299.       GadgetBorder3ainv.FrontPen = dark;
  300.       BigBorder.FrontPen = dark;
  301.       BigBordera.FrontPen = light;
  302.       BigBorder2.FrontPen = dark;
  303.       BigBorder2a.FrontPen = light;
  304.       squarebox.FrontPen = dark;
  305.       squareboxa.FrontPen = light;
  306.       ResBordera.FrontPen = dark;
  307.       ResBorder.FrontPen = light;
  308.       IntBorder.FrontPen = dark;
  309.       IntBordera.FrontPen = light;
  310.       RGadgetBorder3.FrontPen = dark;
  311.       RGadgetBorder3a.FrontPen = light;
  312.       OKBox.FrontPen = dark;
  313.       OKBoxa.FrontPen = light;
  314.    }
  315.  
  316.    Open_All(); /* Open main window */
  317.    LoadData(); /* load previously saved data, if found */
  318.    ShowTables(); /* no comment */
  319.  
  320.    FOREVER /* it has to quit sometime though! */
  321.    {
  322.       /* standard message reading */
  323.       if (!(message = (struct IntuiMessage *)
  324.           GetMsg(Window->UserPort)))
  325.       {
  326.          Wait(1L << Window->UserPort->mp_SigBit);
  327.          continue;
  328.       }
  329.       MessageClass = message->Class;
  330.       code = message->Code;
  331.       GadgetPtr = (struct Gadget *) message->IAddress;
  332.       GadgetNr = GadgetPtr->GadgetID;
  333.       ReplyMsg(message);
  334.       switch(MessageClass)
  335.       {
  336.          case GADGETUP:
  337.             switch(GadgetNr)
  338.             {
  339.                case g_US:
  340.                   /* Get a match result and update tables */
  341.                   if (GetResult())
  342.                   {
  343.                      Data_saved = FALSE;
  344.                      if (g_SU_sel) ShowResults();
  345.                      else ShowTables();
  346.                   }
  347.                   break;
  348.  
  349.                case g_QT:
  350.                /* if data was not yet saved, ask if you may have had forgotten */
  351.                   if (!Data_saved)
  352.                   {
  353.                      if (AutoRequest(Window, &Notsaved_text, &NSYes_text,
  354.                          &NSNo_text, 0L, 0L,
  355.                          IntuiTextLength(&Notsaved_text) + 50L, 60L))
  356.                      {
  357.                         /* deliberately not saved, so exit! */
  358.                         Close_All();
  359.                         exit(0);
  360.                      }
  361.                      else
  362.                      if (Data_saved = SaveData())
  363.                      {
  364.                         /* data saved after all, time to go! */
  365.                         Close_All();
  366.                         exit(0);
  367.                      }
  368.                   }
  369.                   else
  370.                   {
  371.                      /* Data had been saved without asking. Good boy/girl! */
  372.                      Close_All();
  373.                      exit(0);
  374.                   }
  375.                   break;
  376.  
  377.                case g_SV:
  378.                   /* user wants to save data, so we'll try */
  379.                   Data_saved = SaveData();
  380.                   break;
  381.             }
  382.             break;
  383.  
  384.          case GADGETDOWN:
  385.             switch(GadgetNr)
  386.             {
  387.                case g_SS:
  388.                   if (g_SU_sel)
  389.                   {
  390.                      /* Show tables and fix results-gadget */
  391.                      ShowTables();
  392.                      g_SU_sel = FALSE;
  393.                      SSGadget.GadgetRender = &GadgetBorder3inv;
  394.                      SUGadget.GadgetRender = &GadgetBorder3;
  395.                      RefreshGList(&SUGadget, Window, NULL, 2L);
  396.                   }
  397.                   break;
  398.  
  399.                case g_SU:
  400.                   if (!g_SU_sel)
  401.                   {
  402.                      /* Show results and fix tables-gadget */
  403.                      ShowResults();
  404.                      g_SU_sel = TRUE;
  405.                      SUGadget.GadgetRender = &GadgetBorder3inv;
  406.                      SSGadget.GadgetRender = &GadgetBorder3;
  407.                      RefreshGList(&SUGadget, Window, NULL, 2L);
  408.                   }
  409.                   break;
  410.  
  411.                case g_SC:
  412.                   /* change points for a win */
  413.                   Euro_selected = !Euro_selected;
  414.                   if (Euro_selected)
  415.                   {
  416.                      SCGadget.GadgetText = &EuroText;
  417.                      WinPoints = 2;
  418.                   }
  419.                   else
  420.                   {
  421.                      SCGadget.GadgetText = &UKText;
  422.                      WinPoints = 3;
  423.                      /* why is everything different in the UK?
  424.                         why can't they measure distance in metres?
  425.                         why don't they measure beet in litres?
  426.                         why do they give 3 points for a win?
  427.                      */
  428.                   }
  429.                   RefreshGList(&SCGadget, Window, NULL, 1L);
  430.                   if (!g_SU_sel) ShowTables();
  431.                   break;
  432.             }
  433.             break;
  434.       }
  435.    }
  436. }
  437.  
  438. Open_All() /* 'All' is here just one measly window */
  439. {
  440.    struct Window  *OpenWindow();
  441.  
  442.    if (!(Window = (struct Window *)
  443.        OpenWindow(&NewWindow)))
  444.    {
  445.       /* show a system-request when there is no memory for the window */
  446.       /* there wont't be memory for a request then, but who cares! */
  447.       ShowText(NULL, "Fout bij openen venster", NULL);
  448.       Close_All(); /* give up already */
  449.       exit(0);
  450.    }
  451.    RPort = Window->RPort;
  452.    /* do some drawing and printing to make it look nicer */
  453.    DrawBorder(RPort, &BigBorder, 20L, 50L);
  454.    PrintIText(RPort, &SxText, 140L, 20L);
  455.    PrintDepth(RPort, &SHeaderText, 20L, 49L, 0, 0);
  456. }
  457.  
  458. Close_All() /* we may close IntuitionBase and the window, wow! */
  459. {
  460.    if (Window) CloseWindow(Window);
  461.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  462. }
  463.  
  464. BOOL  LoadData() /* TRUE if loading was succesfull */
  465. {
  466.    LONG BR;
  467.  
  468.    if (lock = (struct FileLock *) Lock(FN, ACCESS_READ))
  469.    {
  470.       UnLock(lock);
  471.       F = Open(FN, MODE_OLDFILE);
  472.       if (!F)
  473.       {
  474.          ShowText(NULL, "Error opening file", NULL);
  475.          return(FALSE);
  476.       }
  477.       else
  478.       {
  479.          BR = Read(F, &Data, DATASEGSIZE);
  480.          if (BR != DATASEGSIZE)
  481.          {
  482.             ShowText(NULL, "Error reading data", NULL);
  483.             Close(F);
  484.             return(FALSE);
  485.          }
  486.          Close(F);
  487.          return(TRUE);
  488.       }
  489.    }
  490.    else ShowText(NULL, "Data file not found", NULL);
  491. }
  492. BOOL  SaveData()  /* TRUE if saving was succesfull */
  493. {
  494.    LONG BW;
  495.  
  496.    F = Open(FN, MODE_NEWFILE);
  497.    if (!F)
  498.    {
  499.       ShowText(Window, "error opening file", NULL);
  500.       return(FALSE);
  501.    }
  502.    else
  503.    {
  504.       BW = Write(F, &Data, DATASEGSIZE);
  505.       if (BW != DATASEGSIZE)
  506.       {
  507.          ShowText(Window, "error writing data", NULL);
  508.          Close(F);
  509.          return(FALSE);
  510.       }
  511.       Close(F);
  512.       /* let user know all went the way it was upposed to go */
  513.       ShowText(Window, "Data saved", "Thanks");
  514.       return(TRUE);
  515.    }
  516. }
  517.  
  518. /* print text with shadows, takes more than three times the time to print
  519.    normal text */
  520. PrintDepth(RP, IT, X, Y, Fcol, Bcol)
  521. struct RastPort  *RP;
  522. struct IntuiText  *IT;
  523. LONG  X, Y;
  524. UBYTE  Fcol, Bcol;
  525. {
  526.    UBYTE  FP, DM;
  527.  
  528.    if (!(Fcol | Bcol))
  529.    {
  530.       Fcol = light;
  531.       Bcol = dark;
  532.    }
  533.    FP = IT->FrontPen;
  534.    DM = IT->DrawMode;
  535.    IT->FrontPen = Fcol;
  536.    IT->DrawMode = JAM2;
  537.    PrintIText(RP, IT, X, Y);  /* clear printing area */
  538.    IT->FrontPen = Bcol;
  539.    PrintIText(RP, IT, X + 1, Y + 1); /* shadow */
  540.    IT->FrontPen = Fcol;
  541.    IT->DrawMode = JAM1;
  542.    PrintIText(RP, IT, X, Y); /* print text over shadow */
  543.    IT->FrontPen = FP;
  544.    IT->DrawMode = DM;
  545. }
  546.  
  547. ShowTables()   /* just show the current tables */
  548. {
  549.    int i, j;
  550.    UBYTE  *SP;
  551.    struct PlayerData  *PD;
  552.  
  553.    SortResults(); /* always sort, even if nothing has changed. What a sin! */
  554.    PrintDepth(RPort, &SHeaderText, 20L, 49L, 0, 0);
  555.    SP = ResLine.IText;
  556.    for(i = 0; i < DISPLAYSIZE; i++)
  557.    {
  558.       for (j = 0; SP[j]; j++) SP[j] = ' ';
  559.       {
  560.          PD = &Data.Player[i];
  561.          strcpynz(&SP[plname_pos], PD->pl_name);
  562.          intcpynz(&SP[gp_pos], PD->gw + PD->gd + PD->gl);
  563.          intcpynz(&SP[gw_pos], PD->gw);
  564.          intcpynz(&SP[gd_pos], PD->gd);
  565.          intcpynz(&SP[gl_pos], PD->gl);
  566.          intcpynz(&SP[pt_pos], WinPoints*PD->gw + PD->gd);
  567.          longcpynz(&SP[gf_pos], PD->gf);
  568.          SP[line2_pos] = '-';
  569.          longcpynz(&SP[ga_pos], PD->ga);
  570.          if (PD->gw + PD->gd + PD->gl) ResLine.FrontPen = 1;
  571.          else ResLine.FrontPen = 3;
  572.       }
  573.       PrintIText(RPort, &ResLine, 20L, (LONG) 63 + i*8);
  574.    }
  575. }
  576.  
  577. ShowResults()  /* Show maximal the last 8 played matches results */
  578. {
  579.    int  i, j;
  580.    UBYTE  *SP;
  581.  
  582.    PrintDepth(RPort, &RHeaderText, 20L, 49L, 0, 0);
  583.    SP = ResLine.IText;
  584.    ResLine.FrontPen = 1;
  585.    for (i = 0; i < DISPLAYSIZE; i++)
  586.    {
  587.       for (j = 0; SP[j]; j++) SP[j] = ' ';
  588.       if (i < Data.games_played)
  589.       {
  590.          strcpynz(&SP[pl1name_pos], Data.LastResults[i].TeamA);
  591.          strcpynz(&SP[pl2name_pos], Data.LastResults[i].TeamB);
  592.          strcpynz(&SP[vs_pos], "vs");
  593.          longcpynz(&SP[pl1score_pos], Data.LastResults[i].pl1_score);
  594.          SP[line_pos] = '-';
  595.          longcpynz(&SP[pl2score_pos], Data.LastResults[i].pl2_score);
  596.       }
  597.       PrintIText(RPort, &ResLine, 20L, (LONG) 63 + i*8);
  598.    }
  599. }
  600.  
  601. SortResults() /* probably the most inefficient sorting routine */
  602. {
  603.    int i, j, h;
  604.    LONG  saldo1, saldo2;
  605.    UWORD  mp1, mp2, pts1, pts2;
  606.  
  607.  
  608.    for (i = 7; i >= 0; i--)
  609.    {
  610.       for (j = 0; j < i; j++)
  611.       {
  612.          h = j + 1;
  613.          /* first sort on points */
  614.          pts1 = Data.Player[j].gw*WinPoints + Data.Player[j].gd;
  615.          pts2 = Data.Player[h].gw*WinPoints + Data.Player[h].gd;
  616.          if (pts2 > pts1) Exchange(j, h);
  617.          else if (pts1 == pts2)
  618.          {
  619.             /* in case of equal points, sort on goal difference */
  620.             saldo1 = Data.Player[j].gf - Data.Player[j].ga;
  621.             saldo2 = Data.Player[h].gf - Data.Player[h].ga;
  622.             if (saldo2 > saldo1) Exchange(j, h);
  623.             else if (saldo1 == saldo2)
  624.             {
  625.                /* then on number of played matches */
  626.                mp1 = Data.Player[j].gw + Data.Player[j].gd + Data.Player[j].gl;
  627.                mp2 = Data.Player[h].gw + Data.Player[h].gd + Data.Player[h].gl;
  628.                if (mp1 > mp2) Exchange (j, h);
  629.                else if (mp1 == mp2)
  630.                {
  631.                   /* and finally on number of matches won */
  632.                   if (Data.Player[j].gw < Data.Player[h].gw) Exchange(j, h);
  633.                }
  634.             }
  635.          }
  636.       }
  637.    }
  638. } /* boy, are these many brackets! */
  639.  
  640. Exchange(a, b) /* exchange two entries for sorting */
  641. int  a, b;
  642. {
  643.    struct PlayerData  PD;
  644.  
  645.    PD = Data.Player[a];
  646.    Data.Player[a] = Data.Player[b];
  647.    Data.Player[b] = PD;
  648. }
  649.  
  650. strcpynz(str1, str2) /* copy a string, but not the zero on the end */
  651. UBYTE  str1[], str2[];
  652. {
  653.    int  i = 0;
  654.  
  655.    while (str2[i])
  656.    {
  657.       str1[i] = str2[i];
  658.       i++;
  659.    }
  660. }
  661.  
  662. longcpynz(str1, A) /* convert a long int to a string */
  663. UBYTE  str1[];
  664. ULONG  A;
  665. {
  666.    int  i = 0;
  667.  
  668.    while (A)
  669.    {
  670.       str1[i] = '0' + (A % 10);
  671.       A = A / 10;
  672.       i--; /* work from right to left */
  673.    }
  674.    if (!i) str1[i] = '0'; /* if A was 0, at least print that 0! */
  675. }
  676.  
  677. intcpynz(str1, A) /* convert an int to a string */
  678. UBYTE  str1[];
  679. UWORD  A;
  680. {
  681.    int  i = 0;
  682.  
  683.    while (A)
  684.    {
  685.       str1[i] = '0' + (A % 10);
  686.       A = A / 10;
  687.       i--; /* work from right to left */
  688.    }
  689.    if (!i) str1[i] = '0';
  690. }
  691.  
  692.