|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
1.1.1.2 root 3: *
4: * [n]curses output.
5: *
6: * There are 17 color modes:
7: * -H0/-H1 are black/white output
8: * -H2 through -H16 give you different color allocation strategies. On my
9: * system, -H14 seems to give nice results.
10: *
11: * Copyright 1997 Samuel Devulder, Bernd Schmidt
1.1 root 12: */
13:
14: /****************************************************************************/
15:
16: #include "sysconfig.h"
17: #include "sysdeps.h"
18:
19: #include <ctype.h>
20: #include <signal.h>
21:
22: /****************************************************************************/
23:
24: #include "config.h"
25: #include "options.h"
1.1.1.6 ! root 26: #include "threaddep/thread.h"
1.1.1.2 root 27: #include "uae.h"
1.1 root 28: #include "memory.h"
29: #include "custom.h"
30: #include "newcpu.h"
31: #include "xwin.h"
32: #include "keyboard.h"
33: #include "keybuf.h"
34: #include "disk.h"
35: #include "debug.h"
36: #include "gui.h"
37:
38: #ifdef HAVE_NCURSES_H
39: #include <ncurses.h>
40: #else
41: #include <curses.h>
42: #endif
43:
44: /****************************************************************************/
45:
46: #define MAXGRAYCHAR 128
47:
1.1.1.2 root 48: enum {
49: MYCOLOR_BLACK, MYCOLOR_RED, MYCOLOR_GREEN, MYCOLOR_BLUE,
50: MYCOLOR_YELLOW, MYCOLOR_CYAN, MYCOLOR_MAGENTA, MYCOLOR_WHITE
51: };
52:
53: static int mycolor2curses_map [] = {
54: COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE,
55: COLOR_YELLOW, COLOR_CYAN, COLOR_MAGENTA, COLOR_WHITE
56: };
57:
58: static int mycolor2pair_map[] = { 1,2,3,4,5,6,7,8 };
59:
1.1 root 60: static chtype graychar[MAXGRAYCHAR];
61: static int maxc,max_graychar;
62: static int curses_on;
63:
1.1.1.2 root 64: static int *x2graymap;
1.1 root 65:
1.1.1.2 root 66: /* Keyboard and mouse */
1.1 root 67:
68: static int keystate[256];
69: static int keydelay = 20;
70:
71: static void curses_exit(void);
72:
73: /****************************************************************************/
74:
75: static RETSIGTYPE sigbrkhandler(int foo)
76: {
77: curses_exit();
78: activate_debugger();
79: }
80:
81: void setup_brkhandler(void)
82: {
83: struct sigaction sa;
84: sa.sa_handler = sigbrkhandler;
85: sa.sa_flags = 0;
86: sa.sa_flags = SA_RESTART;
87: sigemptyset(&sa.sa_mask);
88: sigaction(SIGINT, &sa, NULL);
89: }
90:
1.1.1.2 root 91: /***************************************************************************/
92:
93: static void curses_insert_disk(void)
94: {
95: curses_exit();
96: gui_changesettings();
97: flush_screen(0,0);
98: }
99:
1.1 root 100: /****************************************************************************/
101:
1.1.1.2 root 102: /*
103: * old: fmt = " .,:=(Io^vM^vb*X^#M^vX*boI(=:. ^b^vobX^#M" doesn't work: "^vXb*oI(=:. ";
104: * good: fmt = " .':;=(IoJpgFPEB#^vgpJoI(=;:'. ^v^b=(IoJpgFPEB";
105: *
106: * fmt = " .,:=(Io*b^vM^vX^#M^vXb*oI(=:. ";
107: */
108:
1.1 root 109: static void init_graychar(void)
110: {
111: chtype *p = graychar;
112: chtype attrs;
113: int i,j;
114: char *fmt;
115:
116: attrs = termattrs();
1.1.1.2 root 117: if ((currprefs.color_mode & 1) == 0 && (attrs & (A_REVERSE | A_BOLD)))
118: fmt = " .':;=(IoJpgFPEB#^vgpJoI(=;:'. ^v^boJpgFPEB";
119: else if ((currprefs.color_mode & 1) == 0 && (attrs & A_REVERSE))
120: fmt = " .':;=(IoJpgFPEB#^vgpJoI(=;:'. ";
121: else
122: /* One could find a better pattern.. */
123: fmt = " .`'^^\",:;i!1Il+=tfjxznuvyZYXHUOQ0MWB";
124: attrs = A_NORMAL | COLOR_PAIR (0);
1.1 root 125: while(*fmt) {
1.1.1.2 root 126: if(*fmt == '^') {
127: ++fmt;
128: switch(*fmt) {
129: case 's': case 'S': attrs ^= A_STANDOUT; break;
130: case 'v': case 'V': attrs ^= A_REVERSE; break;
131: case 'b': case 'B': attrs ^= A_BOLD; break;
132: case 'd': case 'D': attrs ^= A_DIM; break;
133: case 'u': case 'U': attrs ^= A_UNDERLINE; break;
134: case 'p': case 'P': attrs = A_NORMAL; break;
135: case '#': if(ACS_CKBOARD == ':')
136: *p++ = (attrs | '#');
137: else *p++ = (attrs | ACS_CKBOARD); break;
138: default: *p++ = (attrs | *fmt); break;
139: }
140: ++fmt;
141: } else *p++ = (attrs | *fmt++);
142: if(p >= graychar + MAXGRAYCHAR) break;
1.1 root 143: }
144: max_graychar = (p - graychar) - 1;
1.1.1.2 root 145:
146: for (i = 0; i <= maxc; i++)
147: x2graymap[i] = i * max_graychar / maxc;
1.1 root 148: #if 0
149: for(j=0;j<LINES;++j) {
1.1.1.2 root 150: move(j,0);
151: for(i=0;i<COLS;++i) addch(graychar[i % (max_graychar+1)]);
1.1 root 152: }
153: refresh();
154: sleep(3);
155: #endif
156: }
157:
1.1.1.2 root 158: static int x_map[900], y_map[700], y_rev_map [700];
159:
160:
1.1 root 161: /****************************************************************************/
162:
1.1.1.2 root 163: static void init_colors(void)
1.1 root 164: {
1.1.1.2 root 165: int i;
166:
167: maxc = 0;
168:
169: for(i = 0; i < 4096; ++i) {
170: int r,g,b,r1,g1,b1;
171: int m, comp;
172: int ctype;
173:
174: r = i >> 8;
175: g = (i >> 4) & 15;
176: b = i & 15;
177:
178: xcolors[i] = (77 * r + 151 * g + 28 * b)/16;
179: if(xcolors[i] > maxc)
180: maxc = xcolors[i];
181: m = r;
182: if (g > m)
183: m = g;
184: if (b > m)
185: m = b;
186: if (m == 0) {
187: xcolors[i] |= MYCOLOR_WHITE << 8; /* to get gray instead of black in dark areas */
188: continue;
189: }
190:
191: if ((currprefs.color_mode & ~1) != 0) {
192: r1 = r*15 / m;
193: g1 = g*15 / m;
194: b1 = b*15 / m;
195:
196: comp = 8;
197: for (;;) {
198: if (b1 < comp) {
199: if (r1 < comp)
200: ctype = MYCOLOR_GREEN;
201: else if (g1 < comp)
202: ctype = MYCOLOR_RED;
203: else
204: ctype = MYCOLOR_YELLOW;
205: } else {
206: if (r1 < comp) {
207: if (g1 < comp)
208: ctype = MYCOLOR_BLUE;
209: else
210: ctype = MYCOLOR_CYAN;
211: } else if (g1 < comp)
212: ctype = MYCOLOR_MAGENTA;
213: else {
214: comp += 4;
215: if (comp == 12 && (currprefs.color_mode & 2) != 0)
216: continue;
217: ctype = MYCOLOR_WHITE;
218: }
219: }
220: break;
221: }
222: if (currprefs.color_mode & 8) {
223: if (ctype == MYCOLOR_BLUE && xcolors[i] > /*27*/50)
224: ctype = r1 > (g1+2) ? MYCOLOR_MAGENTA : MYCOLOR_CYAN;
225: if (ctype == MYCOLOR_RED && xcolors[i] > /*75*/ 90)
226: ctype = b1 > (g1+6) ? MYCOLOR_MAGENTA : MYCOLOR_YELLOW;
227: }
228: xcolors[i] |= ctype << 8;
229: }
230: }
231: if (currprefs.color_mode & 4) {
232: int j;
233: for (j = MYCOLOR_RED; j < MYCOLOR_WHITE; j++) {
234: int best = 0, maxv = 0;
235: int multi, divi;
236:
237: for (i = 0; i < 4096; i++)
238: if ((xcolors[i] & 255) > maxv && (xcolors[i] >> 8) == j) {
239: best = i;
240: maxv = (xcolors[best] & 255);
241: }
242: /* Now maxv is the highest intensity a color of type J is supposed to have.
243: * In reality, it will most likely only have intensity maxv*multi/divi.
244: * We try to correct this. */
245: maxv = maxv * 256 / maxc;
246:
247: divi = 256;
248: switch (j) {
249: case MYCOLOR_RED: multi = 77; break;
250: case MYCOLOR_GREEN: multi = 151; break;
251: case MYCOLOR_BLUE: multi = 28; break;
252: case MYCOLOR_YELLOW: multi = 228; break;
253: case MYCOLOR_CYAN: multi = 179; break;
254: case MYCOLOR_MAGENTA: multi = 105; break;
255: default: abort();
256: }
257: #if 1 /* This makes the correction less extreme */
258: if (! (currprefs.color_mode & 8))
259: multi = (multi + maxv) / 2;
260: #endif
261: for (i = 0; i < 4096; i++) {
262: int v = xcolors[i];
263: if ((v >> 8) != j)
264: continue;
265: v &= 255;
266: /* I don't think either of these is completely correct, but
267: * the first one produces rather good results. */
268: #if 1
269: v = v * divi / multi;
270: if (v > maxc)
271: v = maxc;
272: #else
273: v = v * 256 / maxv);
274: if (v > maxc)
275: /*maxc = v*/abort();
276: #endif
277: xcolors[i] = v | (j << 8);
278: }
279: }
280: }
281: x2graymap = (int *)malloc(sizeof(int) * (maxc+1));
282: }
283:
284: static void curses_init(void)
285: {
286: initscr ();
287:
288: start_color ();
289: if (! has_colors () || COLOR_PAIRS < 20 /* whatever */)
290: currprefs.color_mode &= 1;
291: else {
292: init_pair (1, COLOR_BLACK, COLOR_BLACK);
293: init_pair (2, COLOR_RED, COLOR_BLACK);
294: init_pair (3, COLOR_GREEN, COLOR_BLACK);
295: init_pair (4, COLOR_BLUE, COLOR_BLACK);
296: init_pair (5, COLOR_YELLOW, COLOR_BLACK);
297: init_pair (6, COLOR_CYAN, COLOR_BLACK);
298: init_pair (7, COLOR_MAGENTA, COLOR_BLACK);
299: init_pair (8, COLOR_WHITE, COLOR_BLACK);
300: }
301: printf ("curses_init: %d pairs available\n", COLOR_PAIRS);
302:
303: cbreak(); noecho();
304: nonl (); intrflush(stdscr, FALSE); keypad(stdscr, TRUE);
305: nodelay(stdscr, TRUE);
306: leaveok(stdscr, TRUE);
307:
308: attron (A_NORMAL | COLOR_PAIR (0));
309: bkgd(' '|COLOR_PAIR(0));
310:
311: #ifdef NCURSES_MOUSE_VERSION
312: mousemask(BUTTON1_PRESSED | BUTTON1_RELEASED |
313: BUTTON2_PRESSED | BUTTON2_RELEASED |
314: BUTTON3_PRESSED | BUTTON3_RELEASED |
315: REPORT_MOUSE_POSITION, NULL);
316: #endif
317:
318: init_graychar();
319: curses_on = 1;
320: }
321:
322: static void curses_exit(void)
323: {
324: #ifdef NCURSES_MOUSE_VERSION
325: mousemask(0, NULL);
326: #endif
327:
328: nocbreak(); echo(); nl(); intrflush(stdscr, TRUE);
329: keypad(stdscr, FALSE); nodelay(stdscr, FALSE); leaveok(stdscr, FALSE);
330: endwin();
331: curses_on = 0;
1.1 root 332: }
333:
334: /****************************************************************************/
335:
1.1.1.2 root 336: static int getgraycol(int x, int y)
337: {
338: uae_u8 *bufpt;
339: int xs, xl, ys, yl, c, cm;
340:
341: xl = x_map[x+1] - (xs = x_map[x]);
342: yl = y_map[y+1] - (ys = y_map[y]);
343:
344: bufpt = ((uae_u8 *)gfxvidinfo.bufmem) + ys*currprefs.gfx_width + xs;
345:
346: cm = c = 0;
347: for(y = 0; y < yl; y++, bufpt += currprefs.gfx_width)
348: for(x = 0; x < xl; x++) {
349: c += bufpt[x];
350: ++cm;
351: }
352: if (cm)
353: c /= cm;
1.1.1.4 root 354: if (! currprefs.curses_reverse_video)
1.1.1.2 root 355: c = maxc - c;
356: return graychar[x2graymap[c]];
357: }
358:
359: static int getcol(int x, int y)
360: {
361: uae_u16 *bufpt;
362: int xs, xl, ys, yl, c, cm;
363: int bestcol = MYCOLOR_BLACK, bestccnt = 0;
364: unsigned char colcnt [8];
365:
366: memset (colcnt, 0 , sizeof colcnt);
367:
368: xl = x_map[x+1] - (xs = x_map[x]);
369: yl = y_map[y+1] - (ys = y_map[y]);
370:
371: bufpt = ((uae_u16 *)gfxvidinfo.bufmem) + ys*currprefs.gfx_width + xs;
372:
373: cm = c = 0;
374: for(y = 0; y < yl; y++, bufpt += currprefs.gfx_width)
375: for(x = 0; x < xl; x++) {
376: int v = bufpt[x];
377: int cnt;
378:
379: c += v & 0xFF;
380: cnt = ++colcnt[v >> 8];
381: if (cnt > bestccnt) {
382: bestccnt = cnt;
383: bestcol = v >> 8;
384: }
385: ++cm;
386: }
387: if (cm)
388: c /= cm;
1.1.1.4 root 389: if (! currprefs.curses_reverse_video)
1.1.1.2 root 390: c = maxc - c;
391: return (graychar[x2graymap[c]] & ~A_COLOR) | COLOR_PAIR (mycolor2pair_map[bestcol]);
392: }
393:
1.1 root 394: static void flush_line_txt(int y)
395: {
396: int x;
1.1.1.2 root 397: move (y,0);
398: if (currprefs.color_mode < 2)
399: for (x = 0; x < COLS; ++x) {
400: int c;
1.1 root 401:
1.1.1.2 root 402: c = getgraycol(x,y);
403: addch(c);
404: }
405: else
406: for (x = 0; x < COLS; ++x) {
407: int c;
408:
409: c = getcol(x,y);
410: addch(c);
411: }
412: }
1.1 root 413:
414: __inline__ void flush_line(int y)
415: {
1.1.1.2 root 416: if(y < 0 || y >= currprefs.gfx_height) {
1.1 root 417: /* printf("flush_line out of window: %d\n", y); */
418: return;
419: }
1.1.1.2 root 420: if(!curses_on)
421: return;
422: flush_line_txt(y_rev_map[y]);
1.1 root 423: }
424:
425: void flush_block (int ystart, int ystop)
426: {
427: int y;
1.1.1.2 root 428: if(!curses_on)
429: return;
430: ystart = y_rev_map[ystart];
431: ystop = y_rev_map[ystop];
432: for(y = ystart; y <= ystop; ++y)
433: flush_line_txt(y);
1.1 root 434: }
435:
436: void flush_screen (int ystart, int ystop)
437: {
438: if(!debugging && !curses_on) {
1.1.1.2 root 439: curses_init();
440: flush_block(0, currprefs.gfx_height - 1);
1.1 root 441: }
442: refresh();
443: }
444:
445: /****************************************************************************/
446:
1.1.1.2 root 447: struct bstring *video_mode_menu = NULL;
1.1 root 448:
1.1.1.2 root 449: void vidmode_menu_selected(int a)
1.1 root 450: {
451: }
452:
1.1.1.2 root 453: int graphics_setup(void)
1.1 root 454: {
1.1.1.2 root 455: return 1;
1.1 root 456: }
457:
458: int graphics_init(void)
459: {
460: int i;
461:
1.1.1.2 root 462: if (currprefs.color_mode > 16)
463: fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
1.1 root 464:
1.1.1.2 root 465: init_colors();
466:
467: curses_init();
468: fprintf(stderr,"Using %s.\n",longname());
1.1 root 469:
1.1.1.2 root 470: if (debugging)
471: curses_exit ();
1.1 root 472:
1.1.1.2 root 473: /* we have a 320x256x8 pseudo screen */
474:
475: currprefs.gfx_width = 320;
476: currprefs.gfx_height = 256;
477: currprefs.gfx_lores = 1;
478:
479: gfxvidinfo.width = currprefs.gfx_width;
480: gfxvidinfo.height = currprefs.gfx_height;
481: gfxvidinfo.maxblocklines = 1000;
482: gfxvidinfo.pixbytes = currprefs.color_mode < 2 ? 1 : 2;
483: gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
484: gfxvidinfo.bufmem = (char *)calloc(gfxvidinfo.rowbytes, currprefs.gfx_height+1);
485: gfxvidinfo.linemem = 0;
1.1.1.3 root 486: gfxvidinfo.emergmem = 0;
1.1.1.2 root 487: gfxvidinfo.can_double = 0;
488: switch (gfxvidinfo.pixbytes) {
489: case 1:
490: for (i = 0; i < 4096; i++)
491: xcolors[i] = xcolors[i] * 0x01010101;
492: gfxvidinfo.can_double = 1;
493: break;
494: case 2:
495: for (i = 0; i < 4096; i++)
496: xcolors[i] = xcolors[i] * 0x00010001;
497: gfxvidinfo.can_double = 1;
498: break;
499: }
1.1 root 500: if(!gfxvidinfo.bufmem) {
1.1.1.2 root 501: fprintf(stderr,"Not enough memory.\n");
502: return 0;
503: }
1.1 root 504:
1.1.1.2 root 505: for (i = 0; i < sizeof x_map / sizeof *x_map; i++)
506: x_map[i] = (i * currprefs.gfx_width) / COLS;
507: for (i = 0; i < sizeof y_map / sizeof *y_map; i++)
508: y_map[i] = (i * currprefs.gfx_height) / LINES;
509: for (i = 0; i < sizeof y_map / sizeof *y_map - 1; i++) {
510: int l1 = y_map[i];
511: int l2 = y_map[i+1];
512: int j;
513: if (l2 >= sizeof y_rev_map / sizeof *y_rev_map)
514: break;
515: for (j = l1; j < l2; j++)
516: y_rev_map[j] = i;
517: }
1.1 root 518:
519: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
520: for(i=0; i<256; i++)
1.1.1.2 root 521: keystate[i] = 0;
522:
523: lastmx = lastmy = 0;
1.1 root 524: newmousecounters = 0;
525:
526: return 1;
527: }
528:
529: /****************************************************************************/
530:
531: void graphics_leave(void)
532: {
533: curses_exit();
534: }
535:
536: /****************************************************************************/
537:
538: static int keycode2amiga(int ch)
539: {
540: switch(ch) {
1.1.1.2 root 541: case KEY_A1: return AK_NP7;
542: case KEY_UP: return AK_NP8;
543: case KEY_A3: return AK_NP9;
544: case KEY_LEFT: return AK_NP4;
545: case KEY_B2: return AK_NP5;
546: case KEY_RIGHT: return AK_NP6;
547: case KEY_C1: return AK_NP1;
548: case KEY_DOWN: return AK_NP2;
549: case KEY_C3: return AK_NP3;
550: case KEY_ENTER: return AK_ENT;
551: case 13: return AK_RET;
552: case ' ': return AK_SPC;
553: case 27: return AK_ESC;
554: default: return -1;
1.1 root 555: }
556: }
557:
558: /***************************************************************************/
559:
560: void handle_events(void)
561: {
562: int ch;
563: int kc;
564:
565: /* Hack to simulate key release */
566: for(kc = 0; kc < 256; ++kc) {
1.1.1.2 root 567: if(keystate[kc]) if(!--keystate[kc]) record_key((kc << 1) | 1);
1.1 root 568: }
569: if(buttonstate[0]) --buttonstate[0];
570: if(buttonstate[1]) --buttonstate[1];
571: if(buttonstate[2]) --buttonstate[2];
572:
573: newmousecounters = 0;
574: if(!curses_on) return;
575:
576: while((ch = getch())!=ERR) {
1.1.1.2 root 577: if(ch == 12) {clearok(stdscr,TRUE);refresh();}
1.1 root 578: #ifdef NCURSES_MOUSE_VERSION
1.1.1.2 root 579: if(ch == KEY_MOUSE) {
580: MEVENT ev;
581: if(getmouse(&ev) == OK) {
582: lastmx = (ev.x*currprefs.gfx_width)/COLS;
583: lastmy = (ev.y*currprefs.gfx_height)/LINES;
584: if(ev.bstate & BUTTON1_PRESSED) buttonstate[0] = keydelay;
585: if(ev.bstate & BUTTON1_RELEASED) buttonstate[0] = 0;
586: if(ev.bstate & BUTTON2_PRESSED) buttonstate[1] = keydelay;
587: if(ev.bstate & BUTTON2_RELEASED) buttonstate[1] = 0;
588: if(ev.bstate & BUTTON3_PRESSED) buttonstate[2] = keydelay;
589: if(ev.bstate & BUTTON3_RELEASED) buttonstate[2] = 0;
590: }
591: }
1.1 root 592: #endif
1.1.1.2 root 593: if (ch == 6) ++lastmx; /* ^F */
594: if (ch == 2) --lastmx; /* ^B */
595: if (ch == 14) ++lastmy; /* ^N */
596: if (ch == 16) --lastmy; /* ^P */
597: if (ch == 11) {buttonstate[0] = keydelay;ch = 0;} /* ^K */
598: if (ch == 25) {buttonstate[2] = keydelay;ch = 0;} /* ^Y */
599: if (ch == 15) uae_reset (); /* ^O */
600: if (ch == 17) uae_quit (); /* ^Q */
601: if (ch == KEY_F(1)) {
602: curses_insert_disk();
1.1 root 603: ch = 0;
604: }
605:
1.1.1.2 root 606: if(isupper(ch)) {
607: keystate[AK_LSH] =
608: keystate[AK_RSH] = keydelay;
609: record_key(AK_LSH << 1);
610: record_key(AK_RSH << 1);
611: kc = keycode2amiga(tolower(ch));
612: keystate[kc] = keydelay;
613: record_key(kc << 1);
614: } else if((kc = keycode2amiga(ch)) >= 0) {
615: keystate[kc] = keydelay;
616: record_key(kc << 1);
617: }
1.1 root 618: }
619: gui_handle_events();
620: }
621:
622: /***************************************************************************/
623:
624: void target_specific_usage(void)
625: {
626: printf("----------------------------------------------------------------------------\n");
627: printf("[n]curses specific usage:\n");
628: printf(" -x : Display reverse video.\n");
629: printf("By default uae will assume a black on white display. If yours\n");
630: printf("is light on dark, use -x. In case of graphics garbage, ^L will\n");
631: printf("redisplay the screen. ^K simulate left mouse button, ^Y RMB.\n");
632: printf("If you are using a xterm UAE can use the mouse. Else use ^F ^B\n");
633: printf("^P ^N to emulate mouse mouvements.\n");
634: printf("----------------------------------------------------------------------------\n");
635: }
636:
637: /***************************************************************************/
638:
1.1.1.4 root 639: int check_prefs_changed_gfx (void)
640: {
641: return 0;
642: }
643:
1.1 root 644: int debuggable(void)
645: {
646: return 1;
647: }
648:
649: int needmousehack(void)
650: {
651: return 1;
652: }
653:
654: void LED(int on)
655: {
656: }
657:
1.1.1.3 root 658: void write_log (const char *buf, ...)
1.1 root 659: {
660:
1.1.1.2 root 661: }
1.1 root 662:
1.1.1.3 root 663: int lockscr (void)
664: {
665: return 1;
666: }
667:
668: void unlockscr (void)
669: {
670: }
1.1.1.4 root 671:
672: void target_save_options (FILE *f, struct uae_prefs *p)
673: {
674: fprintf (f, "curses.reverse_video=%s\n", p->curses_reverse_video ? "true" : "false");
675: }
676:
677: int target_parse_option (struct uae_prefs *p, char *option, char *value)
678: {
679: return (cfgfile_yesno (option, value, "reverse_video", &p->curses_reverse_video));
680: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.