|
|
1.1 root 1: #include <jerq.h>
2: #include <font.h>
3: #undef xmax
4: #undef ymax
5:
6: #define MAX 32767
7: #define ONE 512
8:
9: #define max(a,b) ((a) > (b)? (a):(b))
10: #define abs(a) ((a) >= 0? (a):-(a))
11:
12: #ifdef lint
13: struct Mouse mouse;
14: #endif lint
15:
16: typedef struct Frame
17: {
18: char time[20];
19: Bitmap *b;
20: } Frame;
21: Frame *frames;
22: int maxframe;
23: int start, nx, ny;
24: int doshade = 0;
25: int showgrid = 0;
26: int ragnorok, nsleep;
27: #define SPEED 128
28: #define MSPEED 8192
29: int speed = SPEED;
30: int period;
31: short floor;
32: short zdata[4096];
33: Rectangle bound;
34: long dtime, rtime;
35: extern char *genfn();
36: Menu menu = { (char **)0, genfn };
37: int N;
38: Point ctr, dpt;
39: int rad;
40: int nf;
41: short xmin, xmax, ymax, ymin;
42:
43: Point
44: grid(x, y)
45: {
46: Point p;
47:
48: p.x = N*(x-y);
49: p.y = -(x+y-ny)*N/2;
50: return(add(p, dpt));
51: }
52:
53: #define BB(n) bitblt(frames[n].b, frames[n].b->rect, &display, ctr, F_STORE)
54: #define STOP ((own()&MOUSE) && button123())
55:
56: main()
57: {
58: int n, done, x, y;
59:
60: request(RCV|SEND|MOUSE|KBD);
61: initgrey();
62:
63: dpt = div(add(Drect.origin, Drect.corner), 2);
64:
65: for(wait(RCV); (n = rcvchar()) != 'Q'; wait(RCV))
66: switch(n)
67: {
68: case 'G':
69: showgrid = 1;
70: break;
71: case 'S':
72: doshade = 1;
73: break;
74: case 'X':
75: nx = getn();
76: break;
77: case 'Y':
78: ny = getn();
79: break;
80: case 'P':
81: period = getn();
82: break;
83: case 'n':
84: nf = getn();
85: frames = (Frame *)alloc(nf*sizeof(struct Frame));
86: break;
87: case 'F':
88: gets(frames[maxframe].time);
89: showf(maxframe, frames[maxframe].time);
90: read(nx*ny);
91: if(maxframe == 0)
92: sizeit();
93: if(frames[maxframe].b = balloc(bound))
94: {
95: draw(frames[maxframe].b);
96: BB(maxframe);
97: maxframe++;
98: }
99: break;
100: case 'I':
101: floor = getn();
102: break;
103: }
104:
105: rectf(&display, Drect, F_CLR);
106: showt();
107: start = 0;
108: done = 0;
109: goto startoff;
110: while(done == 0)
111: {
112: wait(MOUSE);
113: if(!button3()) continue;
114: switch(n = menuhit(&menu, 3))
115: {
116: case -1:
117: case 0:
118: break;
119: case 1:
120: if((speed >>= 1) < 1) speed = 1;
121: break;
122: case 2:
123: if((speed <<= 1) > MSPEED) speed = MSPEED;
124: break;
125: case 3:
126: play(start, start? start-1:maxframe-1);
127: break;
128: case 4:
129: startoff:
130: while(!STOP)
131: play(start, start? start-1:maxframe-1);
132: break;
133: case 5:
134: done = 1;
135: break;
136: default:
137: n -= 6;
138: BB(n);
139: start = n;
140: break;
141: }
142: }
143: sendnchars(2, "x\n");
144: sleep(500);
145: }
146:
147: char buf[128], *str;
148:
149: /*VARARGS2*/
150: spr(s, n, m)
151: char *s;
152: unsigned n, m;
153: {
154: str = buf;
155: while(*s)
156: {
157: if((*str++ = *s++) == '%')
158: {
159: str--;
160: if(n != 0xFFFF) digit(n), n = 0xFFFF;
161: else digit(m);
162: }
163: }
164: *str++ = 0;
165: }
166:
167: digit(n)
168: unsigned n;
169: {
170: if(n >= 10) digit(n/10);
171: *str++ = (n%10) + '0';
172: }
173:
174: showf(n, t)
175: char *t;
176: {
177: spr("reading frame %: time=", n);
178: while(*str++ = *t++);
179: str--;
180: string(&defont, buf, &display, add(Drect.origin, Pt(5, 5)), F_STORE);
181: }
182:
183: showt()
184: {
185: spr("total draw time=%, read time=% Hz", (int)(dtime/maxframe), (int)(rtime/maxframe));
186: string(&defont, buf, &display, Drect.origin, F_STORE);
187: }
188:
189: char *
190: genfn(i)
191: {
192: switch(i)
193: {
194: case 0: spr("% frames t=%", maxframe, ragnorok); break;
195: case 1: spr("slower"); break;
196: case 2: spr("faster"); break;
197: case 3: spr("play %-%", start, start? start-1:maxframe-1); break;
198: case 4: spr("loop %-%", start, start? start-1:maxframe-1); break;
199: case 5: spr("exit"); break;
200: default:
201: i -= 6;
202: if(i >= maxframe) return((char *)0);
203: else
204: {
205: spr("frame % t=", i);
206: strcpy(str, frames[i].time);
207: }
208: break;
209: }
210: return(buf);
211: }
212:
213: getn()
214: {
215: register i, j;
216:
217: if((i = rcvchar()) == -1)
218: {
219: wait(RCV);
220: i = rcvchar();
221: }
222: i <<= 8;
223: if((j = rcvchar()) == -1)
224: {
225: wait(RCV);
226: j = rcvchar();
227: }
228: j &= 0xff;
229: return((i|j)&0xffff);
230: }
231:
232: gets(s)
233: char *s;
234: {
235: register k;
236:
237: for(k = -1; k; s++)
238: {
239: if((k = rcvchar()) == -1)
240: {
241: wait(RCV);
242: k = rcvchar();
243: }
244: *s = k;
245: }
246: }
247:
248: read(n)
249: {
250: register short *s = zdata;
251: long tim;
252:
253: tim = realtime();
254: while(n--)
255: *s++ = getn();
256: rtime += realtime()-tim;
257: }
258:
259: play(a, b)
260: {
261: long target;
262: int step;
263: #define INC(x) if(++x == maxframe) x = 0
264:
265: step = period*60;
266: if(nf > 1) step /= nf-1;
267: step = muldiv(step, SPEED, speed);
268: target = realtime();
269: a--;
270: do
271: {
272: INC(a);
273: BB(a);
274: for(target += step; target > realtime(); sleep(1));
275: } while((a != b) && !STOP);
276: rectf(&display, raddp(frames[0].b->rect, sub(ctr, frames[0].b->rect.origin)), F_CLR);
277: sleep(muldiv(20, SPEED, speed));
278: }
279:
280: Point
281: conv(x, y, z)
282: {
283: Point p;
284: p = grid(x, y);
285: p.y -= muldiv(z, rad, MAX);
286: return(p);
287: }
288:
289: Texture backgnd =
290: {
291: 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA,
292: 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA,
293: };
294:
295: #define Z(x,y) zdata[(x)+nx*(y)]
296: #define POLY(x1,y1,x2,y2,x3,y3,x4,y4) poly(b,conv(x1,y1,Z(x1,y1)),conv(x2,y2,Z(x2,y2)),conv(x3,y3,Z(x3,y3)),conv(x4,y4,Z(x4,y4)),light(x1,y1-1),F_STORE)
297: #define SEG(x1,y1,x2,y2) {int z1,z2; z1=Z(x1,y1); z2=Z(x2,y2); if((z1>=floor)&&(z2>=floor))segment(b,conv(x1,y1,z1),conv(x2,y2,z2),F_OR);}
298:
299: draw(b)
300: Bitmap *b;
301: {
302: register j, x, y;
303: int lasty;
304: long tim;
305:
306: if(doshade)
307: texture(b, b->rect, &backgnd, F_STORE);
308: else
309: rectf(b, b->rect, F_CLR);
310: tim = realtime();
311: if(showgrid && (doshade == 0))
312: {
313: for(y = 0; y < ny; y++)
314: {
315: for(x = 0; x < nx; x++)
316: {
317: if(y) SEG(x, y-1, x, y);
318: if(x) SEG(x-1, y, x, y);
319: }
320: wait(CPU);
321: }
322: }
323: else
324: for(j = nx+ny-3; j > 0; j--)
325: {
326: y = min(ny-1, j);
327: lasty = x = j-y;
328: while(y != lasty)
329: {
330: POLY(x, y, x, y-1, x+1, y-1, x+1, y);
331: x++;
332: y--;
333: }
334: wait(CPU);
335: }
336: dtime += realtime() - tim;
337: }
338:
339: #define NGREY 16
340:
341: Texture grey[NGREY];
342:
343: poly(bm, p1, p2, p3, p4, illum, mode)
344: Bitmap *bm;
345: Point p1, p2, p3, p4;
346: {
347: illum /= ONE/NGREY;
348: if(doshade) ppfill(&p1, 4, bm, &grey[illum], mode);
349: if(showgrid)
350: {
351: if(illum == 0) mode = F_CLR;
352: segment(bm, p1, p2, mode);
353: segment(bm, p2, p3, mode);
354: segment(bm, p3, p4, mode);
355: segment(bm, p4, p1, mode);
356: }
357: }
358:
359: int lx, ly, lz;
360:
361: light(X, Y)
362: {
363: int x, y, z;
364: int res;
365: long a, len, m;
366:
367: if(doshade == 0) return(ONE-1);
368: x = (Z(X+1, Y)-Z(X, Y) + Z(X+1, Y-1)-Z(X, Y-1))/2;
369: y = (Z(X, Y)-Z(X, Y-1) + Z(X+1, Y)-Z(X+1, Y-1))/2;
370: z = (abs(X)+abs(Y));
371: len = sqrt(x*(long)x + y*(long)y + z*(long)z);
372: if(len == 0) len++;
373: x = muldiv(x, ONE, len);
374: y = muldiv(y, ONE, len);
375: z = muldiv(z, ONE, len);
376: res = muldiv(x, lx, ONE) + muldiv(y, ly, ONE) + muldiv(z, lz, ONE);
377: if(res < 0) res = 0;
378: return(res);
379: }
380:
381: initgrey()
382: {
383: register mask, k, level, j, w, i;
384: Rectangle r;
385:
386: lx = -50; ly = 360; lz = 360;
387:
388: r = Drect;
389: r.corner.x = ((NGREY-1)*(long)Drect.origin.x+Drect.corner.x)/NGREY;
390: for(i = 0; i < NGREY-1; i++)
391: {
392: mask = 1;
393: w = 0;
394: level = ONE*i/(NGREY-1);
395: for(j = 0; j < 16; j++)
396: {
397: for(k = 0; k < 16; k++)
398: {
399: if(nrand(ONE) > level) w |= mask;
400: mask <<= 1;
401: }
402: grey[i].bits[j] = w;
403: w = 0;
404: mask = 1;
405: }
406: /*texture(&display, r, &grey[i], F_STORE);
407: r = raddp(r, Pt(r.corner.x-r.origin.x, 0));*/
408: }
409: }
410:
411: nrand(n)
412: {
413: return(muldiv(rand(), n, 32767));
414: }
415:
416: #define FUDGE 20
417:
418: sizeit()
419: {
420: register i, j;
421: Point p;
422: Bitmap *b;
423:
424: for(N = 10; N > 3; N--)
425: {
426: rad = 4*N;
427: xmin = XMAX; xmax = 0; ymax = 0; ymin = YMAX;
428: for(i = 0; i < nx; i++)
429: for(j = 0; j < ny; j++)
430: {
431: p = conv(i, j, Z(i, j));
432: if(p.x < xmin) xmin = p.x;
433: if(p.x > xmax) xmax = p.x;
434: if(p.y > ymax) ymax = p.y;
435: if(p.y < ymin) ymin = p.y;
436: }
437: xmin -= FUDGE; xmax += FUDGE; ymin -= FUDGE; ymax += FUDGE;
438: i = xmax-xmin;
439: j = ymax-ymin;
440: if((i > (Drect.corner.x-Drect.origin.x)) || (j > (Drect.corner.y-Drect.origin.y)))
441: continue;
442: if(b = balloc(Rect(0, 0, i, nf*j)))
443: {
444: bfree(b);
445: break;
446: }
447: }
448: bound = raddp(Rect(xmin, ymin, xmax, ymax), Pt(0, 0));
449: ctr = sub(dpt, Pt((xmax-xmin)/2, (ymax-ymin)/2));
450: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.