|
|
1.1.1.2 ! root 1: /* $Id: cterm.c,v 1.135 2011/09/09 23:59:13 deuce Exp $ */ 1.1 root 2: 3: /**************************************************************************** 4: * @format.tab-size 4 (Plain Text/Source Code File Header) * 5: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * 6: * * 7: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * 8: * * 9: * This library is free software; you can redistribute it and/or * 10: * modify it under the terms of the GNU Lesser General Public License * 11: * as published by the Free Software Foundation; either version 2 * 12: * of the License, or (at your option) any later version. * 13: * See the GNU Lesser General Public License for more details: lgpl.txt or * 14: * http://www.fsf.org/copyleft/lesser.html * 15: * * 16: * Anonymous FTP access to the most recent released source is available at * 17: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * 18: * * 19: * Anonymous CVS access to the development source and modification history * 20: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * 21: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * 22: * (just hit return, no password is necessary) * 23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * 24: * * 25: * For Synchronet coding style and modification guidelines, see * 26: * http://www.synchro.net/source.html * 27: * * 28: * You are encouraged to submit any modifications (preferably in Unix diff * 29: * format) via e-mail to [email protected] * 30: * * 31: * Note: If this box doesn't appear square, then you need to fix your tabs. * 32: ****************************************************************************/ 33: 34: #include <ctype.h> 35: #include <stdlib.h> 36: #include <string.h> 37: #if defined(_WIN32) 38: #include <malloc.h> /* alloca() on Win32 */ 39: #endif 40: 41: #include <genwrap.h> 42: #include <xpbeep.h> 43: #include <link_list.h> 44: #ifdef __unix__ 45: #include <xpsem.h> 46: #endif 47: #include <threadwrap.h> 48: 49: #if (defined CIOLIB_IMPORTS) 50: #undef CIOLIB_IMPORTS 51: #endif 52: #if (defined CIOLIB_EXPORTS) 53: #undef CIOLIB_EXPORTS 54: #endif 55: 56: #include "ciolib.h" 57: #include "keys.h" 58: 59: #include "cterm.h" 60: #include "allfonts.h" 61: 62: #define BUFSIZE 2048 63: 1.1.1.2 ! root 64: const int cterm_tabs[]={1,9,17,25,33,41,49,57,65,73,81,89,97,105,113,121,129,137,145}; 1.1 root 65: 66: const char *octave="C#D#EF#G#A#B"; 67: 68: /* Characters allowed in music strings... if one that is NOT in here is 69: * found, CTerm leaves music capture mode and tosses the buffer away */ 70: const char *musicchars="aAbBcCdDeEfFgGlLmMnNoOpPsStT0123456789.-+#<> "; 71: const uint note_frequency[]={ /* Hz*1000 */ 72: /* Octave 0 (Note 1) */ 73: 65406 74: ,69296 75: ,73416 76: ,77782 77: ,82407 78: ,87307 79: ,92499 80: ,97999 81: ,103820 82: ,110000 83: ,116540 84: ,123470 85: /* Octave 1 */ 86: ,130810 87: ,138590 88: ,146830 89: ,155560 90: ,164810 91: ,174610 92: ,185000 93: ,196000 94: ,207650 95: ,220000 96: ,233080 97: ,246940 98: /* Octave 2 */ 99: ,261620 100: ,277180 101: ,293660 102: ,311130 103: ,329630 104: ,349230 105: ,369990 106: ,392000 107: ,415300 108: ,440000 109: ,466160 110: ,493880 111: /* Octave 3 */ 112: ,523250 113: ,554370 114: ,587330 115: ,622250 116: ,659260 117: ,698460 118: ,739990 119: ,783990 120: ,830610 121: ,880000 122: ,932330 123: ,987770 124: /* Octave 4 */ 125: ,1046500 126: ,1108700 127: ,1174700 128: ,1244500 129: ,1318500 130: ,1396900 131: ,1480000 132: ,1568000 133: ,1661200 134: ,1760000 135: ,1864600 136: ,1975500 137: /* Octave 5 */ 138: ,2093000 139: ,2217500 140: ,2349300 141: ,2489000 142: ,2637000 143: ,2793800 144: ,2959900 145: ,3136000 146: ,3322400 147: ,3520000 148: ,3729300 149: ,3951100 150: /* Octave 6 */ 151: ,4186000 152: ,4435000 153: ,4698600 154: ,4978000 155: ,5274000 156: ,5587000 157: ,5920000 158: ,6272000 159: ,6644000 160: ,7040000 161: ,7458600 162: ,7902200 163: }; 164: 165: struct note_params { 166: int notenum; 167: int notelen; 168: int dotted; 169: int tempo; 170: int noteshape; 171: int foreground; 172: }; 173: 1.1.1.2 ! root 174: #ifdef CTERM_WITHOUT_CONIO ! 175: #define GOTOXY(x,y) cterm->ciolib_gotoxy(cterm, x, y) ! 176: #define WHEREX() cterm->ciolib_wherex(cterm) ! 177: #define WHEREY() cterm->ciolib_wherey(cterm) ! 178: #define GETTEXT(a,b,c,d,e) cterm->ciolib_gettext(cterm, a,b,c,d,e) ! 179: #define GETTEXTINFO(a) cterm->ciolib_gettextinfo(cterm,a) ! 180: #define TEXTATTR(a) cterm->ciolib_textattr(cterm,a) ! 181: #define SETCURSORTYPE(a) cterm->ciolib_setcursortype(cterm,a) ! 182: #define MOVETEXT(a,b,c,d,e,f) cterm->ciolib_movetext(cterm,a,b,c,d,e,f) ! 183: #define CLREOL() cterm->ciolib_clreol(cterm) ! 184: #define CLRSCR() cterm->ciolib_clrscr(cterm) ! 185: #define SETVIDEOFLAGS(a) cterm->ciolib_setvideoflags(cterm,a) ! 186: #define GETVIDEOFLAGS() cterm->ciolib_getvideoflags(cterm) ! 187: #define PUTCH(a) cterm->ciolib_putch(cterm,a) ! 188: #define PUTTEXT(a,b,c,d,e) cterm->ciolib_puttext(cterm,a,b,c,d,e) ! 189: #define WINDOW(a,b,c,d) cterm->ciolib_window(cterm,a,b,c,d) ! 190: #define CPUTS(a) cterm->ciolib_cputs(cterm,a) ! 191: #define SETFONT(a,b,c) cterm->ciolib_setfont(cterm,a,b,c) ! 192: #else ! 193: #define GOTOXY(x,y) cterm->ciolib_gotoxy(x, y) ! 194: #define WHEREX() cterm->ciolib_wherex() ! 195: #define WHEREY() cterm->ciolib_wherey() ! 196: #define GETTEXT(a,b,c,d,e) cterm->ciolib_gettext(a,b,c,d,e) ! 197: #define GETTEXTINFO(a) cterm->ciolib_gettextinfo(a) ! 198: #define TEXTATTR(a) cterm->ciolib_textattr(a) ! 199: #define SETCURSORTYPE(a) cterm->ciolib_setcursortype(a) ! 200: #define MOVETEXT(a,b,c,d,e,f) cterm->ciolib_movetext(a,b,c,d,e,f) ! 201: #define CLREOL() cterm->ciolib_clreol() ! 202: #define CLRSCR() cterm->ciolib_clrscr() ! 203: #define SETVIDEOFLAGS(a) cterm->ciolib_setvideoflags(a) ! 204: #define GETVIDEOFLAGS() cterm->ciolib_getvideoflags() ! 205: #define PUTCH(a) cterm->ciolib_putch(a) ! 206: #define PUTTEXT(a,b,c,d,e) cterm->ciolib_puttext(a,b,c,d,e) ! 207: #define WINDOW(a,b,c,d) cterm->ciolib_window(a,b,c,d) ! 208: #define CPUTS(a) cterm->ciolib_cputs(a) ! 209: #define SETFONT(a,b,c) cterm->ciolib_setfont(a,b,c) ! 210: #endif ! 211: ! 212: #ifdef CTERM_WITHOUT_CONIO ! 213: /***************************************************************/ ! 214: /* These funcions are used when conio is not */ ! 215: /* They are mostly copied from either ciolib.c or bitmap_con.c */ ! 216: /***************************************************************/ ! 217: #define BD ((struct buffer_data *)cterm->extra) ! 218: #define CTERM_INIT() while(BD==NULL) ciolib_init(cterm) ! 219: ! 220: struct buffer_data { ! 221: unsigned char x; ! 222: unsigned char y; ! 223: unsigned char winleft; /* left window coordinate */ ! 224: unsigned char wintop; /* top window coordinate */ ! 225: unsigned char winright; /* right window coordinate */ ! 226: unsigned char winbottom; /* bottom window coordinate */ ! 227: unsigned char attr; /* text attribute */ ! 228: unsigned char currmode; /* current video mode */ ! 229: unsigned char cursor; ! 230: unsigned char *vmem; ! 231: int vflags; ! 232: }; ! 233: ! 234: static void ciolib_init(struct cterminal *cterm) ! 235: { ! 236: BD=malloc(sizeof(struct buffer_data)); ! 237: if(!BD) ! 238: return ! 239: BD->x=1; ! 240: BD->y=1; ! 241: BD->winleft=1; ! 242: BD->wintop=1; ! 243: BD->winright=cterm->width; ! 244: BD->winbottom=cterm->height; ! 245: BD->attr=7; ! 246: BD->currmode=C80; // TODO: Adjust based on size... ! 247: BD->cursor=_NORMALCURSOR; ! 248: BD->vmem=malloc(2*cterm->height*cterm->width); ! 249: if(BD->vmem==NULL) { ! 250: free(BD) ! 251: return; ! 252: } ! 253: BD->vflags=0; ! 254: } ! 255: ! 256: static void ciolib_gotoxy(struct cterminal *cterm,int x,int y) ! 257: { ! 258: CTERM_INIT(); ! 259: ! 260: if(x < 1 ! 261: || x > BD->winright-BD->winleft+1 ! 262: || y < 1 ! 263: || y > BD->winbottom-BD->wintop+1) ! 264: return; ! 265: ! 266: BD->x=x; ! 267: BD->y=y; ! 268: } ! 269: ! 270: static int ciolib_wherex(struct cterminal *cterm) ! 271: { ! 272: CTERM_INIT(); ! 273: return BD->x ! 274: } ! 275: ! 276: static int ciolib_wherey(struct cterminal *cterm) ! 277: { ! 278: CTERM_INIT(); ! 279: return BD->y ! 280: } ! 281: ! 282: static int ciolib_gettext(struct cterminal *cterm,int sx, int sy, int ex, int ey, void *fill) ! 283: { ! 284: int x,y; ! 285: unsigned char *out; ! 286: WORD sch; ! 287: ! 288: CTERM_INIT(); ! 289: if( sx < 1 ! 290: || sy < 1 ! 291: || ex < 1 ! 292: || ey < 1 ! 293: || sx > ex ! 294: || sy > ey ! 295: || ex > cterm->width ! 296: || ey > cterm->height ! 297: || fill==NULL) ! 298: return(0); ! 299: ! 300: out=fill; ! 301: for(y=sy-1;y<ey;y++) { ! 302: for(x=sx-1;x<ex;x++) { ! 303: sch=BD->vmem[y*cio_textinfo.screenwidth+x]; ! 304: *(out++)=sch & 0xff; ! 305: *(out++)=sch >> 8; ! 306: } ! 307: } ! 308: return(1); ! 309: } ! 310: ! 311: static void ciolib_gettextinfo(struct cterminal *cterm,struct text_info *ti) ! 312: { ! 313: CTERM_INIT(); ! 314: ti->winleft=>BD->winleft; ! 315: ti->wintop=BD->wintop; ! 316: ti->winright=BD->winright; ! 317: ti->winbottom=BD->winbottom; ! 318: ti->attribute=BD->attr; ! 319: ti->normattr=7; ! 320: ti->currmode=BD->currmode; ! 321: ti->screenheight=cterm->height; ! 322: ti->screenwidth=cterm->width; ! 323: ti->curx=BD->x; ! 324: ti->cury=BD->y; ! 325: } ! 326: ! 327: static void ciolib_textattr(struct cterminal *cterm,int attr) ! 328: { ! 329: CTERM_INIT(); ! 330: BD->attr=attr; ! 331: } ! 332: ! 333: static void ciolib_setcursortype(struct cterminal *cterm,int cursor) ! 334: { ! 335: CTERM_INIT(); ! 336: BD->cursor=cursor; ! 337: } ! 338: ! 339: static int ciolib_movetext(struct cterminal *cterm, int x, int y, int ex, int ey, int tox, int toy) ! 340: { ! 341: int direction=1; ! 342: int cy; ! 343: int sy; ! 344: int destoffset; ! 345: int sourcepos; ! 346: int width=ex-x+1; ! 347: int height=ey-y+1; ! 348: ! 349: CTERM_INIT(); ! 350: if( x<1 ! 351: || y<1 ! 352: || ex<1 ! 353: || ey<1 ! 354: || tox<1 ! 355: || toy<1 ! 356: || x>cterm->width ! 357: || ex>cterm->width ! 358: || tox>cterm->width ! 359: || y>cterm->height ! 360: || ey>cterm->height ! 361: || toy>cterm->height) ! 362: return(0); ! 363: ! 364: if(toy > y) ! 365: direction=-1; ! 366: ! 367: sourcepos=(y-1)*cterm->width+(x-1); ! 368: destoffset=(((toy-1)*cterm->width+(tox-1))-sourcepos); ! 369: ! 370: for(cy=(direction==-1?(height-1):0); cy<height && cy>=0; cy+=direction) { ! 371: sourcepos=((y-1)+cy)*cio_textinfo.screenwidth+(x-1); ! 372: memmove(&(BD->vmem[sourcepos+destoffset]), &(BD->vmem[sourcepos]), sizeof(BD->vmem[0])*width); ! 373: } ! 374: return(1); ! 375: } ! 376: ! 377: static void conio_clreol(struct cterminal *cterm) ! 378: { ! 379: int pos,x; ! 380: WORD fill=(BD->attr<<8)|space; ! 381: ! 382: CTERM_INIT(); ! 383: pos=(BD->y+BD->wintop-2)*cterm->width; ! 384: for(x=BD->x+BD->winleft-2; x<BD->right; x++) ! 385: BD->vmem[pos+x]=fill; ! 386: } ! 387: ! 388: static void ciolib_clrscr(struct cterminal *cterm) ! 389: { ! 390: int x,y; ! 391: WORD fill=(BD->attr<<8)|space; ! 392: ! 393: CTERM_INIT(); ! 394: for(y=cio_textinfo.wintop-1; y<cio_textinfo.winbottom; y++) { ! 395: for(x=BD->winleft-1; x<BD->winright; x++) ! 396: BD->vmem[y*cterm->width+x]=fill; ! 397: } ! 398: } ! 399: ! 400: static void ciolib_setvideoflags(struct cterminal *cterm, int flags) ! 401: { ! 402: CTERM_INIT(); ! 403: BD->vflags=flags; ! 404: } ! 405: ! 406: static int ciolib_getvideoflags(struct cterminal *cterm) ! 407: { ! 408: CTERM_INIT(); ! 409: return BD->vflags; ! 410: } ! 411: ! 412: static void ciolib_wscroll(struct cterminal *cterm) ! 413: { ! 414: int os; ! 415: ! 416: CTERM_INIT(); ! 417: MOVETEXT(BD->winleft ! 418: ,BD->wintop+1 ! 419: ,BD->winright ! 420: ,BD->winbottom ! 421: ,BD->winleft ! 422: ,BD->wintop); ! 423: GOTOXY(cterm, 1,BD->winbottom-BD->wintop+1); ! 424: os=_wscroll; ! 425: _wscroll=0; ! 426: CLREOL(cterm); ! 427: _wscroll=os; ! 428: GOTOXY(cterm, BD->x,BD->y); ! 429: } ! 430: ! 431: static int ciolib_putch(struct cterminal *cterm,int a) ! 432: { ! 433: unsigned char a1=a; ! 434: unsigned char buf[2]; ! 435: int i; ! 436: ! 437: CTERM_INIT(); ! 438: buf[0]=a1; ! 439: buf[1]=BD->attr; ! 440: ! 441: switch(a1) { ! 442: case '\r': ! 443: GOTOXY(1,cio_textinfo.cury); ! 444: break; ! 445: case '\n': ! 446: if(BD->y==BD->winbottom-BD->wintop+1) ! 447: ciolib_wscroll(cterm); ! 448: else ! 449: GOTOXY(BD->x, BD->y+1); ! 450: break; ! 451: case '\b': ! 452: if(BD->x>1) { ! 453: GOTOXY(BD->x-1,BD->y); ! 454: buf[0]=' '; ! 455: PUTTEXT(BD->x+BD->winleft-1 ! 456: ,BD->y+BD->wintop-1 ! 457: ,BD->x+BD->winleft-1 ! 458: ,BD->y+BD->wintop-1 ! 459: ,buf); ! 460: } ! 461: break; ! 462: case 7: /* Bell */ ! 463: break; ! 464: case '\t': ! 465: for(i=0;i<(sizeof(cterm_tabs)/sizeof(int));i++) { ! 466: if(cterm_tabs[i]>BD->x) { ! 467: buf[0]=' '; ! 468: while(BD->x<cterm_tabs[i]) { ! 469: PUTTEXT(BD->x+BD->winleft-1 ! 470: ,BD->y+BD->wintop-1 ! 471: ,BD->x+BD->winleft-1 ! 472: ,BD->y+BD->wintop-1 ! 473: ,buf); ! 474: GOTOXY(BD->x+1,BD->y); ! 475: if(BD->x==cterm->width) ! 476: break; ! 477: } ! 478: break; ! 479: } ! 480: } ! 481: if(BD->x==cterm->width) { ! 482: GOTOXY(1,BD->y); ! 483: if(BD->y==BD->winbottom-BD->wintop+1) ! 484: ciolib_wscroll(cterm); ! 485: else ! 486: GOTOXY(BD->x, BD->y+1); ! 487: } ! 488: break; ! 489: default: ! 490: if(BD->y==BD->winbottom-BD->wintop+1 ! 491: && BD->x==BD->winright-BD->winleft+1) { ! 492: PUTTEXT(WHEREX()+BD->winleft-1 ! 493: ,WHEREY()+BD->wintop-1 ! 494: ,WHEREX()+BD->winleft-1 ! 495: ,WHEREY()+BD->wintop-1 ! 496: ,buf); ! 497: ciolib_wscroll(cterm); ! 498: GOTOXY(1, BD->winbottom-BD->wintop+1); ! 499: } ! 500: else { ! 501: if(BD->x==BD->winright-BD->winleft+1) { ! 502: PUTTEXT(WHEREX()+BD->winleft-1 ! 503: ,WHEREY()+BD->wintop-1 ! 504: ,WHEREX()+BD->winleft-1 ! 505: ,WHEREY()+BD->wintop-1 ! 506: ,buf); ! 507: GOTOXY(1,BD->y+1); ! 508: } ! 509: else { ! 510: PUTTEXT(WHEREX()+BD->winleft-1 ! 511: ,WHEREY()+BD->wintop-1 ! 512: ,WHEREX()+BD->winleft-1 ! 513: ,WHEREY()+BD->wintop-1 ! 514: ,buf); ! 515: GOTOXY(BD->x+1, BD->y); ! 516: } ! 517: } ! 518: break; ! 519: } ! 520: ! 521: return(a1); ! 522: } ! 523: ! 524: static int ciolib_puttext(struct cterminal *cterm,int sx, int sy, int ex, int ey, void *fill) ! 525: { ! 526: int x,y; ! 527: unsigned char *out; ! 528: WORD sch; ! 529: ! 530: CTERM_INIT(); ! 531: if( sx < 1 ! 532: || sy < 1 ! 533: || ex < 1 ! 534: || ey < 1 ! 535: || sx > cterm->width ! 536: || sy > cterm->height ! 537: || sx > ex ! 538: || sy > ey ! 539: || ex > cterm->width ! 540: || ey > cterm->height ! 541: || fill==NULL) ! 542: return(0); ! 543: ! 544: out=fill; ! 545: for(y=sy-1;y<ey;y++) { ! 546: for(x=sx-1;x<ex;x++) { ! 547: sch=*(out++); ! 548: sch |= (*(out++))<<8; ! 549: BD->vmem[y*cterm->width+x]=sch; ! 550: } ! 551: } ! 552: return(1); ! 553: } ! 554: ! 555: static void ciolib_window(struct cterminal *cterm,int sx, int sy, int ex, int ey) ! 556: { ! 557: CTERM_INIT(); ! 558: if( sx < 1 ! 559: || sy < 1 ! 560: || ex < 1 ! 561: || ey < 1 ! 562: || sx > cterm->width ! 563: || sy > cterm->height ! 564: || sx > ex ! 565: || sy > ey ! 566: || ex > cterm->width ! 567: || ey > cterm->height) ! 568: return; ! 569: BD->winleft=sx; ! 570: BD->wintop=sy; ! 571: BD->winright=ex; ! 572: BD->winbottom=ey; ! 573: GOTOXY(1,1); ! 574: } ! 575: ! 576: static int ciolib_cputs(struct cterminal *cterm, char *str) ! 577: { ! 578: int pos; ! 579: int ret=0; ! 580: int olddmc; ! 581: ! 582: CTERM_INIT(); ! 583: for(pos=0;str[pos];pos++) ! 584: { ! 585: ret=str[pos]; ! 586: if(str[pos]=='\n') ! 587: PUTCH('\r'); ! 588: PUTCH(str[pos]); ! 589: } ! 590: GOTOXY(WHEREX(),WHEREY()); ! 591: return(ret); ! 592: } ! 593: ! 594: static int ciolib_setfont(struct cterminal *,int font, int force, int font_num) ! 595: { ! 596: CTERM_INIT(); ! 597: return -1; ! 598: } ! 599: #endif 1.1 root 600: 1.1.1.2 ! root 601: static void playnote_thread(void *args) 1.1 root 602: { 603: /* Tempo is quarter notes per minute */ 604: int duration; 605: int pauselen; 606: struct note_params *note; 607: int device_open=FALSE; 1.1.1.2 ! root 608: struct cterminal *cterm=(struct cterminal *)args; ! 609: 1.1 root 610: 1.1.1.2 ! root 611: cterm->playnote_thread_running=TRUE; 1.1 root 612: while(1) { 613: if(device_open) { 1.1.1.2 ! root 614: if(!listSemTryWaitBlock(&cterm->notes,5000)) { 1.1 root 615: xptone_close(); 616: device_open=FALSE; 1.1.1.2 ! root 617: listSemWait(&cterm->notes); 1.1 root 618: } 619: } 620: else 1.1.1.2 ! root 621: listSemWait(&cterm->notes); ! 622: device_open=xptone_open(); ! 623: note=listShiftNode(&cterm->notes); 1.1 root 624: if(note==NULL) 625: break; 626: if(note->dotted) 627: duration=360000/note->tempo; 628: else 629: duration=240000/note->tempo; 630: duration/=note->notelen; 631: switch(note->noteshape) { 632: case CTERM_MUSIC_STACATTO: 633: pauselen=duration/4; 634: break; 635: case CTERM_MUSIC_LEGATO: 636: pauselen=0; 637: break; 638: case CTERM_MUSIC_NORMAL: 639: default: 640: pauselen=duration/8; 641: break; 642: } 643: duration-=pauselen; 1.1.1.2 ! root 644: if(note->notenum < 72 && note->notenum >= 0) { ! 645: if(device_open) ! 646: xptone(((double)note_frequency[note->notenum])/1000,duration,WAVE_SHAPE_SINE_SAW_HARM); ! 647: else ! 648: xpbeep(((double)note_frequency[note->notenum])/1000,duration); ! 649: } 1.1 root 650: else 651: SLEEP(duration); 652: SLEEP(pauselen); 653: if(note->foreground) 1.1.1.2 ! root 654: sem_post(&cterm->note_completed_sem); 1.1 root 655: free(note); 656: } 1.1.1.2 ! root 657: cterm->playnote_thread_running=FALSE; ! 658: sem_post(&cterm->playnote_thread_terminated); 1.1 root 659: } 660: 1.1.1.2 ! root 661: static void play_music(struct cterminal *cterm) 1.1 root 662: { 663: int i; 664: char *p; 665: char *out; 666: int offset; 667: char note; 668: int notelen; 669: char numbuf[10]; 670: int dotted; 671: int notenum; 672: struct note_params *np; 673: int fore_count; 674: 1.1.1.2 ! root 675: if(cterm->quiet) { ! 676: cterm->music=0; ! 677: cterm->musicbuf[0]=0; ! 678: return; ! 679: } ! 680: p=cterm->musicbuf; 1.1 root 681: fore_count=0; 1.1.1.2 ! root 682: if(cterm->music==1) { 1.1 root 683: switch(toupper(*p)) { 684: case 'F': 1.1.1.2 ! root 685: cterm->musicfore=TRUE; 1.1 root 686: p++; 687: break; 688: case 'B': 1.1.1.2 ! root 689: cterm->musicfore=FALSE; 1.1 root 690: p++; 691: break; 692: case 'N': 693: if(!isdigit(*(p+1))) { 1.1.1.2 ! root 694: cterm->noteshape=CTERM_MUSIC_NORMAL; 1.1 root 695: p++; 696: } 697: break; 698: case 'L': 1.1.1.2 ! root 699: cterm->noteshape=CTERM_MUSIC_LEGATO; 1.1 root 700: p++; 701: break; 702: case 'S': 1.1.1.2 ! root 703: cterm->noteshape=CTERM_MUSIC_STACATTO; 1.1 root 704: p++; 705: break; 706: } 707: } 708: for(;*p;p++) { 709: notenum=0; 710: offset=0; 711: switch(toupper(*p)) { 712: case 'M': 713: p++; 714: switch(toupper(*p)) { 715: case 'F': 1.1.1.2 ! root 716: cterm->musicfore=TRUE; 1.1 root 717: break; 718: case 'B': 1.1.1.2 ! root 719: cterm->musicfore=FALSE; 1.1 root 720: break; 721: case 'N': 1.1.1.2 ! root 722: cterm->noteshape=CTERM_MUSIC_NORMAL; 1.1 root 723: break; 724: case 'L': 1.1.1.2 ! root 725: cterm->noteshape=CTERM_MUSIC_LEGATO; 1.1 root 726: break; 727: case 'S': 1.1.1.2 ! root 728: cterm->noteshape=CTERM_MUSIC_STACATTO; 1.1 root 729: break; 730: default: 731: p--; 732: } 733: break; 734: case 'T': /* Tempo */ 735: out=numbuf; 736: while(isdigit(*(p+1))) 737: *(out++)=*(++p); 738: *out=0; 1.1.1.2 ! root 739: cterm->tempo=strtoul(numbuf,NULL,10); ! 740: if(cterm->tempo>255) ! 741: cterm->tempo=255; ! 742: if(cterm->tempo<32) ! 743: cterm->tempo=32; 1.1 root 744: break; 745: case 'O': /* Octave */ 746: out=numbuf; 747: while(isdigit(*(p+1))) 748: *(out++)=*(++p); 749: *out=0; 1.1.1.2 ! root 750: cterm->octave=strtoul(numbuf,NULL,10); ! 751: if(cterm->octave>6) ! 752: cterm->octave=6; 1.1 root 753: break; 754: case 'L': 755: out=numbuf; 756: while(isdigit(*(p+1))) 757: *(out++)=*(++p); 758: *out=0; 1.1.1.2 ! root 759: cterm->notelen=strtoul(numbuf,NULL,10); ! 760: if(cterm->notelen<1) ! 761: cterm->notelen=1; ! 762: if(cterm->notelen>64) ! 763: cterm->notelen=64; 1.1 root 764: break; 765: case 'N': /* Note by number */ 766: if(isdigit(*(p+1))) { 767: out=numbuf; 768: while(isdigit(*(p+1))) { 769: *(out++)=*(p+1); 770: p++; 771: } 772: *out=0; 1.1.1.2 ! root 773: notenum=strtoul(numbuf,NULL,10); 1.1 root 774: } 775: if(notenum==0) { 776: notenum=-1; 777: offset=1; 778: } 779: /* Fall-through */ 780: case 'A': /* Notes in current octave by letter */ 781: case 'B': 782: case 'C': 783: case 'D': 784: case 'E': 785: case 'F': 786: case 'G': 787: case 'P': 788: note=toupper(*p); 1.1.1.2 ! root 789: notelen=cterm->notelen; 1.1 root 790: dotted=0; 791: i=1; 792: while(i) { 793: i=0; 794: if(*(p+1)=='+' || *(p+1)=='#') { /* SHARP */ 795: offset+=1; 796: p++; 797: i=1; 798: } 799: if(*(p+1)=='-') { /* FLAT */ 800: offset-=1; 801: p++; 802: i=1; 803: } 804: if(*(p+1)=='.') { /* Dotted note (1.5*notelen) */ 805: dotted=1; 806: p++; 807: i=1; 808: } 809: if(isdigit(*(p+1))) { 810: out=numbuf; 811: while(isdigit(*(p+1))) { 812: *(out++)=*(p+1); 813: p++; 814: } 815: *out=0; 1.1.1.2 ! root 816: notelen=strtoul(numbuf,NULL,10); 1.1 root 817: i=1; 818: } 819: } 820: if(note=='P') { 821: notenum=-1; 822: offset=0; 823: } 824: if(notenum==0) { 825: out=strchr(octave,note); 826: if(out==NULL) { 827: notenum=-1; 828: offset=1; 829: } 830: else { 1.1.1.2 ! root 831: notenum=cterm->octave*12+1; 1.1 root 832: notenum+=(out-octave); 833: } 834: } 835: notenum+=offset; 836: np=(struct note_params *)malloc(sizeof(struct note_params)); 837: if(np!=NULL) { 838: np->notenum=notenum; 839: np->notelen=notelen; 840: np->dotted=dotted; 1.1.1.2 ! root 841: np->tempo=cterm->tempo; ! 842: np->noteshape=cterm->noteshape; ! 843: np->foreground=cterm->musicfore; ! 844: listPushNode(&cterm->notes, np); ! 845: if(cterm->musicfore) 1.1 root 846: fore_count++; 847: } 848: break; 849: case '<': /* Down one octave */ 1.1.1.2 ! root 850: cterm->octave--; ! 851: if(cterm->octave<0) ! 852: cterm->octave=0; 1.1 root 853: break; 854: case '>': /* Up one octave */ 1.1.1.2 ! root 855: cterm->octave++; ! 856: if(cterm->octave>6) ! 857: cterm->octave=6; 1.1 root 858: break; 859: } 860: } 1.1.1.2 ! root 861: cterm->music=0; ! 862: cterm->musicbuf[0]=0; 1.1 root 863: while(fore_count) { 1.1.1.2 ! root 864: sem_wait(&cterm->note_completed_sem); 1.1 root 865: fore_count--; 866: } 867: } 868: 1.1.1.2 ! root 869: static void scrolldown(struct cterminal *cterm) 1.1 root 870: { 1.1.1.2 ! root 871: int x,y; 1.1 root 872: 1.1.1.2 ! root 873: MOVETEXT(cterm->x,cterm->y,cterm->x+cterm->width-1,cterm->y+cterm->height-2,cterm->x,cterm->y+1); ! 874: x=WHEREX(); ! 875: y=WHEREY(); ! 876: GOTOXY(1,1); ! 877: CLREOL(); ! 878: GOTOXY(x,y); 1.1 root 879: } 880: 1.1.1.2 ! root 881: static void scrollup(struct cterminal *cterm) 1.1 root 882: { 1.1.1.2 ! root 883: int x,y; 1.1 root 884: 1.1.1.2 ! root 885: cterm->backpos++; ! 886: if(cterm->scrollback!=NULL) { ! 887: if(cterm->backpos>cterm->backlines) { ! 888: memmove(cterm->scrollback,cterm->scrollback+cterm->width*2,cterm->width*2*(cterm->backlines-1)); ! 889: cterm->backpos--; 1.1 root 890: } 1.1.1.2 ! root 891: GETTEXT(cterm->x, cterm->y, cterm->x+cterm->width-1, cterm->y, cterm->scrollback+(cterm->backpos-1)*cterm->width*2); 1.1 root 892: } 1.1.1.2 ! root 893: MOVETEXT(cterm->x,cterm->y+1,cterm->x+cterm->width-1,cterm->y+cterm->height-1,cterm->x,cterm->y); ! 894: x=WHEREX(); ! 895: y=WHEREY(); ! 896: GOTOXY(1,cterm->height); ! 897: CLREOL(); ! 898: GOTOXY(x,y); 1.1 root 899: } 900: 1.1.1.2 ! root 901: static void dellines(struct cterminal * cterm, int lines) 1.1 root 902: { 1.1.1.2 ! root 903: int i; 1.1 root 904: int linestomove; 1.1.1.2 ! root 905: int x,y; 1.1 root 906: 907: if(lines<1) 908: return; 1.1.1.2 ! root 909: linestomove=cterm->height-WHEREY(); ! 910: MOVETEXT(cterm->x,cterm->y+WHEREY()-1+lines,cterm->x+cterm->width-1,cterm->y+cterm->height-1,cterm->x,cterm->y+WHEREY()-1); ! 911: x=WHEREX(); ! 912: y=WHEREY(); ! 913: for(i=cterm->height-lines+1; i<=cterm->height; i++) { ! 914: GOTOXY(1,i); ! 915: CLREOL(); 1.1 root 916: } 1.1.1.2 ! root 917: GOTOXY(x,y); 1.1 root 918: } 919: 1.1.1.2 ! root 920: static void clear2bol(struct cterminal * cterm) 1.1 root 921: { 922: char *buf; 923: int i,j,k; 924: 1.1.1.2 ! root 925: k=WHEREX(); 1.1 root 926: buf=(char *)alloca(k*2); 927: j=0; 928: for(i=0;i<k;i++) { 1.1.1.2 ! root 929: if(cterm->emulation == CTERM_EMULATION_ATASCII) ! 930: buf[j++]=0; ! 931: else ! 932: buf[j++]=' '; ! 933: buf[j++]=cterm->attr; 1.1 root 934: } 1.1.1.2 ! root 935: PUTTEXT(cterm->x,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,buf); 1.1 root 936: } 937: 1.1.1.2 ! root 938: void cterm_clearscreen(struct cterminal *cterm, char attr) 1.1 root 939: { 1.1.1.2 ! root 940: if(!cterm->started) ! 941: cterm_start(cterm); 1.1 root 942: 1.1.1.2 ! root 943: if(cterm->scrollback!=NULL) { ! 944: cterm->backpos+=cterm->height; ! 945: if(cterm->backpos>cterm->backlines) { ! 946: memmove(cterm->scrollback,cterm->scrollback+cterm->width*2*(cterm->backpos-cterm->backlines),cterm->width*2*(cterm->backlines-(cterm->backpos-cterm->backlines))); ! 947: cterm->backpos=cterm->backlines; 1.1 root 948: } 1.1.1.2 ! root 949: GETTEXT(cterm->x,cterm->y,cterm->x+cterm->width-1,cterm->y+cterm->height-1,cterm->scrollback+(cterm->backpos-cterm->height)*cterm->width*2); 1.1 root 950: } 1.1.1.2 ! root 951: CLRSCR(); ! 952: GOTOXY(1,1); 1.1 root 953: } 954: 1.1.1.2 ! root 955: static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *speed) 1.1 root 956: { 957: char *p; 958: char *p2; 959: char tmp[1024]; 960: int i,j,k,l; 961: int row,col; 1.1.1.2 ! root 962: struct text_info ti; 1.1 root 963: 1.1.1.2 ! root 964: switch(cterm->escbuf[0]) { 1.1 root 965: case '[': 966: /* ANSI stuff */ 1.1.1.2 ! root 967: p=cterm->escbuf+strlen(cterm->escbuf)-1; ! 968: if(cterm->escbuf[1]>=60 && cterm->escbuf[1] <= 63) { /* Private extenstions */ 1.1 root 969: switch(*p) { 970: case 'M': 1.1.1.2 ! root 971: if(cterm->escbuf[1] == '=') { /* ANSI Music setup */ ! 972: i=strtoul(cterm->escbuf+2,NULL,10); 1.1 root 973: switch(i) { 974: case 1: /* BANSI (ESC[N) music only) */ 1.1.1.2 ! root 975: cterm->music_enable=CTERM_MUSIC_BANSI; 1.1 root 976: break; 977: case 2: /* ESC[M ANSI music */ 1.1.1.2 ! root 978: cterm->music_enable=CTERM_MUSIC_ENABLED; 1.1 root 979: break; 980: default: /* Disable ANSI Music */ 1.1.1.2 ! root 981: cterm->music_enable=CTERM_MUSIC_SYNCTERM; 1.1 root 982: break; 983: } 984: } 985: break; 1.1.1.2 ! root 986: case 'h': ! 987: if(!strcmp(cterm->escbuf,"[?25h")) { ! 988: cterm->cursor=_NORMALCURSOR; ! 989: SETCURSORTYPE(cterm->cursor); ! 990: } ! 991: if(!strcmp(cterm->escbuf,"[?31h")) { ! 992: i=GETVIDEOFLAGS(); ! 993: i|=CIOLIB_VIDEO_ALTCHARS; ! 994: SETVIDEOFLAGS(i); ! 995: } ! 996: if(!strcmp(cterm->escbuf,"[?32h")) { ! 997: i=GETVIDEOFLAGS(); ! 998: i|=CIOLIB_VIDEO_NOBRIGHT; ! 999: SETVIDEOFLAGS(i); ! 1000: } ! 1001: if(!strcmp(cterm->escbuf,"[?33h")) { ! 1002: i=GETVIDEOFLAGS(); ! 1003: i|=CIOLIB_VIDEO_BGBRIGHT; ! 1004: SETVIDEOFLAGS(i); ! 1005: } ! 1006: if(!strcmp(cterm->escbuf,"[=255h")) ! 1007: cterm->doorway_mode=1; ! 1008: break; ! 1009: case 'l': ! 1010: if(!strcmp(cterm->escbuf,"[?25l")) { ! 1011: cterm->cursor=_NOCURSOR; ! 1012: SETCURSORTYPE(cterm->cursor); ! 1013: } ! 1014: if(!strcmp(cterm->escbuf,"[?31l")) { ! 1015: i=GETVIDEOFLAGS(); ! 1016: i&=~CIOLIB_VIDEO_ALTCHARS; ! 1017: SETVIDEOFLAGS(i); ! 1018: } ! 1019: if(!strcmp(cterm->escbuf,"[?32l")) { ! 1020: i=GETVIDEOFLAGS(); ! 1021: i&=~CIOLIB_VIDEO_NOBRIGHT; ! 1022: SETVIDEOFLAGS(i); ! 1023: } ! 1024: if(!strcmp(cterm->escbuf,"[?33l")) { ! 1025: i=GETVIDEOFLAGS(); ! 1026: i&=~CIOLIB_VIDEO_BGBRIGHT; ! 1027: SETVIDEOFLAGS(i); ! 1028: } ! 1029: if(!strcmp(cterm->escbuf,"[=255l")) ! 1030: cterm->doorway_mode=0; ! 1031: break; 1.1 root 1032: case '{': 1.1.1.2 ! root 1033: if(cterm->escbuf[1] == '=') { /* Font loading */ 1.1 root 1034: i=255; 1035: j=0; 1.1.1.2 ! root 1036: if(strlen(cterm->escbuf)>2) { ! 1037: if((p=strtok(cterm->escbuf+2,";"))!=NULL) { ! 1038: i=strtoul(p,NULL,10); ! 1039: if(!i && cterm->escbuf[2] != '0') 1.1 root 1040: i=255; 1041: if((p=strtok(NULL,";"))!=NULL) { 1.1.1.2 ! root 1042: j=strtoul(p,NULL,10); 1.1 root 1043: } 1044: } 1045: } 1046: if(i>255) 1047: break; 1.1.1.2 ! root 1048: cterm->font_read=0; ! 1049: cterm->font_slot=i; 1.1 root 1050: switch(j) { 1051: case 0: 1.1.1.2 ! root 1052: cterm->font_size=4096; 1.1 root 1053: break; 1054: case 1: 1.1.1.2 ! root 1055: cterm->font_size=3586; 1.1 root 1056: break; 1057: case 2: 1.1.1.2 ! root 1058: cterm->font_size=2048; 1.1 root 1059: break; 1060: default: 1.1.1.2 ! root 1061: cterm->font_size=0; 1.1 root 1062: break; 1063: } 1064: } 1065: break; 1066: } 1067: break; 1068: } 1069: switch(*p) { 1070: case '@': /* Insert Char */ 1.1.1.2 ! root 1071: i=WHEREX(); ! 1072: j=WHEREY(); ! 1073: k=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1074: if(k<1) 1075: k=1; 1.1.1.2 ! root 1076: if(k>cterm->width - j) ! 1077: k=cterm->width - j; ! 1078: MOVETEXT(cterm->x+i-1,cterm->y+j-1,cterm->x+cterm->width-1-k,cterm->y+j-1,cterm->x+i-1+k,cterm->y+j-1); 1.1 root 1079: for(l=0; l< k; l++) 1.1.1.2 ! root 1080: PUTCH(' '); ! 1081: GOTOXY(i,j); 1.1 root 1082: break; 1083: case 'A': /* Cursor Up */ 1.1.1.2 ! root 1084: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1085: if(i==0) 1086: i=1; 1.1.1.2 ! root 1087: i=WHEREY()-i; 1.1 root 1088: if(i<1) 1089: i=1; 1.1.1.2 ! root 1090: GOTOXY(WHEREX(),i); 1.1 root 1091: break; 1092: case 'B': /* Cursor Down */ 1.1.1.2 ! root 1093: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1094: if(i==0) 1095: i=1; 1.1.1.2 ! root 1096: i=WHEREY()+i; ! 1097: if(i>cterm->height) ! 1098: i=cterm->height; ! 1099: GOTOXY(WHEREX(),i); 1.1 root 1100: break; 1101: case 'C': /* Cursor Right */ 1.1.1.2 ! root 1102: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1103: if(i==0) 1104: i=1; 1.1.1.2 ! root 1105: i=WHEREX()+i; ! 1106: if(i>cterm->width) ! 1107: i=cterm->width; ! 1108: GOTOXY(i,WHEREY()); 1.1 root 1109: break; 1110: case 'D': /* Cursor Left and Font Select */ 1111: if(*(p-1)==' ') { /* Font Select */ 1112: i=0; 1113: j=0; 1.1.1.2 ! root 1114: if(strlen(cterm->escbuf)>2) { ! 1115: if((p=strtok(cterm->escbuf+1,";"))!=NULL) { ! 1116: i=strtoul(p,NULL,10); 1.1 root 1117: if((p=strtok(NULL,";"))!=NULL) { 1.1.1.2 ! root 1118: j=strtoul(p,NULL,10); 1.1 root 1119: } 1120: } 1.1.1.2 ! root 1121: switch(i) { ! 1122: case 0: /* Only the primary and secondary font is currently supported */ ! 1123: case 1: ! 1124: SETFONT(j,FALSE,i+1); 1.1 root 1125: } 1126: } 1127: } 1128: else { 1.1.1.2 ! root 1129: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1130: if(i==0) 1131: i=1; 1.1.1.2 ! root 1132: i=WHEREX()-i; 1.1 root 1133: if(i<1) 1134: i=1; 1.1.1.2 ! root 1135: GOTOXY(i,WHEREY()); 1.1 root 1136: } 1137: break; 1138: case 'E': /* Cursor next line */ 1.1.1.2 ! root 1139: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1140: if(i==0) 1141: i=1; 1.1.1.2 ! root 1142: i=WHEREY()+i; ! 1143: if(i>cterm->height) ! 1144: i=cterm->height; ! 1145: GOTOXY(1,i); 1.1 root 1146: break; 1147: case 'F': /* Cursor preceding line */ 1.1.1.2 ! root 1148: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1149: if(i==0) 1150: i=1; 1.1.1.2 ! root 1151: i=WHEREY()-i; 1.1 root 1152: if(i<1) 1153: i=1; 1.1.1.2 ! root 1154: GOTOXY(1,i); ! 1155: break; ! 1156: case 'G': ! 1157: col=strtoul(cterm->escbuf+1,NULL,10); ! 1158: if(col<1) ! 1159: col=1; ! 1160: if(col>cterm->width) ! 1161: col=cterm->width; ! 1162: GOTOXY(col,WHEREY()); 1.1 root 1163: break; 1164: case 'f': 1165: case 'H': 1166: row=1; 1167: col=1; 1168: *p=0; 1.1.1.2 ! root 1169: if(strlen(cterm->escbuf)>1) { ! 1170: if((p=strtok(cterm->escbuf+1,";"))!=NULL) { ! 1171: row=strtoul(p,NULL,10); 1.1 root 1172: if((p=strtok(NULL,";"))!=NULL) { 1.1.1.2 ! root 1173: col=strtoul(p,NULL,10); 1.1 root 1174: } 1175: } 1176: } 1177: if(row<1) 1178: row=1; 1179: if(col<1) 1180: col=1; 1.1.1.2 ! root 1181: if(row>cterm->height) ! 1182: row=cterm->height; ! 1183: if(col>cterm->width) ! 1184: col=cterm->width; ! 1185: GOTOXY(col,row); 1.1 root 1186: break; 1187: case 'J': 1.1.1.2 ! root 1188: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1189: switch(i) { 1190: case 0: 1.1.1.2 ! root 1191: CLREOL(); ! 1192: row=WHEREY(); ! 1193: col=WHEREX(); ! 1194: for(i=row+1;i<=cterm->height;i++) { ! 1195: GOTOXY(1,i); ! 1196: CLREOL(); 1.1 root 1197: } 1.1.1.2 ! root 1198: GOTOXY(col,row); 1.1 root 1199: break; 1200: case 1: 1.1.1.2 ! root 1201: clear2bol(cterm); ! 1202: row=WHEREY(); ! 1203: col=WHEREX(); ! 1204: for(i=row-1;i>=1;i--) { ! 1205: GOTOXY(1,i); ! 1206: CLREOL(); 1.1 root 1207: } 1.1.1.2 ! root 1208: GOTOXY(col,row); 1.1 root 1209: break; 1210: case 2: 1.1.1.2 ! root 1211: cterm_clearscreen(cterm, (char)cterm->attr); ! 1212: GOTOXY(1,1); 1.1 root 1213: break; 1214: } 1215: break; 1216: case 'K': 1.1.1.2 ! root 1217: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1218: switch(i) { 1219: case 0: 1.1.1.2 ! root 1220: CLREOL(); 1.1 root 1221: break; 1222: case 1: 1.1.1.2 ! root 1223: clear2bol(cterm); 1.1 root 1224: break; 1225: case 2: 1.1.1.2 ! root 1226: row=WHEREY(); ! 1227: col=WHEREX(); ! 1228: GOTOXY(1,row); ! 1229: CLREOL(); ! 1230: GOTOXY(col,row); 1.1 root 1231: break; 1232: } 1233: break; 1234: case 'L': /* Insert line */ 1.1.1.2 ! root 1235: row=WHEREY(); ! 1236: col=WHEREX(); ! 1237: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1238: if(i==0) 1239: i=1; 1.1.1.2 ! root 1240: if(i>cterm->height-row) ! 1241: i=cterm->height-row; ! 1242: if(i) ! 1243: MOVETEXT(cterm->x,cterm->y+row-1,cterm->x+cterm->width-1,cterm->y+cterm->height-1-i,cterm->x,cterm->y+row-1+i); 1.1 root 1244: for(j=0;j<i;j++) { 1.1.1.2 ! root 1245: GOTOXY(1,row+j); ! 1246: CLREOL(); 1.1 root 1247: } 1.1.1.2 ! root 1248: GOTOXY(col,row); 1.1 root 1249: break; 1250: case 'M': /* ANSI music and also supposed to be delete line! */ 1.1.1.2 ! root 1251: if(cterm->music_enable==CTERM_MUSIC_ENABLED) { ! 1252: cterm->music=1; 1.1 root 1253: } 1254: else { 1.1.1.2 ! root 1255: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1256: if(i<1) 1257: i=1; 1.1.1.2 ! root 1258: dellines(cterm, i); 1.1 root 1259: } 1260: break; 1261: case 'N': 1262: /* BananANSI style... does NOT start with MF or MB */ 1263: /* This still conflicts (ANSI erase field) */ 1.1.1.2 ! root 1264: if(cterm->music_enable >= CTERM_MUSIC_BANSI) ! 1265: cterm->music=2; 1.1 root 1266: break; 1267: case 'P': /* Delete char */ 1.1.1.2 ! root 1268: row=WHEREY(); ! 1269: col=WHEREX(); ! 1270: ! 1271: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1272: if(i==0) 1273: i=1; 1.1.1.2 ! root 1274: if(i>cterm->width-col+1) ! 1275: i=cterm->width-col+1; ! 1276: MOVETEXT(cterm->x+col-1+i,cterm->y+row-1,cterm->x+cterm->width-1,cterm->y+row-1,cterm->x+col-1,cterm->y+row-1); ! 1277: GOTOXY(cterm->width-i,col); ! 1278: CLREOL(); ! 1279: GOTOXY(col,row); 1.1 root 1280: break; 1281: case 'S': 1.1.1.2 ! root 1282: i=strtoul(cterm->escbuf+1,NULL,10); ! 1283: if(i==0 && cterm->escbuf[1] != '0') 1.1 root 1284: i=1; 1285: for(j=0; j<i; j++) 1.1.1.2 ! root 1286: scrollup(cterm); 1.1 root 1287: break; 1288: case 'T': 1.1.1.2 ! root 1289: i=strtoul(cterm->escbuf+1,NULL,10); ! 1290: if(i==0 && cterm->escbuf[1] != '0') 1.1 root 1291: i=1; 1292: for(j=0; j<i; j++) 1.1.1.2 ! root 1293: scrolldown(cterm); 1.1 root 1294: break; 1295: #if 0 1296: case 'U': 1.1.1.2 ! root 1297: GETTEXTINFO(&ti); ! 1298: cterm_clearscreen(cterm, ti.normattr); ! 1299: GOTOXY(1,1); 1.1 root 1300: break; 1301: #endif 1302: case 'X': 1.1.1.2 ! root 1303: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1304: if(i<1) 1305: i=1; 1.1.1.2 ! root 1306: if(i>cterm->width-WHEREX()) ! 1307: i=cterm->width-WHEREX(); 1.1 root 1308: p2=alloca(i*2); 1309: j=0; 1310: for(k=0;k<i;k++) { 1311: p2[j++]=' '; 1.1.1.2 ! root 1312: p2[j++]=cterm->attr; 1.1 root 1313: } 1.1.1.2 ! root 1314: PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1+i-1,cterm->y+WHEREY()-1,p2); 1.1 root 1315: break; 1316: case 'Z': 1.1.1.2 ! root 1317: i=strtoul(cterm->escbuf+1,NULL,10); ! 1318: if(i==0 && cterm->escbuf[0] != '0') 1.1 root 1319: i=1; 1.1.1.2 ! root 1320: for(j=(sizeof(cterm_tabs)/sizeof(cterm_tabs[0]))-1;j>=0;j--) { ! 1321: if(cterm_tabs[j]<WHEREX()) { 1.1 root 1322: k=j-i+1; 1323: if(k<0) 1324: k=0; 1.1.1.2 ! root 1325: GOTOXY(cterm_tabs[k],WHEREY()); 1.1 root 1326: break; 1327: } 1328: } 1329: break; 1330: case 'b': /* ToDo? Banana ANSI */ 1331: break; 1332: case 'c': /* Device Attributes */ 1.1.1.2 ! root 1333: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1334: if(!i) { 1335: if(retbuf!=NULL) { 1.1.1.2 ! root 1336: if(strlen(retbuf)+strlen(cterm->DA) < retsize) ! 1337: strcat(retbuf,cterm->DA); 1.1 root 1338: } 1339: } 1340: break; 1341: case 'g': /* ToDo? VT100 Tabs */ 1342: break; 1.1.1.2 ! root 1343: case 'h': /* ToDo? Scrolling region, word-wrap */ 1.1 root 1344: break; 1345: case 'i': /* ToDo? Printing */ 1346: break; 1.1.1.2 ! root 1347: case 'l': /* ToDo? Scrolling region, word-wrap */ 1.1 root 1348: break; 1349: case 'm': 1350: *(p--)=0; 1.1.1.2 ! root 1351: p2=cterm->escbuf+1; ! 1352: GETTEXTINFO(&ti); 1.1 root 1353: if(p2>p) { 1.1.1.2 ! root 1354: cterm->attr=ti.normattr; ! 1355: TEXTATTR(cterm->attr); 1.1 root 1356: break; 1357: } 1358: while((p=strtok(p2,";"))!=NULL) { 1359: p2=NULL; 1.1.1.2 ! root 1360: switch(strtoul(p,NULL,10)) { 1.1 root 1361: case 0: 1.1.1.2 ! root 1362: cterm->attr=ti.normattr; 1.1 root 1363: break; 1364: case 1: 1.1.1.2 ! root 1365: cterm->attr|=8; 1.1 root 1366: break; 1367: case 2: 1.1.1.2 ! root 1368: cterm->attr&=247; 1.1 root 1369: break; 1370: case 4: /* Underscore */ 1371: break; 1372: case 5: 1373: case 6: 1.1.1.2 ! root 1374: cterm->attr|=128; 1.1 root 1375: break; 1376: case 7: 1377: case 27: 1.1.1.2 ! root 1378: i=cterm->attr&7; ! 1379: j=cterm->attr&112; ! 1380: cterm->attr &= 136; ! 1381: cterm->attr |= j>>4; ! 1382: cterm->attr |= i<<4; 1.1 root 1383: break; 1384: case 8: 1.1.1.2 ! root 1385: j=cterm->attr&112; ! 1386: cterm->attr&=112; ! 1387: cterm->attr |= j>>4; 1.1 root 1388: break; 1389: case 22: 1.1.1.2 ! root 1390: cterm->attr &= 0xf7; 1.1 root 1391: break; 1392: case 25: 1.1.1.2 ! root 1393: cterm->attr &= 0x7f; 1.1 root 1394: break; 1395: case 30: 1.1.1.2 ! root 1396: cterm->attr&=248; 1.1 root 1397: break; 1398: case 31: 1.1.1.2 ! root 1399: cterm->attr&=248; ! 1400: cterm->attr|=4; 1.1 root 1401: break; 1402: case 32: 1.1.1.2 ! root 1403: cterm->attr&=248; ! 1404: cterm->attr|=2; 1.1 root 1405: break; 1406: case 33: 1.1.1.2 ! root 1407: cterm->attr&=248; ! 1408: cterm->attr|=6; 1.1 root 1409: break; 1410: case 34: 1.1.1.2 ! root 1411: cterm->attr&=248; ! 1412: cterm->attr|=1; 1.1 root 1413: break; 1414: case 35: 1.1.1.2 ! root 1415: cterm->attr&=248; ! 1416: cterm->attr|=5; 1.1 root 1417: break; 1418: case 36: 1.1.1.2 ! root 1419: cterm->attr&=248; ! 1420: cterm->attr|=3; 1.1 root 1421: break; 1422: case 37: 1423: case 39: 1.1.1.2 ! root 1424: cterm->attr&=248; ! 1425: cterm->attr|=7; 1.1 root 1426: break; 1427: case 40: 1.1.1.2 ! root 1428: cterm->attr&=143; 1.1 root 1429: break; 1430: case 41: 1.1.1.2 ! root 1431: cterm->attr&=143; ! 1432: cterm->attr|=4<<4; 1.1 root 1433: break; 1434: case 42: 1.1.1.2 ! root 1435: cterm->attr&=143; ! 1436: cterm->attr|=2<<4; 1.1 root 1437: break; 1438: case 43: 1.1.1.2 ! root 1439: cterm->attr&=143; ! 1440: cterm->attr|=6<<4; 1.1 root 1441: break; 1442: case 44: 1.1.1.2 ! root 1443: cterm->attr&=143; ! 1444: cterm->attr|=1<<4; 1.1 root 1445: break; 1446: case 45: 1.1.1.2 ! root 1447: cterm->attr&=143; ! 1448: cterm->attr|=5<<4; 1.1 root 1449: break; 1450: case 46: 1.1.1.2 ! root 1451: cterm->attr&=143; ! 1452: cterm->attr|=3<<4; 1.1 root 1453: break; 1454: case 47: 1455: case 49: 1.1.1.2 ! root 1456: cterm->attr&=143; ! 1457: cterm->attr|=7<<4; 1.1 root 1458: break; 1459: } 1460: } 1.1.1.2 ! root 1461: TEXTATTR(cterm->attr); 1.1 root 1462: break; 1463: case 'n': 1.1.1.2 ! root 1464: i=strtoul(cterm->escbuf+1,NULL,10); 1.1 root 1465: switch(i) { 1466: case 5: 1467: if(retbuf!=NULL) { 1468: strcpy(tmp,"\x1b[0n"); 1469: if(strlen(retbuf)+strlen(tmp) < retsize) 1470: strcat(retbuf,tmp); 1471: } 1472: break; 1473: case 6: 1474: if(retbuf!=NULL) { 1.1.1.2 ! root 1475: sprintf(tmp,"%c[%d;%dR",27,WHEREY(),WHEREX()); 1.1 root 1476: if(strlen(retbuf)+strlen(tmp) < retsize) 1477: strcat(retbuf,tmp); 1478: } 1479: break; 1480: case 255: 1481: if(retbuf!=NULL) { 1.1.1.2 ! root 1482: sprintf(tmp,"%c[%d;%dR",27,cterm->height,cterm->width); 1.1 root 1483: if(strlen(retbuf)+strlen(tmp) < retsize) 1484: strcat(retbuf,tmp); 1485: } 1486: break; 1487: } 1488: break; 1489: case 'p': /* ToDo? ANSI keyboard reassignment */ 1490: break; 1491: case 'q': /* ToDo? VT100 keyboard lights */ 1492: break; 1493: case 'r': /* ToDo? Scrolling reigon */ 1494: /* Set communication speed (if has a * before it) */ 1495: if(*(p-1) == '*' && speed != NULL) { 1496: /* 1497: * Ps1 Comm Line Ps2 Communication Speed 1498: * none, 0, 1 Host Transmit none, 0 Use default speed. 1499: * 2 Host Receive 1 300 1500: * 3 Printer 2 600 1501: * 4 Modem Hi 3 1200 1502: * 5 Modem Lo 4 2400 1503: * 5 4800 1504: * 6 9600 1505: * 7 19200 1506: * 8 38400 1507: * 9 57600 1508: * 10 76800 1509: * 11 115200 1510: */ 1511: int newspeed=0; 1512: 1513: *(--p)=0; 1.1.1.2 ! root 1514: if(cterm->escbuf[1]) { ! 1515: p=strtok(cterm->escbuf+1,";"); 1.1 root 1516: if(p!=NULL) { 1.1.1.2 ! root 1517: if(p!=cterm->escbuf+1 || strtoul(p,NULL,10)<2) { ! 1518: if(p==cterm->escbuf+1) 1.1 root 1519: p=strtok(NULL,";"); 1520: if(p!=NULL) { 1.1.1.2 ! root 1521: switch(strtoul(p,NULL,10)) { 1.1 root 1522: case 0: 1523: newspeed=0; 1524: break; 1525: case 1: 1526: newspeed=300; 1527: break; 1528: case 2: 1529: newspeed=600; 1530: break; 1531: case 3: 1532: newspeed=1200; 1533: break; 1534: case 4: 1535: newspeed=2400; 1536: break; 1537: case 5: 1538: newspeed=4800; 1539: break; 1540: case 6: 1541: newspeed=9600; 1542: break; 1543: case 7: 1544: newspeed=19200; 1545: break; 1546: case 8: 1547: newspeed=38400; 1548: break; 1549: case 9: 1550: newspeed=57600; 1551: break; 1552: case 10: 1553: newspeed=76800; 1554: break; 1555: case 11: 1556: newspeed=115200; 1557: break; 1558: default: 1559: newspeed=-1; 1560: break; 1561: } 1562: } 1563: } 1564: else 1565: newspeed = -1; 1566: } 1567: } 1568: if(newspeed >= 0) 1569: *speed = newspeed; 1570: } 1571: break; 1572: case 's': 1.1.1.2 ! root 1573: cterm->save_xpos=WHEREX(); ! 1574: cterm->save_ypos=WHEREY(); 1.1 root 1575: break; 1576: case 'u': 1.1.1.2 ! root 1577: if(cterm->save_ypos>0 && cterm->save_ypos<=cterm->height ! 1578: && cterm->save_xpos>0 && cterm->save_xpos<=cterm->width) { ! 1579: GOTOXY(cterm->save_xpos,cterm->save_ypos); 1.1 root 1580: } 1581: break; 1582: case 'y': /* ToDo? VT100 Tests */ 1583: break; 1584: case 'z': /* ToDo? Reset */ 1585: break; 1586: case '|': /* SyncTERM ANSI Music */ 1.1.1.2 ! root 1587: cterm->music=1; 1.1 root 1588: break; 1589: } 1590: break; 1591: #if 0 1592: case 'D': 1.1.1.2 ! root 1593: scrollup(cterm); 1.1 root 1594: break; 1595: case 'M': 1.1.1.2 ! root 1596: scrolldown(cterm); 1.1 root 1597: break; 1598: #endif 1599: case 'c': 1600: /* ToDo: Reset Terminal */ 1601: break; 1602: } 1.1.1.2 ! root 1603: cterm->escbuf[0]=0; ! 1604: cterm->sequence=0; 1.1 root 1605: } 1606: 1.1.1.2 ! root 1607: struct cterminal *cterm_init(int height, int width, int xpos, int ypos, int backlines, unsigned char *scrollback, int emulation) 1.1 root 1608: { 1.1.1.2 ! root 1609: char *revision="$Revision: 1.135 $"; 1.1 root 1610: char *in; 1611: char *out; 1.1.1.2 ! root 1612: int i; ! 1613: struct cterminal *cterm; 1.1 root 1614: 1.1.1.2 ! root 1615: if((cterm=malloc(sizeof(struct cterminal)))==NULL) ! 1616: return cterm; ! 1617: memset(cterm, 0, sizeof(struct cterminal)); ! 1618: cterm->x=xpos; ! 1619: cterm->y=ypos; ! 1620: cterm->height=height; ! 1621: cterm->width=width; ! 1622: cterm->save_xpos=0; ! 1623: cterm->save_ypos=0; ! 1624: cterm->escbuf[0]=0; ! 1625: cterm->sequence=0; ! 1626: cterm->music_enable=CTERM_MUSIC_BANSI; ! 1627: cterm->music=0; ! 1628: cterm->tempo=120; ! 1629: cterm->octave=4; ! 1630: cterm->notelen=4; ! 1631: cterm->noteshape=CTERM_MUSIC_NORMAL; ! 1632: cterm->musicfore=TRUE; ! 1633: cterm->backpos=0; ! 1634: cterm->backlines=backlines; ! 1635: cterm->scrollback=scrollback; ! 1636: cterm->log=CTERM_LOG_NONE; ! 1637: cterm->logfile=NULL; ! 1638: cterm->emulation=emulation; ! 1639: cterm->cursor=_NORMALCURSOR; ! 1640: if(cterm->scrollback!=NULL) ! 1641: memset(cterm->scrollback,0,cterm->width*2*cterm->backlines); ! 1642: strcpy(cterm->DA,"\x1b[=67;84;101;114;109;"); ! 1643: out=strchr(cterm->DA, 0); 1.1 root 1644: if(out != NULL) { 1645: for(in=revision; *in; in++) { 1646: if(isdigit(*in)) 1647: *(out++)=*in; 1648: if(*in=='.') 1649: *(out++)=';'; 1650: } 1651: *out=0; 1652: } 1.1.1.2 ! root 1653: strcat(cterm->DA,"c"); 1.1 root 1654: /* Fire up note playing thread */ 1.1.1.2 ! root 1655: if(!cterm->playnote_thread_running) { ! 1656: listInit(&cterm->notes, LINK_LIST_SEMAPHORE|LINK_LIST_MUTEX); ! 1657: sem_init(&cterm->note_completed_sem,0,0); ! 1658: sem_init(&cterm->playnote_thread_terminated,0,0); ! 1659: _beginthread(playnote_thread, 0, cterm); ! 1660: } ! 1661: ! 1662: /* Set up tabs for ATASCII */ ! 1663: if(cterm->emulation == CTERM_EMULATION_ATASCII) { ! 1664: for(i=0; i<(sizeof(cterm_tabs)/sizeof(cterm_tabs[0])); i++) ! 1665: cterm->escbuf[cterm_tabs[i]]=1; ! 1666: } ! 1667: ! 1668: #ifndef CTERM_WITHOUT_CONIO ! 1669: cterm->ciolib_gotoxy=ciolib_gotoxy; ! 1670: cterm->ciolib_wherex=ciolib_wherex; ! 1671: cterm->ciolib_wherey=ciolib_wherey; ! 1672: cterm->ciolib_gettext=ciolib_gettext; ! 1673: cterm->ciolib_gettextinfo=ciolib_gettextinfo; ! 1674: cterm->ciolib_textattr=ciolib_textattr; ! 1675: cterm->ciolib_setcursortype=ciolib_setcursortype; ! 1676: cterm->ciolib_movetext=ciolib_movetext; ! 1677: cterm->ciolib_clreol=ciolib_clreol; ! 1678: cterm->ciolib_clrscr=ciolib_clrscr; ! 1679: cterm->ciolib_setvideoflags=ciolib_setvideoflags; ! 1680: cterm->ciolib_getvideoflags=ciolib_getvideoflags; ! 1681: cterm->ciolib_putch=ciolib_putch; ! 1682: cterm->ciolib_puttext=ciolib_puttext; ! 1683: cterm->ciolib_window=ciolib_window; ! 1684: cterm->ciolib_cputs=ciolib_cputs; ! 1685: cterm->ciolib_setfont=ciolib_setfont; ! 1686: cterm->_wscroll=&_wscroll; ! 1687: cterm->puttext_can_move=&puttext_can_move; ! 1688: cterm->hold_update=&hold_update; ! 1689: #endif ! 1690: ! 1691: return cterm; ! 1692: } ! 1693: ! 1694: void cterm_start(struct cterminal *cterm) ! 1695: { ! 1696: struct text_info ti; ! 1697: ! 1698: if(!cterm->started) { ! 1699: GETTEXTINFO(&ti); ! 1700: cterm->attr=ti.normattr; ! 1701: TEXTATTR(cterm->attr); ! 1702: SETCURSORTYPE(cterm->cursor); ! 1703: cterm->started=1; ! 1704: if(ti.winleft != cterm->x || ti.wintop != cterm->y || ti.winright != cterm->x+cterm->width-1 || ti.winleft != cterm->y+cterm->height-1) ! 1705: WINDOW(cterm->x,cterm->y,cterm->x+cterm->width-1,cterm->y+cterm->height-1); ! 1706: cterm_clearscreen(cterm, cterm->attr); ! 1707: GOTOXY(1,1); 1.1 root 1708: } 1709: } 1710: 1.1.1.2 ! root 1711: static void ctputs(struct cterminal *cterm, char *buf) 1.1 root 1712: { 1713: char *outp; 1714: char *p; 1715: int oldscroll; 1716: int cx; 1717: int cy; 1718: int i; 1719: 1720: outp=buf; 1.1.1.2 ! root 1721: oldscroll=*cterm->_wscroll; ! 1722: *cterm->_wscroll=0; ! 1723: cx=WHEREX(); ! 1724: cy=WHEREY(); ! 1725: if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) ! 1726: fputs(buf, cterm->logfile); 1.1 root 1727: for(p=buf;*p;p++) { 1728: switch(*p) { 1729: case '\r': 1730: cx=1; 1731: break; 1732: case '\n': 1733: *p=0; 1.1.1.2 ! root 1734: CPUTS(outp); 1.1 root 1735: outp=p+1; 1.1.1.2 ! root 1736: if(cy==cterm->height) ! 1737: scrollup(cterm); 1.1 root 1738: else 1739: cy++; 1.1.1.2 ! root 1740: GOTOXY(cx,cy); 1.1 root 1741: break; 1742: case '\b': 1743: *p=0; 1.1.1.2 ! root 1744: CPUTS(outp); 1.1 root 1745: outp=p+1; 1.1.1.2 ! root 1746: if(cx>1) 1.1 root 1747: cx--; 1.1.1.2 ! root 1748: GOTOXY(cx,cy); 1.1 root 1749: break; 1750: case 7: /* Bell */ 1751: break; 1752: case '\t': 1.1.1.2 ! root 1753: *p=0; ! 1754: CPUTS(outp); ! 1755: outp=p+1; ! 1756: for(i=0;i<sizeof(cterm_tabs)/sizeof(cterm_tabs[0]);i++) { 1.1 root 1757: if(cterm_tabs[i]>cx) { 1.1.1.2 ! root 1758: cx=cterm_tabs[i]; 1.1 root 1759: break; 1760: } 1761: } 1.1.1.2 ! root 1762: if(cx>cterm->width) { 1.1 root 1763: cx=1; 1.1.1.2 ! root 1764: if(cy==cterm->height) ! 1765: scrollup(cterm); 1.1 root 1766: else 1767: cy++; 1768: } 1.1.1.2 ! root 1769: GOTOXY(cx,cy); 1.1 root 1770: break; 1771: default: 1.1.1.2 ! root 1772: if(cy==cterm->height ! 1773: && cx==cterm->width) { 1.1 root 1774: char ch; 1.1.1.2 ! root 1775: ch=*(p+1); ! 1776: *(p+1)=0; ! 1777: CPUTS(outp); ! 1778: *(p+1)=ch; ! 1779: outp=p+1; ! 1780: scrollup(cterm); 1.1 root 1781: cx=1; 1.1.1.2 ! root 1782: GOTOXY(cx,cy); 1.1 root 1783: } 1784: else { 1.1.1.2 ! root 1785: if(cx==cterm->width) { 1.1 root 1786: cx=1; 1787: cy++; 1788: } 1789: else { 1790: cx++; 1791: } 1792: } 1793: break; 1794: } 1795: } 1.1.1.2 ! root 1796: CPUTS(outp); ! 1797: *cterm->_wscroll=oldscroll; 1.1 root 1798: } 1799: 1.1.1.2 ! root 1800: char *cterm_write(struct cterminal * cterm, const unsigned char *buf, int buflen, char *retbuf, size_t retsize, int *speed) 1.1 root 1801: { 1802: unsigned char ch[2]; 1803: unsigned char prn[BUFSIZE]; 1.1.1.2 ! root 1804: int j,k,l; 1.1 root 1805: struct text_info ti; 1806: int olddmc; 1807: int oldptnm; 1808: 1.1.1.2 ! root 1809: if(!cterm->started) ! 1810: cterm_start(cterm); ! 1811: ! 1812: oldptnm=*cterm->puttext_can_move; ! 1813: *cterm->puttext_can_move=1; ! 1814: olddmc=*cterm->hold_update; ! 1815: *cterm->hold_update=1; 1.1 root 1816: if(retbuf!=NULL) 1817: retbuf[0]=0; 1.1.1.2 ! root 1818: GETTEXTINFO(&ti); ! 1819: if(ti.winleft != cterm->x || ti.wintop != cterm->y || ti.winright != cterm->x+cterm->width-1 || ti.winbottom != cterm->y+cterm->height-1) ! 1820: WINDOW(cterm->x,cterm->y,cterm->x+cterm->width-1,cterm->y+cterm->height-1); ! 1821: GOTOXY(cterm->xpos,cterm->ypos); ! 1822: TEXTATTR(cterm->attr); ! 1823: SETCURSORTYPE(cterm->cursor); 1.1 root 1824: ch[1]=0; 1.1.1.2 ! root 1825: if(buflen==-1) ! 1826: buflen=strlen(buf); 1.1 root 1827: switch(buflen) { 1828: case 0: 1829: break; 1830: default: 1.1.1.2 ! root 1831: if(cterm->log==CTERM_LOG_RAW && cterm->logfile != NULL) ! 1832: fwrite(buf, buflen, 1, cterm->logfile); 1.1 root 1833: prn[0]=0; 1834: for(j=0;j<buflen;j++) { 1.1.1.2 ! root 1835: if(strlen(prn) >= sizeof(prn)-sizeof(cterm->escbuf)) { ! 1836: ctputs(cterm, prn); ! 1837: prn[0]=0; ! 1838: } 1.1 root 1839: ch[0]=buf[j]; 1.1.1.2 ! root 1840: if(cterm->font_size) { ! 1841: cterm->fontbuf[cterm->font_read++]=ch[0]; ! 1842: if(cterm->font_read == cterm->font_size) { ! 1843: #ifndef CTERM_WITHOUT_CONIO 1.1 root 1844: char *buf; 1845: 1.1.1.2 ! root 1846: if((buf=(char *)malloc(cterm->font_size))!=NULL) { ! 1847: memcpy(buf,cterm->fontbuf,cterm->font_size); ! 1848: if(cterm->font_slot >= CONIO_FIRST_FREE_FONT) { ! 1849: switch(cterm->font_size) { 1.1 root 1850: case 4096: 1.1.1.2 ! root 1851: FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_sixteen); ! 1852: conio_fontdata[cterm->font_slot].eight_by_sixteen=buf; ! 1853: FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); ! 1854: conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); 1.1 root 1855: break; 1856: case 3586: 1.1.1.2 ! root 1857: FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_fourteen); ! 1858: conio_fontdata[cterm->font_slot].eight_by_fourteen=buf; ! 1859: FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); ! 1860: conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); 1.1 root 1861: break; 1862: case 2048: 1.1.1.2 ! root 1863: FREE_AND_NULL(conio_fontdata[cterm->font_slot].eight_by_eight); ! 1864: conio_fontdata[cterm->font_slot].eight_by_eight=buf; ! 1865: FREE_AND_NULL(conio_fontdata[cterm->font_slot].desc); ! 1866: conio_fontdata[cterm->font_slot].desc=strdup("Remote Defined Font"); 1.1 root 1867: break; 1868: } 1869: } 1870: else 1871: FREE_AND_NULL(buf); 1872: } 1.1.1.2 ! root 1873: #endif ! 1874: cterm->font_size=0; 1.1 root 1875: } 1876: } 1.1.1.2 ! root 1877: else if(cterm->sequence) { ! 1878: k=strlen(cterm->escbuf); ! 1879: if(k+1 >= sizeof(cterm->escbuf)) { ! 1880: /* Broken sequence detected */ ! 1881: strcat(prn,"\033"); ! 1882: strcat(prn,cterm->escbuf); ! 1883: cterm->escbuf[0]=0; ! 1884: cterm->sequence=0; ! 1885: } ! 1886: else { ! 1887: strcat(cterm->escbuf,ch); ! 1888: if(k) { ! 1889: if(cterm->escbuf[0] != '[') { /* Not a CSI code. */ ! 1890: /* ANSI control characters */ ! 1891: if(ch[0] >= 32 && ch[0] <= 47) { ! 1892: /* Legal intermediate character */ ! 1893: } ! 1894: else if(ch[0] >= 48 && ch[0] <= 126) { ! 1895: /* Terminating character */ ! 1896: do_ansi(cterm, retbuf, retsize, speed); ! 1897: } ! 1898: else { 1.1 root 1899: /* Broken sequence detected */ 1900: strcat(prn,"\033"); 1.1.1.2 ! root 1901: strcat(prn,cterm->escbuf); ! 1902: cterm->escbuf[0]=0; ! 1903: cterm->sequence=0; 1.1 root 1904: } 1905: } 1.1.1.2 ! root 1906: else { ! 1907: /* We know that it was a CSI at this point */ ! 1908: /* Here's where we get funky! */ ! 1909: /* the last character defines the set of legal next characters */ ! 1910: if(ch[0] >= 48 && ch[0] <= 63) { ! 1911: /* Parameter character. Only legal after '[' and other param chars */ ! 1912: if(cterm->escbuf[k]!='[' ! 1913: && (cterm->escbuf[k] < 48 || cterm->escbuf[k] > 63)) { ! 1914: /* Broken sequence detected */ ! 1915: strcat(prn,"\033"); ! 1916: strcat(prn,cterm->escbuf); ! 1917: cterm->escbuf[0]=0; ! 1918: cterm->sequence=0; ! 1919: } ! 1920: } ! 1921: else if(ch[0] >= 32 && ch[0] <= 47) { ! 1922: /* Intermediate character. Legal after '[', param, or intermetiate chars */ ! 1923: if(cterm->escbuf[k]!='[' ! 1924: && (cterm->escbuf[k] < 48 || cterm->escbuf[k] > 63) ! 1925: && (cterm->escbuf[k] < 32 || cterm->escbuf[k] > 47)) { ! 1926: /* Broken sequence detected */ ! 1927: strcat(prn,"\033"); ! 1928: strcat(prn,cterm->escbuf); ! 1929: cterm->escbuf[0]=0; ! 1930: cterm->sequence=0; ! 1931: } ! 1932: } ! 1933: else if(ch[0] >= 64 && ch[0] <= 126) { ! 1934: /* Terminating character. Always legal at this point. */ ! 1935: do_ansi(cterm, retbuf, retsize, speed); ! 1936: } ! 1937: else { 1.1 root 1938: /* Broken sequence detected */ 1939: strcat(prn,"\033"); 1.1.1.2 ! root 1940: strcat(prn,cterm->escbuf); ! 1941: cterm->escbuf[0]=0; ! 1942: cterm->sequence=0; 1.1 root 1943: } 1944: } 1.1.1.2 ! root 1945: } ! 1946: else { ! 1947: /* First char after the ESC */ ! 1948: if(ch[0] >= 32 && ch[0] <= 47) { ! 1949: /* Legal intermediate character */ ! 1950: /* No CSI then */ ! 1951: } ! 1952: else if(ch[0]=='[') { ! 1953: /* CSI received */ ! 1954: } ! 1955: else if(ch[0] >= 48 && ch[0] <= 126) { ! 1956: /* Terminating character */ ! 1957: do_ansi(cterm, retbuf, retsize, speed); 1.1 root 1958: } 1959: else { 1960: /* Broken sequence detected */ 1961: strcat(prn,"\033"); 1.1.1.2 ! root 1962: strcat(prn,cterm->escbuf); ! 1963: cterm->escbuf[0]=0; ! 1964: cterm->sequence=0; 1.1 root 1965: } 1966: } 1.1.1.2 ! root 1967: if(ch[0]=='\033') { /* Broken sequence followed by a legal one! */ ! 1968: if(prn[0]) /* Don't display the ESC */ ! 1969: prn[strlen(prn)-1]=0; ! 1970: ctputs(cterm, prn); ! 1971: prn[0]=0; ! 1972: cterm->sequence=1; 1.1 root 1973: } 1.1.1.2 ! root 1974: } ! 1975: } ! 1976: else if (cterm->music) { ! 1977: if(ch[0]==14) { ! 1978: *cterm->hold_update=0; ! 1979: *cterm->puttext_can_move=0; ! 1980: GOTOXY(WHEREX(),WHEREY()); ! 1981: SETCURSORTYPE(cterm->cursor); ! 1982: *cterm->hold_update=1; ! 1983: *cterm->puttext_can_move=1; ! 1984: play_music(cterm); ! 1985: } 1.1 root 1986: else { 1987: if(strchr(musicchars,ch[0])!=NULL) 1.1.1.2 ! root 1988: strcat(cterm->musicbuf,ch); 1.1 root 1989: else { 1990: /* Kill non-music strings */ 1.1.1.2 ! root 1991: cterm->music=0; ! 1992: cterm->musicbuf[0]=0; 1.1 root 1993: } 1994: } 1995: } 1996: else { 1.1.1.2 ! root 1997: if(cterm->emulation == CTERM_EMULATION_ATASCII) { ! 1998: if(cterm->attr==7) { ! 1999: switch(buf[j]) { ! 2000: case 27: /* ESC */ ! 2001: cterm->attr=1; ! 2002: break; ! 2003: case 28: /* Up (TODO: Wraps??) */ ! 2004: l=WHEREY()-1; ! 2005: if(l<1) ! 2006: l=cterm->height; ! 2007: GOTOXY(WHEREX(),l); ! 2008: break; ! 2009: case 29: /* Down (TODO: Wraps??) */ ! 2010: l=WHEREY()+1; ! 2011: if(l>cterm->height) ! 2012: l=1; ! 2013: GOTOXY(WHEREX(),l); ! 2014: break; ! 2015: case 30: /* Left (TODO: Wraps around to same line?) */ ! 2016: l=WHEREX()-1; ! 2017: if(l<1) ! 2018: l=cterm->width; ! 2019: GOTOXY(l,WHEREY()); ! 2020: break; ! 2021: case 31: /* Right (TODO: Wraps around to same line?) */ ! 2022: l=WHEREX()+1; ! 2023: if(l>cterm->width) ! 2024: l=1; ! 2025: GOTOXY(l,WHEREY()); ! 2026: break; ! 2027: case 125: /* Clear Screen */ ! 2028: cterm_clearscreen(cterm, cterm->attr); ! 2029: break; ! 2030: case 126: /* Backspace (TODO: Wraps around to previous line?) */ ! 2031: /* DOES NOT delete char, merely erases */ ! 2032: k=WHEREY(); ! 2033: l=WHEREX()-1; ! 2034: ! 2035: if(l<1) { ! 2036: k--; ! 2037: if(k<1) ! 2038: break; ! 2039: l=cterm->width; ! 2040: } ! 2041: GOTOXY(l,k); ! 2042: PUTCH(0); ! 2043: GOTOXY(l,k); ! 2044: break; ! 2045: /* We abuse the ESC buffer for tab stops */ ! 2046: case 127: /* Tab (Wraps around to next line) */ ! 2047: l=WHEREX(); ! 2048: for(k=l+1; k<=cterm->width; k++) { ! 2049: if(cterm->escbuf[k]) { ! 2050: l=k; ! 2051: break; ! 2052: } ! 2053: } ! 2054: if(k>cterm->width) { ! 2055: l=1; ! 2056: k=WHEREY()+1; ! 2057: if(k>cterm->height) { ! 2058: scrollup(cterm); ! 2059: k=cterm->height; ! 2060: } ! 2061: GOTOXY(l,k); ! 2062: } ! 2063: else ! 2064: GOTOXY(l,WHEREY()); ! 2065: break; ! 2066: case 155: /* Return */ ! 2067: k=WHEREY(); ! 2068: if(k==cterm->height) ! 2069: scrollup(cterm); ! 2070: else ! 2071: k++; ! 2072: GOTOXY(1,k); ! 2073: break; ! 2074: case 156: /* Delete Line */ ! 2075: dellines(cterm, 1); ! 2076: GOTOXY(1,WHEREY()); ! 2077: break; ! 2078: case 157: /* Insert Line */ ! 2079: l=WHEREX(); ! 2080: k=WHEREY(); ! 2081: if(k<cterm->height) ! 2082: MOVETEXT(cterm->x,cterm->y+k-1 ! 2083: ,cterm->x+cterm->width-1,cterm->y+cterm->height-2 ! 2084: ,cterm->x,cterm->y+k); ! 2085: GOTOXY(1,k); ! 2086: CLREOL(); ! 2087: break; ! 2088: case 158: /* Clear Tab */ ! 2089: cterm->escbuf[WHEREX()]=0; ! 2090: break; ! 2091: case 159: /* Set Tab */ ! 2092: cterm->escbuf[WHEREX()]=1; ! 2093: break; ! 2094: case 253: /* Beep */ ! 2095: if(!cterm->quiet) { ! 2096: #ifdef __unix__ ! 2097: PUTCH(7); ! 2098: #else ! 2099: MessageBeep(MB_OK); ! 2100: #endif ! 2101: } ! 2102: break; ! 2103: case 254: /* Delete Char */ ! 2104: l=WHEREX(); ! 2105: k=WHEREY(); ! 2106: if(l<cterm->width) ! 2107: MOVETEXT(cterm->x+l,cterm->y+k-1 ! 2108: ,cterm->x+cterm->width-1,cterm->y+k-1 ! 2109: ,cterm->x+l-1,cterm->y+k-1); ! 2110: GOTOXY(cterm->width,k); ! 2111: CLREOL(); ! 2112: GOTOXY(l,k); ! 2113: break; ! 2114: case 255: /* Insert Char */ ! 2115: l=WHEREX(); ! 2116: k=WHEREY(); ! 2117: if(l<cterm->width) ! 2118: MOVETEXT(cterm->x+l-1,cterm->y+k-1 ! 2119: ,cterm->x+cterm->width-2,cterm->y+k-1 ! 2120: ,cterm->x+l,cterm->y+k-1); ! 2121: PUTCH(0); ! 2122: GOTOXY(l,k); ! 2123: break; ! 2124: default: ! 2125: /* Translate to screen codes */ ! 2126: k=buf[j]; ! 2127: if(k < 32) { ! 2128: k +=64; ! 2129: } ! 2130: else if(k < 96) { ! 2131: k -= 32; ! 2132: } ! 2133: else if(k < 128) { ! 2134: /* No translation */ ! 2135: } ! 2136: else if(k < 160) { ! 2137: k +=64; ! 2138: } ! 2139: else if(k < 224) { ! 2140: k -= 32; ! 2141: } ! 2142: else if(k < 256) { ! 2143: /* No translation */ ! 2144: } ! 2145: ch[0] = k; ! 2146: ch[1] = cterm->attr; ! 2147: PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); ! 2148: ch[1]=0; ! 2149: if(WHEREX()==cterm->width) { ! 2150: if(WHEREY()==cterm->height) { ! 2151: scrollup(cterm); ! 2152: GOTOXY(1,WHEREY()); ! 2153: } ! 2154: else ! 2155: GOTOXY(1,WHEREY()+1); ! 2156: } ! 2157: else ! 2158: GOTOXY(WHEREX()+1,WHEREY()); 1.1 root 2159: break; 1.1.1.2 ! root 2160: } ! 2161: } ! 2162: else { ! 2163: switch(buf[j]) { ! 2164: case 155: /* Return */ ! 2165: k=WHEREY(); ! 2166: if(k==cterm->height) ! 2167: scrollup(cterm); ! 2168: else ! 2169: k++; ! 2170: GOTOXY(1,k); ! 2171: break; ! 2172: default: ! 2173: /* Translate to screen codes */ ! 2174: k=buf[j]; ! 2175: if(k < 32) { ! 2176: k +=64; ! 2177: } ! 2178: else if(k < 96) { ! 2179: k -= 32; ! 2180: } ! 2181: else if(k < 128) { ! 2182: /* No translation */ ! 2183: } ! 2184: else if(k < 160) { ! 2185: k +=64; ! 2186: } ! 2187: else if(k < 224) { ! 2188: k -= 32; ! 2189: } ! 2190: else if(k < 256) { ! 2191: /* No translation */ ! 2192: } ! 2193: ch[0] = k; ! 2194: ch[1] = cterm->attr; ! 2195: PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); ! 2196: ch[1]=0; ! 2197: if(WHEREX()==cterm->width) { ! 2198: if(WHEREY()==cterm->height) { ! 2199: scrollup(cterm); ! 2200: GOTOXY(1,cterm->height); ! 2201: } ! 2202: else ! 2203: GOTOXY(1,WHEREY()+1); ! 2204: } ! 2205: else ! 2206: GOTOXY(WHEREX()+1,WHEREY()); ! 2207: break; ! 2208: } ! 2209: cterm->attr=7; ! 2210: } ! 2211: } ! 2212: else if(cterm->emulation == CTERM_EMULATION_PETASCII) { ! 2213: switch(buf[j]) { ! 2214: case 5: /* White */ ! 2215: case 28: /* Red */ ! 2216: case 30: /* Green */ ! 2217: case 31: /* Blue */ ! 2218: case 129: /* Orange */ ! 2219: case 144: /* Black */ ! 2220: case 149: /* Brown */ ! 2221: case 150: /* Light Red */ ! 2222: case 151: /* Dark Gray */ ! 2223: case 152: /* Grey */ ! 2224: case 153: /* Light Green */ ! 2225: case 154: /* Light Blue */ ! 2226: case 155: /* Light Gray */ ! 2227: case 156: /* Purple */ ! 2228: case 158: /* Yellow */ ! 2229: case 159: /* Cyan */ ! 2230: cterm->attr &= 0xf0; ! 2231: switch(buf[j]) { ! 2232: case 5: /* White */ ! 2233: cterm->attr |= 1; ! 2234: break; ! 2235: case 28: /* Red */ ! 2236: cterm->attr |= 2; ! 2237: break; ! 2238: case 30: /* Green */ ! 2239: cterm->attr |= 5; ! 2240: break; ! 2241: case 31: /* Blue */ ! 2242: cterm->attr |= 6; ! 2243: break; ! 2244: case 129: /* Orange */ ! 2245: cterm->attr |= 8; ! 2246: break; ! 2247: case 144: /* Black */ ! 2248: cterm->attr |= 0; ! 2249: break; ! 2250: case 149: /* Brown */ ! 2251: cterm->attr |= 9; ! 2252: break; ! 2253: case 150: /* Light Red */ ! 2254: cterm->attr |= 10; ! 2255: break; ! 2256: case 151: /* Dark Gray */ ! 2257: cterm->attr |= 11; ! 2258: break; ! 2259: case 152: /* Grey */ ! 2260: cterm->attr |= 12; ! 2261: break; ! 2262: case 153: /* Light Green */ ! 2263: cterm->attr |= 13; ! 2264: break; ! 2265: case 154: /* Light Blue */ ! 2266: cterm->attr |= 14; ! 2267: break; ! 2268: case 155: /* Light Gray */ ! 2269: cterm->attr |= 15; ! 2270: break; ! 2271: case 156: /* Purple */ ! 2272: cterm->attr |= 4; ! 2273: break; ! 2274: case 158: /* Yellow */ ! 2275: cterm->attr |= 7; ! 2276: break; ! 2277: case 159: /* Cyan */ ! 2278: cterm->attr |= 3; ! 2279: break; 1.1 root 2280: } 1.1.1.2 ! root 2281: TEXTATTR(cterm->attr); ! 2282: break; ! 2283: ! 2284: /* Movement */ ! 2285: case 13: /* "\r\n" and disabled reverse. */ ! 2286: case 141: ! 2287: GOTOXY(1, WHEREY()); ! 2288: /* Fall-through */ ! 2289: case 17: ! 2290: if(WHEREY()==cterm->height) ! 2291: scrollup(cterm); ! 2292: else ! 2293: GOTOXY(WHEREX(), WHEREY()+1); ! 2294: break; ! 2295: case 147: ! 2296: cterm_clearscreen(cterm, cterm->attr); ! 2297: /* Fall through */ ! 2298: case 19: ! 2299: GOTOXY(1,1); ! 2300: break; ! 2301: case 20: /* Delete (Wrapping backspace) */ ! 2302: k=WHEREY(); ! 2303: l=WHEREX(); ! 2304: ! 2305: if(l==1) { ! 2306: if(k==1) ! 2307: break; ! 2308: GOTOXY((l=cterm->width), k-1); ! 2309: } ! 2310: else ! 2311: GOTOXY(--l, k); ! 2312: if(l<cterm->width) ! 2313: MOVETEXT(cterm->x+l,cterm->y+k-1 ! 2314: ,cterm->x+cterm->width-1,cterm->y+k-1 ! 2315: ,cterm->x+l-1,cterm->y+k-1); ! 2316: GOTOXY(cterm->width,k); ! 2317: CLREOL(); ! 2318: GOTOXY(l,k); ! 2319: break; ! 2320: case 157: /* Cursor Left (wraps) */ ! 2321: if(WHEREX()==1) { ! 2322: if(WHEREY() > 1) ! 2323: GOTOXY(cterm->width, WHEREY()-1); ! 2324: } ! 2325: else ! 2326: GOTOXY(WHEREX()-1, WHEREY()); ! 2327: break; ! 2328: case 29: /* Cursor Right (wraps) */ ! 2329: if(WHEREX()==cterm->width) { ! 2330: if(WHEREY()==cterm->height) { ! 2331: scrollup(cterm); ! 2332: GOTOXY(1,WHEREY()); ! 2333: } ! 2334: else ! 2335: GOTOXY(1,WHEREY()+1); ! 2336: } ! 2337: else ! 2338: GOTOXY(WHEREX()+1,WHEREY()); ! 2339: break; ! 2340: case 145: /* Cursor Up (No scroll */ ! 2341: if(WHEREY()>1) ! 2342: GOTOXY(WHEREX(),WHEREY()-1); ! 2343: break; ! 2344: case 148: /* Insert TODO verify last column */ ! 2345: /* CGTerm does nothing there... we */ ! 2346: /* Erase under cursor. */ ! 2347: l=WHEREX(); ! 2348: k=WHEREY(); ! 2349: if(l<=cterm->width) ! 2350: MOVETEXT(cterm->x+l-1,cterm->y+k-1 ! 2351: ,cterm->x+cterm->width-2,cterm->y+k-1 ! 2352: ,cterm->x+l,cterm->y+k-1); ! 2353: PUTCH(' '); ! 2354: GOTOXY(l,k); ! 2355: break; ! 2356: ! 2357: /* Font change... whee! */ ! 2358: case 14: /* Lower case font */ ! 2359: if(ti.currmode == C64_40X25) ! 2360: SETFONT(33,FALSE,1); ! 2361: else /* Assume C128 */ ! 2362: SETFONT(35,FALSE,1); ! 2363: break; ! 2364: case 142: /* Upper case font */ ! 2365: if(ti.currmode == C64_40X25) ! 2366: SETFONT(32,FALSE,1); ! 2367: else /* Assume C128 */ ! 2368: SETFONT(34,FALSE,1); ! 2369: break; ! 2370: case 18: /* Reverse mode on */ ! 2371: cterm->c64reversemode = 1; ! 2372: break; ! 2373: case 146: /* Reverse mode off */ ! 2374: cterm->c64reversemode = 0; ! 2375: break; ! 2376: ! 2377: /* Extras */ ! 2378: case 7: /* Beep */ ! 2379: if(!cterm->quiet) { ! 2380: #ifdef __unix__ ! 2381: PUTCH(7); ! 2382: #else ! 2383: MessageBeep(MB_OK); ! 2384: #endif ! 2385: } ! 2386: break; ! 2387: ! 2388: /* Translate to screen codes */ ! 2389: default: ! 2390: k=buf[j]; ! 2391: if(k<32) { ! 2392: break; ! 2393: } ! 2394: else if(k<64) { ! 2395: /* No translation */ ! 2396: } ! 2397: else if(k<96) { ! 2398: k -= 64; ! 2399: } ! 2400: else if(k<128) { ! 2401: k -= 32; ! 2402: } ! 2403: else if(k<160) { ! 2404: break; ! 2405: } ! 2406: else if(k<192) { ! 2407: k -= 64; ! 2408: } ! 2409: else if(k<224) { ! 2410: k -= 128; ! 2411: } ! 2412: else { ! 2413: if(k==255) ! 2414: k = 94; ! 2415: else ! 2416: k -= 128; ! 2417: } ! 2418: if(cterm->c64reversemode) ! 2419: k+=128; ! 2420: ch[0] = k; ! 2421: ch[1] = cterm->attr; ! 2422: PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); ! 2423: ch[1]=0; ! 2424: if(WHEREX()==cterm->width) { ! 2425: if(WHEREY()==cterm->height) { ! 2426: scrollup(cterm); ! 2427: GOTOXY(1,WHEREY()); ! 2428: } ! 2429: else ! 2430: GOTOXY(1,WHEREY()+1); ! 2431: } ! 2432: else ! 2433: GOTOXY(WHEREX()+1,WHEREY()); ! 2434: break; ! 2435: } ! 2436: } ! 2437: else { /* ANSI-BBS */ ! 2438: if(cterm->doorway_char) { ! 2439: ctputs(cterm, prn); ! 2440: ch[1]=cterm->attr; ! 2441: PUTTEXT(cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,cterm->x+WHEREX()-1,cterm->y+WHEREY()-1,ch); ! 2442: ch[1]=0; ! 2443: if(WHEREX()==cterm->width) { ! 2444: if(WHEREY()==cterm->height) { ! 2445: scrollup(cterm); ! 2446: GOTOXY(1,WHEREY()); ! 2447: } ! 2448: else ! 2449: GOTOXY(1,WHEREY()+1); 1.1 root 2450: } 1.1.1.2 ! root 2451: else ! 2452: GOTOXY(WHEREX()+1,WHEREY()); ! 2453: cterm->doorway_char=0; ! 2454: } ! 2455: else { ! 2456: switch(buf[j]) { ! 2457: case 0: ! 2458: if(cterm->doorway_mode) ! 2459: cterm->doorway_char=1; ! 2460: break; ! 2461: case 7: /* Beep */ ! 2462: ctputs(cterm, prn); ! 2463: prn[0]=0; ! 2464: if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) ! 2465: fputs("\x07", cterm->logfile); ! 2466: if(!cterm->quiet) { ! 2467: #ifdef __unix__ ! 2468: PUTCH(7); ! 2469: #else ! 2470: MessageBeep(MB_OK); ! 2471: #endif ! 2472: } ! 2473: break; ! 2474: case 12: /* ^L - Clear screen */ ! 2475: ctputs(cterm, prn); ! 2476: prn[0]=0; ! 2477: if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL) ! 2478: fputs("\x0c", cterm->logfile); ! 2479: cterm_clearscreen(cterm, (char)cterm->attr); ! 2480: GOTOXY(1,1); ! 2481: break; ! 2482: case 27: /* ESC */ ! 2483: ctputs(cterm, prn); ! 2484: prn[0]=0; ! 2485: cterm->sequence=1; ! 2486: break; ! 2487: default: ! 2488: strcat(prn,ch); ! 2489: } ! 2490: } 1.1 root 2491: } 2492: } 2493: } 1.1.1.2 ! root 2494: ctputs(cterm, prn); 1.1 root 2495: prn[0]=0; 2496: break; 2497: } 1.1.1.2 ! root 2498: cterm->xpos=WHEREX(); ! 2499: cterm->ypos=WHEREY(); 1.1 root 2500: #if 0 1.1.1.2 ! root 2501: if(ti.winleft != cterm->x || ti.wintop != cterm->y || ti.winright != cterm->x+cterm->width-1 || ti.winleft != cterm->y+cterm->height-1) ! 2502: WINDOW(ti.winleft,ti.wintop,ti.winright,ti.winbottom); ! 2503: GOTOXY(ti.curx,ti.cury); ! 2504: TEXTATTR(ti.attribute); 1.1 root 2505: #endif 2506: 1.1.1.2 ! root 2507: *cterm->hold_update=olddmc; ! 2508: *cterm->puttext_can_move=oldptnm; ! 2509: GOTOXY(WHEREX(),WHEREY()); ! 2510: SETCURSORTYPE(cterm->cursor); 1.1 root 2511: return(retbuf); 2512: } 2513: 1.1.1.2 ! root 2514: int cterm_openlog(struct cterminal *cterm, char *logfile, int logtype) 1.1 root 2515: { 1.1.1.2 ! root 2516: if(!cterm->started) ! 2517: cterm_start(cterm); ! 2518: ! 2519: cterm->logfile=fopen(logfile, "a"); ! 2520: if(cterm->logfile==NULL) 1.1 root 2521: return(0); 1.1.1.2 ! root 2522: cterm->log=logtype; 1.1 root 2523: return(1); 2524: } 2525: 1.1.1.2 ! root 2526: void cterm_closelog(struct cterminal *cterm) 1.1 root 2527: { 1.1.1.2 ! root 2528: if(!cterm->started) ! 2529: cterm_start(cterm); ! 2530: ! 2531: if(cterm->logfile != NULL) ! 2532: fclose(cterm->logfile); ! 2533: cterm->logfile=NULL; ! 2534: cterm->log=CTERM_LOG_NONE; 1.1 root 2535: } 2536: 1.1.1.2 ! root 2537: void cterm_end(struct cterminal *cterm) 1.1 root 2538: { 2539: int i; 2540: 1.1.1.2 ! root 2541: if(cterm) { ! 2542: cterm_closelog(cterm); ! 2543: #ifdef CTERM_WITHOUT_CONIO ! 2544: FREE_AND_NULL(BD->vmem); ! 2545: FREE_AND_NULL(BD); ! 2546: #else ! 2547: for(i=CONIO_FIRST_FREE_FONT; i < 256; i++) { ! 2548: FREE_AND_NULL(conio_fontdata[i].eight_by_sixteen); ! 2549: FREE_AND_NULL(conio_fontdata[i].eight_by_fourteen); ! 2550: FREE_AND_NULL(conio_fontdata[i].eight_by_eight); ! 2551: FREE_AND_NULL(conio_fontdata[i].desc); ! 2552: } ! 2553: #endif ! 2554: if(cterm->playnote_thread_running) { ! 2555: if(sem_trywait(&cterm->playnote_thread_terminated)==-1) { ! 2556: listSemPost(&cterm->notes); ! 2557: sem_wait(&cterm->playnote_thread_terminated); ! 2558: } ! 2559: sem_destroy(&cterm->playnote_thread_terminated); ! 2560: sem_destroy(&cterm->note_completed_sem); ! 2561: listFree(&cterm->notes); 1.1 root 2562: } 1.1.1.2 ! root 2563: free(cterm); 1.1 root 2564: } 2565: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.