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