home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 115 / af115sub.adf / yahzee.lzx / yahzee / highscores.c < prev    next >
C/C++ Source or Header  |  1998-06-03  |  7KB  |  265 lines

  1. /*
  2.  * highscores.c
  3.  * ============
  4.  * Handles highscores.
  5.  *
  6.  * Copyright © 1994-1998 Håkan L. Younes (lorens@hem.passagen.se)
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <exec/types.h>
  13. #include "requesters.h"
  14. #include "localize.h"
  15. #include "layout_const.h"
  16. #include "highscores.h"
  17.  
  18. #include <clib/dos_protos.h>
  19. #include <clib/exec_protos.h>
  20. #include <clib/graphics_protos.h>
  21. #include <clib/intuition_protos.h>
  22.  
  23.  
  24. #define NUM_SCORES   10
  25.  
  26.  
  27. extern struct Window  *main_win;
  28. extern APTR   vis_info;
  29. extern UBYTE   text_pen;
  30.  
  31.  
  32. static char    names[NUM_SCORES][4][31];
  33. static UWORD   scores[NUM_SCORES][4];
  34. static UBYTE   saved_rolls[NUM_SCORES][2];
  35. static BOOL    need_save = FALSE;
  36.  
  37.  
  38. void
  39. load_high_scores (
  40.    char  *default_name)
  41. {
  42.    register UWORD   i = 0, j = 0, k = 0, m;
  43.    FILE  *score_file;
  44.    int   ch;
  45.    char   num_str[4];
  46.    UBYTE   status = 0;
  47.    
  48.    if (score_file = fopen ("yahzee.hiscore", "r"))
  49.    {
  50.       while ((ch = fgetc (score_file)) != EOF && k < NUM_SCORES)
  51.       {
  52.          if (status == 0)
  53.          {
  54.             if (ch == '\n')
  55.             {
  56.                names[k][j][i] = '\0';
  57.                ++status;
  58.                i = 0;
  59.             }
  60.             else
  61.             {
  62.                names[k][j][i] = ch;
  63.                ++i;
  64.             }
  65.          }
  66.          else
  67.          {
  68.             if (ch == '\n')
  69.             {
  70.                num_str[i] = '\0';
  71.                if (status == 1)
  72.                   scores[k][j] = atoi (num_str);
  73.                else
  74.                   saved_rolls[k][j - 2] = atoi (num_str);
  75.                ++status;
  76.                if (status > 2 || j < 2)
  77.                {
  78.                   status = 0;
  79.                   ++j;
  80.                   if (j > 3)
  81.                   {
  82.                      j = 0;
  83.                      ++k;
  84.                   }
  85.                }
  86.                i = 0;
  87.             }
  88.             else
  89.             {
  90.                num_str[i] = ch;
  91.                ++i;
  92.             }
  93.          }
  94.       }
  95.       fclose (score_file);
  96.    }
  97.    
  98.    for (m = k; m < NUM_SCORES; ++m)
  99.    {
  100.       for (i = j; i < 4; ++i)
  101.       {
  102.          switch (status)
  103.          {
  104.          case 0:
  105.             strncpy (names[m][i], default_name, 30);
  106.          case 1:
  107.             scores[m][i] = 0;
  108.          case 2:
  109.             if (i >= 2)
  110.                saved_rolls[m][i - 2] = 0;
  111.             status = 0;
  112.             break;
  113.          }
  114.       }
  115.    }
  116. }
  117.  
  118. void
  119. save_high_scores (void)
  120. {
  121.    register UBYTE   i, j;
  122.    FILE *score_file;
  123.    
  124.    if (need_save)
  125.    {
  126.       if (score_file = fopen ("yahzee.hiscore", "w"))
  127.       {
  128.          for (j = 0; j < NUM_SCORES; ++j)
  129.          {
  130.             for (i = 0; i < 4; ++i)
  131.             {
  132.                fputs (names[j][i], score_file);
  133.                fputc ('\n', score_file);
  134.                fprintf (score_file, "%d\n", scores[j][i]);
  135.                if (i >= 2)
  136.                   fprintf (score_file, "%d\n", saved_rolls[j][i - 2]);
  137.             }
  138.          }
  139.          fclose (score_file);
  140.          SetProtection ("yahzee.hiscore", 2);
  141.       }
  142.    }
  143. }
  144.  
  145. BOOL
  146. update_high_score (
  147.    UBYTE   game,
  148.    UBYTE   player,
  149.    UWORD   score,
  150.    UBYTE   rolls)
  151. {
  152.    char   buf[81], name[31];
  153.    BYTE   n = NUM_SCORES - 1;
  154.    BOOL   get_name = TRUE;
  155.    
  156.    name[0] = '\0';
  157.    
  158.    while (n >= 0)
  159.    {
  160.       if (score > scores[n][game] || (score == scores[n][game] && game < 2) ||
  161.           (score == scores[n][game] && game >= 2 &&
  162.            rolls >= saved_rolls[n][game - 2]))
  163.       {
  164.          need_save = TRUE;
  165.          
  166.          if (n < NUM_SCORES - 1)
  167.          {
  168.             strcpy (names[n + 1][game], names[n][game]);
  169.             scores[n + 1][game] = scores[n][game];
  170.             if (game >= 2)
  171.                saved_rolls[n + 1][game - 2] = saved_rolls[n][game - 2];
  172.          }
  173.          
  174.          if (get_name)
  175.          {
  176.             sprintf (buf, localized_string (MSG_NAME_REQTITLE), player + 1);
  177.             string_requester (main_win, vis_info, buf,
  178.                               localized_string (MSG_NAME_GAD),
  179.                               name, 30);
  180.             get_name = FALSE;
  181.          }
  182.          
  183.          strcpy (names[n][game], name);
  184.          scores[n][game] = score;
  185.          if (game >= 2)
  186.             saved_rolls[n][game - 2] = rolls;
  187.       }
  188.       --n;
  189.    }
  190.    
  191.    return (BOOL)(!get_name);
  192. }
  193.  
  194. void
  195. display_high_scores (
  196.    UBYTE   game)
  197. {
  198.    register UBYTE   n;
  199.    struct Window  *win;
  200.    struct IntuiMessage  *msg;
  201.    BOOL   done = FALSE;
  202.    struct Requester   req;
  203.    BOOL   win_sleep = FALSE;
  204.    char   text_buf[81];
  205.    UWORD   width, height;
  206.    WORD    left, top;
  207.    
  208.    win_sleep = window_sleep (main_win, &req);
  209.    width = main_win->BorderLeft + main_win->BorderRight +
  210.            (34 + ((game >= 2) ? 5 : 0)) * main_win->RPort->TxWidth +
  211.            2 * INTERWIDTH;
  212.    height = main_win->BorderTop + main_win->BorderBottom +
  213.             NUM_SCORES * main_win->RPort->TxHeight + 2 * INTERHEIGHT;
  214.    left = main_win->LeftEdge + (main_win->Width - width) / 2;
  215.    top = main_win->TopEdge + (main_win->Height - height) / 2;
  216.    win = OpenWindowTags (NULL,
  217.                          WA_Left, (width > main_win->WScreen->Width - left) ?
  218.                                   main_win->WScreen->Width - width : left,
  219.                          WA_Top, (height > main_win->WScreen->Height - top) ?
  220.                                  main_win->WScreen->Height - height : top,
  221.                          WA_Width, width,
  222.                          WA_Height, height,
  223.                          WA_AutoAdjust, FALSE,
  224.                          WA_Title, localized_string (MSG_HIGHSCORE_REQTITLE),
  225.                          WA_ScreenTitle, main_win->ScreenTitle,
  226.                          WA_PubScreen, main_win->WScreen,
  227.                          WA_IDCMP, IDCMP_MOUSEBUTTONS,
  228.                          WA_DragBar, TRUE,
  229.                          WA_DepthGadget, TRUE,
  230.                          WA_Activate, TRUE,
  231.                          TAG_DONE);
  232.    if (win != NULL)
  233.    {
  234.       SetAPen (win->RPort, text_pen);
  235.       for (n = 0; n < NUM_SCORES; ++n)
  236.       {
  237.          Move (win->RPort, win->BorderLeft + INTERWIDTH,
  238.                win->BorderTop + INTERHEIGHT + n * win->RPort->TxHeight +
  239.                win->RPort->TxBaseline);
  240.          if (game < 2)
  241.             sprintf (text_buf, "%-30s %3d", names[n][game], scores[n][game]);
  242.          else
  243.          {
  244.             sprintf (text_buf, "%-30s %3d (%2d)",
  245.                   names[n][game], scores[n][game], saved_rolls[n][game - 2]);
  246.          }
  247.          Text (win->RPort, text_buf, strlen (text_buf));
  248.       }
  249.       
  250.       while (!done)
  251.       {
  252.          WaitPort (win->UserPort);
  253.          while (msg = (struct IntuiMessage *)GetMsg (win->UserPort))
  254.          {
  255.             done = (msg->Class == IDCMP_MOUSEBUTTONS &&
  256.                     msg->Code == SELECTDOWN);
  257.             ReplyMsg ((struct Message *)msg);
  258.          }
  259.       }
  260.       CloseWindow (win);
  261.    }
  262.    if (win_sleep)
  263.       window_wakeup (main_win, &req);
  264. }
  265.