Annotation of uae/src/ncurses.c, revision 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.