1 /*
2  * cmdv.c  SYSTEM35 V command
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: cmdv.c,v 1.21 2001/05/09 04:11:24 chikama Exp $ */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <sys/time.h>
30 #include "portab.h"
31 #include "xsystem35.h"
32 #include "ags.h"
33 #include "imput.h"
34 
35 extern void sys_set_signalhandler(int SIG, void (*handler)(int));
36 
37 typedef struct {
38 	int x0Unit;
39 	int y0Unit;
40 	int nxUnit;
41 	int nyUnit;
42 	int bSpCol;
43 	boolean fEnable;
44 	boolean useTTP;
45 	int TTPunit;
46 } UnitMapSrcImg;
47 
48 typedef struct {
49 	int unitWidth;     /* Unit���礭�� */
50 	int unitHeight;
51 	int patternNum;    /* �ѥ������ */
52 	int intervaltime;  /* �����ֳ� */
53 	int srcX;          /* �������� */
54 	int srcY;
55 	int startX;        /* ɽ������ */
56 	int startY;
57 	int endX;          /* ��ư�� */
58 	int endY;
59 	int saveX;         /* �ط�������� */
60 	int saveY;
61 	int spType;        /* ���ץ饤����ˡ */
62 	int spCol;         /* ���ץ饤�ȿ� */
63 	int state;         /* ���ߤξ���  0:��� 1:ư */
64 	int elaspCut;      /* �вᥳ�޿� */
65 	int quantmsec;     /* �в��ÿ� */
66 	int totalCut;      /* �����޿� */
67 	int preX;          /* ����ΰ��� */
68 	int preY;
69 	int curX;          /* ���߰��� */
70 	int curY;
71 	boolean draw;      /* UNIT�������� */
72 	boolean nomove;    /* ��ư���ꡦ�ʤ� */
73 	boolean rewrite;   /* ���̹�����ɬ�פ��� */
74 } VaParam;
75 
76 typedef struct {
77 	int x;
78 	int y;
79 } VhMark;
80 
81 #define UNITMAP_DISPLAY_PAGE_MAX       16  /* VS�κ���ڡ����� */
82 #define UNITMAP_VARIABLE_IMMOVALE     255  /* ����ڥ���Ȥΰ�ư�Բ�ǽ�ޡ��� */
83 #define UNITMAP_VARIABLE_OUTOFRANGE 65535  /* �ϰϳ��Υޡ��� */
84 #define UNITMAP_ATTRIB_DEPTH      (4)
85 #define UNITMAP_ATTRIB_UNITNUMBER (0)
86 #define UNITMAP_ATTRIB_VARIABLE   (1)
87 #define UNITMAP_ATTRIB_WALKPAINT  (2)
88 #define UNITMAP_ATTRIB_WALKRESULT (3)
89 
90 /* UnitMAP ���ΤؤΥݥ��� */
91 static int *UnitMap = NULL;
92 /* VC command */
93 static int nPageNum;
94 static int x0Map;
95 static int y0Map;
96 static int cxMap;
97 static int cyMap;
98 static int cxUnit;
99 static int cyUnit;
100 /* VH command */
101 static VhMark *vh_src, *vh_dst, *_vh_src, *_vh_dst;
102 static int     vh_cnt_src, vh_cnt_dst;
103 /* VP command */
104 static UnitMapSrcImg *srcimg;
105 /* VA command state */
106 #define VA_STOPPED     0
107 #define VA_RUNNING     1
108 #define VACMD_MAX 20                      /* Panyo��18�ޤ� */
109 static  VaParam VAcmd[VACMD_MAX];
110 static  boolean inAnimation      = FALSE; /* ���̹����� */
111 
112 /* UnitMap �Ƽ�ޥ��� */
113 #define MAPSIZE_PER_ATTRIB (cxMap * cyMap)
114 #define MAPSIZE_PER_PAGE   ((MAPSIZE_PER_ATTRIB) * UNITMAP_ATTRIB_DEPTH)
115 
116 #define UNITMAP_UNITNUMBER(page,x,y) (UnitMap + (page) * (MAPSIZE_PER_PAGE) + UNITMAP_ATTRIB_UNITNUMBER * (MAPSIZE_PER_ATTRIB) + (y) * cxMap + (x))
117 #define UNITMAP_VARIABLE(page,x,y)   (UnitMap + (page) * (MAPSIZE_PER_PAGE) + UNITMAP_ATTRIB_VARIABLE *   (MAPSIZE_PER_ATTRIB) + (y) * cxMap + (x))
118 #define UNITMAP_WALKPAINT(page,x,y)  (UnitMap + (page) * (MAPSIZE_PER_PAGE) + UNITMAP_ATTRIB_WALKPAINT *  (MAPSIZE_PER_ATTRIB) + (y) * cxMap + (x))
119 #define UNITMAP_WALKRESULT(page,x,y) (UnitMap + (page) * (MAPSIZE_PER_PAGE) + UNITMAP_ATTRIB_WALKRESULT * (MAPSIZE_PER_ATTRIB) + (y) * cxMap + (x))
120 
121 #define UNITMAP_UNITNUMBER_PAGETOP(page) UNITMAP_UNITNUMBER((page),0,0)
122 #define UNITMAP_VARIABLE_PAGETOP(page)   UNITMAP_VARIABLE((page),0,0)
123 #define UNITMAP_WALKPAINT_PAGETOP(page)  UNITMAP_WALKPAINT((page),0,0)
124 #define UNITMAP_WALKRESULT_PAGETOP(page) UNITMAP_WALKRESULT((page),0,0)
125 
126 static boolean vh_checkImmovableArea(int page, int x, int y, int w, int h);
127 static void    vh_append_pos(int x, int y);
128 static void    vh_copy_to_src();
129 static void    vh_check_udlr(int n, int nPage, int x, int y);
130 static void    va_drawUnit(int no);
131 static void    va_restoreUnit(int no);
132 static void    va_updateUnit(int i);
133 static void    va_updatePreArea(int i);
134 static void    va_animationAlone(int i);
135 static void    va_interval_process();
136 static void    va_init_itimer();
137 static void    va_pause_itimer();
138 static void    va_unpause_itimer();
139 static void    alarmHandler();
140 
commandVC()141 void commandVC() { /* from Rance4 */
142 	nPageNum = getCaliValue();
143 	x0Map    = getCaliValue();
144 	y0Map    = getCaliValue();
145 	cxMap    = getCaliValue();
146 	cyMap    = getCaliValue();
147 	cxUnit   = getCaliValue();
148 	cyUnit   = getCaliValue();
149 
150 	DEBUG_COMMAND("VC %d,%d,%d,%d,%d,%d,%d:\n",nPageNum, x0Map, y0Map, cxMap, cyMap, cxUnit, cyUnit);
151 
152 	if (NULL != UnitMap ) {
153 		free(UnitMap);
154 		free(srcimg);
155 		free(_vh_src);
156 		free(_vh_dst);
157 	}
158 
159 	if (nPageNum > UNITMAP_DISPLAY_PAGE_MAX) {
160 		WARNING("VC nPageNum too big %d\n", nPageNum);
161 		sysVar[0] = 0;
162 		return;
163 	}
164 
165 	UnitMap = (int *)calloc(cxMap * cyMap * nPageNum * UNITMAP_ATTRIB_DEPTH, sizeof(int));
166 	srcimg  = (UnitMapSrcImg *)calloc(nPageNum, sizeof(UnitMapSrcImg));
167 
168 	if (NULL == UnitMap || NULL == srcimg) {
169 		NOMEMERR();
170 	}
171 
172 	_vh_src = (VhMark *)calloc(3 * (cxMap + cyMap), sizeof(VhMark));
173 	_vh_dst = (VhMark *)calloc(3 * (cxMap + cyMap), sizeof(VhMark));
174 	if (NULL == _vh_src || NULL == _vh_dst) {
175 		NOMEMERR();
176 	}
177 	sysVar[0] = 1;
178 }
179 
commandVP()180 void commandVP() { /* from T2 */
181 	int nPage  = getCaliValue();
182 	int x0Unit = getCaliValue();
183 	int y0Unit = getCaliValue();
184 	int nxUnit = getCaliValue();
185 	int nyUnit = getCaliValue();
186 	int bSpCol = getCaliValue();
187 
188 	DEBUG_COMMAND("VP %d,%d,%d,%d,%d,%d:\n",nPage, x0Unit, y0Unit, nxUnit, nyUnit, bSpCol);
189 
190 	if (nPage >= nPageNum) {
191 		WARNING("VP nPage too large %d\n", nPage);
192 		return;
193 	}
194 
195 	srcimg[nPage].x0Unit = x0Unit;
196 	srcimg[nPage].y0Unit = y0Unit;
197 	srcimg[nPage].nxUnit = nxUnit;
198 	srcimg[nPage].nyUnit = nyUnit;
199 	srcimg[nPage].bSpCol = bSpCol;
200 	srcimg[nPage].useTTP = FALSE;
201 	srcimg[nPage].fEnable = TRUE;
202 }
203 
commandVS()204 void commandVS() { /* from Rance4 */
205 	int nPage = getCaliValue();
206 	int nType = getCaliValue();
207 	int x     = getCaliValue();
208 	int y     = getCaliValue();
209 	int wData = getCaliValue();
210 
211 	DEBUG_COMMAND("VS %d,%d,%d,%d,%d:\n",nPage, nType, x, y, wData);
212 
213 	if (nPage >= nPageNum) {
214 		WARNING("VS nPage too large %d\n", nPage);
215 		return;
216 	}
217 
218 	if (x >= cxMap || x < 0) {
219 		WARNING("VS x out of range %d\n", x);
220 		return;
221 	}
222 
223 	if (y >= cyMap || y < 0) {
224 		WARNING("VS y out of range %d\n", y);
225 		return;
226 	}
227 	if (wData < 0) {
228 		WARNING("VS wData illegal value %d\n", wData);
229 		return;
230 	}
231 
232 	/* �ɤ���顢 sysVar[0] ���ͤ��֤��ƤϤ����ʤ��餷�� thanx ¼�Ĥ���*/
233 	switch(nType) {
234 	case 1:
235 		/* sysVar[0] = *UNITMAP_UNITNUMBER(nPage, x, y); */
236 		*UNITMAP_UNITNUMBER(nPage, x, y) = wData;
237 		break;
238 	case 2:
239 		/* sysVar[0] = *UNITMAP_VARIABLE(nPage,   x, y); */
240 		*UNITMAP_VARIABLE(nPage,   x, y) = wData;
241 		break;
242 	case 3:
243 		/* sysVar[0] = *UNITMAP_WALKPAINT(nPage,  x, y); */
244 		*UNITMAP_WALKPAINT(nPage,  x, y) = wData;
245 		break;
246 	case 4:
247 		/* sysVar[0] = *UNITMAP_WALKRESULT(nPage, x, y); */
248 		*UNITMAP_WALKRESULT(nPage, x, y) = wData;
249 		break;
250 	default:
251 		WARNING("VS unknown type %d\n", nType);
252 	}
253 }
254 
commandVG()255 void commandVG() { /* from Rance4 */
256 	int nPage = getCaliValue();
257 	int nType = getCaliValue();
258 	int x = getCaliValue();
259 	int y = getCaliValue();
260 
261 	DEBUG_COMMAND("VG %d,%d,%d,%d:\n",nPage, nType, x, y);
262 
263 	if (nPage >= nPageNum) {
264 		WARNING("VG nPage too large %d\n", nPage);
265 		return;
266 	}
267 
268 	if (x >= cxMap || x < 0) {
269 		NOTICE("VG x out of range %d\n", x);
270 		sysVar[0] = UNITMAP_VARIABLE_OUTOFRANGE;
271 		return;
272 	}
273 
274 	if (y >= cyMap || y < 0) {
275 		NOTICE("VG y out of range %d\n", y);
276 		sysVar[0] = UNITMAP_VARIABLE_OUTOFRANGE;
277 		return;
278 	}
279 
280 	switch(nType) {
281 	case 1:
282 		sysVar[0] = *UNITMAP_UNITNUMBER(nPage, x, y); break;
283 		break;
284 	case 2:
285 		sysVar[0] = *UNITMAP_VARIABLE(nPage,   x, y); break;
286 	case 3:
287 		sysVar[0] = *UNITMAP_WALKPAINT(nPage,  x, y); break;
288 	case 4:
289 		sysVar[0] = *UNITMAP_WALKRESULT(nPage, x, y); break;
290 	default:
291 		WARNING("VG unknown type %d\n", nType);
292 	}
293 }
294 
commandVH()295 void commandVH() { /* from Rance4 */
296 	int nPage  = getCaliValue();
297 	int x      = getCaliValue();
298 	int y      = getCaliValue();
299 	int width  = getCaliValue();
300 	int height = getCaliValue();
301 	int _max   = getCaliValue();
302 	int xx, yy, i, n;
303 	int maxfoot, lmtx, lmty, lmtw, lmth;
304 
305 	DEBUG_COMMAND("VH %d,%d,%d,%d,%d,%d:\n",nPage, x, y, width, height, _max);
306 
307 	if (nPage >= nPageNum) {
308 		WARNING("VH nPage too large %d\n", nPage);
309 		return;
310 	}
311 	if (x >= cxMap || x < 0) {
312 		WARNING("VH x out of range %d\n", x);
313 		return;
314 	}
315 
316 	if (y >= cyMap || y < 0) {
317 		WARNING("VH y out of range %d\n", y);
318 		return;
319 	}
320 
321 	if (_max == 0) {
322 		for (yy = 0; yy < cyMap; yy++) {
323 			for (xx = 0; xx < cxMap; xx++) {
324 				*UNITMAP_WALKRESULT(nPage, xx , yy) = UNITMAP_VARIABLE_IMMOVALE;;
325 			}
326 		}
327 		/* ��ʬ���Ȥ� 0 */
328 		*UNITMAP_WALKRESULT(nPage, x , y) = 0;
329 		return;
330 	}
331 	/*
332 	for (yy = 0; yy < cyMap; yy++) {
333 		for (xx = 0; xx < cxMap; xx++) {
334 			*UNITMAP_WALKPAINT(nPage, xx, yy) == 255 ? putchar('*') : putchar(' '+ *UNITMAP_WALKPAINT(nPage, xx, yy));
335 		}
336 		printf("\n");
337 	}
338 	*/
339 	maxfoot = min(_max, UNITMAP_VARIABLE_IMMOVALE);
340         lmtx = max(0, x - maxfoot);
341         lmty = max(0, y - maxfoot);
342         lmtw = min(maxfoot + cxMap - x, min(cxMap, 2 * maxfoot + 1));
343         lmth = min(maxfoot + cyMap - y, min(cyMap, 2 * maxfoot + 1));
344 
345 	for (yy = 0; yy < cyMap; yy++) {
346 		for (xx = 0; xx < cxMap; xx++) {
347 			/* ��������γ����Բ� */
348 			if (maxfoot < (abs(yy-y)+abs(xx-x))) {
349 				*UNITMAP_WALKRESULT(nPage, xx , yy) = UNITMAP_VARIABLE_IMMOVALE;
350 			} else if (*UNITMAP_WALKPAINT(nPage, xx, yy) >= UNITMAP_VARIABLE_IMMOVALE) {
351 				/* �㳲ʪ�ʤ� */
352 				*UNITMAP_WALKRESULT(nPage, xx , yy) = UNITMAP_VARIABLE_IMMOVALE;
353 			} else {
354 				/* ������Ǥ�ʤ��Ȥ��� 0 �Ǥʤ餹 */
355 				*UNITMAP_WALKRESULT(nPage, xx , yy) = 0;
356 			}
357 		}
358 	}
359 
360 	/* ��ư�Բ��ΰ�η��� */
361 	if (width > 1 || height > 1) {
362 		for (yy = 0; yy < lmth; yy++) {
363 			for (xx = 0; xx < lmtw; xx++) {
364 				if (vh_checkImmovableArea(nPage, xx + lmtx, yy + lmty, width, height)) {
365 					*UNITMAP_WALKRESULT(nPage, xx + lmtx , yy + lmty) = UNITMAP_VARIABLE_IMMOVALE;
366 				}
367 			}
368 		}
369 	}
370 
371 	/* list �ν���� */
372 	vh_src = _vh_src;
373 	vh_dst = _vh_dst;
374 	/* ������֤����� */
375 	vh_src -> x = x;
376 	vh_src -> y = y;
377 	vh_cnt_src = n = 1;
378 	vh_cnt_dst = 0;
379 
380 	while(TRUE) {
381 		for (i = 0; i < vh_cnt_src; i++) {
382 			vh_check_udlr(n, nPage, (vh_src + i)->x, (vh_src + i)->y);
383 		}
384 		if (vh_cnt_dst == 0) break;  /* ̤Ƨ�Ϥ�̵���ʤä��齪λ */
385 		vh_copy_to_src();
386 		if (n >= maxfoot)    break;  /* maxfoot �ޤǥޡ��������齪λ */
387 		n++;
388 	}
389 
390 	/* ���ΰ��255�� */
391 	for (yy = 0; yy < lmth; yy++) {
392 		for (xx = 0; xx < lmtw; xx++) {
393 			if (*UNITMAP_WALKRESULT(nPage, xx + lmtx, yy + lmty) == 0) {
394 				*UNITMAP_WALKRESULT(nPage, xx + lmtx , yy + lmty) = UNITMAP_VARIABLE_IMMOVALE;
395 			}
396 		}
397 	}
398 
399 	/* ��ʬ���Ȥ� 0 */
400 	*UNITMAP_WALKRESULT(nPage, x , y) = 0;
401 
402 	/*
403 	for (yy = 0; yy < cyMap; yy++) {
404 		for (xx = 0; xx < cxMap; xx++) {
405 			*UNITMAP_WALKRESULT(nPage, xx, yy) == 255 ? putchar('*') :putchar('0' + *UNITMAP_WALKRESULT(nPage, xx, yy));
406 		}
407 		printf("\n");
408 	}
409 	*/
410 }
411 
commandVF()412 void commandVF() { /* from Panyo */
413 	int x, y, i;
414 	int unit, unit_x, unit_y;
415 	UnitMapSrcImg *img;
416 
417 	for (i = 0; i < nPageNum; i++) {
418 		img = &srcimg[i];
419 
420 		if (img->fEnable == FALSE) continue;
421 
422 		for (y = 0; y < cyMap; y++) {
423 			for (x = 0; x < cxMap; x++) {
424 				unit = *UNITMAP_UNITNUMBER(i, x, y);
425 				if (img->useTTP == TRUE && img->TTPunit == unit) continue;
426 				// printf("i = %d, x = %d, y = %d, unit no = %d\n", i, x, y,unit);
427 				unit_x = unit % img->nxUnit;
428 				unit_y = unit / img->nxUnit;
429 				if (img->bSpCol == 256) {
430 					ags_copyArea(img->x0Unit + cxUnit * unit_x,
431 						     img->y0Unit + cyUnit * unit_y,
432 						     cxUnit, cyUnit,
433 						     x0Map + x * cxUnit,
434 						     y0Map + y * cyUnit);
435 				} else {
436 					ags_copyAreaSP(img->x0Unit + cxUnit * unit_x,
437 						       img->y0Unit + cyUnit * unit_y,
438 						       cxUnit, cyUnit,
439 						       x0Map + x * cxUnit,
440 						       y0Map + y * cyUnit, img->bSpCol);
441 				}
442 			}
443 		}
444 	}
445 
446 	ags_updateArea(x0Map, y0Map, cxMap * cxUnit, cyMap * cyUnit);
447 	DEBUG_COMMAND("VF:\n");
448 }
449 
commandVV()450 void commandVV() { /* from T2 */
451 	int nPage   = getCaliValue();
452 	int fEnable = getCaliValue();
453 
454 	DEBUG_COMMAND("VV %d,%d:\n",nPage, fEnable);
455 
456 	srcimg[nPage].fEnable = (fEnable == 1 ? TRUE : FALSE);
457 }
458 
commandVR()459 void commandVR() { /* from Rance4 */
460 	int nPage = getCaliValue();
461 	int nType = getCaliValue();
462 	int *var  = getCaliVariable();
463 	int *dst;
464 
465 	DEBUG_COMMAND("VR %d,%d,%p:\n",nPage, nType, var);
466 
467 	if (nPage >= nPageNum) {
468 		WARNING("VR nPage too large %d\n", nPage);
469 		return;
470 	}
471 
472 	switch(nType) {
473 	case 1:
474 		dst = UNITMAP_UNITNUMBER_PAGETOP(nPage); break;
475 	case 2:
476 		dst = UNITMAP_VARIABLE_PAGETOP(nPage); break;
477 	case 3:
478 		dst = UNITMAP_WALKPAINT_PAGETOP(nPage); break;
479 	case 4:
480 		dst = UNITMAP_WALKRESULT_PAGETOP(nPage); break;
481 	default:
482 		WARNING("VR unknown type %d\n", nType);
483 		return;
484 	}
485 
486 	memcpy(dst, var, sizeof(int) * MAPSIZE_PER_ATTRIB);
487 }
488 
commandVW()489 void commandVW() { /* from Rance4 */
490 	int nPage = getCaliValue();
491 	int nType = getCaliValue();
492 	int *var  = getCaliVariable();
493 	int *src;
494 
495 	DEBUG_COMMAND("VW %d,%d,%p:\n",nPage, nType, var);
496 
497 	if (nPage >= nPageNum) {
498 		WARNING("VW nPage too large %d\n", nPage);
499 		return;
500 	}
501 
502 	switch(nType) {
503 	case 1:
504 		src = UNITMAP_UNITNUMBER_PAGETOP(nPage); break;
505 	case 2:
506 		src = UNITMAP_VARIABLE_PAGETOP(nPage); break;
507 	case 3:
508 		src = UNITMAP_WALKPAINT_PAGETOP(nPage); break;
509 	case 4:
510 		src = UNITMAP_WALKRESULT_PAGETOP(nPage); break;
511 	default:
512 		WARNING("VW unknown type %d\n", nType);
513 		return;
514 	}
515 
516 	memcpy(var, src, sizeof(int) * MAPSIZE_PER_ATTRIB);
517 }
518 
commandVE()519 void commandVE() { /* from T2 */
520 	int x       = getCaliValue();
521 	int y       = getCaliValue();
522 	int width   = getCaliValue();
523 	int height  = getCaliValue();
524 	int out_ptn = getCaliValue();
525 	int flag    = getCaliValue();
526 	int xx, yy, i;
527 	int unit, unit_x, unit_y;
528 	UnitMapSrcImg *img;
529 
530 	DEBUG_COMMAND("VE %d,%d,%d,%d,%d,%d:\n", x, y, width, height, out_ptn, flag);
531 	if (flag == 1) {
532 		WARNING("VE flag1 is not yet\n");
533 	}
534 
535 	for (i = 0; i < nPageNum; i++) {
536 		img = &srcimg[i];
537 		/* VV �ˤ�� */
538 		if (img->fEnable == FALSE) continue;
539 
540 		for (yy = y; yy < (y+height); yy++) {
541 			for (xx = x; xx < (x+width); xx++) {
542 				if (xx >= cxMap || yy >= cyMap) {
543 					unit = out_ptn;
544 				} else {
545 					unit = *UNITMAP_UNITNUMBER(i, xx, yy);
546 				}
547 
548 				if (img->useTTP == TRUE && img->TTPunit == unit) continue;
549 				//printf("i = %d, xx = %d, yy = %d, unit no = %d\n", i, xx, yy,unit);
550 				unit_x = unit % img->nxUnit;
551 				unit_y = unit / img->nxUnit;
552 				ags_copyAreaSP(img->x0Unit + cxUnit * unit_x,
553 					       img->y0Unit + cyUnit * unit_y,
554 					       cxUnit, cyUnit,
555 					       x0Map + (xx-x) * cxUnit,
556 					       y0Map + (yy-y) * cyUnit, img->bSpCol);
557 			}
558 		}
559 	}
560 
561 	ags_updateArea(x0Map, y0Map, cxMap * cxUnit, cyMap * cyUnit);
562 }
563 
commandVZ()564 void commandVZ() { /* from T2 */
565 	int p1 = sys_getc();
566 	int p2 = getCaliValue();
567 	int p3 = getCaliValue();
568 
569 	DEBUG_COMMAND("VZ %d,%d,%d:\n", p1, p2, p3);
570 
571 	switch(p1) {
572 	case 0:
573 		srcimg[p2].useTTP = FALSE; break;
574 	case 1:
575 		srcimg[p2].useTTP = TRUE;
576 		srcimg[p2].TTPunit = p3;
577 		break;
578 	case 2:
579 		x0Map = p2; y0Map = p3;
580 		break;
581 	case 3:
582 		cxUnit = p2; cyUnit = p3;
583 		break;
584 	default:
585 		WARNING("unknown VZ %d:\n", p1);
586 	}
587 }
588 
commandVX()589 void commandVX() { /* from T2 */
590 	int p1 = getCaliValue();
591 	int p2 = getCaliValue();
592 	int p3 = getCaliValue();
593 	int p4 = getCaliValue();
594 
595 	DEBUG_COMMAND("VX %d,%d,%d,%d:\n", p1, p2, p3, p4);
596 
597 	switch(p1) {
598 	case 0:
599 		srcimg[p2].x0Unit = p3;
600 		srcimg[p2].y0Unit = p4; break;
601 	case 1:
602 		srcimg[p2].nxUnit = p3;
603 		srcimg[p2].nyUnit = p4; break;
604 	case 2:
605 		srcimg[p2].bSpCol = p3; break;
606 	case 3:
607 		/* ������ˤ��ˤ祢�ꥹ�����꤬�Ф��ΤǤȤꤢ���� */
608 		// commandVF();
609 		break;
610 	default:
611 		WARNING("VX unknown command %d:\n", p1);
612 	}
613 }
614 
commandVT()615 void commandVT() { /* from Panyo */
616 	int sp     = getCaliValue();
617 	int sa     = getCaliValue();
618 	int sx     = getCaliValue();
619 	int sy     = getCaliValue();
620 	int width  = getCaliValue();
621 	int height = getCaliValue();
622 	int dp     = getCaliValue();
623 	int da     = getCaliValue();
624 	int dx     = getCaliValue();
625 	int dy     = getCaliValue();
626 	int x, y, u;
627 
628 	for (y = 0; y < height; y++) {
629 		for (x = 0; x < width; x++) {
630 			switch(sa) {
631 			case 1:
632 				u = *UNITMAP_UNITNUMBER(sp, sx + x, sy + y); break;
633 			case 2:
634 				u = *UNITMAP_VARIABLE(sp, sx + x, sy + y)  ; break;
635 			case 3:
636 				u = *UNITMAP_WALKPAINT(sp, sx + x, sy + y) ; break;
637 			case 4:
638 				u = *UNITMAP_WALKRESULT(sp, sx + x, sy + y); break;
639 			default:
640 				WARNING("VT unknown type %d\n", sa); u = 0;
641 			}
642 			switch(da) {
643 			case 1:
644 				*UNITMAP_UNITNUMBER(dp, dx + x, dy + y) = u; break;
645 			case 2:
646 				*UNITMAP_VARIABLE(dp, dx + x, dy + y)   = u; break;
647 			case 3:
648 				*UNITMAP_WALKPAINT(dp, dx + x, dy + y)  = u; break;
649 			case 4:
650 				*UNITMAP_WALKRESULT(dp, dx + x, dy + y) = u; break;
651 			}
652 		}
653 	}
654 
655 	DEBUG_COMMAND("VT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", sp, sa, sx, sy, width, height, dp, da, dx, dy);
656 }
657 
commandVB()658 void commandVB() {
659 	int page   = getCaliValue();
660 	int type   = getCaliValue();
661 	int x_pos  = getCaliValue();
662 	int y_pos  = getCaliValue();
663 	int x_size = getCaliValue();
664 	int y_size = getCaliValue();
665 	int data   = getCaliValue();
666 
667 	DEBUG_COMMAND_YET("VB %d,%d,%d,%d,%d,%d,%d:\n", page, type, x_pos, y_pos, x_size, y_size, data);
668 }
669 
commandVIC()670 void commandVIC() { /* from Panyo */
671 	int sx     = getCaliValue();
672 	int sy     = getCaliValue();
673 	int width  = getCaliValue();
674 	int height = getCaliValue();
675 	int unit, unit_x, unit_y;
676 	int x, y, i;
677 	UnitMapSrcImg *img;
678 
679 	DEBUG_COMMAND("VIC %d,%d,%d,%d:\n", sx, sy, width, height);
680 
681 	for (i = 0; i < nPageNum; i++) {
682 		img = &srcimg[i];
683 		if (img->fEnable == FALSE) continue;
684 		for (y = 0; y < height; y++) {
685 			for (x = 0; x < width; x++) {
686 				unit = *UNITMAP_UNITNUMBER(i, sx + x, sy + y);
687 				if (img->useTTP == TRUE && img->TTPunit == unit) continue;
688 				//printf("i = %d, xx = %d, yy = %d, unit no = %d\n", i, xx, yy, unit);
689 				unit_x = unit % img->nxUnit;
690 				unit_y = unit / img->nxUnit;
691 				ags_copyAreaSP(img->x0Unit + cxUnit * unit_x,
692 					       img->y0Unit + cyUnit * unit_y,
693 					       cxUnit, cyUnit,
694 					       x0Map + (sx + x) * cxUnit,
695 					       y0Map + (sy + y) * cyUnit, img->bSpCol);
696 			}
697 		}
698 	}
699 	ags_updateArea(x0Map + sx * cxUnit, y0Map + sy * cyUnit, width * cxUnit, height * cyUnit);
700 }
701 
commandVIP()702 void commandVIP() {
703 	int x      = getCaliValue();
704 	int y      = getCaliValue();
705 	int width  = getCaliValue();
706 	int height = getCaliValue();
707 
708 	DEBUG_COMMAND_YET("VIP %d,%d,%d,%d:\n", x, y, width, height);
709 }
710 
commandVJ()711 void commandVJ() {
712 	/* �Ť��դ�����ڥ���� */
713 	int page  = getCaliValue();
714 	int x     = getCaliValue();
715 	int y     = getCaliValue();
716 	int max   = getCaliValue();
717 
718 	DEBUG_COMMAND_YET("VJ %d,%d,%d,%d:\n", page, x, y, max);
719 }
720 
commandVA()721 void commandVA() { /* from Panyo */
722 	static boolean startedItimer = FALSE;
723 	int no = sys_getc();
724 	int p1 = getCaliValue();
725 	int p2, p3;
726 	int *var1, *var2;
727 
728 	if (no >= 10) {
729 		var1 = getCaliVariable();
730 		var2 = getCaliVariable();
731 		DEBUG_COMMAND("VA %d,%d,%p,%p:\n", no, p1, var1, var2);
732 	} else {
733 		p2 = getCaliValue();
734 		p3 = getCaliValue();
735 		DEBUG_COMMAND("VA %d,%d,%d,%d:\n", no, p1, p2, p3);
736 	}
737 
738 	if (p1 > VACMD_MAX) {
739 		WARNING("VA p1 is too lagrge %d\n", p1);
740 		return;
741 	}
742 
743 	p1--;
744 	switch(no) {
745 	case 0:
746 		if (p2 == 0) {
747 			/* ��� */
748 			inAnimation = TRUE;
749 			VAcmd[p1].state = VA_STOPPED;
750 			VAcmd[p1].draw  = TRUE;
751 			if (p3 == 0) {
752 				/* ��˥åȾä� */
753 				va_restoreUnit(p1);
754 				va_updatePreArea(p1);
755 			} else {
756 				/* ��˥åȽ� */
757 				va_drawUnit(p1);
758 				va_updateUnit(p1);
759 			}
760 			VAcmd[p1].draw  = FALSE;
761 		} else {
762 			/* ���� (p3=���޿�,0:̵��(���ϰ���==��λ���֤ΤȤ�))*/
763 			inAnimation = TRUE;
764 			VAcmd[p1].elaspCut  = 0;
765 			VAcmd[p1].quantmsec = 0;
766 			VAcmd[p1].totalCut  = p3;
767 
768 			if (p3 == 0) {
769 				VAcmd[p1].nomove = TRUE;
770 			} else {
771 				if (VAcmd[p1].startX == VAcmd[p1].endX && VAcmd[p1].startY == VAcmd[p1].endY) {
772 					VAcmd[p1].nomove = TRUE;
773 				} else {
774 					VAcmd[p1].nomove = FALSE;
775 				}
776 			}
777 			/* animation start */
778 			if (startedItimer) {
779 				va_unpause_itimer();
780 			} else {
781 				startedItimer = TRUE;
782 				va_init_itimer();
783 			}
784 
785 			VAcmd[p1].state   = VA_RUNNING;
786 			VAcmd[p1].draw    = TRUE;
787 			va_drawUnit(p1);
788 			va_updateUnit(p1);
789 			if (p2 == 2) {
790 				VAcmd[p1].rewrite = TRUE;
791 				/* ����ȴ��̵�� ,p3=0�ϻ����Բ� */
792 				while(VAcmd[p1].state == VA_RUNNING) {
793 					va_animationAlone(p1);
794 					usleep(10*1000);
795 				}
796 				va_drawUnit(p1);
797 				va_updateUnit(p1);
798 			} else if (p2 == 3) {
799 				/* ����ȴ������ ,p3=0�ϻ����Բ�*/
800 				int key = 0;
801 				VAcmd[p1].rewrite = TRUE;
802 				while(VAcmd[p1].state == VA_RUNNING) {
803 					va_animationAlone(p1);
804 					usleep(10*1000);
805 					key = sys_getInputInfo();
806 					if (key != 0) {
807 						sysVar[0] = key;
808 						break;
809 					}
810 
811 				}
812 				va_drawUnit(p1);
813 				va_updateUnit(p1);
814 			} else {
815 				/* ������������᤹ */
816 			}
817 		}
818 		break;
819 	case 1:
820 		/* ɽ������ */
821 		VAcmd[p1].curX = VAcmd[p1].preX = VAcmd[p1].startX = p2;
822 		VAcmd[p1].curY = VAcmd[p1].preY = VAcmd[p1].startY = p3; break;
823 	case 2:
824 		/* ��ư��(���ä��鼫ưŪ����� */
825 		VAcmd[p1].endX = p2;
826 		VAcmd[p1].endY = p3; break;
827 	case 3:
828 		/* ������ */
829 		VAcmd[p1].unitWidth  = p2;
830 		VAcmd[p1].unitHeight = p3; break;
831 	case 4:
832 		/* �ѥ�����������شֳ�(1/100sec) */
833 		VAcmd[p1].patternNum   = p2;
834 		VAcmd[p1].intervaltime = p3; break;
835 	case 5:
836 		/* �������� */
837 		VAcmd[p1].srcX = p2;
838 		VAcmd[p1].srcY = p3; break;
839 	case 6:
840 		/* �ط�������� */
841 		VAcmd[p1].saveX = p2;
842 		VAcmd[p1].saveY = p3; break;
843 	case 7:
844 		/* ���ץ饤����ˡ���� */
845 		VAcmd[p1].spType = p2;             /* p2=0:�̾拾�ԡ� , p2=1:�����ꥹ�ץ饤��, p2=2:�ƥǡ������ץ饤�� */
846 		VAcmd[p1].spCol  = p3; break;
847 	case 10:
848 		/* ���ּ���(var1=0:���1:ư,var2=�ֹ�) */
849 		*var1 = VAcmd[p1].state == 0 ? 0 : 1;
850 		*var2 = VAcmd[p1].elaspCut; break;
851 	case 11:
852 		/* ���ּ��� */
853 		*var1 = VAcmd[p1].curX;
854 		*var2 = VAcmd[p1].curY; break;
855 	default:
856 		WARNING("Unknown VA command %d\n", no);
857 	}
858 }
859 
vh_checkImmovableArea(int page,int x,int y,int w,int h)860 static boolean vh_checkImmovableArea(int page, int x, int y, int w, int h) {
861 	int _x, _y;
862 
863 	if (x + w > cxMap) return TRUE;
864 
865 	if (y + h > cyMap) return TRUE;
866 
867 	for (_y = y; _y < (y+h); _y++) {
868 		for (_x = x; _x < (x+w); _x++) {
869 			if (*UNITMAP_WALKRESULT(page, _x, _y) == 255) return TRUE;
870 		}
871 	}
872 
873 	return FALSE;
874 }
875 
vh_append_pos(int x,int y)876 static void vh_append_pos(int x, int y) {
877 	/* x, y �� list ���ɲ� */
878 	(vh_dst + vh_cnt_dst)->x = x;
879 	(vh_dst + vh_cnt_dst)->y = y;
880 	vh_cnt_dst++;
881 }
882 
vh_copy_to_src()883 static void vh_copy_to_src() {
884 	VhMark *tmp;
885 
886 	/* src list �� dst list �����촹�� */
887 	tmp    = vh_src;
888 	vh_src = vh_dst;
889 	vh_dst = tmp;
890 
891 	vh_cnt_src = vh_cnt_dst;
892 	vh_cnt_dst = 0;
893 }
894 
vh_check_udlr(int n,int nPage,int x,int y)895 static void vh_check_udlr(int n, int nPage, int x, int y) {
896 	/* �岼������̤Ƨ�Ϥʤ��ͤ��åȤ���list���ɲ� */
897 	if (x > 0) {
898                 if (*UNITMAP_WALKRESULT(nPage, x -1, y) == 0) {
899                         *UNITMAP_WALKRESULT(nPage, x -1, y) = n;
900                         vh_append_pos(x -1, y);
901                 }
902         }
903         if (x < (cxMap-1)) {
904                 if (*UNITMAP_WALKRESULT(nPage, x +1, y) == 0) {
905                         *UNITMAP_WALKRESULT(nPage, x +1, y) = n;
906                         vh_append_pos(x +1, y);
907                 }
908         }
909         if (y > 0) {
910                 if (*UNITMAP_WALKRESULT(nPage, x, y -1) == 0) {
911                         *UNITMAP_WALKRESULT(nPage, x, y -1) = n;
912                         vh_append_pos(x, y -1);
913                 }
914         }
915         if (y < (cyMap-1)) {
916                 if (*UNITMAP_WALKRESULT(nPage, x, y +1) == 0) {
917                         *UNITMAP_WALKRESULT(nPage, x, y +1) = n;
918                         vh_append_pos(x, y +1);
919                 }
920 	}
921 }
922 
va_drawUnit(int no)923 static void va_drawUnit(int no) {
924 	int unitno = VAcmd[no].elaspCut % VAcmd[no].patternNum;
925 	int unitX = unitno % 10; /* ������ʤ��ä� :-p */
926 	int unitY = unitno / 10;
927 
928 	/* save */
929 	ags_copyArea(VAcmd[no].curX, VAcmd[no].curY, VAcmd[no].unitWidth, VAcmd[no].unitHeight,
930 		     VAcmd[no].saveX, VAcmd[no].saveY);
931 	/* drawUnit */
932 	if (VAcmd[no].spType == 0) {
933 		ags_copyArea(VAcmd[no].srcX + VAcmd[no].unitWidth * unitX,
934 			     VAcmd[no].srcY + VAcmd[no].unitHeight * unitY,
935 			     VAcmd[no].unitWidth, VAcmd[no].unitHeight,
936 			     VAcmd[no].curX, VAcmd[no].curY);
937 	} else if (VAcmd[no].spType == 1) {
938 		ags_copyAreaSP(VAcmd[no].srcX + VAcmd[no].unitWidth * unitX,
939 			       VAcmd[no].srcY + VAcmd[no].unitHeight * unitY,
940 			       VAcmd[no].unitWidth, VAcmd[no].unitHeight,
941 			       VAcmd[no].curX, VAcmd[no].curY,
942 			       VAcmd[no].spCol);
943 	}
944 }
945 
va_restoreUnit(int no)946 static void va_restoreUnit(int no) {
947 	ags_copyArea(VAcmd[no].saveX, VAcmd[no].saveY, VAcmd[no].unitWidth, VAcmd[no].unitHeight,
948 		     VAcmd[no].preX, VAcmd[no].preY);
949 }
950 
va_updateUnit(int i)951 static void va_updateUnit(int i) {
952 	ags_updateArea(VAcmd[i].curX, VAcmd[i].curY, VAcmd[i].unitWidth, VAcmd[i].unitHeight);
953 }
954 
va_updatePreArea(int i)955 static void va_updatePreArea(int i) {
956 	ags_updateArea(VAcmd[i].preX, VAcmd[i].preY, VAcmd[i].unitWidth, VAcmd[i].unitHeight);
957 }
958 
va_animation()959 void va_animation() {
960 	int i;
961 	int x, y, w, h;
962 
963 	inAnimation = TRUE;
964 
965 	for (i = 0; i < VACMD_MAX; i++) {
966 		if (VAcmd[i].state == VA_STOPPED) continue;
967 		if (!VAcmd[i].rewrite)            continue;
968 		if (VAcmd[i].draw) va_restoreUnit(i);
969 		if (VAcmd[i].draw) va_drawUnit(i);
970 		x = min(VAcmd[i].curX, VAcmd[i].preX);
971 		y = min(VAcmd[i].curY, VAcmd[i].preY);
972 		w = max(VAcmd[i].curX + VAcmd[i].unitWidth, VAcmd[i].preX + VAcmd[i].unitWidth) - x;
973 		h = max(VAcmd[i].curY + VAcmd[i].unitHeight, VAcmd[i].preY + VAcmd[i].unitHeight) - y;
974 		ags_updateArea(x, y, w, h);
975 		// printf("x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
976 		VAcmd[i].rewrite = FALSE;
977 	}
978 
979 	inAnimation = FALSE;
980 }
981 
va_animationAlone(int i)982 static void va_animationAlone(int i) {
983 	int x, y, w, h; /* update region */
984 
985 	if (!VAcmd[i].rewrite) return;
986 
987 	inAnimation = TRUE;
988 
989 	va_restoreUnit(i);
990 	va_drawUnit(i);
991 
992 	x = min(VAcmd[i].curX, VAcmd[i].preX);
993 	y = min(VAcmd[i].curY, VAcmd[i].preY);
994 	w = max(VAcmd[i].curX + VAcmd[i].unitWidth, VAcmd[i].preX + VAcmd[i].unitWidth) - x;
995 	h = max(VAcmd[i].curY + VAcmd[i].unitHeight, VAcmd[i].preY + VAcmd[i].unitHeight) - y;
996 	ags_updateArea(x, y, w, h);
997 
998 	VAcmd[i].rewrite = FALSE;
999 	inAnimation = FALSE;
1000 }
1001 
va_interval_process()1002 static void va_interval_process() {
1003 	boolean proceeding = FALSE;
1004 	int i;
1005 
1006 	for (i = 0; i < VACMD_MAX; i++) {
1007 		if (VAcmd[i].state == VA_RUNNING) {
1008 			proceeding = TRUE;
1009 			VAcmd[i].quantmsec++;
1010 
1011 			if (VAcmd[i].quantmsec >= VAcmd[i].intervaltime) {
1012 				/* �ޤ��������Ƥ��ʤ�����skip */
1013 				if (VAcmd[i].rewrite) continue;
1014 				VAcmd[i].rewrite = TRUE;
1015 				VAcmd[i].quantmsec = 0;
1016  				VAcmd[i].elaspCut++;
1017 				/* �Ť���� */
1018 				VAcmd[i].preX = VAcmd[i].curX;
1019 				VAcmd[i].preY = VAcmd[i].curY;
1020 				/* �����޽��ä��齪λ */
1021 				if (VAcmd[i].elaspCut >= VAcmd[i].totalCut) {
1022 					VAcmd[i].state = VA_STOPPED;
1023 					continue;
1024 				}
1025 				/* ��ư�ʤ��ξ��� skip */
1026 				if (VAcmd[i].nomove)  continue;
1027 				/* ��������� */
1028 				VAcmd[i].curX = VAcmd[i].startX + VAcmd[i].elaspCut * (VAcmd[i].endX - VAcmd[i].startX) / VAcmd[i].totalCut;
1029 				VAcmd[i].curY = VAcmd[i].startY + VAcmd[i].elaspCut * (VAcmd[i].endY - VAcmd[i].startY) / VAcmd[i].totalCut;
1030  			}
1031 		}
1032 	}
1033 	/* ���������Τ�̵�����ϡ������ޡ���ߤ�ơ����˥᡼������ȥå� */
1034 	if (!proceeding) {
1035 		va_pause_itimer();
1036 		nact->is_va_animation = FALSE;
1037 	}
1038 }
1039 
alarmHandler()1040 static void alarmHandler() {
1041 	if (!inAnimation) {
1042 		va_interval_process();
1043 	}
1044 }
1045 
va_init_itimer()1046 static void va_init_itimer() {
1047 	sys_set_signalhandler(SIGALRM, alarmHandler);
1048 	va_unpause_itimer();
1049 }
1050 
va_pause_itimer()1051 static void va_pause_itimer() {
1052 	struct itimerval value;
1053 
1054 	value.it_interval.tv_sec  = 0;
1055 	value.it_interval.tv_usec = 0;
1056 	value.it_value.tv_sec  = 0;
1057 	value.it_value.tv_usec = 0;
1058 	setitimer(ITIMER_REAL, &value, NULL);
1059 }
1060 
va_unpause_itimer()1061 static void va_unpause_itimer() {
1062 	struct itimerval value;
1063 
1064 	value.it_interval.tv_sec  = 0;
1065 	value.it_interval.tv_usec = 10 * 1000;
1066 	value.it_value.tv_sec  = 0;
1067 	value.it_value.tv_usec = 10 * 1000;
1068 	setitimer(ITIMER_REAL, &value, NULL);
1069 	nact->is_va_animation = TRUE;
1070 }
1071