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