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