0001:
0002: /* $Id: atariio.c,v 1.1.1.1 2000/05/10 14:20:50 jholder Exp $
0003: * --------------------------------------------------------------------
0004: * see doc/License.txt for License Information
0005: * --------------------------------------------------------------------
0006: *
0007: * File name: $Id: atariio.c,v 1.1.1.1 2000/05/10 14:20:50 jholder Exp $
0008: *
0009: * Description:
0010: *
0011: * Modification history:
0012: * $Log: atariio.c,v $
0013: * Revision 1.1.1.1 2000/05/10 14:20:50 jholder
0014: *
0015: * imported
0016: *
0017: *
0018: * --------------------------------------------------------------------
0019: */
0020:
0021:
0022: #include <stdio.h>
0023: #include <osbind.h>
0024: #include <mintbind.h>
0025:
0026: #include <ncurses/termcap.h>
0027:
0028: /* atariio.c */
0029:
0030: #include "ztypes.h"
0031:
0032: #if defined(BSD)
0033: #include <sgtty.h>
0034: #endif /* defined(BSD) */
0035: #if defined(SYSTEM_FIVE)
0036: #include <termio.h>
0037: #endif /* defined(SYSTEM_FIVE) */
0038: #if defined(POSIX)
0039: #include <termios.h>
0040: #endif /* defined(POSIX) */
0041:
0042: #include <signal.h>
0043: #include <sys/types.h>
0044: #include <sys/time.h>
0045:
0046: /* needed by AIX */
0047: #if defined(AIX)
0048: #include <sys/select.h>
0049: #endif
0050:
0051: /* new stuff for command editing */
0052: int BUFFER_SIZE;
0053: char *commands;
0054: int space_avail;
0055: static int ptr1, ptr2 = 0;
0056: static int end_ptr = 0;
0057: static int row, head_col;
0058: static int keypad_avail = 1;
0059:
0060: /* done with editing global info */
0061:
0062: static int ismint = 0;
0063: static int current_row = 1;
0064: static int current_col = 1;
0065:
0066: static int saved_row;
0067: static int saved_col;
0068:
0069: static int cursor_saved = OFF;
0070:
0071: static char tcbuf[1024];
0072: static char cmbuf[1024];
0073: static char *cmbufp;
0074:
0075: volatile long volatile *_systicks = ( long * ) 0x4baL;
0076: static char *CE, *CL, *CM, *CS, *DL, *MD, *ME, *MR, *SE, *SO, *TE, *TI, *UE, *US, *KD, *KL, *KR,
0077:
0078: *KU;
0079:
0080: #define GET_TC_STR(p1, p2) if ((p1 = tgetstr (p2, &cmbufp)) == NULL) p1 = ""
0081:
0082: #define BELL 7
0083: static int Agetchar( void );
0084: static int outc( );
0085: static void display_string( );
0086: static int wait_for_char( );
0087: static int read_key( );
0088: static void set_cbreak_mode( );
0089: static void rundown( );
0090:
0091: /*extern int tgetent( );
0092: extern int tgetnum( );
0093: extern char *tgetstr( );
0094: extern char *tgoto( );
0095: extern void tputs( );*/ // already declared in termcap
0096:
0097: static int colours = 0;
0098: static int outc( c )
0099: int c;
0100: {
0101: putchar( c ); return 0;
0102: } /* outc */
0103:
0104: void set_colours( int foreground, int background )
0105: {
0106: /* Somewhere, we have a termcap entry, but we'll have to get a
0107: * bit machine specific for this one */
0108: static int cmap2b[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
0109: static int cmap2f[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
0110: static int cmap4b[] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 };
0111: static int cmap4f[] = { 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0 };
0112: static int cmap16f[] = { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 };
0113: static int cmap16b[] = { 15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0 };
0114:
0115: if ( !colours )
0116: {
0117: int mode;
0118:
0119: putchar( '\033' );
0120: putchar( 'w' );
0121: mode = Getrez( );
0122: switch ( mode )
0123: {
0124: case 1:
0125: colours = 4;
0126: break;
0127: case 6:
0128: case 2:
0129: colours = 2;
0130: break;
0131: default:
0132: /* At least 16, and possibly 16 million */
0133: colours = 16;
0134: break;
0135: }
0136: }
0137:
0138: switch ( colours )
0139: {
0140: case 2:
0141: foreground = cmap2f[foreground - 1];
0142: background = cmap2b[background - 1];
0143: putchar( '\033' );
0144: putchar( 'b' );
0145: putchar( foreground );
0146: putchar( '\033' );
0147: putchar( 'c' );
0148: putchar( foreground + 1 );
0149: break;
0150: case 4:
0151: foreground = cmap4f[foreground - 1];
0152: background = cmap4b[background - 1];
0153: putchar( '\033' );
0154: putchar( 'b' );
0155: putchar( foreground );
0156: putchar( '\033' );
0157: putchar( 'c' );
0158: putchar( ( foreground == background ) ? foreground + 1 : background );
0159: break;
0160: case 16:
0161: foreground = cmap16f[foreground - 1];
0162: background = cmap16b[background - 1];
0163: putchar( '\033' );
0164: putchar( 'b' );
0165: putchar( foreground );
0166: putchar( '\033' );
0167: putchar( 'c' );
0168: putchar( ( foreground == background ) ? foreground + 1 : background );
0169: break;
0170: default:
0171: fatal( "set_colours(): Terminal error in colour handling." );
0172: }
0173: }
0174:
0175: void initialize_screen( )
0176: {
0177: char *term;
0178: int row, col;
0179:
0180: ismint = Pgetpid( ) != -32;
0181:
0182: if ( ( term = getenv( "TERM" ) ) == NULL )
0183: {
0184: /* If there is no termcap entry available, then make the standard default */
0185: fudge:
0186: term =
0187: "vt52|dec-vt52|dec vt52:do=^J:le=^H:bs:cd=\\EJ:ce=\\EK:"
0188: "cl=\\EH\\EJ:cm=\\EY%+ %+ :co#80:li#24:nd=\\EC:pt:sr=\\EI:up=\\EA:"
0189: "ku=\\EA:kd=\\EB:kr=\\EC:kl=\\ED:kb=^H:so=\\Ep:se=\\Eq:al=\\EL:dl=\\EM:";
0190: CE = "\033K";
0191: CL = "\033H\033J";
0192: CM = "\033Y%+ %+ ";
0193: MR = MD = ME = CS = US = UE = "";
0194: KU = "\033A";
0195: KD = "\033B";
0196: KL = "\033C";
0197: KR = "\033D";
0198: DL = "\033M";
0199: SO = "\033p";
0200: SE = "\033q";
0201: TE = "\033v";
0202: TI = "\033w";
0203: screen_cols = 80;
0204: if ( !Getrez( ) )
0205: screen_cols /= 2;
0206: screen_rows = 25;
0207: }
0208: else
0209: {
0210: if ( tgetent( tcbuf, term ) <= 0 )
0211: {
0212: goto fudge;
0213: /* fatal ("No termcap entry for this terminal"); */
0214: }
0215:
0216: cmbufp = cmbuf;
0217:
0218: GET_TC_STR( CE, "ce" );
0219: GET_TC_STR( CL, "cl" );
0220: GET_TC_STR( CM, "cm" );
0221: GET_TC_STR( CS, "cs" );
0222: GET_TC_STR( DL, "dl" );
0223: GET_TC_STR( MD, "md" );
0224: GET_TC_STR( ME, "me" );
0225: GET_TC_STR( MR, "mr" );
0226: GET_TC_STR( SE, "se" );
0227: GET_TC_STR( SO, "so" );
0228: GET_TC_STR( TE, "te" );
0229: GET_TC_STR( TI, "ti" );
0230: GET_TC_STR( UE, "ue" );
0231: GET_TC_STR( US, "us" );
0232: GET_TC_STR( KU, "ku" );
0233: GET_TC_STR( KD, "kd" );
0234: GET_TC_STR( KR, "kr" );
0235: GET_TC_STR( KL, "kl" );
0236:
0237: if ( !KU || !*KU )
0238: {
0239: KU = "\033A";
0240: KD = "\033B";
0241: KL = "\033C";
0242: KR = "\033D";
0243: }
0244: if ( screen_cols == 0 && ( screen_cols = tgetnum( "co" ) ) == -1 )
0245: screen_cols = DEFAULT_COLS;
0246:
0247: if ( screen_rows == 0 && ( screen_rows = tgetnum( "li" ) ) == -1 )
0248: screen_rows = DEFAULT_ROWS;
0249:
0250: }
0251: if ( *MD == '\0' || *ME == '\0' || *MR == '\0' )
0252: {
0253: MD = SO;
0254: ME = SE;
0255: MR = SO;
0256: }
0257: if ( *UE == '\0' || *US == '\0' )
0258: {
0259: UE = SE;
0260: US = SO;
0261: }
0262:
0263: tputs( TI, 1, outc );
0264:
0265: clear_screen( );
0266:
0267: row = screen_rows / 2 - 1;
0268: col = ( screen_cols - ( sizeof ( JZIPVER ) - 1 ) ) / 2;
0269: move_cursor( row, col );
0270: display_string( JZIPVER );
0271: row = screen_rows / 2;
0272: col = ( screen_cols - ( sizeof ( "The story is loading..." ) - 1 ) ) / 2;
0273: move_cursor( row, col );
0274: display_string( "The story is loading..." );
0275:
0276: h_interpreter = INTERP_ATARI_ST;
0277:
0278: commands = ( char * ) malloc( hist_buf_size * sizeof ( char ) );
0279:
0280: if ( commands == NULL )
0281: fatal( "initialize_screen(): Could not allocate history buffer!" );
0282: BUFFER_SIZE = hist_buf_size;
0283: space_avail = hist_buf_size - 1;
0284:
0285: set_cbreak_mode( 1 );
0286: interp_initialized = 1;
0287:
0288: } /* initialize_screen */
0289:
0290: void restart_screen( )
0291: {
0292: zbyte_t high = 1, low = 0;
0293:
0294: cursor_saved = OFF;
0295:
0296: set_byte( H_STANDARD_HIGH, high );
0297: set_byte( H_STANDARD_LOW, low );
0298: if ( h_type < V4 )
0299: set_byte( H_CONFIG, ( get_byte( H_CONFIG ) | CONFIG_WINDOWS ) );
0300: else
0301: {
0302: /* turn stuff on */
0303: set_byte( H_CONFIG,
0304: ( get_byte( H_CONFIG ) | CONFIG_BOLDFACE | CONFIG_EMPHASIS | CONFIG_FIXED |
0305: CONFIG_TIMEDINPUT ) );
0306: #if defined HARD_COLORS
0307: set_byte( H_CONFIG, ( get_byte( H_CONFIG ) | CONFIG_COLOUR ) );
0308: #endif
0309: /* turn stuff off */
0310: set_byte( H_CONFIG, ( get_byte( H_CONFIG ) & ~CONFIG_PICTURES & ~CONFIG_SFX ) );
0311: }
0312:
0313: /* Force graphics off as we can't do them */
0314: set_word( H_FLAGS, ( get_word( H_FLAGS ) & ( ~GRAPHICS_FLAG ) ) );
0315:
0316: } /* restart_screen */
0317:
0318: void reset_screen( )
0319: {
0320: /* only do this stuff on exit when called AFTER initialize_screen */
0321: if ( interp_initialized )
0322: {
0323: delete_status_window( );
0324: select_text_window( );
0325: set_attribute( NORMAL );
0326:
0327: set_cbreak_mode( 0 );
0328:
0329: tputs( TE, 1, outc );
0330: }
0331:
0332: } /* reset_screen */
0333:
0334: void clear_screen( )
0335: {
0336:
0337: tputs( CL, 1, outc );
0338: current_row = 1;
0339: current_col = 1;
0340:
0341: } /* clear_screen */
0342:
0343: void select_status_window( )
0344: {
0345:
0346: save_cursor_position( );
0347:
0348: } /* select_status_window */
0349:
0350: void select_text_window( )
0351: {
0352:
0353: restore_cursor_position( );
0354:
0355: } /* select_text_window */
0356:
0357: void create_status_window( )
0358: {
0359: int row, col;
0360:
0361: if ( *CS )
0362: {
0363: get_cursor_position( &row, &col );
0364:
0365: tputs( tgoto( CS, screen_rows - 1, status_size ), 1, outc );
0366:
0367: move_cursor( row, col );
0368: }
0369:
0370: } /* create_status_window */
0371:
0372: void delete_status_window( )
0373: {
0374: int row, col;
0375:
0376: if ( *CS )
0377: {
0378: get_cursor_position( &row, &col );
0379:
0380: tputs( tgoto( CS, screen_rows - 1, 0 ), 1, outc );
0381:
0382: move_cursor( row, col );
0383: }
0384:
0385: } /* delete_status_window */
0386:
0387: void clear_line( )
0388: {
0389:
0390: tputs( CE, 1, outc );
0391:
0392: } /* clear_line */
0393:
0394: void clear_text_window( )
0395: {
0396: int i, row, col;
0397:
0398: get_cursor_position( &row, &col );
0399:
0400: for ( i = status_size + 1; i <= screen_rows; i++ )
0401: {
0402: move_cursor( i, 1 );
0403: clear_line( );
0404: }
0405:
0406: move_cursor( row, col );
0407:
0408: } /* clear_text_window */
0409:
0410: void clear_status_window( )
0411: {
0412: int i, row, col;
0413:
0414: get_cursor_position( &row, &col );
0415:
0416: for ( i = status_size; i; i-- )
0417: {
0418: move_cursor( i, 1 );
0419: clear_line( );
0420: }
0421:
0422: move_cursor( row, col );
0423:
0424: } /* clear_status_window */
0425:
0426: void move_cursor( row, col )
0427: int row;
0428: int col;
0429: {
0430:
0431: tputs( tgoto( CM, col - 1, row - 1 ), 1, outc );
0432: current_row = row;
0433: current_col = col;
0434:
0435: } /* move_cursor */
0436:
0437: void get_cursor_position( row, col )
0438: int *row;
0439: int *col;
0440: {
0441:
0442: *row = current_row;
0443: *col = current_col;
0444:
0445: } /* get_cursor_position */
0446:
0447: void save_cursor_position( )
0448: {
0449:
0450: if ( cursor_saved == OFF )
0451: {
0452: get_cursor_position( &saved_row, &saved_col );
0453: cursor_saved = ON;
0454: }
0455:
0456: } /* save_cursor_position */
0457:
0458: void restore_cursor_position( )
0459: {
0460:
0461: if ( cursor_saved == ON )
0462: {
0463: move_cursor( saved_row, saved_col );
0464: cursor_saved = OFF;
0465: }
0466:
0467: } /* restore_cursor_position */
0468:
0469: void set_attribute( attribute )
0470: int attribute;
0471: {
0472:
0473: if ( attribute == NORMAL )
0474: {
0475: tputs( ME, 1, outc );
0476: tputs( UE, 1, outc );
0477: }
0478:
0479: if ( attribute & REVERSE )
0480: tputs( MR, 1, outc );
0481:
0482: if ( attribute & BOLD )
0483: tputs( MD, 1, outc );
0484:
0485: if ( attribute & EMPHASIS )
0486: tputs( US, 1, outc );
0487:
0488: if ( attribute & FIXED_FONT )
0489: ;
0490:
0491: } /* set_attribute */
0492:
0493: static void display_string( s )
0494: char *s;
0495: {
0496:
0497: while ( *s )
0498: display_char( *s++ );
0499:
0500: } /* display_string */
0501:
0502: void display_char( c )
0503: int c;
0504: {
0505:
0506: outc( c );
0507:
0508: if ( ++current_col > screen_cols )
0509: current_col = screen_cols;
0510:
0511: } /* display_char */
0512:
0513: void scroll_line( )
0514: {
0515: int row, col;
0516:
0517: get_cursor_position( &row, &col );
0518:
0519: if ( *CS || row < screen_rows )
0520: {
0521: display_char( '\n' );
0522: }
0523: else
0524: {
0525: move_cursor( status_size + 1, 1 );
0526: tputs( DL, 1, outc );
0527: move_cursor( row, 1 );
0528: }
0529:
0530: current_col = 1;
0531: if ( ++current_row > screen_rows )
0532: current_row = screen_rows;
0533:
0534: } /* scroll_line */
0535:
0536: int display_command( char *buffer )
0537: {
0538: int counter, loop;
0539:
0540: move_cursor( row, head_col );
0541: clear_line( );
0542: move_cursor( row, head_col );
0543: /* ptr1 == end_ptr when the player has selected beyond any previously
0544: * saved command */
0545: if ( ptr1 == end_ptr )
0546: return 0;
0547: else
0548: {
0549: counter = 0;
0550: for ( loop = ptr1; loop <= ptr2; loop++ )
0551: {
0552: buffer[counter] = commands[loop];
0553: display_char( buffer[counter++] );
0554: }
0555: return counter;
0556: }
0557: }
0558:
0559: void get_prev_command( void )
0560: {
0561: if ( ptr1 > 0 )
0562: {
0563: ptr2 = ptr1 -= 2;
0564: if ( ptr1 < 0 )
0565: ptr1 = 0;
0566: if ( ptr2 < 0 )
0567: ptr2 = 0;
0568: if ( ptr1 > 0 )
0569: {
0570: do
0571: ptr1--;
0572: while ( ( commands[ptr1] != '\n' ) && ( ptr1 >= 0 ) );
0573: ptr1++;
0574: }
0575: }
0576: }
0577:
0578: void get_next_command( void )
0579: {
0580: if ( ptr2 < end_ptr )
0581: {
0582: ptr1 = ptr2 += 2;
0583: if ( ptr2 >= end_ptr )
0584: ptr1 = ptr2 = end_ptr;
0585: else
0586: {
0587: do
0588: ptr2++;
0589: while ( ( commands[ptr2] != '\n' ) && ( ptr2 <= end_ptr ) );
0590: ptr2--;
0591: }
0592: }
0593: }
0594:
0595: void get_first_command( void )
0596: {
0597: if ( end_ptr > 1 )
0598: {
0599: ptr1 = ptr2 = 0;
0600: do
0601: ptr2++;
0602: while ( ( commands[ptr2] != '\n' ) && ( ptr2 <= end_ptr ) );
0603: ptr2--;
0604: }
0605:
0606: }
0607:
0608: void delete_command( void )
0609: {
0610: int loop;
0611:
0612: do
0613: {
0614: for ( loop = 0; loop < end_ptr; loop++ )
0615: {
0616: commands[loop] = commands[loop + 1];
0617: }
0618: end_ptr--;
0619: space_avail++;
0620: }
0621: while ( commands[0] != '\n' );
0622: for ( loop = 0; loop < end_ptr; loop++ )
0623: {
0624: commands[loop] = commands[loop + 1];
0625: }
0626: end_ptr--;
0627: space_avail++;
0628: ptr1 = ptr2 = end_ptr;
0629: }
0630:
0631: void add_command( char *buffer, int size )
0632: {
0633: int loop, counter;
0634:
0635: counter = 0;
0636: for ( loop = end_ptr; loop < ( end_ptr + size ); loop++ )
0637: {
0638: commands[loop] = buffer[counter++];
0639: }
0640: end_ptr += size + 1;
0641: ptr1 = ptr2 = end_ptr;
0642: commands[end_ptr - 1] = '\n';
0643: space_avail -= size + 1;
0644: }
0645:
0646:
0647:
0648:
0649:
0650:
0651: /*
0652: * Patched 28-June-1995: Changed this routine's expectation of a \n to
0653: * a \r so the form in Bureaucracy works. Patch
0654: * applied by John Holder.
0655: */
0656: int input_character( int timeout )
0657: {
0658: struct timeval tv;
0659: struct timezone tz;
0660: int c;
0661:
0662: /* gettimeofday (&tv, &tz);
0663: *
0664: * tv.tv_sec += timeout; */
0665:
0666: fflush( stdout );
0667:
0668: if ( timeout != 0 )
0669: {
0670: if ( wait_for_char( timeout ) )
0671: return ( -1 );
0672: }
0673:
0674: c = read_key( );
0675:
0676: if ( c == '\n' )
0677: c = '\r';
0678:
0679: return ( c );
0680:
0681: } /* input_character */
0682:
0683: int input_line( int buflen, char *buffer, int timeout, int *read_size )
0684: {
0685: struct timeval tv;
0686: struct timezone tz;
0687: int c, col;
0688: int init_char_pos, curr_char_pos, loop, tail_col, keyfunc = 0;
0689:
0690: get_cursor_position( &row, &col );
0691: head_col = tail_col = col;
0692: init_char_pos = curr_char_pos = *read_size;
0693: ptr1 = ptr2 = end_ptr;
0694:
0695: /*
0696: if(timeout!=0)
0697: {
0698: gettimeofday (&tv, &tz);
0699: tv.tv_usec+=timeout*100000;
0700: while(tv.tv_usec>1000000)
0701: {
0702: tv.tv_sec++;
0703: tv.tv_usec-=1000000;
0704: }
0705: }
0706: */
0707:
0708: for ( ;; )
0709: {
0710:
0711: get_cursor_position( &row, &col );
0712: keyfunc = 0;
0713: /* Read a single keystroke */
0714: fflush( stdout );
0715:
0716: if ( timeout != 0 )
0717: if ( wait_for_char( timeout ) )
0718: return ( -1 );
0719: c = read_key( );
0720:
0721: if ( keypad_avail )
0722: {
0723: if ( c == ( char ) *KU )
0724: {
0725: for ( loop = 0; loop < ( strlen( KU ) - 1 ); loop++ )
0726: do
0727: c = Agetchar( );
0728: while ( c == '[' );
0729: if ( c == ( unsigned char ) KU[strlen( KU ) - 1] )
0730: {
0731: get_prev_command( );
0732: curr_char_pos = *read_size = display_command( buffer );
0733: tail_col = head_col + *read_size;
0734: keyfunc = 1;
0735: }
0736: else if ( c == ( unsigned char ) KD[strlen( KD ) - 1] )
0737: {
0738: get_next_command( );
0739: curr_char_pos = *read_size = display_command( buffer );
0740: tail_col = head_col + *read_size;
0741: keyfunc = 1;
0742: }
0743: else if ( c == ( unsigned char ) KL[strlen( KL ) - 1] )
0744: {
0745: get_cursor_position( &row, &col );
0746: if ( col > head_col )
0747: {
0748: move_cursor( row, --col );
0749: curr_char_pos--;
0750: }
0751: keyfunc = 1;
0752: }
0753: else if ( c == ( unsigned char ) KR[strlen( KR ) - 1] )
0754: {
0755: get_cursor_position( &row, &col );
0756: if ( col < tail_col )
0757: {
0758: move_cursor( row, ++col );
0759: curr_char_pos++;
0760: }
0761: keyfunc = 1;
0762: }
0763: }
0764: }
0765: if ( keyfunc )
0766: continue;
0767:
0768: if ( !keyfunc )
0769: {
0770: if ( c == '\b' )
0771: {
0772: /* Backspace */
0773: get_cursor_position( &row, &col );
0774: if ( col > head_col )
0775: {
0776: move_cursor( row, --col );
0777: for ( loop = curr_char_pos; loop < *read_size; loop++ )
0778: {
0779: buffer[loop - 1] = buffer[loop];
0780: display_char( buffer[loop - 1] );
0781: }
0782: display_char( ' ' );
0783: curr_char_pos--;
0784: tail_col--;
0785: ( *read_size )--;
0786: move_cursor( row, col );
0787: }
0788: }
0789: else
0790: {
0791: /* Normal key action */
0792: if ( *read_size == ( buflen - 1 ) )
0793: {
0794: /* Ring bell if buffer is full */
0795: outc( BELL );
0796: }
0797: else
0798: {
0799: /* Scroll line if return key pressed */
0800: if ( c == '\n' || c == '\r' )
0801: {
0802: c = '\n';
0803: scroll_line( );
0804: }
0805: if ( c == '\n' )
0806: {
0807: if ( *read_size > BUFFER_SIZE )
0808: return ( c );
0809: while ( *read_size > space_avail )
0810: {
0811: delete_command( );
0812: }
0813: if ( *read_size > 0 )
0814: add_command( buffer, *read_size );
0815: return c;
0816: }
0817: else
0818: {
0819: get_cursor_position( &row, &col );
0820: if ( col < tail_col )
0821: {
0822: for ( loop = *read_size; loop >= curr_char_pos; loop-- )
0823: buffer[loop + 1] = buffer[loop];
0824: buffer[curr_char_pos] = ( char ) c;
0825: ( *read_size )++;
0826: tail_col++;
0827: #if 1
0828: move_cursor( row, col );
0829: for ( loop = curr_char_pos; loop < *read_size; loop++ )
0830: display_char( buffer[loop] );
0831: move_cursor( row, ++col );
0832: curr_char_pos++;
0833: #endif
0834: #if 0
0835: move_cursor( row, head_col );
0836: for ( loop = 0; loop < *read_size; loop++ )
0837: display_char( buffer[loop] );
0838: move_cursor( row, ++col );
0839: #endif
0840: }
0841: else
0842: {
0843: buffer[curr_char_pos++] = ( char ) c;
0844: display_char( c );
0845: ( *read_size )++;
0846: tail_col++;
0847: }
0848: }
0849: }
0850: }
0851: }
0852: }
0853: } /* input_line */
0854:
0855: long Systicks( void )
0856: {
0857: long rval;
0858: long sssp;
0859:
0860: sssp = Super( 0L );
0861: rval = *_systicks;
0862: Super( sssp );
0863: return rval;
0864: }
0865:
0866: static int wait_for_char( int timeout )
0867: {
0868: int nfds, status;
0869: fd_set readfds;
0870: struct timeval tv;
0871: struct timezone tz;
0872:
0873: printf( "timeout %d/ticks %ld\n", timeout, Systicks( ) );
0874: if ( !ismint )
0875: {
0876: /* if in TOS then the timeout value is just stored in tv.usec */
0877: printf( "timeout %d/ticks %ld\n", timeout, Systicks( ) );
0878: timeout = ( timeout * 20 ) + Systicks( );
0879: while ( Systicks( ) < ( long ) timeout )
0880: if ( Cconis( ) )
0881: return 0;
0882: return -1;
0883: }
0884:
0885: gettimeofday( &tv, &tz );
0886:
0887: /*
0888: * if (tv.tv_sec >= timeout->tv_sec && tv.tv_usec >= timeout->tv_usec)
0889: * return (-1);
0890: */
0891: if ( !timeout )
0892: return ( -1 );
0893:
0894: /*
0895: tv.tv_sec = timeout->tv_sec - tv.tv_sec;
0896: if (timeout->tv_usec < tv.tv_usec) {
0897: tv.tv_sec--;
0898: tv.tv_usec = (timeout->tv_usec + 1000000) - tv.tv_usec;
0899: } else
0900: tv.tv_usec = timeout->tv_usec - tv.tv_usec;
0901: */
0902: tv.tv_sec = ( timeout * 100000 ) / 1000000;
0903: tv.tv_usec = ( timeout * 100000 ) % 1000000;
0904:
0905: /* used to be the following, but some boxen have no getdtablesize() */
0906: /* nfds = getdtablesize (); */
0907: nfds = FD_SETSIZE;
0908:
0909: FD_ZERO( &readfds );
0910: FD_SET( fileno( stdin ), &readfds );
0911:
0912: status = select( nfds, &readfds, NULL, NULL, &tv );
0913: if ( status < 0 )
0914: {
0915: perror( "select" );
0916: return ( -1 );
0917: }
0918:
0919: if ( status == 0 )
0920: return ( -1 );
0921: else
0922: return ( 0 );
0923:
0924: } /* wait_for_char */
0925:
0926: static int Agetchar( void )
0927: {
0928: static int holdover = 0;
0929: int c, c1;
0930:
0931: if ( ismint )
0932: {
0933: c = getchar( );
0934: if ( c == 13 )
0935: c = 10;
0936: return c;
0937: }
0938: if ( holdover )
0939: {
0940: c = holdover;
0941: holdover = 0;
0942: return c;
0943: }
0944: reloop:
0945: c1 = Cnecin( );
0946: if ( c1 & 0xff )
0947: return c1 & 0xff;
0948: c = ( ( c1 & 0x00ff0000 ) >> 16 );
0949: switch ( c )
0950: {
0951: case 0x48:
0952: holdover = 'A';
0953: return 27;
0954: case 0x50:
0955: holdover = 'B';
0956: return 27;
0957: case 0x4b:
0958: holdover = 'C';
0959: return 27;
0960: case 0x4d:
0961: holdover = 'D';
0962: return 27;
0963: default:
0964: goto reloop;
0965: }
0966: }
0967:
0968:
0969: static int read_key( )
0970: {
0971: int c;
0972:
0973: c = Agetchar( );
0974:
0975:
0976: if ( c == 127 )
0977: c = '\b';
0978: else if ( c == 13 )
0979: c = 10;
0980:
0981: return ( c );
0982:
0983: } /* read_key */
0984:
0985: static void set_cbreak_mode( mode )
0986: int mode;
0987: {
0988: int status;
0989:
0990: #if defined(BSD)
0991: struct sgttyb new_tty;
0992: static struct sgttyb old_tty;
0993: #endif /* defined(BSD) */
0994: #if defined(SYSTEM_FIVE)
0995: struct termio new_termio;
0996: static struct termio old_termio;
0997: #endif /* defined(SYSTEM_FIVE) */
0998: #if defined(POSIX)
0999: struct termios new_termios;
1000: static struct termios old_termios;
1001: #endif /* defined(POSIX) */
1002:
1003: #if defined(BSD)
1004: status = ioctl( fileno( stdin ), ( mode ) ? TIOCGETP : TIOCSETP, &old_tty );
1005: #endif /* defined(BSD) */
1006: #if defined(SYSTEM_FIVE)
1007: status = ioctl( fileno( stdin ), ( mode ) ? TCGETA : TCSETA, &old_termio );
1008: #endif /* defined(SYSTEM_FIVE) */
1009: #if defined(POSIX)
1010: if ( mode )
1011: status = tcgetattr( fileno( stdin ), &old_termios );
1012: else
1013: status = tcsetattr( fileno( stdin ), TCSANOW, &old_termios );
1014: #endif /* defined(POSIX) */
1015: if ( status && ismint )
1016: {
1017: perror( "ioctl" );
1018: exit( 1 );
1019: }
1020:
1021: if ( mode )
1022: {
1023: signal( SIGINT, rundown );
1024: signal( SIGTERM, rundown );
1025: }
1026:
1027: if ( mode )
1028: {
1029: #if defined(BSD)
1030: status = ioctl( fileno( stdin ), TIOCGETP, &new_tty );
1031: #endif /* defined(BSD) */
1032: #if defined(SYSTEM_FIVE)
1033: status = ioctl( fileno( stdin ), TCGETA, &new_termio );
1034: #endif /* defined(SYSTEM_FIVE) */
1035: #if defined(POSIX)
1036: status = tcgetattr( fileno( stdin ), &new_termios );
1037: #endif /* defined(POSIX) */
1038: if ( status && ismint )
1039: {
1040: perror( "ioctl" );
1041: exit( 1 );
1042: }
1043:
1044: #if defined(BSD)
1045: new_tty.sg_flags |= CBREAK;
1046: new_tty.sg_flags &= ~ECHO;
1047: #endif /* defined(BSD) */
1048: #if defined(SYSTEM_FIVE)
1049: new_termio.c_lflag &= ~( ICANON | ECHO );
1050: #endif /* defined(SYSTEM_FIVE) */
1051: #if defined(POSIX)
1052: new_termios.c_lflag &= ~( ICANON | ECHO );
1053:
1054: /* the next two lines of code added by Mark Phillips. The patch */
1055: /* was for sun and __hpux, active only if those were #defined, */
1056: /* but most POSIX boxen (SunOS, HP-UX, Dec OSF, Irix for sure) */
1057: /* can use this... It makes character input work. VMIN and */
1058: /* VTIME are reused on some systems, so when the mode is switched */
1059: /* to RAW all character access is, by default, buffered wrong. */
1060: /* For the curious: VMIN='\004' and VTIME='\005' octal on */
1061: /* these systems. VMIN is usually EOF and VTIME is EOL. (JDH) */
1062: new_termios.c_cc[VMIN] = 1;
1063: new_termios.c_cc[VTIME] = 2;
1064: #endif /* defined(POSIX) */
1065:
1066: #if defined(BSD)
1067: status = ioctl( fileno( stdin ), TIOCSETP, &new_tty );
1068: #endif /* defined(BSD) */
1069: #if defined(SYSTEM_FIVE)
1070: status = ioctl( fileno( stdin ), TCSETA, &new_termio );
1071: #endif /* defined(SYSTEM_FIVE) */
1072: #if defined(POSIX)
1073: status = tcsetattr( fileno( stdin ), TCSANOW, &new_termios );
1074: #endif /* defined(POSIX) */
1075: if ( status && ismint )
1076: {
1077: perror( "ioctl" );
1078: exit( 1 );
1079: }
1080: }
1081:
1082: if ( mode == 0 )
1083: {
1084: signal( SIGINT, SIG_DFL );
1085: signal( SIGTERM, SIG_DFL );
1086: }
1087:
1088: } /* set_cbreak_mode */
1089:
1090: static void rundown( )
1091: {
1092: unload_cache( );
1093: close_story( );
1094: close_script( );
1095: reset_screen( );
1096: } /* rundown */
1097:
1098:
1099:
1100:
1101:
1102:
1103:
1104:
1105:
1106:
1107: /*
1108: * codes_to_text
1109: *
1110: * Translate Z-code characters to machine specific characters. These characters
1111: * include line drawing characters and international characters.
1112: *
1113: * The routine takes one of the Z-code characters from the following table and
1114: * writes the machine specific text replacement. The target replacement buffer
1115: * is defined by MAX_TEXT_SIZE in ztypes.h. The replacement text should be in a
1116: * normal C, zero terminated, string.
1117: *
1118: * Return 0 if a translation was available, otherwise 1.
1119: *
1120: * Arrow characters (0x18 - 0x1b):
1121: *
1122: * 0x18 Up arrow
1123: * 0x19 Down arrow
1124: * 0x1a Right arrow
1125: * 0x1b Left arrow
1126: *
1127: * International characters (0x9b - 0xa3):
1128: *
1129: * 0x9b a umlaut (ae)
1130: * 0x9c o umlaut (oe)
1131: * 0x9d u umlaut (ue)
1132: * 0x9e A umlaut (Ae)
1133: * 0x9f O umlaut (Oe)
1134: * 0xa0 U umlaut (Ue)
1135: * 0xa1 sz (ss)
1136: * 0xa2 open quote (>>)
1137: * 0xa3 close quota (<<)
1138: *
1139: * Line drawing characters (0xb3 - 0xda):
1140: *
1141: * 0xb3 vertical line (|)
1142: * 0xba double vertical line (#)
1143: * 0xc4 horizontal line (-)
1144: * 0xcd double horizontal line (=)
1145: * all other are corner pieces (+)
1146: *
1147: */
1148:
1149: int codes_to_text( int c, char *s )
1150: {
1151: return 1;
1152: } /* codes_to_text */