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