|
|
1.1 root 1: #include <stdio.h>
2: #include <libc.h>
3: #include <math.h>
4: #include "3610op.h"
5:
6: minit(cold)
7: {
8: msnare();
9: mcmd(INI);
10: mcmd(WRMSKL); mlong(0xffffffff);
11: mcmd(WRBANK); mbyte(15);
12: mcmd(SELRES); mbyte(0xc0); mbyte(0); /* 8-bit mode */
13: mcmd(CMSEL); mbyte(0); mbyte(0); /* write in cmap buffer 0 */
14: mcmd(CMRAMP);mword(0);mword(256); /* default linear color map */
15: mbyte(0);mbyte(0);mbyte(0);
16: mbyte(255);mbyte(255);mbyte(255);
17: mcmd(CMACT); /* make current buffer active */
18: mcmd(SETCLL); mbyte(0); mbyte(0); mbyte(0); mbyte(0);
19: mcmd(CLEAR); /* clear all pixels */
20: mflush();
21: }
22:
23: colmap(maxi,mapr,mapg,mapb)
24: int maxi;
25: int mapr[],mapg[],mapb[]; /* colors, 0 through maxi */
26: {
27: int i;
28: mcmd(CMSEL); mbyte(0); mbyte(0); /* write in cmap buffer 0 */
29: mcmd(CMLDM); mword(0);mword(maxi+2); /* load entries at loc. 0 */
30: mbyte(0);mbyte(0);mbyte(0); /* index 0 is for black background */
31: for(i=0; i<=maxi; i++){
32: mbyte(mapr[i]); mbyte(mapg[i]); mbyte(mapb[i]);
33: }
34: if((maxi+2)&1) mbyte(0);
35: mcmd(CMACT); /* make current buffer active */
36: mflush();
37: }
38:
39: image(in, x0, y0, x1, y1)
40: char *in;
41: {
42: int around=0;
43: long n, saved, m;
44: if(((int)in)&1){ error("odd address\n"); }
45: n=(x1-x0+1)*(y1-y0+1);
46: mcmd(MOVP1); mword(x0); mword(1023-y1); /* upper left */
47: mcmd(MOVP2); mword(x1); mword(1023-y0); /* lower right */
48: mcmd(WRR);
49: mflush();
50: if(n&1) n++; /* hope this doesn't lead to a memory fault */
51: Write(mfd, in, n);
52: }
53:
54: zoom(fact)
55: int fact;
56: {
57: mcmd(ZOOM);mbyte(fact);
58: }
59:
60: pan(x,y)
61: int x, y; /* upper left corner */
62: {
63: mcmd(SYNCH);mword(0); /* next instruction should happen during vert retrace */
64: mcmd(MOVP1);mword(x);mword(1023-y);
65: mcmd(PPAN);
66: mflush();
67: }
68:
69:
70: #define SAVCOLOR mapr[i]=255.499*r;mapg[i]=255.499*g;mapb[i]=255.499*b;
71:
72: cvmap ( map, maxi, mapr,mapg,mapb ) /* load color map */
73: char *map; /* string describing kind of map */
74: int maxi;
75: int mapr[],mapg[],mapb[]; /* colors, 0 through maxi */
76: {
77: int i, j;
78: int max1, max2;
79: double r, g, b;
80: double dm = maxi;
81: double sqrt();
82: FILE *mapf;
83: if(maxi<0) error("maxi must be >= 0");
84: if(maxi>=254) error("maxi must be < 254");
85: switch(*map){
86: case 'f': /* input from file */
87: mapf = fopen(map+1,"r");
88: if( mapf==NULL ) error("can't open %s",map+1);
89: for(i=0; i<=maxi; i++){
90: if(fscanf(mapf,"%d %d %d",&mapr[i],&mapg[i],&mapb[i])!=3)
91: error("trouble reading color map %d",i);
92: }
93: fclose(mapf);
94: break;
95: case 'r': /* red v. blue */
96: for(i=0; i<=maxi; i++){
97: r=sqrt(i/dm); g=sqrt(0.); b=sqrt(1-i/dm);
98: brit(&r,&g,&b);
99: SAVCOLOR;
100: }
101: break;
102: case NULL:
103: case 's': /* blue-to-red rainbow */
104: for(i=0; i<=maxi; i++){
105: rainbow(1-i/dm,1.,1.,&r,&g,&b);
106: r=sqrt(r); g=sqrt(g); b=sqrt(b);
107: SAVCOLOR;
108: }
109: break;
110: case 'g': /* normal map, corrected for gamma */
111: for(i=0; i<=maxi; i++){
112: r=sqrt(i/dm); g=sqrt(i/dm); b=sqrt(i/dm);
113: SAVCOLOR;
114: }
115: break;
116: case 'i': /* like g, but inverse video */
117: for(i=0; i<=maxi; i++){
118: r=sqrt(1-i/dm); g=sqrt(1-i/dm); b=sqrt(1-i/dm);
119: SAVCOLOR;
120: }
121: break;
122: case 'n': /* no-op, use default linear color map */
123: return(0);
124: default:
125: err:
126: fprintf(stderr,"unrecognized color map %s\n",map);
127: }
128: colmap(maxi,mapr,mapg,mapb);
129: }
130:
131: brit(r,g,b)
132: double *r, *g, *b;
133: {
134: /* convert from r+g+b=1 to max(r,g,b)=1 */
135: double t;
136: t = (*r>*b)?*r:*b;
137: if(*g>t) t = *g;
138: *r /= t;
139: *g /= t;
140: *b /= t;
141: }
142:
143:
144:
145: /**** taken from /n/research/netlib/misc/rainbow *****/
146: /* rainbow(h, s, v, r, g, b)
147: double h, s, v, *r, *g, *b;
148:
149: This routine computes colors suitable for use in color level plots.
150: Typically s=v=1 and h varies from 0 (red) to 1 (blue) in
151: equally spaced steps. (h>1 gives magenta.)
152: To convert for frame buffer, use R = (int)(255.999*sqrt(*r)) etc.
153: complaints => Eric Grosse research!ehg 201-582-5828
154: */
155:
156: #include <math.h>
157: double huextab[] = {
158: .0000,.0156,.0313,.0469,.0625,.0781,.0938,.1094,.1250,.1406,
159: .1563,.1719,.1875,.2031,.2188,.2344,.2500,.2656,.2813,.2969,
160: .3125,.3281,.3438,.3594,.3750,.3906,.4063,.4219,.4375,.4531,
161: .4688,.4844,.5000,.5156,.5313,.5469,.5625,.5781,.5938,.6094,
162: .6250,.6406,.6563,.6719,.6875,.7031,.7188,.7344,.7500,.7656,
163: .7813,.7969,.8125,.8281,.8438,.8594,.8750,.8906,.9063,.9219,
164: .9375,.9531,.9688,.9844,1. };
165: double huettab[] = {
166: .0000,.0052,.0105,.0160,.0218,.0277,.0339,.0404,.0471,.0542,
167: .0616,.0693,.0775,.0862,.0954,.1052,.1157,.1269,.1390,.1519,
168: .1660,.1824,.1974,.2115,.2248,.2374,.2495,.2609,.2719,.2824,
169: .2926,.3023,.3118,.3210,.3300,.3456,.3600,.3761,.3943,.4153,
170: .4399,.4688,.5048,.5211,.5359,.5494,.5617,.5729,.5832,.5925,
171: .6010,.6088,.6160,.6225,.6285,.6340,.6390,.6436,.6478,.6516,
172: .6552,.6584,.6614,.6642,.6667 };
173: /* computed from the FMC-1 color difference formula */
174: /* Hitachi monitor, max(r,g,b)=1, n=65, 7 Jan 1985 */
175:
176: rainbow(h, s, v, r, g, b)
177: double h, s, v, *r, *g, *b;
178: {
179: double *x = huextab;
180: double *t = huettab;
181: while( (x[1]<=h) && (x[1]<1.) ){ ++x; ++t; }
182: h = t[0] + (t[1]-t[0])*(h-x[0])/(x[1]-x[0]);
183: dhsv2rgb(h,s,v,r,g,b);
184: }
185:
186: dhsv2rgb(h, s, v, r, g, b) /*...hexcone model...*/
187: double h, s, v, *r, *g, *b; /* all variables in range [0,1] */
188: {
189: int i;
190: double f, m, n, k;
191: h *= 6;
192: i = (int)floor(h);
193: f = h-i;
194: m = (1-s);
195: n = (1-s*f);
196: k = (1-(s*(1-f)));
197: switch(i){
198: case 0: *r=1; *g=k; *b=m; break;
199: case 1: *r=n; *g=1; *b=m; break;
200: case 2: *r=m; *g=1; *b=k; break;
201: case 3: *r=m; *g=n; *b=1; break;
202: case 4: *r=k; *g=m; *b=1; break;
203: case 5: *r=1; *g=m; *b=n; break;
204: default: error("bad i: %f %d",h,i);
205: }
206: f = *r;
207: if( f < *g ) f = *g;
208: if( f < *b ) f = *b;
209: f = v / f;
210: *r *= f;
211: *g *= f;
212: *b *= f;
213: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.