Annotation of uae/src/ncurses.c, revision 1.1.1.1

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * [n]curses output. May be usefull for people with very poor configuration.
                      5:   * [ Hardly think so (800x600 is faster on my machine), but this is good fun.
                      6:   *   You should get locked up for this, though. FIXME: this file wants color
                      7:   *   support added to it. -- Bernd ]
                      8:   * 
                      9:   * Copyright 1997, Samuel Devulder.
                     10:   */
                     11: 
                     12: /****************************************************************************/
                     13: 
                     14: #include "sysconfig.h"
                     15: #include "sysdeps.h"
                     16: 
                     17: #include <ctype.h>
                     18: #include <signal.h>
                     19: 
                     20: /****************************************************************************/
                     21: 
                     22: #include "uae.h"
                     23: #include "config.h"
                     24: #include "options.h"
                     25: #include "memory.h"
                     26: #include "custom.h"
                     27: #include "readcpu.h"
                     28: #include "newcpu.h"
                     29: #include "xwin.h"
                     30: #include "keyboard.h"
                     31: #include "keybuf.h"
                     32: #include "disk.h"
                     33: #include "debug.h"
                     34: #include "gui.h"
                     35: 
                     36: #ifdef HAVE_NCURSES_H
                     37: #include <ncurses.h>
                     38: #else
                     39: #include <curses.h>
                     40: #endif
                     41: 
                     42: /****************************************************************************/
                     43: 
                     44: #define MAXGRAYCHAR 128
                     45: 
                     46: static chtype graychar[MAXGRAYCHAR];
                     47: static int maxc,max_graychar;
                     48: static int curses_on;
                     49: 
                     50: xcolnr xcolors[4096];
                     51: 
                     52:  /* Keyboard and mouse */
                     53: 
                     54: static int keystate[256];
                     55: static int keydelay = 20;
                     56: 
                     57: int buttonstate[3];
                     58: int lastmx, lastmy;
                     59: int newmousecounters;
                     60: 
                     61: struct vidbuf_description gfxvidinfo;
                     62: 
                     63: /****************************************************************************/
                     64: 
                     65: static void curses_init(void);
                     66: static void curses_exit(void);
                     67: static void init_colors(void);
                     68: static void curses_insert_disk(int);
                     69: 
                     70: /****************************************************************************/
                     71: 
                     72: static RETSIGTYPE sigbrkhandler(int foo)
                     73: {
                     74:     curses_exit();
                     75:     activate_debugger();
                     76: }
                     77: 
                     78: void setup_brkhandler(void)
                     79: {
                     80:     struct sigaction sa;
                     81:     sa.sa_handler = sigbrkhandler;
                     82:     sa.sa_flags = 0;
                     83:     sa.sa_flags = SA_RESTART;
                     84:     sigemptyset(&sa.sa_mask);
                     85:     sigaction(SIGINT, &sa, NULL);
                     86: }
                     87: 
                     88: /****************************************************************************/
                     89: 
                     90: static void init_graychar(void)
                     91: {
                     92:     chtype *p = graychar;
                     93:     chtype attrs;
                     94:     int i,j;
                     95:     char *fmt;
                     96: 
                     97:     attrs = termattrs();
                     98:     if(attrs & A_REVERSE) fmt = " .:=obIXMB^v^#MXIbo=:. ";
                     99:     else                  fmt = " .`'^^\",:;i!1Il+=tfjxznuvyZYXHUOQ0MWB";
                    100:     /*                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
                    101:     /* One could find a better pattern..                                */
                    102:     attrs = A_NORMAL;
                    103:     while(*fmt) {
                    104:         if(*fmt == '^') {
                    105:             ++fmt;
                    106:             switch(*fmt) {
                    107:                 case 'v': case 'V': attrs ^= A_REVERSE; break;
                    108:                 case 'b': case 'B': attrs ^= A_BOLD; break;
                    109:                 case 'd': case 'D': attrs ^= A_DIM; break;
                    110:                 case 'u': case 'U': attrs ^= A_UNDERLINE; break;
                    111:                 case 'p': case 'P': attrs  = A_NORMAL; break;
                    112:                 case '#': if(ACS_CKBOARD == ':')
                    113:                                *p++ = (attrs | '#');
                    114:                           else *p++ = (attrs | ACS_CKBOARD); break;
                    115:                 default:  *p++ = (attrs | *fmt); break;
                    116:             }
                    117:             ++fmt;
                    118:         } else *p++ = (attrs | *fmt++);
                    119:         if(p >= graychar + MAXGRAYCHAR) break;
                    120:     }
                    121:     max_graychar = (p - graychar) - 1;
                    122: #if 0
                    123:     for(j=0;j<LINES;++j) {
                    124:         move(j,0);
                    125:         for(i=0;i<COLS;++i) addch(graychar[i % (max_graychar+1)]);
                    126:     }
                    127:     refresh();
                    128:     sleep(3);
                    129: #endif
                    130: }
                    131: 
                    132: /****************************************************************************/
                    133: 
                    134: static int getcol(int x, int y)
                    135: {
                    136:     int xs, xe, ys, ye, c, cm;
                    137:     cm = c = 0;
                    138:     xs = ((x+0)*gfx_requested_width)/COLS;
                    139:     xe = ((x+1)*gfx_requested_width)/COLS;
                    140:     ys = ((y+0)*gfx_requested_height)/LINES;
                    141:     ye = ((y+1)*gfx_requested_height)/LINES;
                    142:     for(y = ys; y < ye; ++y)
                    143:     for(x = xs; x < xe; ++x)
                    144:         {
                    145:             c  += (UBYTE)gfxvidinfo.bufmem[x + y*gfx_requested_width];
                    146:             ++cm;
                    147:         }
                    148:     return cm?c/cm:0;
                    149: }
                    150: 
                    151: /****************************************************************************/
                    152: 
                    153: static void flush_line_txt(int y)
                    154: {
                    155:     int x;
                    156:     move(y,0);
                    157:     for(x=0;x<COLS;++x)
                    158:         {
                    159:             int c;
                    160:             c = getcol(x,y);
                    161:             if(!no_xhair) c = maxc - c;
                    162:             addch(graychar[(c*max_graychar)/maxc]);
                    163:         }
                    164: }
                    165: 
                    166: /****************************************************************************/
                    167: 
                    168: __inline__ void flush_line(int y)
                    169: {
                    170:     if(y<0 || y>=gfx_requested_height) {
                    171: /*       printf("flush_line out of window: %d\n", y); */
                    172:        return;
                    173:     }
                    174:     if(!curses_on) return;
                    175:     flush_line_txt((y*LINES)/gfx_requested_height);
                    176: }
                    177: 
                    178: /****************************************************************************/
                    179: 
                    180: void flush_block (int ystart, int ystop)
                    181: {
                    182:     int y;
                    183:     if(!curses_on) return;
                    184:     ystart = (ystart * LINES)/gfx_requested_height;
                    185:     ystop  = (ystop  * LINES)/gfx_requested_height;
                    186:     for(y=ystart; y<=ystop; ++y) flush_line_txt(y);
                    187: }
                    188: 
                    189: /****************************************************************************/
                    190: 
                    191: void flush_screen (int ystart, int ystop)
                    192: {
                    193:     if(!debugging && !curses_on) {
                    194:         curses_init();
                    195:         flush_block(0, gfx_requested_height - 1);
                    196:     }
                    197:     refresh();
                    198: }
                    199: 
                    200: /****************************************************************************/
                    201: 
                    202: static void init_colors(void)
                    203: {
                    204:     int i;
                    205:     for(i=0;i<4096;++i) {
                    206:         int r,g,b;
                    207:         r =  i>>8;
                    208:         g = (i>>4)&15;
                    209:         b =  i&15;
                    210:         xcolors[i] = (77 * r + 151 * g + 28 * b)/16;
                    211:         if(xcolors[i] > maxc) maxc = xcolors[i];
                    212:     }
                    213: }
                    214: 
                    215: /****************************************************************************/
                    216: 
                    217: static void curses_init()
                    218: {
                    219:     initscr();cbreak();noecho();
                    220:     nonl();intrflush(stdscr, FALSE); keypad(stdscr, TRUE);
                    221:     nodelay(stdscr, TRUE);
                    222:     leaveok(stdscr, TRUE);
                    223: 
                    224: #ifdef NCURSES_MOUSE_VERSION
                    225:     mousemask(BUTTON1_PRESSED | BUTTON1_RELEASED |
                    226:               BUTTON2_PRESSED | BUTTON2_RELEASED |
                    227:               BUTTON3_PRESSED | BUTTON3_RELEASED |
                    228:               REPORT_MOUSE_POSITION, NULL);
                    229: #endif
                    230: 
                    231:     init_graychar();
                    232:     curses_on = 1;
                    233: }
                    234: 
                    235: /****************************************************************************/
                    236: 
                    237: static void curses_exit()
                    238: {
                    239: #ifdef NCURSES_MOUSE_VERSION
                    240:     mousemask(0, NULL);
                    241: #endif
                    242: 
                    243:     nocbreak(); echo(); nl(); intrflush(stdscr, TRUE); 
                    244:     keypad(stdscr, FALSE); nodelay(stdscr, FALSE); leaveok(stdscr, FALSE);
                    245:     endwin();
                    246:     curses_on = 0;
                    247: }
                    248: 
                    249: /****************************************************************************/
                    250: 
                    251: int graphics_init(void)
                    252: {
                    253:     int i;
                    254: 
                    255:     if(!debugging) {
                    256:         curses_init();
                    257:         fprintf(stderr,"Using %s.\n",longname());
                    258:     }
                    259: 
                    260:     /* we have a 320x256x8 pseudo screen */
                    261: 
                    262:     gfx_requested_width      = 320;
                    263:     gfx_requested_height     = 256;
                    264:     gfx_requested_lores      = 1;
                    265: 
                    266:     gfxvidinfo.maxlinetoscr  = gfx_requested_width;
                    267:     gfxvidinfo.maxline       = gfx_requested_height;
                    268:     gfxvidinfo.maxblocklines = 100; /* whatever */
                    269:     gfxvidinfo.pixbytes      = 1;
                    270:     gfxvidinfo.rowbytes      = gfxvidinfo.pixbytes * gfx_requested_width;
                    271:     gfxvidinfo.bufmem        = (char *)calloc(gfxvidinfo.rowbytes, gfx_requested_height+1);
                    272: 
                    273:     if(!gfxvidinfo.bufmem) {
                    274:         fprintf(stderr,"Not enough memory.\n");
                    275:         return 0;
                    276:     } 
                    277: 
                    278:     init_colors();
                    279: 
                    280:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
                    281:     for(i=0; i<256; i++)
                    282:         keystate[i] = 0;
                    283:     
                    284:     lastmx = lastmy = 0; 
                    285:     newmousecounters = 0;
                    286: 
                    287:     return 1;
                    288: }
                    289: 
                    290: /****************************************************************************/
                    291: 
                    292: void graphics_leave(void)
                    293: {
                    294:     curses_exit();
                    295: }
                    296: 
                    297: /****************************************************************************/
                    298: 
                    299: static int keycode2amiga(int ch)
                    300: {
                    301:     switch(ch) {
                    302:         case KEY_A1:    return AK_NP7;
                    303:         case KEY_UP:    return AK_NP8;
                    304:         case KEY_A3:    return AK_NP9;
                    305:         case KEY_LEFT:  return AK_NP4;
                    306:         case KEY_B2:    return AK_NP5;
                    307:         case KEY_RIGHT: return AK_NP6;
                    308:         case KEY_C1:    return AK_NP1;
                    309:         case KEY_DOWN:  return AK_NP2;
                    310:         case KEY_C3:    return AK_NP3;
                    311:         case KEY_ENTER: return AK_ENT;
                    312:         case 13:        return AK_RET;
                    313:         case ' ':       return AK_SPC;
                    314:         case 27:        return AK_ESC;
                    315:         default: return -1;
                    316:     }
                    317: }
                    318: 
                    319: /***************************************************************************/
                    320: 
                    321: void handle_events(void)
                    322: {
                    323:     int ch;
                    324:     int kc;
                    325: 
                    326:     /* Hack to simulate key release */
                    327:     for(kc = 0; kc < 256; ++kc) {
                    328:         if(keystate[kc]) if(!--keystate[kc]) record_key((kc << 1) | 1);
                    329:     }
                    330:     if(buttonstate[0]) --buttonstate[0];
                    331:     if(buttonstate[1]) --buttonstate[1];
                    332:     if(buttonstate[2]) --buttonstate[2];
                    333: 
                    334:     newmousecounters = 0;
                    335:     if(!curses_on) return;
                    336: 
                    337:     while((ch = getch())!=ERR) {
                    338:         if(ch == 12) {clearok(stdscr,TRUE);refresh();}
                    339: #ifdef NCURSES_MOUSE_VERSION
                    340:         if(ch == KEY_MOUSE) {
                    341:             MEVENT ev;
                    342:             if(getmouse(&ev) == OK) {
                    343:                 lastmx = (ev.x*gfx_requested_width)/COLS;
                    344:                 lastmy = (ev.y*gfx_requested_height)/LINES;
                    345:                 if(ev.bstate & BUTTON1_PRESSED)  buttonstate[0] = keydelay;
                    346:                 if(ev.bstate & BUTTON1_RELEASED) buttonstate[0] = 0;
                    347:                 if(ev.bstate & BUTTON2_PRESSED)  buttonstate[1] = keydelay;
                    348:                 if(ev.bstate & BUTTON2_RELEASED) buttonstate[1] = 0;
                    349:                 if(ev.bstate & BUTTON3_PRESSED)  buttonstate[2] = keydelay;
                    350:                 if(ev.bstate & BUTTON3_RELEASED) buttonstate[2] = 0;
                    351:             }
                    352:         }
                    353: #endif
                    354:         if(ch == 6)  ++lastmx; /* ^F */
                    355:         if(ch == 2)  --lastmx; /* ^B */
                    356:         if(ch == 14) ++lastmy; /* ^N */
                    357:         if(ch == 16) --lastmy; /* ^P */
                    358:        if(ch == 11) {buttonstate[0] = keydelay;ch = 0;} /* ^K */
                    359:        if(ch == 25) {buttonstate[2] = keydelay;ch = 0;} /* ^Y */
                    360:        
                    361:         if(ch >= KEY_F(1) && ch<=KEY_F(4)) {
                    362:          curses_insert_disk(ch - KEY_F(1));
                    363:          ch = 0;
                    364:        }
                    365: 
                    366:         if(isupper(ch)) {
                    367:             keystate[AK_LSH] =
                    368:             keystate[AK_RSH] = keydelay;
                    369:             record_key(AK_LSH << 1);
                    370:             record_key(AK_RSH << 1);
                    371:             kc = keycode2amiga(tolower(ch));
                    372:             keystate[kc] = keydelay;
                    373:             record_key(kc << 1);
                    374:         } else if((kc = keycode2amiga(ch)) >= 0) {
                    375:             keystate[kc] = keydelay;
                    376:             record_key(kc << 1);
                    377:         }
                    378:     }
                    379:     gui_handle_events();
                    380: }
                    381: 
                    382: /***************************************************************************/
                    383: 
                    384: void target_specific_usage(void)
                    385: {
                    386:     printf("----------------------------------------------------------------------------\n");
                    387:     printf("[n]curses specific usage:\n");
                    388:     printf("  -x : Display reverse video.\n");
                    389:     printf("By default uae will assume a black on white display. If yours\n");
                    390:     printf("is light on dark, use -x. In case of graphics garbage, ^L will\n");
                    391:     printf("redisplay the screen. ^K simulate left mouse button, ^Y RMB.\n");
                    392:     printf("If you are using a xterm UAE can use the mouse. Else use ^F ^B\n");
                    393:     printf("^P ^N to emulate mouse mouvements.\n");
                    394:     printf("----------------------------------------------------------------------------\n");
                    395: }
                    396: 
                    397: /***************************************************************************/
                    398: 
                    399: int debuggable(void)
                    400: {
                    401:     return 1;
                    402: }
                    403: 
                    404: /***************************************************************************/
                    405: 
                    406: int needmousehack(void)
                    407: {
                    408:     return 1;
                    409: }
                    410: 
                    411: /***************************************************************************/
                    412: 
                    413: void LED(int on)
                    414: {
                    415: }
                    416: 
                    417: /***************************************************************************/
                    418: 
                    419: static void curses_insert_disk(int dsk)
                    420: {
                    421:     char buff[256];
                    422:     char *s = buff;
                    423:     curses_exit();
                    424:     fprintf(stderr, "Old DF%d filename: %s\n", dsk, dsk==0?df0:dsk==1?df1:
                    425:                                                     dsk==2?df2:df3);
                    426:     fprintf(stderr,"Please type filename for drive %d: ", dsk);
                    427:     fflush(stderr);
                    428:     fgets(buff, 255, stdin);
                    429:     while(*s) if(*s == '\n') *s='\0'; else ++s;
                    430:     if(*buff) disk_insert(dsk, buff);
                    431:     flush_screen(0,0);
                    432: }
                    433: 
                    434: /***************************************************************************/
                    435: 
                    436: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.