1 /*
2    XMascot Ver 2.6
3    Copyright(c) 1996,1997 Go Watanabe     go@cclub.tutcc.tut.ac.jp
4                           Tsuyoshi IIda   iida@cclub.tutcc.tut.ac.jp
5 */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <math.h>
10 #include <X11/Xlib.h>
11 #include <X11/Xutil.h>
12 
13 #ifdef SHAPE
14 #include <X11/extensions/shape.h>
15 #endif
16 
17 #include "xmascot.h"
18 
19 extern Widget   mascot, *chain;
20 extern double   disp_dpm;	/* dot per mm */
21 extern volatile int time_fl;	/* ���西���ߥ��ե饰 */
22 extern volatile int time_cnt;	/* ������             */
23 
24 #ifdef BIFF
25 extern Widget   biff;
26 extern unsigned biff_r;
27 extern unsigned biff_h;
28 extern unsigned biff_w_off;
29 
30 #ifdef USE_DOUBLE
31 extern double   biff_th;
32 #else
33 extern int      biff_th;
34 #endif
35 
36 extern int      mbox_flag;
37 #endif
38 
39 extern Pixmap   pixmap[17];	/* mascot �� pixmap */
40 #ifdef SHAPE
41 extern Pixmap   bitmap[17];	/* mask   �� bitmap */
42 #endif
43 
44 extern int      px, py;		/* pin Geometry */
45 extern unsigned ms;		/* mascot size  */
46 
47 #ifdef USE_CHAINPAT
48 extern unsigned chain_w;
49 extern unsigned chain_h;
50 #define CHAIN_W chain_w
51 #define CHAIN_H chain_h
52 #else
53 #define CHAIN_W (CHAIN_SIZE/2)
54 #define CHAIN_H (CHAIN_SIZE/2)
55 #endif
56 
57 double          sim_param;
58 
59 #ifdef USE_DOUBLE
60 double          th;		/* ����            */
61 double          om = 0;		/* ��®��          */
62 #else
63 int             th;		/* ����            */
64 int             om = 0;		/* ��®��          */
65 #endif
66 
67 static int      so = 8, mxo = 0, myo = 0;	/* �����ξ��� */
68 
69 extern AppData  adat;		/* ���ܥ꥽���� */
70 extern unsigned mh;
71 extern int      map_fl;		/* �ޥ����åȤ�ɽ������Ƥ��뤫 */
72 
73 /* ���ߥ�졼������ѥѥ�᡼������ */
74 void
set_sim_param(void)75 set_sim_param(void)
76 {
77 	int             i;
78 
79 	sim_param = adat.grav * disp_dpm * 10 / adat.chain_len;
80 
81 	/* ����ɽ���Ŀ����� (�������ʬ��ɽ�����ʤ�) */
82 
83 	if (adat.chain_len < mh - CHAIN_H) {
84 		adat.chain_disp_num = 0;
85 	} else {
86 		adat.chain_disp_num = adat.chain_num -
87 			(mh - CHAIN_H) / (adat.chain_len / (adat.chain_num + 1));
88 	}
89 	if (map_fl) {
90 		for (i = 0; i < adat.chain_disp_num; i++)
91 			XtMapWidget(chain[i]);
92 		for (; i < adat.chain_num; i++)
93 			XtUnmapWidget(chain[i]);
94 	}
95 }
96 
97 void
reset_pos(void)98 reset_pos(void)
99 {
100 	so = mxo = myo = -9999;
101 }
102 
103 /* ���֤η׻� ����� ɽ���ѥ�������ѹ� */
104 void
set_pos(void)105 set_pos(void)
106 {
107 	int             mx, my;
108 	int             i, s;
109 	Window          win = XtWindow(mascot);
110 	Display        *dpy = XtDisplay(mascot);
111 
112 #ifdef USE_DOUBLE
113 	double bx, by, dx, dy;
114 	double sn = sin(th) * adat.chain_len;
115 	double cs = cos(th) * adat.chain_len;
116 	mx = px + sn;
117 	my = py + cs;
118 #else
119 	int bx, by, dx, dy;
120 	int sn = isin(th) * adat.chain_len;
121 	int cs = icos(th) * adat.chain_len;
122 	mx = px + (sn >> 8);
123 	my = py + (cs >> 8);
124 #endif
125 
126 	if (mxo != mx || myo != my) {	/* ɽ�����֤�ư���� */
127 		/* ɽ���ѥ�����η��� */
128 #ifdef USE_DOUBLE
129 		s = sqrt(fabs(th)) * 8 / sqrt(ANGLE_PI / 4);
130 #else
131 		s = sqrt(abs(th)) * 8 / sqrt(ANGLE_PI / 4);
132 #endif
133 		if (th < 0)
134 			s = s + 8;
135 		else
136 			s = 8 - s;
137 		if (s > 16)
138 			s = 16;
139 		if (s < 0)
140 			s = 0;
141 		if (s != so) {	/* ɽ���ѥ�������ѹ� */
142 			XSetWindowBackgroundPixmap(dpy, win, pixmap[s]);
143 #ifdef SHAPE
144 			XShapeCombineMask(dpy, win, ShapeBounding, 0, 0,
145 							  bitmap[s], ShapeSet);
146 #endif
147 			XClearWindow(dpy, win);
148 			so = s;
149 		}
150 #ifdef BIFF
151 		if (mbox_flag) {
152 #ifdef USE_DOUBLE
153 			double          th2;
154 #else
155 			int             th2;
156 #endif
157 			/* �������� */
158 			if (th > ANGLE_PI / 4)
159 				th2 = biff_th + ANGLE_PI / 4;
160 			else if (th < -ANGLE_PI / 4)
161 				th2 = biff_th - ANGLE_PI / 4;
162 			else
163 				th2 = biff_th + th;
164 			if (th2 > ANGLE_PI)
165 				th2 -= ANGLE_PI * 2;
166 			else if (th2 <= -ANGLE_PI)
167 				th2 += ANGLE_PI * 2;
168 
169 #ifdef USE_DOUBLE
170 			bx = mx - biff_r * sin(th2);
171 			by = my - biff_r * cos(th2);
172 #else
173 			bx = mx - ((biff_r * isin(th2)) >> 8);
174 			by = my - ((biff_r * icos(th2)) >> 8);
175 #endif
176 			XtMoveWidget(biff, (Position) (bx - biff_w_off),
177 				     (Position) (by - biff_h));
178 		}
179 #endif
180 
181 		/* ����ɽ�� */
182 #ifdef USE_DOUBLE
183 		dx = sn / (adat.chain_num + 1);
184 		dy = cs / (adat.chain_num + 1);
185 #else
186 		dx = sn / (adat.chain_num + 1) >> 8;
187 		dy = cs / (adat.chain_num + 1) >> 8;
188 #endif
189 
190 		bx = px + dx - CHAIN_W;
191 		by = py + dy - CHAIN_H;
192 
193 		XtMoveWidget(mascot, (Position) (mx - ms), (Position) (my - ms));
194 		for (i = 0; i < adat.chain_num; i++, bx += dx, by += dy)
195 			XtMoveWidget(chain[i], (Position) bx, (Position) by);
196 
197 		/* ���������ޤ��Ԥ� */
198 		XSync(dpy, False);
199 		mxo = mx;
200 		myo = my;
201 	}
202 }
203 
204 
205 /* ���ҤΥ��ߥ�졼����� */
206 void
sim(void)207 sim(void)
208 {
209 #ifdef USE_DOUBLE
210 	double          dom;
211 #else
212 	int             dom;
213 #endif
214 	while (time_cnt > 0) {
215 #ifdef USE_DOUBLE
216 		dom = sim_param * sin(th);
217 #else
218 		dom = sim_param * isin(th);
219 #endif
220 		om -= dom * DT / 1000.0 + adat.damping * om;
221 		th += om * DT / 1000.0;
222 		while (th > ANGLE_PI)
223 			th -= ANGLE_PI * 2;
224 		while (th <= -ANGLE_PI)
225 			th += ANGLE_PI * 2;
226 
227 #ifdef USE_DOUBLE
228 		if (fabs(om) < 0.02 && fabs(dom) < 0.02) {
229 #else
230 		if (abs(om) < 5 && abs(dom) < 5) {
231 #endif
232 			stop_timer();
233 			om = 0;
234 			dom = 0;
235 		}
236 		time_cnt--;
237 	}
238 	time_fl = 0;
239 	set_pos();
240 }
241