Subversion Repositories Games.Rick Dangerous

Rev

Rev 9 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * src/scr_getname.c
  3.  *
  4.  * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
  5.  *
  6.  * The use and distribution terms for this software are contained in the file
  7.  * named README, which can be found in the root of this distribution. By
  8.  * using this software in any fashion, you are agreeing to be bound by the
  9.  * terms of this license.
  10.  *
  11.  * You must not remove this notice, or any other, from this software.
  12.  */
  13.  
  14. #include <stdlib.h> // Pierre-Marie Baty -- for qsort()
  15. #include <string.h> // Pierre-Marie Baty -- for memcmp()
  16.  
  17. #include "system.h"
  18. #include "game.h"
  19. #include "screens.h"
  20.  
  21. #include "draw.h"
  22. #include "control.h"
  23.  
  24. /*
  25.  * local vars
  26.  */
  27. static U8 seq = 0;
  28. static U8 x, y, p;
  29. static U8 name[10];
  30.  
  31. #define TILE_POINTER '\072'
  32. #define TILE_CURSOR '\073'
  33. #define TOPLEFT_X 116
  34. #define TOPLEFT_Y 64
  35. #define NAMEPOS_X 120
  36. #define NAMEPOS_Y 160
  37. #define AUTOREPEAT_TMOUT 100
  38.  
  39.  
  40. // Pierre-Marie Baty -- external prototype
  41. extern int sort_hscores (const void *q1, const void *q2);
  42.  
  43.  
  44. /*
  45.  * prototypes
  46.  */
  47. static void pointer_show (U8);
  48. static void name_update (void);
  49. static void name_draw (void);
  50.  
  51.  
  52. /*
  53.  * Get name
  54.  *
  55.  * return: 0 while running, 1 when finished.
  56.  */
  57. U8 screen_getname (void)
  58. {
  59.    static U32 tm = 0;
  60.    U8 i, j;
  61.  
  62.    if (seq == 0)
  63.    {
  64.       /* figure out if this is a high score */
  65.       if (game_score < game_hscores[7].score)
  66.          return SCREEN_DONE;
  67.  
  68.       /* prepare */
  69.       draw_tilesBank = 0;
  70.  
  71.       for (i = 0; i < 10; i++)
  72.          name[i] = '@';
  73.  
  74.       x = y = p = 0;
  75.       game_rects = &draw_SCREENRECT;
  76.       seq = 1;
  77.    }
  78.  
  79.    switch (seq)
  80.    {
  81.    case 1:   /* prepare screen */
  82.       sysvid_clear ();
  83.       draw_setfb (76, 40);
  84.       draw_tilesListImm ((U8 *) "PLEASE@ENTER@YOUR@NAME\376");
  85.  
  86.       for (i = 0; i < 6; i++)
  87.          for (j = 0; j < 4; j++)
  88.          {
  89.             draw_setfb (TOPLEFT_X + i * 8 * 2, TOPLEFT_Y + j * 8 * 2);
  90.             draw_tile ((U8) ('A' + i + j * 6));
  91.          }
  92.  
  93.       draw_setfb (TOPLEFT_X, TOPLEFT_Y + 64);
  94.       draw_tilesListImm ((U8 *) "Y@Z@.@@@\074\373\374\375\376");
  95.       name_draw ();
  96.       pointer_show (TRUE);
  97.       seq = 2;
  98.  
  99.       break;
  100.  
  101.    case 2:   /* wait for key pressed */
  102.       if (control_status & CONTROL_FIRE)
  103.          seq = 3;
  104.  
  105.       if (control_status & CONTROL_UP)
  106.       {
  107.          if (y > 0)
  108.          {
  109.             pointer_show (FALSE);
  110.             y--;
  111.             pointer_show (TRUE);
  112.             tm = sys_gettime ();
  113.          }
  114.          seq = 4;
  115.       }
  116.  
  117.       if (control_status & CONTROL_DOWN)
  118.       {
  119.          if (y < 4)
  120.          {
  121.             pointer_show (FALSE);
  122.             y++;
  123.             pointer_show (TRUE);
  124.             tm = sys_gettime ();
  125.          }
  126.          seq = 5;
  127.       }
  128.  
  129.       if (control_status & CONTROL_LEFT)
  130.       {
  131.          if (x > 0)
  132.          {
  133.             pointer_show (FALSE);
  134.             x--;
  135.             pointer_show (TRUE);
  136.             tm = sys_gettime ();
  137.          }
  138.          seq = 6;
  139.       }
  140.  
  141.       if (control_status & CONTROL_RIGHT)
  142.       {
  143.          if (x < 5)
  144.          {
  145.             pointer_show (FALSE);
  146.             x++;
  147.             pointer_show (TRUE);
  148.             tm = sys_gettime ();
  149.          }
  150.          seq = 7;
  151.       }
  152.  
  153.       if (seq == 2)
  154.          sys_sleep (50);
  155.  
  156.       break;
  157.  
  158.    case 3:   /* wait for FIRE released */
  159.       if (!(control_status & CONTROL_FIRE))
  160.       {
  161.          if (x == 5 && y == 4)
  162.          {
  163.             /* end */
  164.  
  165.             if (memcmp (name, "POOKY@@@@@", 10) == 0)
  166.             {
  167.                // cheat code: restart at last episode
  168.                sysarg_args_map = game_map;
  169.                syssnd_play (WAV_DIE, 1);
  170.             }
  171.             else if (memcmp (name, "FLUFOMATIC", 10) == 0)
  172.             {
  173.                // cheat code: restart at last map
  174.                sysarg_args_submap = game_submap;
  175.                syssnd_play (WAV_DIE, 1);
  176.             }
  177.  
  178.             // Pierre-Marie Baty -- discard empty names
  179.             else if (memcmp (name, "@@@@@@@@@@", 10) != 0)
  180.             {
  181.                // Pierre-Marie Baty -- look if this same name already exists in the hiscore table
  182.                for (i = 0; i < 8; i++)
  183.                   if (memcmp (game_hscores[i].name, name, 10) == 0)
  184.                      break;
  185.                if (i == 8) // new name ?
  186.                {
  187.                   i = 0;
  188.  
  189.                   while (game_score < game_hscores[i].score)
  190.                      i++;
  191.  
  192.                   j = 7;
  193.  
  194.                   while (j > i)
  195.                   {
  196.                      game_hscores[j].score = game_hscores[j - 1].score;
  197.  
  198.                      for (x = 0; x < 10; x++)
  199.                         game_hscores[j].name[x] = game_hscores[j - 1].name[x];
  200.  
  201.                      j--;
  202.                   }
  203.  
  204.                   game_hscores[i].score = game_score;
  205.  
  206.                   for (x = 0; x < 10; x++)
  207.                      game_hscores[i].name[x] = name[x];
  208.                }
  209.                else if (game_score > game_hscores[i].score) // existing name: update only if score is higher, else discard
  210.                {
  211.                   game_hscores[i].score = game_score;
  212.                   qsort (game_hscores, 8, sizeof (hscore_t), sort_hscores);
  213.                }
  214.             }
  215.  
  216.             seq = 99;
  217.          }
  218.          else
  219.          {
  220.             name_update ();
  221.             name_draw ();
  222.             seq = 2;
  223.          }
  224.       }
  225.       else
  226.          sys_sleep (50);
  227.  
  228.       break;
  229.  
  230.    case 4:   /* wait for UP released */
  231.       if (!(control_status & CONTROL_UP) || sys_gettime () - tm > AUTOREPEAT_TMOUT)
  232.          seq = 2;
  233.       else
  234.          sys_sleep (50);
  235.  
  236.       break;
  237.  
  238.    case 5:   /* wait for DOWN released */
  239.       if (!(control_status & CONTROL_DOWN) || sys_gettime () - tm > AUTOREPEAT_TMOUT)
  240.          seq = 2;
  241.       else
  242.          sys_sleep (50);
  243.  
  244.       break;
  245.  
  246.    case 6:   /* wait for LEFT released */
  247.       if (!(control_status & CONTROL_LEFT) || sys_gettime () - tm > AUTOREPEAT_TMOUT)
  248.          seq = 2;
  249.       else
  250.          sys_sleep (50);
  251.  
  252.       break;
  253.  
  254.    case 7:   /* wait for RIGHT released */
  255.       if (!(control_status & CONTROL_RIGHT) || sys_gettime () - tm > AUTOREPEAT_TMOUT)
  256.          seq = 2;
  257.       else
  258.          sys_sleep (50);
  259.  
  260.       break;
  261.  
  262.    }
  263.  
  264.    if (control_status & CONTROL_EXIT)   /* check for exit request */
  265.       return SCREEN_EXIT;
  266.  
  267.    if (seq == 99)
  268.    {   /* seq 99, we're done */
  269.       sysvid_clear ();
  270.       seq = 0;
  271.       return SCREEN_DONE;
  272.    }
  273.    else
  274.       return SCREEN_RUNNING;
  275. }
  276.  
  277.  
  278. static void pointer_show (U8 show)
  279. {
  280.    draw_setfb (TOPLEFT_X + x * 8 * 2, TOPLEFT_Y + y * 8 * 2 + 8);
  281.    draw_tile ((U8) ((show == TRUE) ? TILE_POINTER : '@'));
  282. }
  283.  
  284.  
  285. static void name_update (void)
  286. {
  287.    U8 i;
  288.  
  289.    i = x + y * 6;
  290.  
  291.    if (i < 26 && p < 10)
  292.       name[p++] = 'A' + i;
  293.    if (i == 26 && p < 10)
  294.       name[p++] = '.';
  295.    if (i == 27 && p < 10)
  296.       name[p++] = '@';
  297.    if (i == 28 && p > 0)
  298.       name[p--] = '@';
  299. }
  300.  
  301.  
  302. static void name_draw (void)
  303. {
  304.    U8 i;
  305.  
  306.    draw_setfb (NAMEPOS_X, NAMEPOS_Y);
  307.    for (i = 0; i < p; i++)
  308.       draw_tile (name[i]);
  309.    for (i = p; i < 10; i++)
  310.       draw_tile (TILE_CURSOR);
  311.  
  312.    draw_setfb (NAMEPOS_X, NAMEPOS_Y + 8);
  313.    for (i = 0; i < 10; i++)
  314.       draw_tile ('@');
  315.    draw_setfb (NAMEPOS_X + 8 * (p < 9 ? p : 9), NAMEPOS_Y + 8);
  316.    draw_tile (TILE_POINTER);
  317. }
  318.