1 /*
2  * sprite_event.c: SACT��� mouse/key ���٥�ȤΥϥ�ɥ�
3  *
4  * Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
5  *               1998-                           <masaki-c@is.aist-nara.ac.jp>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21 */
22 /* $Id: sprite_event.c,v 1.5 2003/11/09 15:06:13 chikama Exp $ */
23 
24 #include "config.h"
25 
26 #include <stdio.h>
27 #include <glib.h>
28 
29 #include "portab.h"
30 #include "system.h"
31 #include "counter.h"
32 #include "menu.h"
33 #include "imput.h"
34 #include "nact.h"
35 #include "key.h"
36 #include "sact.h"
37 #include "sprite.h"
38 #include "sactsound.h"
39 #include "sactlog.h"
40 
41 /*
42   SACT���SpriteKey�Ԥ����å�����Key�Ԥ��ʤɤ�¸����뤿�ᡢX|SDL ����
43   Key/Mouse ���٥�Ȥ����ä��Ȥ��ˡ�nact->ags.eventcb()�ˤ�ä�¾�Υ⥸�塼��
44   �˥��٥�Ȥ����ФǤ���褦�ˤ�����
45 
46   SACT�ǤϺǽ�� spev_callback �ǥ��٥�Ȥ�������褦�ˤ������ߤΥ����Ԥ���
47   ����(sact.waittype)�ˤ�äƤ��줾��Υ��٥�ȥϥ�ɥ��ƤӽФ��Ƥ��롣
48 
49   ���ߤΤȤ���1) ��å����������Ԥ���2) ñ�㥭���Ԥ���3) ��˥塼�����Ԥ���
50   4) ���ץ饤�ȥ��� 5) �Хå��������Ԥ��Σ��Ĥ����롣
51 
52   1)��å����������Ԥ�
53     �����������������ޤ��Ԥġ�Z�������ץ饤�Ȥξõ�Ǥ��롣
54 
55   2)ñ�㥭���Ԥ�
56     1)��Ʊ��
57 
58   3)��˥塼�����Ԥ�
59     ��˥塼�����ץ���ν������ޥ�����ư�������ȡ�����(or�ܥ���)��Υ�줿�Ȥ���
60     �����Ĥ��ν�����Ԥ���
61 
62   4)���ץ饤���Ԥ�
63     SW/GETA/GETB/PUT/SWPUT���ץ饤�Ȥγƽ�����Ԥ���
64     ���ץ饤�Ȥ��ֹ�ξ�������Τ����˾�˽Ťͤ�ɽ���������ˤʤäƤ���
65     ���ץ饤�Ȥ˥��٥�Ȥ������ʤ��褦�ˤ���
66     -> SpriteKey�Ԥ���ľ���˥��ץ饤�Ȥ��ֹ�ˤ�� depth map ���������
67        �ޥ����ΰ��֤ˤ��륹�ץ饤�Ȥ��ֹ��Ǽ��Ф���
68        Alpha�ޥ����Ĥ���Sprite�ξ�硢�����ȿ�Ǥ���ɽ�����Ƥ�����Τߤ�
69        depthmap��ȿ�ǡ�
70 
71       drag��Υ��ץ饤�ȤϾ�˺Ǿ�̤ˤ���褦��ɽ�������ޥ�����ư���Υ��٥��
72       �Ϻǽ�˽������롣
73 
74   5)�Хå���ɽ����Υ����Ԥ�
75     ���ꥸ�ʥ��Ʊ���������ΤϤ�
76 */
77 
78 
79 static void cb_focused_swsp(gpointer s, gpointer data);
80 static void cb_defocused_swsp(gpointer s, gpointer data);
81 static int  cb_focused(sprite_t *sp);
82 static int  cb_defocused(sprite_t *sp);
83 static void cb_waitkey_simple(agsevent_t *e);
84 static void cb_waitkey_sprite(agsevent_t *e);
85 static void cb_waitkey_selection(agsevent_t *e);
86 
87 /*
88  �ե����������������ץ饤�Ȥ��������ץ饤�Ȥ���Ͽ����Ƥ�������
89  �������ץ饤�Ȥ�ɽ��ON
90 */
cb_focused_swsp(gpointer s,gpointer data)91 static void cb_focused_swsp(gpointer s, gpointer data) {
92 	sprite_t *sp = (sprite_t *)s;
93 	int *update  = (int *)data;
94 	boolean oldstate = sp->show;
95 
96 	WARNING("show up spex %d\n", sp->no);
97 
98 	sp->show = TRUE;
99 	if (oldstate != sp->show) {
100 		(*update)++;
101 		sp_updateme(sp);
102 	}
103 }
104 
105 /*
106  �ե����������������ץ饤�Ȥ��������ץ饤�Ȥ���Ͽ����Ƥ�������
107  �������ץ饤�Ȥ�ɽ��OFF
108 */
cb_defocused_swsp(gpointer s,gpointer data)109 static void cb_defocused_swsp(gpointer s, gpointer data) {
110 	sprite_t *sp = (sprite_t *)s;
111 	int *update  = (int *)data;
112 	boolean oldstate = sp->show;
113 
114 	WARNING("hide spex %d\n", sp->no);
115 
116 	sp->show = FALSE;
117 	if (oldstate != sp->show) {
118 		(*update)++;
119 		sp_updateme(sp);
120 	}
121 }
122 
123 // zkey hide off
cb_focused_zkey(gpointer s,gpointer data)124 static void cb_focused_zkey(gpointer s, gpointer data) {
125 	sprite_t *sp = (sprite_t *)s;
126 	int *update  = (int *)data;
127 	boolean oldstate = sp->show;
128 
129 	sp->show = sp->show_save;
130 	if (oldstate != sp->show) {
131 		(*update)++;
132 		sp_updateme(sp);
133 	}
134 }
135 
136 // zkey hide on
cb_defocused_zkey(gpointer s,gpointer data)137 static void cb_defocused_zkey(gpointer s, gpointer data) {
138 	sprite_t *sp = (sprite_t *)s;
139 	int *update  = (int *)data;
140 	boolean oldstate = sp->show;
141 
142 	sp->show = FALSE;
143 	if (oldstate != sp->show) {
144 		(*update)++;
145 		sp_updateme(sp);
146 		sp->show_save = oldstate;
147 	}
148 }
149 
150 /*
151   �ե����������������ץ饤�Ȥν���
152     cg2�������curcg��cg2������
153 
154     drag��Υ��ץ饤�Ȥ�������
155       -> PUT/SWPUT���ץ饤�ȤΤ�ȿ��
156     drag��Υ��ץ饤�Ȥ��ʤ����
157       -> GETA/GETB/SWPUT���ץ饤�ȤΤ�ȿ��
158 */
cb_focused(sprite_t * sp)159 static int cb_focused(sprite_t *sp) {
160 	int update = 0;
161 
162 	if (sact.draggedsp) {
163 		if (sp->type != SPRITE_PUT &&
164 		    sp->type != SPRITE_SWPUT) return 0;
165 	} else {
166 		if (sp->type == SPRITE_PUT) return 0;
167 	}
168 
169 	if (!sp->focused) {
170 		if (sp->cg2) {
171 			if (sp->curcg != sp->cg2) {
172 				sp_updateme(sp);
173 			}
174 			sp->curcg = sp->cg2;
175 			update++;
176 		}
177 		sp->focused = TRUE;
178 		WARNING("get forcused %d, type %d\n", sp->no, sp->type);
179 		if (sp->numsound1) {
180 			ssnd_play(sp->numsound1);
181 		}
182 	}
183 
184 	return update;
185 }
186 
187 /*
188   �ե����������ä����ץ饤�Ȥν���
189     curcg �� cg1 �˥��å�
190 */
cb_defocused(sprite_t * sp)191 static int cb_defocused(sprite_t *sp) {
192 	int update = 0;
193 
194 	if (sp->focused) {
195 		if (sp->curcg != sp->cg1) {
196 			sp_updateme(sp);
197 		}
198 		sp->curcg = sp->cg1;
199 		update++;
200 		sp->focused = FALSE;
201 		WARNING("lost forcused %d\n", sp->no);
202 	}
203 
204 	return update;
205 }
206 
207 /*
208   WaitKeySimple��callback
209 */
cb_waitkey_simple(agsevent_t * e)210 static void cb_waitkey_simple(agsevent_t *e) {
211 	int cur, update = 0;
212 
213 	switch (e->type) {
214 	case AGSEVENT_KEY_PRESS:
215 		if (e->d3 == KEY_Z) {
216 			cur = get_high_counter(SYSTEMCOUNTER_MSEC);
217 			if (!sact.zhiding) {
218 				g_slist_foreach(sact.sp_zhide, cb_defocused_zkey, &update);
219 				sact.zhiding = TRUE;
220 				sact.zdooff = TRUE;
221 				sact.zofftime = cur;
222 			} else {
223 				sact.zdooff = FALSE;
224 			}
225 		}
226 		break;
227 
228 	case AGSEVENT_BUTTON_RELEASE:
229 		// back log view mode �˰ܹ�
230 		if (e->d3 == AGSEVENT_WHEEL_UP ||
231 		    e->d3 == AGSEVENT_WHEEL_DN) {
232 			// MessageKey �Ԥ��ΤȤ��Τ�
233 			if (sact.waittype != KEYWAIT_MESSAGE) break;
234 			sblog_start();
235 			sact.waittype = KEYWAIT_BACKLOG;
236 			break;
237 		}
238 		if (sact.zhiding) {
239 			g_slist_foreach(sact.sp_zhide, cb_focused_zkey, &update);
240 			sact.zhiding = FALSE;
241 		}
242 		// fall through
243 
244 	case AGSEVENT_KEY_RELEASE:
245 		switch(e->d3) {
246 		case KEY_Z:
247 			cur = get_high_counter(SYSTEMCOUNTER_MSEC);
248 			if (500 < (cur - sact.zofftime) || !sact.zdooff) {
249 				g_slist_foreach(sact.sp_zhide, cb_focused_zkey, &update);
250 				sact.zhiding = FALSE;
251 			}
252 			break;
253 		case KEY_PAGEUP:
254 		case KEY_PAGEDOWN:
255 			// MessageKey �Ԥ��ΤȤ��Τ�
256 			if (sact.waittype != KEYWAIT_MESSAGE) break;
257 			sblog_start();
258 			sact.waittype = KEYWAIT_BACKLOG;
259 			break;
260 		default:
261 			sact.waitkey = e->d3;
262 			break;
263 		}
264 	}
265 
266 	if (update) {
267 		sp_update_clipped();
268 	}
269 }
270 
271 /*
272   WaitKeySprite��callback
273 */
cb_waitkey_sprite(agsevent_t * e)274 static void cb_waitkey_sprite(agsevent_t *e) {
275 	GSList *node;
276 	sprite_t *focused_sp = NULL;   // focus �����Ƥ��� sprite
277 	sprite_t *defocused_sp = NULL; // focus ���ä� sprite
278 	int update = 0;
279 
280 	// �������٥�Ȥ�̵��
281 	switch(e->type) {
282 	case AGSEVENT_KEY_RELEASE:
283 	case AGSEVENT_KEY_PRESS:
284 		return;
285 	}
286 
287 	if (sact.draggedsp) {
288 		// ��� drag���sprite�˥��٥�Ȥ�����
289 		update = sact.draggedsp->eventcb(sact.draggedsp, e);
290 	} else {
291 		// ������å��������
292 		// drag��Ǥʤ����Τߡ�������������դ���
293 		if (e->type == AGSEVENT_BUTTON_RELEASE &&
294 		    e->d3   == AGSEVENT_BUTTON_RIGHT) {
295 			sact.waitkey = 0;
296 			return;
297 		}
298 	}
299 
300 	// forcus�����Ƥ��� sprite �� focus���ä� sprite ��õ��
301 	for (node = sact.eventlisteners; node; node = node->next) {
302 		sprite_t *sp = (sprite_t *)node->data;
303 
304 		if (sp == NULL) continue;
305 		if (!sp->show) continue;
306 
307 		// freeze���֤Ǥ�CG���Ѳ����ʤ�
308 		if (sp->freezed_state != 0) continue;
309 
310 		// dragg��� sprite ��̵�뤹��
311 		if (sp == sact.draggedsp) continue;
312 
313 		if (focused_sp == NULL && sp_is_insprite(sp, e->d1, e->d2)) {
314 			/*
315 			  focus�����Ƥ��� sprite
316 			*/
317 			update += cb_focused(sp);
318 			focused_sp = sp;
319 		} else {
320 			/*
321 			   ���ߤΥ���������֤ˤϤ��޽������Ƥ����ֹ��sprite
322 			   ��¸�ߤ��ʤ��Τǡ�defocus �ν�����Ԥ���
323 			   ����Υޥ�����ư���٥�Ȥˤ��focus���ä��Τ�
324 			   ����С�cb_decocused(sp)�� 1 ���֤�
325 			*/
326 			int ret = cb_defocused(sp);
327 			if (ret > 0) defocused_sp = sp;
328 			update += ret;
329 		}
330 	}
331 
332 	// focus������ sprite �� BUTTON���٥�ȤΤߤ�����
333 	if (focused_sp && e->type != AGSEVENT_MOUSE_MOTION) {
334 		update += focused_sp->eventcb(focused_sp, e);
335 	}
336 
337 	// �ϰϳ�(focus�����Ƥ���sprite���ʤ����)����å������Ȥ��β�
338 	if (!focused_sp &&
339 	    e->type != AGSEVENT_MOUSE_MOTION &&
340 	    sact.numsoundob) {
341 		ssnd_play(sact.numsoundob);
342 	}
343 
344 	// drag��Ǥʤ����ϡ��������ץ饤�Ȥ�ɽ�����õ��Ԥ�
345 	if (sact.draggedsp == NULL && e->type == AGSEVENT_MOUSE_MOTION) {
346 		// focus ���ä� sprite �� ���� sprite �ξõ�
347 		if (defocused_sp) {
348 			sprite_t *sp = defocused_sp;
349 			if (sp->expsp) {
350 				g_slist_foreach(sp->expsp, cb_defocused_swsp, &update);
351 			}
352 		}
353 
354 		// focus ������ sprite �� ���� sprite ��ɽ��
355 		if (focused_sp) {
356 			sprite_t *sp = focused_sp;
357 			if (sp->expsp) {
358 				g_slist_foreach(sp->expsp, cb_focused_swsp, &update);
359 			}
360 		}
361 	}
362 
363 	// ɽ�����֤��ѹ�������Ф����ΰ����
364 	if (update) {
365 		sp_update_clipped();
366 	}
367 }
368 
369 /*
370   ����� Window Open ���� callback
371 */
cb_waitkey_selection(agsevent_t * e)372 static void cb_waitkey_selection(agsevent_t *e) {
373 	switch (e->type) {
374 	case AGSEVENT_BUTTON_RELEASE:
375 		sact.sel.cbrelease(e);
376 		break;
377 
378 	case AGSEVENT_MOUSE_MOTION:
379 		sact.sel.cbmove(e);
380 		break;
381 	}
382 }
383 
384 /*
385   �Хå������Ȼ�
386 */
cb_waitkey_backlog(agsevent_t * e)387 static void cb_waitkey_backlog(agsevent_t *e) {
388 	switch (e->type) {
389 	case AGSEVENT_KEY_RELEASE:
390 		switch (e->d3) {
391 		case KEY_ESC:
392 			sblog_end();
393 			sact.waittype = KEYWAIT_MESSAGE;
394 			break;
395 		case KEY_PAGEUP:
396 			sblog_pageup();
397 			break;
398 		case KEY_PAGEDOWN:
399 			sblog_pagedown();
400 			break;
401 		case KEY_UP:
402 			sblog_pagenext();
403 			break;
404 		case KEY_DOWN:
405 			sblog_pagepre();
406 			break;
407 		}
408 		break;
409 
410 	case AGSEVENT_BUTTON_RELEASE:
411 		switch(e->d3) {
412 		case AGSEVENT_WHEEL_UP:
413 			sblog_pagenext();
414 			break;
415 		case AGSEVENT_WHEEL_DN:
416 			sblog_pagepre();
417 			break;
418 		case AGSEVENT_BUTTON_RIGHT:
419 			sblog_end();
420 			sact.waittype = KEYWAIT_MESSAGE;
421 			break;
422 		}
423 		break;
424 	}
425 }
426 
427 /*
428   X|SDL �Υ��٥�ȥǥ����ѥå��㤫�餯��ǽ�ξ��
429 */
spev_callback(agsevent_t * e)430 void spev_callback(agsevent_t *e) {
431 	// menu open���̵��
432 	if (nact->popupmenu_opened) {
433 		return;
434 	}
435 
436 	if (sact.waittype != KEYWAIT_BACKLOG) {
437 		if (e->type == AGSEVENT_KEY_PRESS && e->d3 == KEY_CTRL) {
438 			sact.waitskiplv = 2;
439 			sact.waitkey = e->d3;
440 			return;
441 		}
442 
443 		if (e->type == AGSEVENT_KEY_RELEASE && e->d3 == KEY_CTRL) {
444 			sact.waitskiplv = 0;
445 			sact.waitkey = e->d3;
446 			return;
447 		}
448 	}
449 
450 	switch (sact.waittype) {
451 	case KEYWAIT_MESSAGE:
452 	case KEYWAIT_SIMPLE:
453 		cb_waitkey_simple(e);
454 		break;
455 
456 	case KEYWAIT_SPRITE:
457 		cb_waitkey_sprite(e);
458 		break;
459 
460 	case KEYWAIT_SELECT:
461 		cb_waitkey_selection(e);
462 		break;
463 
464 	case KEYWAIT_BACKLOG:
465 		cb_waitkey_backlog(e);
466 		break;
467 
468 	default:
469 		return;
470 	}
471 }
472 
473 /*
474   �ƥ��ץ饤����Υ��٥�� callback ����Ͽ
475 */
spev_add_eventlistener(sprite_t * sp,int (* cb)(sprite_t *,agsevent_t *))476 void spev_add_eventlistener(sprite_t *sp, int (*cb)(sprite_t *, agsevent_t *)) {
477 	sp->eventcb = cb;
478 	sact.eventlisteners = g_slist_append(sact.eventlisteners, sp);
479 }
480 
481 /*
482   �����Ͽ���� callback �κ��
483 */
spev_remove_eventlistener(sprite_t * sp)484 void spev_remove_eventlistener(sprite_t *sp) {
485 	sact.eventlisteners = g_slist_remove(sact.eventlisteners, sp);
486 }
487 
488