home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / EXTRA-ST / APPLE-II / APPLE2-V.TAR / apple2 / interface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-09  |  32.7 KB  |  1,412 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <vga.h>
  4. #include <dirent.h>
  5. #include <termios.h>
  6. #include "colors.h"
  7.  
  8. static struct termio    newtermio, original;
  9.  
  10. unsigned char         interface_font[0x800*8];
  11.  
  12. extern unsigned char    char_rom[0x800];
  13. extern unsigned char    *GM;         /* --- Base address of graphic area --- */
  14.  
  15. extern unsigned char    vmode_text;
  16. extern unsigned char    vmode_mixed;
  17. extern unsigned char    vmode_page2;
  18. extern unsigned char    vmode_hires;
  19. extern unsigned char    vmode_active;
  20.  
  21. extern unsigned char    file_name_6[2][1024];
  22. extern int        compressed[2];
  23.  
  24. unsigned char        disk_path[1024] = "./disks";
  25.  
  26. extern unsigned short    apple_speed;
  27. extern short        joy_step;
  28. extern short        joy_center_x;
  29. extern short        joy_center_y;
  30. extern short        joy_mode;
  31. extern short        color_mode;
  32. extern short        sound_mode;
  33.  
  34. void c_update_video_screen();
  35.  
  36. typedef enum { False, True } Tr;    /* --- Domain of Truth values
  37.                            (using the notation by
  38.                            John Allen -
  39.                         "The Anatomy of LISP") --- */
  40.  
  41. void c_load_character( int ascii, unsigned char bitmap[8][8] )
  42. {
  43.     int        i, j;
  44.  
  45.     for (i = 0; i < 8; i++)
  46.     for (j = 0; j < 7; j++)
  47.         interface_font[64 * ascii + i * 8 + j] = 
  48.             (bitmap[ i ][ j ] == '*') ? COLOR_LIGHT_WHITE : 0;
  49. }
  50.  
  51. /* -------------------------------------------------------------------------
  52.     c_load_interface_font()
  53.    ------------------------------------------------------------------------- */
  54.  
  55. void c_load_interface_font()
  56. {
  57.     int            c, i, j, v, p;
  58.  
  59.     static unsigned char ul_corner[8][8] = { ".......",
  60.                          ".......",
  61.                          ".......",
  62.                          ".......",
  63.                          "...****",
  64.                          "...*...",
  65.                          "...*...",
  66.                          "...*..." };
  67.  
  68.     static unsigned char ur_corner[8][8] = { ".......",
  69.                          ".......",
  70.                          ".......",
  71.                          ".......",
  72.                          "****...",
  73.                          "...*...",
  74.                          "...*...",
  75.                          "...*..." };
  76.  
  77.     static unsigned char dl_corner[8][8] = { "...*...",
  78.                          "...*...",
  79.                          "...*...",
  80.                          "...*...",
  81.                          "...****",
  82.                          ".......",
  83.                          ".......",
  84.                          "......." };
  85.  
  86.     static unsigned char dr_corner[8][8] = { "...*...",
  87.                          "...*...",
  88.                          "...*...",
  89.                          "...*...",
  90.                          "****...",
  91.                          ".......",
  92.                          ".......",
  93.                          "......." };
  94.  
  95.     static unsigned char    v_line[8][8] = { "...*...",
  96.                          "...*...",
  97.                          "...*...",
  98.                          "...*...",
  99.                          "...*...",
  100.                          "...*...",
  101.                          "...*...",
  102.                          "...*..." };
  103.  
  104.     static unsigned char    h_line[8][8] = { ".......",
  105.                          ".......",
  106.                          ".......",
  107.                          ".......",
  108.                          "*******",
  109.                          ".......",
  110.                          ".......",
  111.                          "......." };
  112.  
  113.     static unsigned char   tl_junc[8][8] = { "...*...",
  114.                          "...*...",
  115.                          "...*...",
  116.                          "...*...",
  117.                          "...****",
  118.                          "...*...",
  119.                          "...*...",
  120.                          "...*..." };
  121.  
  122.     static unsigned char   tr_junc[8][8] = { "...*...",
  123.                          "...*...",
  124.                          "...*...",
  125.                          "...*...",
  126.                          "****...",
  127.                          "...*...",
  128.                          "...*...",
  129.                          "...*..." };
  130.  
  131.     static unsigned char   tu_junc[8][8] = { ".......",
  132.                          ".......",
  133.                          ".......",
  134.                          ".......",
  135.                          "*******",
  136.                          "...*...",
  137.                          "...*...",
  138.                          "...*..." };
  139.  
  140.     static unsigned char   td_junc[8][8] = { "...*...",
  141.                          "...*...",
  142.                          "...*...",
  143.                          "...*...",
  144.                          "*******",
  145.                          ".......",
  146.                          ".......",
  147.                          "......." };
  148.  
  149.     static unsigned char   x_junc[8][8] =  { "...*...",
  150.                          "...*...",
  151.                          "...*...",
  152.                          "...*...",
  153.                          "*******",
  154.                          "...*...",
  155.                          "...*...",
  156.                          "...*..." };
  157.  
  158.     for (p = 0, c = 0; c < 256; c++)
  159.     for (i = c * 8; i < c * 8 + 8; i++, p++)
  160.         for (v = char_rom[ i ] >> 2, j = 0; j < 7; j++, v >>= 1, p++)
  161.             interface_font[ p ] = (c < 128) ?
  162.                       ((v & 1) ? 0 : COLOR_LIGHT_WHITE) :
  163.                       ((v & 1) ? COLOR_LIGHT_WHITE : 0);
  164.  
  165.     for (c = 0; c < 96; c++)
  166.     for (i = 0; i < 64; i++)
  167.         interface_font[ (c + 32) * 64 + i ] =
  168.         interface_font[ (c + 160) * 64 + i ];
  169.  
  170.     c_load_character( 0x80, ul_corner );
  171.     c_load_character( 0x81, ur_corner );
  172.     c_load_character( 0x82, dl_corner );
  173.     c_load_character( 0x83, dr_corner );
  174.     c_load_character( 0x84, v_line );
  175.     c_load_character( 0x85, h_line );
  176.     c_load_character( 0x86, tl_junc );
  177.     c_load_character( 0x87, tr_junc );
  178.     c_load_character( 0x88, tu_junc );
  179.     c_load_character( 0x89, td_junc );
  180.     c_load_character( 0x8A, x_junc );
  181.  
  182.     for (c = 32; c < 128; c++)
  183.     for (i = 0; i < 64; i++)
  184.         interface_font[ (c + 128) * 64 + i ] =
  185.         (interface_font[ c * 64 + i ] == 0) ? COLOR_LIGHT_WHITE : 0;
  186. }
  187.  
  188. /* -------------------------------------------------------------------------
  189.     c_interface_textcolor()
  190.    ------------------------------------------------------------------------- */
  191.  
  192. void c_interface_textcolor( short foreground, short background )
  193. {
  194.     static short    prev_foreground = COLOR_LIGHT_WHITE;
  195.     static short    prev_background = 0;
  196.  
  197.     int            i;
  198.  
  199.     for (i = 0; i < 16384; i++)
  200.     {
  201.     if (interface_font[ i ] == prev_foreground)
  202.         interface_font[ i ] = foreground;
  203.     else
  204.     if (interface_font[ i ] == prev_background)
  205.         interface_font[ i ] = background;
  206.     }
  207.  
  208.     prev_background = background;
  209.     prev_foreground = foreground;
  210. }
  211.  
  212. /* -------------------------------------------------------------------------
  213.     c_interface_print_char()
  214.    ------------------------------------------------------------------------- */
  215.  
  216. void c_interface_print_char( int x, int y, unsigned char c )
  217. {
  218.     unsigned char *d = GM + y * 320 * 8 + x * 7 + 1300;
  219.     unsigned char *s = interface_font + c * 64;
  220.  
  221.     *(unsigned long *)d = *(unsigned long *)s;
  222.     d += 4, s += 4;
  223.     *(unsigned int *)d = *(unsigned int *)s;
  224.     d += 2, s += 2;
  225.     *(unsigned char *)d = *(unsigned char *)s;
  226.     d += 314, s += 2;
  227.  
  228.     *(unsigned long *)d = *(unsigned long *)s;
  229.     d += 4, s += 4;
  230.     *(unsigned int *)d = *(unsigned int *)s;
  231.     d += 2, s += 2;
  232.     *(unsigned char *)d = *(unsigned char *)s;
  233.     d += 314, s += 2;
  234.  
  235.     *(unsigned long *)d = *(unsigned long *)s;
  236.     d += 4, s += 4;
  237.     *(unsigned int *)d = *(unsigned int *)s;
  238.     d += 2, s += 2;
  239.     *(unsigned char *)d = *(unsigned char *)s;
  240.     d += 314, s += 2;
  241.  
  242.     *(unsigned long *)d = *(unsigned long *)s;
  243.     d += 4, s += 4;
  244.     *(unsigned int *)d = *(unsigned int *)s;
  245.     d += 2, s += 2;
  246.     *(unsigned char *)d = *(unsigned char *)s;
  247.     d += 314, s += 2;
  248.  
  249.     *(unsigned long *)d = *(unsigned long *)s;
  250.     d += 4, s += 4;
  251.     *(unsigned int *)d = *(unsigned int *)s;
  252.     d += 2, s += 2;
  253.     *(unsigned char *)d = *(unsigned char *)s;
  254.     d += 314, s += 2;
  255.  
  256.     *(unsigned long *)d = *(unsigned long *)s;
  257.     d += 4, s += 4;
  258.     *(unsigned int *)d = *(unsigned int *)s;
  259.     d += 2, s += 2;
  260.     *(unsigned char *)d = *(unsigned char *)s;
  261.     d += 314, s += 2;
  262.  
  263.     *(unsigned long *)d = *(unsigned long *)s;
  264.     d += 4, s += 4;
  265.     *(unsigned int *)d = *(unsigned int *)s;
  266.     d += 2, s += 2;
  267.     *(unsigned char *)d = *(unsigned char *)s;
  268.     d += 314, s += 2;
  269.  
  270.     *(unsigned long *)d = *(unsigned long *)s;
  271.     d += 4, s += 4;
  272.     *(unsigned int *)d = *(unsigned int *)s;
  273.     d += 2, s += 2;
  274.     *(unsigned char *)d = *(unsigned char *)s;
  275. }
  276.  
  277. /* -------------------------------------------------------------------------
  278.     c_interface_print_char_inverse()
  279.    ------------------------------------------------------------------------- */
  280.  
  281. void c_interface_print_char_inverse( int x, int y, unsigned char c )
  282. {
  283.     c_interface_print_char( x, y, c | 0x80 );
  284. }
  285.  
  286. /* -------------------------------------------------------------------------
  287.     c_interface_print()
  288.    ------------------------------------------------------------------------- */
  289.  
  290. void c_interface_print( int x, int y, unsigned char *s )
  291. {
  292.     int        i;
  293.  
  294.     for (i = x; *s; i++, s++)
  295.     c_interface_print_char( i, y, *s );
  296. }
  297.  
  298. /* -------------------------------------------------------------------------
  299.     c_interface_print_inverse()
  300.    ------------------------------------------------------------------------- */
  301.  
  302. void c_interface_print_inverse( int x, int y, unsigned char *s )
  303. {
  304.     int        i;
  305.  
  306.     for (i = x; *s; i++, s++)
  307.     c_interface_print_char_inverse( i, y, *s );
  308. }
  309.  
  310. /* -------------------------------------------------------------------------
  311.     c_interface_translate_screen()
  312.    ------------------------------------------------------------------------- */
  313.  
  314. #define IsGraphic(c) ((c) == '|' || ((c) >= 0x80 && (c) <= 0x8A))
  315. #define IsInside(x,y) ((x) >= 0 && (x) <= 39 && (y) >= 0 && (y) <= 23)
  316.  
  317. void c_interface_translate_screen( unsigned char screen[24][41] )
  318. {
  319.     static char    map[11][3][4] ={ { "...",
  320.                    ".||",
  321.                    ".|." },
  322.  
  323.                  { "...",
  324.                    "||.",
  325.                    ".|." },
  326.  
  327.                  { ".|.",
  328.                    ".||",
  329.                    "..." },
  330.  
  331.                  { ".|.",
  332.                    "||.",
  333.                    "..." },
  334.  
  335.                  { ".|.",
  336.                    ".|.",
  337.                    ".|." },
  338.  
  339.                  { "...",
  340.                    "|||",
  341.                    "..." },
  342.  
  343.                  { ".|.",
  344.                    ".||",
  345.                    ".|." },
  346.  
  347.                  { ".|.",
  348.                    "||.",
  349.                    ".|." },
  350.  
  351.                  { "...",
  352.                    "|||",
  353.                    ".|." },
  354.  
  355.                  { ".|.",
  356.                    "|||",
  357.                    "..." },
  358.  
  359.                  { ".|.",
  360.                    "|||",
  361.                    ".|." } };
  362.  
  363.     int        x, y, i, j, k;
  364.  
  365.     for (y = 0; y < 24; y++)
  366.     for (x = 0; x < 40; x++)
  367.         {
  368.         if (screen[ y ][ x ] == '|')
  369.         {
  370.         Tr flag = False;
  371.  
  372.         for (k = 10; !flag && k >= 0; flag ? : k--)
  373.             {
  374.             flag = True;
  375.  
  376.             for (i = y - 1; flag && i <= y + 1; i++)
  377.                 for (j = x - 1; flag && j <= x + 1; j++)
  378.                 if (IsInside(j, i))
  379.                 if (!(IsGraphic( screen[ i ][ j ])) &&
  380.                         (map[k][ i - y + 1 ][ j - x + 1 ] == '|'))
  381.                         flag = False;
  382.                 else;
  383.                 else
  384.                 if (map[k][ i - y + 1 ][ j - x + 1 ] == '|')
  385.                     flag = False;
  386.         }
  387.  
  388.         if (flag)
  389.             screen[ y ][ x ] = 0x80 + k;
  390.         }
  391.     }
  392. }
  393.  
  394. Tr c_interface_cut_name(char *name)
  395. {
  396.     char *p = name + strlen(name) - 1;
  397.     Tr    is_gz = False;
  398.  
  399.     if (p >= name && *p == 'z')
  400.     {
  401.     p--;
  402.     if (p >= name && *p == 'g')
  403.     {
  404.         p--;
  405.         if (p >= name && *p == '.')
  406.         p--, is_gz = True;
  407.     }
  408.     }
  409.  
  410.     for (; *p != '.'; p--) { }
  411.  
  412.     *p = '\0';
  413.  
  414.     return is_gz;
  415. }
  416.  
  417. void c_interface_cut_gz(char *name)
  418. {
  419.     char *p = name + strlen(name) - 1;
  420.  
  421.     p--; 
  422.     p--;
  423.     *p = '\0';
  424. }
  425.  
  426. Tr c_interface_is_gz(char *name)
  427. {
  428.     char *p = name + strlen( name ) - 1;
  429.  
  430.     if (p >= name && *p == 'z')
  431.     {
  432.     p--;
  433.     if (p >= name && *p == 'g')
  434.     {
  435.         p--;
  436.         if (p >= name && *p == '.')
  437.             return True;
  438.     }
  439.     }
  440.  
  441.     return False;
  442. }
  443.  
  444. int c_interface_disk_select(const struct dirent *e)
  445. {
  446.     static char        cmp[ 4096 ];
  447.     char *p;
  448.  
  449.     strcpy( cmp, disk_path );
  450.     strcat( cmp, "/" );
  451.     strcat( cmp, e -> d_name );
  452.  
  453.     if (strcmp( cmp, file_name_6[0] ) == 0 ||
  454.         strcmp( cmp, file_name_6[1] ) == 0)
  455.     return 0;
  456.  
  457.     p = e -> d_name + strlen( e -> d_name ) - 1;
  458.  
  459.     if (p >= e -> d_name && *p == 'z')
  460.     {
  461.     p--;
  462.     if (p >= e -> d_name && *p == 'g')
  463.     {
  464.         p--;
  465.         if (p >= e -> d_name && *p == '.')
  466.         p--;
  467.         else
  468.         return 0;
  469.     }
  470.     else
  471.         return 0;
  472.     }
  473.     
  474.     if (p >= e -> d_name && *p == 'd')
  475.     {
  476.     p--;
  477.     if (p >= e -> d_name && *p == '2')
  478.     {
  479.         p--;
  480.         if (p >= e -> d_name && *p == 'a')
  481.         {
  482.         p--;
  483.         if (p >= e -> d_name && *p == '.')
  484.             return True;
  485.         }
  486.         }
  487.     }
  488.  
  489.     return False;
  490. }
  491.  
  492. void c_interface_normal_keyboard_on()
  493. {
  494.     ioctl(fileno(stdin), TCGETA, &original);
  495.     newtermio = original;
  496.     newtermio.c_iflag &= (ISTRIP|IGNBRK);
  497.     newtermio.c_cc[VMIN] = 0;
  498.     newtermio.c_cc[VTIME] = 0;
  499.     newtermio.c_lflag = 0;
  500.     ioctl(fileno(stdin), TCSETA, &newtermio);
  501. }
  502.  
  503. void c_interface_normal_keyboard_off()
  504. {
  505.     ioctl(fileno(stdin), TCSETA, &original);
  506. }
  507.  
  508. int c_mygetch()
  509. {
  510.     char     c;
  511.  
  512.     if (read(fileno(stdin), &c, 1) == 1)
  513.     return c;
  514.     else
  515.     return -1;
  516. }
  517.  
  518. /* -------------------------------------------------------------------------
  519.     c_interface_exit()
  520.    ------------------------------------------------------------------------- */
  521.  
  522. void c_interface_exit()
  523. {
  524.     c_interface_normal_keyboard_off();
  525.     c_setpage( vmode_active );
  526.     c_setscreen( vmode_page2 );
  527.     c_update_video_screen();
  528. }
  529.  
  530. /* -------------------------------------------------------------------------
  531.     c_interface_info()
  532.    ------------------------------------------------------------------------- */
  533.  
  534. void c_interface_info( char *filename )
  535. {
  536.     static unsigned char screen[24][41] =
  537.       { "||||||||||||||||||||||||||||||||||||||||",
  538.     "|              Information             |",
  539.     "||||||||||||||||||||||||||||||||||||||||",
  540.     "|                                      |",
  541.     "|                                      |",
  542.     "|                                      |",
  543.     "|                                      |",
  544.     "|                                      |",
  545.     "|                                      |",
  546.     "|                                      |",
  547.     "|                                      |",
  548.     "|                                      |",
  549.     "|                                      |",
  550.     "|                                      |",
  551.     "|                                      |",
  552.     "|                                      |",
  553.     "|                                      |",
  554.     "|                                      |",
  555.     "|                                      |",
  556.     "|                                      |",
  557.     "||||||||||||||||||||||||||||||||||||||||",
  558.     "|     Use arrow keys to move cursor    |",
  559.     "|          (Press ESC to exit)         |",
  560.     "||||||||||||||||||||||||||||||||||||||||" };
  561.  
  562.     static char     temp[4096];
  563.     FILE         *f;
  564.     int            i, j, lines;
  565.     int            x_pos, y_pos, x_cur, y_cur;
  566.     static char        *info_buf[4096];
  567.     static int        info_buf_len[4096];
  568.     char        ch;
  569.     Tr            found;
  570.  
  571.     c_interface_translate_screen( screen );
  572.  
  573.     c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  574.     for (i = 0; i < 24; i++)
  575.     c_interface_print( 0, i, screen[ i ] );
  576.     c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  577.  
  578.     sprintf( temp, "%s/a2d.info", disk_path );
  579.  
  580.     f = fopen( temp, "r" );
  581.     if (f == NULL)
  582.     {
  583.     c_interface_print( 5, 11, "Could not find file a2d.info!" );
  584.     usleep(1500000);
  585.     return;
  586.     }
  587.  
  588.     found = False;
  589.     for (;;)
  590.     {
  591.     if (fgets( temp, 4000, f ) == NULL)
  592.         break;
  593.     if (temp[ 0 ] == '{')
  594.     {
  595.         int     r_brace;
  596.  
  597.         for (r_brace = 1;
  598.          temp[ r_brace ] != '}' && temp[ r_brace ] != '\0';
  599.          r_brace++) { }
  600.             if (temp[ r_brace ] == '}' &&
  601.         strncmp( filename, temp + 1, r_brace - 1 ) == 0)
  602.         {
  603.         found = True;
  604.         break;
  605.         }
  606.     }
  607.     }
  608.  
  609.     if (!found)
  610.     {
  611.     fclose( f );
  612.     c_interface_print( 9, 11, "No information found!");
  613.     usleep(1500000);
  614.     return;
  615.     }
  616.  
  617.     for (lines = 0; lines < 4096; lines++)
  618.     {
  619.     if (fgets(temp, 4000, f) == NULL)
  620.         break;
  621.         if (temp[0] == '{')
  622.         break;
  623.  
  624.     info_buf_len[ lines ] = strlen( temp );
  625.     if (temp[ info_buf_len[ lines ] - 1 ] == 10)
  626.         temp[ info_buf_len[ lines ] - 1 ] = '\0',
  627.         info_buf_len[ lines ]--;
  628.  
  629.     info_buf[ lines ] = malloc( info_buf_len[ lines ] + 1 );
  630.     
  631.     strcpy( info_buf[ lines ], temp );
  632.     }
  633.  
  634.     x_pos = y_pos = x_cur = y_cur = 0;
  635.  
  636.     c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  637.  
  638.     for (;;)
  639.     {
  640.     for (i = 0; i < 17; i++)
  641.     {
  642.         if (y_pos + i < lines)
  643.             for (j = 0; j < 38; j++)
  644.             {
  645.             if (i == y_cur && j == x_cur)
  646.                     c_interface_textcolor( COLOR_LIGHT_GREEN, COLOR_MEDIUM_BLUE );
  647.  
  648.             if (x_pos + j >= info_buf_len[ y_pos + i ])
  649.                 c_interface_print_char( j + 1, i + 3, ' ' );
  650.             else
  651.             c_interface_print_char( j + 1, i + 3,
  652.                     info_buf[ y_pos + i ][ x_pos + j ] );
  653.  
  654.             if (i == y_cur && j == x_cur)
  655.                     c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  656.         }
  657.         else
  658.         c_interface_print( 1, i + 3, "                                      ");
  659.     }
  660.  
  661.     do
  662.     {
  663.         ch = c_mygetch();
  664.     }
  665.     while (ch == -1);
  666.  
  667.     if (ch == 27)
  668.     {
  669.         char ch = c_mygetch();
  670.  
  671.         if (ch == '[')
  672.         {
  673.         char ch = c_mygetch();
  674.  
  675.         if (ch == 'A')        /* Arrow up */
  676.                 if (y_cur > 0)
  677.             y_cur--;
  678.             else    
  679.             if (y_pos > 0)
  680.             y_pos--;
  681.             else;
  682.         else
  683.         if (ch == 'B')        /* Arrow down */
  684.             if (y_cur < 16)
  685.             if (y_pos + y_cur < lines - 1)
  686.                 y_cur++;
  687.             else;
  688.             else
  689.             if (y_pos < lines - 17)
  690.             y_pos++;
  691.             else;
  692.         else
  693.         if (ch == 'D')        /* Arrow left */
  694.                 if (x_cur > 0)
  695.             x_cur--;
  696.             else    
  697.             if (x_pos > 0)
  698.             x_pos--;
  699.             else;
  700.         else
  701.         if (ch == 'C')        /* Arrow right */
  702.             if (x_cur < 37)
  703.             if (x_pos + x_cur < 4000)
  704.                 x_cur++;
  705.             else;
  706.             else
  707.             if (x_pos < 3962)
  708.             x_pos++;
  709.             else;
  710.         else
  711.         if (ch == '6')
  712.         {
  713.             char ch = c_mygetch();
  714.             if (ch == '~')    /* Page down */
  715.             {
  716.             y_pos += 16;
  717.             if (y_pos > lines - 17)
  718.             {
  719.                 y_cur += (y_pos - (lines - 17));
  720.                 if (y_cur > 16)
  721.                 y_cur = 16;
  722.                 y_pos = lines - 17;
  723.             }
  724.             }
  725.         }
  726.         else
  727.         if (ch == '5')
  728.         {
  729.             char ch = c_mygetch();
  730.             if (ch == '~')    /* Page up */
  731.             {
  732.             y_pos -= 16;
  733.             if (y_pos < 0)
  734.             {
  735.                 y_cur += y_pos;
  736.                 if (y_cur < 0)
  737.                 y_cur = 0;
  738.                 y_pos = 0;
  739.             }
  740.             }
  741.         }
  742.         else
  743.         if (ch == '1')
  744.         {
  745.             char ch = c_mygetch();
  746.             if (ch == '~')    /* Home */
  747.             x_pos = y_pos = x_cur = y_cur = 0;
  748.         }
  749.         else
  750.         if (ch == '4')
  751.         {
  752.             char ch = c_mygetch();
  753.             if (ch == '~')    /* End */
  754.             y_pos = lines - 17;
  755.         }
  756.         }
  757.         else
  758.         if (ch == -1)
  759.         return;
  760.     }
  761.     }
  762.  
  763.     fclose( f );
  764. }
  765.  
  766. /* -------------------------------------------------------------------------
  767.     c_interface_select_diskette()
  768.    ------------------------------------------------------------------------- */
  769.  
  770. void c_interface_select_diskette( int drive )
  771. {
  772.     static unsigned char screen[24][41] =
  773.       { "||||||||||||||||||||||||||||||||||||||||",
  774.     "| Insert diskette into Drive A, Slot 6 |",
  775.     "||||||||||||||||||||||||||||||||||||||||",
  776.     "|                                      |",
  777.     "|                                      |",
  778.     "|                                      |",
  779.     "|                                      |",
  780.     "|                                      |",
  781.     "|                                      |",
  782.     "|                                      |",
  783.     "|                                      |",
  784.     "|                                      |",
  785.     "|                                      |",
  786.     "|                                      |",
  787.     "|                                      |",
  788.     "|                                      |",
  789.     "|                                      |",
  790.     "|                                      |",
  791.     "|                                      |",
  792.     "|                                      |",
  793.     "||||||||||||||||||||||||||||||||||||||||",
  794.     "| Use arrow keys and RETURN to select  |",
  795.     "| Press SPACE for info (ESC = cancel)  |",
  796.     "||||||||||||||||||||||||||||||||||||||||" };
  797.  
  798.     static char        temp[4096], cmd[4096];
  799.  
  800.     struct dirent     **namelist;
  801.     int              entries;
  802.  
  803.     int            i;
  804.     static int        curpos = 0;
  805.  
  806.     char        ch;
  807.  
  808.     screen[ 1 ][ 29 ] = (drive == 0) ? 'A' : 'B';
  809.  
  810.     c_setpage( 0 );
  811.     c_setscreen( 0 );
  812.  
  813.     c_interface_translate_screen( screen );
  814.  
  815.     c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  816.     for (i = 0; i < 24; i++)
  817.     c_interface_print( 0, i, screen[ i ] );
  818.     c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  819.  
  820.     entries = scandir(disk_path, &namelist, c_interface_disk_select, alphasort );
  821.  
  822.     if (entries <= 0)
  823.     {
  824.     c_interface_print( 5, 11, "No Apple II+ diskettes found!" );
  825.     usleep(1500000);
  826.     c_interface_exit();
  827.     return;
  828.     }
  829.  
  830.     if (curpos >= entries)
  831.     curpos = entries - 1;
  832.     c_interface_normal_keyboard_on();
  833.  
  834.     for (;;)
  835.     {
  836.         c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  837.         for (i = 0; i < 17; i++)
  838.         {
  839.         int        ent_no = curpos - 8 + i, slen;
  840.  
  841.             strcpy( temp, " " );
  842.         if (ent_no >= 0 && ent_no < entries)
  843.         {
  844.             strcpy( temp + 1, namelist[ ent_no ] -> d_name );
  845.             if (c_interface_cut_name( temp ))
  846.             strcat( temp, " <gz>");
  847.         }
  848.  
  849.         slen = strlen( temp );
  850.         while (slen < 38)
  851.             temp[ slen++ ] = ' ';
  852.         temp[ 38 ] = '\0';
  853.  
  854.         if (ent_no == curpos)
  855.         {
  856.                 c_interface_textcolor( COLOR_LIGHT_GREEN, COLOR_MEDIUM_BLUE );
  857.             c_interface_print( 1, i + 3, temp );
  858.                 c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  859.         }
  860.         else
  861.             c_interface_print( 1, i + 3, temp );
  862.     }
  863.  
  864.     do
  865.     {
  866.         ch = c_mygetch();
  867.     }
  868.     while (ch == -1);
  869.  
  870.     if (ch == 27)
  871.     {
  872.         char ch = c_mygetch();
  873.  
  874.         if (ch == '[')
  875.         {
  876.         char ch = c_mygetch();
  877.  
  878.         if (ch == 'A')        /* Arrow up */
  879.                 if (curpos > 0)
  880.             curpos--;
  881.             else;
  882.         else
  883.         if (ch == 'B')        /* Arrow down */
  884.             if (curpos < entries - 1)
  885.             curpos++;
  886.             else;
  887.         else
  888.         if (ch == '6')
  889.         {
  890.             char ch = c_mygetch();
  891.             if (ch == '~')    /* Page down */
  892.             {
  893.             curpos += 16;
  894.             if (curpos > entries - 1)
  895.                 curpos = entries - 1;
  896.             }
  897.         }
  898.         else
  899.         if (ch == '5')
  900.         {
  901.             char ch = c_mygetch();
  902.             if (ch == '~')    /* Page up */
  903.             {
  904.             curpos -= 16;
  905.             if (curpos < 0)
  906.                 curpos = 0;
  907.             }
  908.         }
  909.         else
  910.         if (ch == '1')
  911.         {
  912.             char ch = c_mygetch();
  913.             if (ch == '~')    /* Home */
  914.             curpos = 0;
  915.         }
  916.         else
  917.         if (ch == '4')
  918.         {
  919.             char ch = c_mygetch();
  920.             if (ch == '~')    /* End */
  921.             curpos = entries - 1;
  922.         }
  923.         }
  924.         else
  925.         if (ch == -1)
  926.         {
  927.             for (i = 0; i < entries; i++)
  928.             free(namelist[ i ]);
  929.         c_interface_exit();
  930.         return;
  931.         }
  932.     }
  933.     else
  934.     if (ch == 13) /* Return */
  935.     {
  936.         int        cmpr = False;
  937.  
  938.             sprintf( temp, "%s/%s", disk_path, namelist[ curpos ] -> d_name );
  939.         if (c_interface_is_gz( temp ))
  940.         {
  941.         c_interface_print( 1, 21,
  942.             "            Uncompressing...          " );
  943.             c_interface_print( 1, 22,
  944.             "                                      " );
  945.  
  946.         sprintf(cmd, "gunzip '%s'", temp );
  947.         system(cmd);
  948.         c_interface_cut_gz( temp );
  949.         cmpr = True;
  950.         }
  951.         if (compressed[ drive ])
  952.         {
  953.         c_interface_print( 1, 21,
  954.             "      Compressing old diskette...     " );
  955.             c_interface_print( 1, 22,
  956.             "                                      " );
  957.         }
  958.         c_new_diskette_6( drive, temp, cmpr );
  959.         for (i = 0; i < entries; i++)
  960.         free(namelist[ i ]);
  961.         c_interface_exit();
  962.         return;
  963.     }
  964.     else
  965.     if (ch == ' ')
  966.     {
  967.          strcpy( temp, namelist[ curpos ] -> d_name );
  968.          c_interface_cut_name( temp );
  969.          c_interface_info( temp );
  970.  
  971.              c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  972.              for (i = 0; i < 24; i++)
  973.              c_interface_print( 0, i, screen[ i ] );
  974.     }
  975.     }
  976. }
  977.  
  978. /* -------------------------------------------------------------------------
  979.     c_interface_parameters()
  980.    ------------------------------------------------------------------------- */
  981.  
  982. void c_interface_parameters()
  983. {
  984.     static unsigned char screen[24][41] =
  985.       { "||||||||||||||||||||||||||||||||||||||||",
  986.     "|     Apple II+ Emulator for Linux     |",
  987.     "|   by Alexander Jean-Claude Bottema   |",
  988.     "||||||||||||||||||||||||||||||||||||||||",
  989.     "|                                      |",
  990.     "|                                      |",
  991.     "|                                      |",
  992.     "|                                      |",
  993.     "|                                      |",
  994.     "|                                      |",
  995.     "|                                      |",
  996.     "|                                      |",
  997.     "|                                      |",
  998.     "||||||||||||||||||||||||||||||||||||||||",
  999.     "| F1 : Drive A, Slot 6  F9 : Max speed |",
  1000.     "| F2 : Drive B, Slot 6       (On/Off)  |",
  1001.     "| F4 : Pause         Pause : Reboot    |",
  1002.     "| F5 : Keyb. layout  Pr.Scr: Reset     |",
  1003.     "| F8 : Words from the author           |",
  1004.     "| F10: This menu                       |",
  1005.     "||||||||||||||||||||||||||||||||||||||||",
  1006.     "| Use arrow keys (or Return) to modify |",
  1007.     "| parameters. (Press ESC to exit menu) |",
  1008.     "||||||||||||||||||||||||||||||||||||||||" };
  1009.  
  1010.     static char        temp[4096], cmd[4096];
  1011.     static char        *options[9] =
  1012.         { " Speed    : ",
  1013.                   " Path     : ",
  1014.           " Color    : ",
  1015.           " Sound    : ",
  1016.           " Joystick : ",
  1017.           " Origin X : ",
  1018.           " Origin Y : ",
  1019.           " Sens.    : ", 
  1020.           " Quit       " };
  1021.  
  1022.     int            i, j;
  1023.     char        ch;
  1024.     static int        option = 0;
  1025.     static int        cur_x = 0, cur_pos = 0;
  1026.  
  1027.     c_setpage( 0 );
  1028.     c_setscreen( 0 );
  1029.  
  1030.     c_interface_translate_screen( screen );
  1031.  
  1032.     c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  1033.     for (i = 0; i < 24; i++)
  1034.     c_interface_print( 0, i, screen[ i ] );
  1035.     c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  1036.  
  1037.     c_interface_normal_keyboard_on();
  1038.  
  1039.     for (;;)
  1040.     {
  1041.     for (i = 0; i < 9; i++)
  1042.     {
  1043.         if (option == i)
  1044.         c_interface_textcolor( COLOR_LIGHT_GREEN,
  1045.                        COLOR_MEDIUM_BLUE );
  1046.         c_interface_print( 1, 4 + i, options[ i ] );
  1047.         if (option == i)
  1048.         c_interface_textcolor( COLOR_LIGHT_GREEN,
  1049.                        0 );
  1050.         switch (i)
  1051.         {
  1052.         case 0:
  1053.         sprintf(temp, "%03d%%", 101 - apple_speed );
  1054.         break;
  1055.         case 1:
  1056.         strncpy( temp, disk_path + cur_pos, 24 );
  1057.         temp[24] = '\0';
  1058.         break;
  1059.         case 2:
  1060.         sprintf(temp, "%s", (color_mode == 0) ? "Off         " :
  1061.                     (color_mode == 1) ? "On          " :
  1062.                                         "Interpolated");
  1063.         break;
  1064.         case 3:
  1065.         sprintf(temp, "%s", (sound_mode == 0) ? "Off       " :
  1066.                                         "PC speaker");
  1067.         break;
  1068.         case 4:
  1069.         sprintf(temp, "%s", (joy_mode == 0) ? "Linear " :
  1070.                     (joy_mode == 1) ? "Digital" :
  1071.                                                       "Off    ");
  1072.         break;
  1073.         case 5:
  1074.         sprintf(temp, "%03d", joy_center_x);
  1075.         break;
  1076.         case 6:
  1077.         sprintf(temp, "%03d", joy_center_y);
  1078.         break;
  1079.         case 7:
  1080.         sprintf(temp, "%03d%%", joy_step );
  1081.         break;
  1082.         case 8:
  1083.         strcpy( temp, "" );
  1084.         break;
  1085.         default:
  1086.         break;
  1087.         }
  1088.  
  1089.         if (i != 1)
  1090.             c_interface_print( 14, 4 + i, temp );
  1091.         else
  1092.         {
  1093.             int    j;
  1094.  
  1095.         for (j = 0; j < 24; j++)
  1096.             if (cur_x != j)
  1097.             {
  1098.             if (temp[ j ] == '\0')
  1099.             {
  1100.                     c_interface_print_char( 14 + j, 5, ' ' );
  1101.                 j++;
  1102.                 break;
  1103.             }
  1104.             else
  1105.                     c_interface_print_char( 14 + j, 5, temp[ j ] );
  1106.             }
  1107.             else
  1108.             {
  1109.             if (option == 1)
  1110.                     c_interface_textcolor( COLOR_LIGHT_GREEN,
  1111.                                    COLOR_MEDIUM_BLUE );
  1112.             if (temp[ j ] == '\0')
  1113.             {
  1114.                     c_interface_print_char( 14 + j, 5, ' ' );
  1115.                 if (option == 1)
  1116.                         c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  1117.                 j++;
  1118.                 break;
  1119.             }
  1120.             else
  1121.                     c_interface_print_char( 14 + j, 5, temp[ j ] );
  1122.             if (option == 1)
  1123.                     c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  1124.             }
  1125.         for (; j < 24; j++)
  1126.             c_interface_print_char( 14 + j, 5, ' ' );
  1127.          }
  1128.         }
  1129.  
  1130.     do
  1131.     {
  1132.         ch = c_mygetch();
  1133.     }
  1134.     while (ch == -1);
  1135.  
  1136.     if (ch == 27)
  1137.     {
  1138.         char ch = c_mygetch();
  1139.  
  1140.         if (ch == '[')
  1141.         {
  1142.         char ch = c_mygetch();
  1143.  
  1144.         if (ch == 'A')        /* Arrow up */
  1145.                 if (option > 0)
  1146.             option--;
  1147.             else
  1148.             option = 8;
  1149.         else
  1150.         if (ch == 'B')        /* Arrow down */
  1151.             if (option < 8)
  1152.             option++;
  1153.             else
  1154.             option = 0;
  1155.         if (ch == 'D')        /* Arrow left */
  1156.         {
  1157.             switch (option)
  1158.             {
  1159.             case 0:
  1160.             if (apple_speed < 100)
  1161.                 apple_speed++;
  1162.             break;
  1163.             case 1:
  1164.             if (cur_x > 0)
  1165.                 cur_x--;
  1166.             else
  1167.             if (cur_pos > 0)
  1168.                 cur_pos--;
  1169.             break;
  1170.             case 2:
  1171.             color_mode--;
  1172.             if (color_mode < 0)
  1173.                 color_mode = 2;
  1174.             break;
  1175.             case 3:
  1176.             sound_mode--;
  1177.             if (sound_mode < 0)
  1178.                 sound_mode = 1;
  1179.             break;
  1180.             case 4:
  1181.             joy_mode--;
  1182.             if (joy_mode < 0)
  1183.                 joy_mode = 2;
  1184.             break;
  1185.             case 5:
  1186.             if (joy_center_x > 0)
  1187.                 joy_center_x--;
  1188.             break;
  1189.             case 6:
  1190.             if (joy_center_y > 0)
  1191.                 joy_center_y--;
  1192.             break;
  1193.             case 7:
  1194.             if (joy_step > 1)
  1195.                 joy_step--;
  1196.             break;
  1197.             }
  1198.         }
  1199.         else
  1200.         if (ch == 'C')        /* Arrow right */
  1201.         {
  1202.             switch (option)
  1203.             {
  1204.             case 0:
  1205.             if (apple_speed > 1)
  1206.                 apple_speed--;
  1207.             break;
  1208.             case 1:
  1209.             if (cur_x < 23)
  1210.             {
  1211.                 if (disk_path[cur_pos + cur_x] != '\0')
  1212.                     cur_x++;
  1213.             }
  1214.             else
  1215.             if (disk_path[cur_pos + cur_x] != '\0')
  1216.                 cur_pos++;
  1217.             break;
  1218.             case 2:
  1219.             color_mode++;
  1220.             if (color_mode > 2)
  1221.                 color_mode = 0;
  1222.             break;
  1223.             case 3:
  1224.             sound_mode++;
  1225.             if (sound_mode > 1)
  1226.                 sound_mode = 0;
  1227.             break;
  1228.             case 4:
  1229.             joy_mode++;
  1230.             if (joy_mode > 2)
  1231.                 joy_mode = 0;
  1232.             break;
  1233.             case 5:
  1234.             if (joy_center_x < 255)
  1235.                 joy_center_x++;
  1236.             break;
  1237.             case 6:
  1238.             if (joy_center_y < 255)
  1239.                 joy_center_y++;
  1240.             break;
  1241.             case 7:
  1242.             if (joy_step < 100)
  1243.                 joy_step++;
  1244.             break;
  1245.             }
  1246.         }
  1247.         else;
  1248.         }
  1249.         else
  1250.         if (ch == -1)
  1251.         {
  1252.         c_initialize_sound();
  1253.         c_initialize_highres_values();
  1254.             c_interface_exit();
  1255.             return;
  1256.             }
  1257.     }
  1258.     else
  1259.     {
  1260.         if (ch >= ' ' && ch < 127 && option == 1)
  1261.         {
  1262.         int        i;
  1263.  
  1264.         strcpy(temp, disk_path);        
  1265.         for (i = strlen(temp); i >= cur_pos + cur_x; i--)
  1266.             temp[ i + 1 ] = temp[ i ];
  1267.         temp[ cur_pos + cur_x ] = ch;
  1268.         strcpy(disk_path, temp);
  1269.         if (cur_x < 23)
  1270.             cur_x++;
  1271.         else
  1272.         if (disk_path[cur_pos + cur_x] != '\0')
  1273.             cur_pos++;
  1274.         }
  1275.  
  1276.         if ((ch == 127 || ch == 8) && cur_pos + cur_x - 1 >= 0) /* Backspace */
  1277.         {
  1278.             int        i;
  1279.  
  1280.         for (i = cur_pos + cur_x - 1; disk_path[ i ] != '\0'; i++)
  1281.             disk_path[ i ] = disk_path[ i + 1 ];
  1282.  
  1283.         if (cur_x > 0)
  1284.             cur_x--;
  1285.         else
  1286.         if (cur_pos > 0)
  1287.             cur_pos--;
  1288.         }
  1289.  
  1290.         if (ch == 13 && option == 8)
  1291.         {
  1292.         char ch;
  1293.  
  1294.         c_interface_print( 1, 22, "          Are you sure? (Y/N)         " );
  1295.         while ((ch = c_mygetch()) == -1) { }
  1296.         ch = toupper(ch);
  1297.         if (ch == 'Y')
  1298.         {
  1299.                     c_new_diskette_6( 0, "", False );
  1300.                     c_new_diskette_6( 1, "", False );
  1301.                     c_interface_normal_keyboard_off();
  1302.             c_mouse_close();
  1303.             vga_setmode(TEXT);
  1304.             printf("Linux! ...and there were much rejoicing! oyeeeeh...\n");
  1305.             exit( 0 );
  1306.         }
  1307.                 c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  1308.             c_interface_print( 0, 22, screen[ 22 ] );
  1309.                 c_interface_textcolor( COLOR_LIGHT_GREEN, 0 );
  1310.         }
  1311.     }
  1312.     }
  1313. }
  1314.  
  1315. /* -------------------------------------------------------------------------
  1316.     c_interface_words()
  1317.    ------------------------------------------------------------------------- */
  1318.  
  1319. void c_interface_words()
  1320. {
  1321.     static unsigned char screen[24][41] =
  1322.       { "||||||||||||||||||||||||||||||||||||||||",
  1323.     "|    Apple II+ Emulator Version 0.01   |",
  1324.     "||||||||||||||||||||||||||||||||||||||||",
  1325.     "| If you have problems with your       |",
  1326.     "| keyboard concerning the mapping of   |",
  1327.     "| various keys, please let me know.    |",
  1328.     "| I use a Swedish keyboard for myself  |",
  1329.     "| and the scancodes may differ from US |",
  1330.     "| keyboards (or other countries as     |",
  1331.     "| well). Currently, my email address   |",
  1332.     "| is: d91a1bo@meryl.csd.uu.se. This    |",
  1333.     "| address is valid at least one more   |",
  1334.     "| year, i.e. as long as I am Computer  |",
  1335.     "| Science student at the University    |",
  1336.     "| of Uppsala. \"...and there were much  |",
  1337.     "| rejoicing! oyeeeeeh\"                 |",
  1338.     "|                                      |",
  1339.     "|                                      |",
  1340.     "|                                      |",
  1341.     "|                                      |",
  1342.     "|              / Alexander  Oct 9 1994 |",
  1343.     "||||||||||||||||||||||||||||||||||||||||",
  1344.     "|       (Press any key to exit)        |",
  1345.     "||||||||||||||||||||||||||||||||||||||||" };
  1346.  
  1347.     int        i;
  1348.  
  1349.     c_setpage( 0 );
  1350.     c_setscreen( 0 );
  1351.  
  1352.     c_interface_translate_screen( screen );
  1353.  
  1354.     c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  1355.     for (i = 0; i < 24; i++)
  1356.     c_interface_print( 0, i, screen[ i ] );
  1357.  
  1358.     c_interface_normal_keyboard_on();
  1359.     while (c_mygetch() == -1) { }
  1360.     c_interface_exit();
  1361. }
  1362.  
  1363. /* -------------------------------------------------------------------------
  1364.     c_interface_keyboard_layout()
  1365.    ------------------------------------------------------------------------- */
  1366.  
  1367. void c_interface_keyboard_layout()
  1368. {
  1369.     static unsigned char screen[24][41] =
  1370.       { "||||||||||||||||||||||||||||||||||||||||",
  1371.     "|     Apple II+ US Keyboard Layout     |",
  1372.     "||||||||||||||||||||||||||||||||||||||||",
  1373.     "| Keyboard:                            |",
  1374.     "|                                      |",
  1375.     "| 1! 2\" 3# 4$ 5% 6& 7' 8( 9) 0 :* -=   |",
  1376.     "|  Q  W  E  R  T  Y  U  I  O  P Rep CR |",
  1377.     "|   A  S  D  F  G  H  J  K  L  ;+ <- ->|",
  1378.     "|    Z  X  C  V  B  N  M ,< .> /?      |",
  1379.     "| Where <- -> are the left and right   |",
  1380.     "| arrow keys respectively. Rep is the  |",
  1381.     "| \"repeat\" key.                        |",
  1382.     "||||||||||||||||||||||||||||||||||||||||",
  1383.     "| Joystick emulation on numeric keypad |",
  1384.     "|                                      |",
  1385.     "| 7  8  9  for various directions.     |",
  1386.     "| 4     6  Press 5 to center linear    |",
  1387.     "| 1  2  3  joystick.                   |",
  1388.     "|                                      |",
  1389.     "| Delete, End and Page Down emulates   |",
  1390.     "| pushbuttons 0, 1 and 2 respectively. |",
  1391.     "||||||||||||||||||||||||||||||||||||||||",
  1392.     "|       (Press any key to exit)        |",
  1393.     "||||||||||||||||||||||||||||||||||||||||" };
  1394.  
  1395.     int        i;
  1396.  
  1397.     c_setpage( 0 );
  1398.     c_setscreen( 0 );
  1399.  
  1400.     c_interface_translate_screen( screen );
  1401.  
  1402.     c_interface_textcolor( COLOR_LIGHT_RED, 0 );
  1403.     for (i = 0; i < 24; i++)
  1404.     c_interface_print( 0, i, screen[ i ] );
  1405.  
  1406.     c_interface_normal_keyboard_on();
  1407.     while (c_mygetch() == -1) { }
  1408.     c_interface_exit();
  1409. }
  1410.  
  1411.  
  1412.