1 /*
2 * scenario.c ���ʥꥪ�����¹�
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: scenario.c,v 1.30 2003/04/25 17:23:55 chikama Exp $ */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "portab.h"
29 #include "ald_manager.h"
30 #include "variable.h"
31 #include "scenario.h"
32 #include "LittleEndian.h"
33 #include "xsystem35.h"
34
35 /* stack data type */
36 #define STACK_NEARJMP 1
37 #define STACK_FARJMP 2
38 #define STACK_VARIABLE 3
39 #define STACK_DATA 4
40
41 /* static mathods */
42 static void popVars(int *tmp);
43 static void popDatas(int *tmp);
44 static void showStackInfo();
45 static void sl_push(int type, int *val, int cnt);
46 static int* sl_pop();
47
48 /* static variables */
49 static BYTE *sl_sco; /* scenario data */
50 static int *sco_stackbuf; /* stack data */
51 static int *sco_stackindex; /* stack index */
52 static int sco_stacksize = 1024; /* default stack size */
53
54 static int sl_page; /* current scenario page no */
55 static int sl_index; /* cureent scenario address in page */
56
57 static int labelCallCnt = 0;
58 static int pageCallCnt = 0;
59 static int labelCallCnt_afterPageCall = 0;
60 static int dataPushCnt = 0;
61
62 /* driobject */
63 static dridata *dfile;
64
65 /* debug: show stack information */
showStackInfo()66 static void showStackInfo() {
67 DEBUG_MESSAGE("stack top = %p, cur = %p, size=%d\n", sco_stackbuf, sco_stackindex, sco_stacksize);
68 }
69
70 /* debbug: show current scenario pointer information */
showIndexInfo()71 static void showIndexInfo() {
72 DEBUG_MESSAGE("page = %d, index = %x\n", sl_page, sl_index);
73 }
74
75 #ifdef DEBUG
showStackData()76 static void showStackData() {
77 int i, j;
78 int *var;
79 FILE *fp = fopen("STACKS.TXT","a");
80 if (fp == NULL) return;
81
82 fprintf(fp, "Page = %d, index = %x\n", sl_getPage(), sl_getIndex());
83 fprintf(fp, "stack top = %p, cur = %p, size=%d, index=%d\n", sco_stackbuf, sco_stackindex, sco_stacksize, (sco_stackindex - sco_stackbuf));
84
85 var = sco_stackbuf;
86 for (i = 0; i < sco_stacksize; i+=10) {
87 for (j = 0; j < 10; j++) {
88 fprintf(fp, "%d,", *var); var++;
89 }
90 fprintf(fp, "\n");
91 }
92 fprintf(fp, "\n");
93
94 fclose(fp);
95 }
96 #endif
97
98 /* initilize stack and load first scenario data */
sl_init()99 boolean sl_init() {
100 sco_stackbuf = calloc(sco_stacksize, sizeof(int));
101 if (sco_stackbuf == NULL)
102 NOMEMERR();
103
104 sco_stackindex = sco_stackbuf;
105 sl_jmpFar(0);
106
107 labelCallCnt = 0;
108 pageCallCnt = 0;
109 labelCallCnt_afterPageCall = 0;
110 return TRUE;
111 }
112
113 /* UD 0 command, reinitilized scenario loader */
sl_reinit()114 boolean sl_reinit() {
115 free(sco_stackbuf);
116 return sl_init();
117 }
118
sl_push(int type,int * val,int cnt)119 static void sl_push(int type, int *val, int cnt) {
120 int i;
121
122 if (sco_stackindex + cnt >= sco_stackbuf + sco_stacksize) {
123 i = sco_stackindex - sco_stackbuf;
124 sco_stacksize <<= 1;
125 sco_stackbuf = realloc(sco_stackbuf, sco_stacksize * sizeof(int));
126 if (sco_stackbuf == NULL)
127 NOMEMERR();
128 sco_stackindex = sco_stackbuf + i;
129 }
130 val += (cnt - 1);
131 for (i = 0 ; i < cnt; i++) {
132 *sco_stackindex++ = *val--;
133 }
134 *sco_stackindex++ = cnt;
135 *sco_stackindex++ = type;
136 // showStackInfo();
137 // showStackData();
138 }
139
sl_pop()140 static int* sl_pop() {
141 int i, type, cnt;
142 int *tmp, *_tmp;
143
144 type = *--sco_stackindex;
145 cnt = *--sco_stackindex;
146
147 tmp = _tmp = malloc(sizeof(int) * (cnt + 2));
148 if (_tmp == NULL)
149 NOMEMERR();
150
151 *tmp++ = type;
152 *tmp++ = cnt;
153 for (i = 0; i < cnt; i++) {
154 *tmp++ = *--sco_stackindex;
155 }
156 if (sco_stackindex < sco_stackbuf) {
157 SYSERROR("Stack buffer is illegal\n");
158 }
159
160 // showStackInfo();
161 // showStackData();
162 return _tmp;
163 }
164
sl_getc()165 int sl_getc() {
166 return sl_sco[sl_index++];
167 }
168
sl_getw()169 int sl_getw() {
170 int c0,c1;
171
172 c0 = sl_getc();
173 c1 = sl_getc();
174 return c0 + (c1 << 8);
175 }
176
sl_getcAt(int adr)177 int sl_getcAt(int adr) {
178 return sl_sco[adr];
179 }
180
sl_getwAt(int adr)181 int sl_getwAt(int adr) {
182 int c0,c1;
183
184 c0 = sl_sco[adr];
185 c1 = sl_sco[adr + 1];
186 return c0 + (c1 << 8);
187 }
188
sl_getdAt(int adr)189 int sl_getdAt(int adr) {
190 int c0, c1;
191
192 c0 = sl_getwAt(adr);
193 c1 = sl_getwAt(adr + 2);
194 return c0 + (c1 << 16);
195 }
196
sl_getadr()197 int sl_getadr() {
198 int c0,c1;
199 c0 = sl_getw();
200 c1 = sl_getw();
201 return c0 + (c1 << 16);
202 }
203
204 /* @address */
sl_jmpNear(int address)205 void sl_jmpNear(int address) {
206 sl_index = address;
207 // showIndexInfo();
208 }
209
210 /*
211 #page
212 page = 0~
213 */
sl_jmpFar(int page)214 boolean sl_jmpFar(int page) {
215 if (dfile) {
216 ald_freedata(dfile);
217 }
218
219 dfile = ald_getdata(DRIFILE_SCO, page);
220 if (dfile == NULL) {
221 return FALSE;
222 }
223
224 sl_sco = dfile->data;
225 sl_page = page;
226 sl_index = LittleEndian_getDW(sl_sco, 4);
227 // showIndexInfo();
228 return TRUE;
229 }
230
231 /*
232 ~page,address
233 page = 1~
234 */
sl_jmpFar2(int page,int address)235 boolean sl_jmpFar2(int page, int address) {
236 if (dfile) {
237 ald_freedata(dfile);
238 }
239
240 dfile = ald_getdata(DRIFILE_SCO, page);
241 if (dfile == NULL) {
242 DEBUG_MESSAGE("ald_getdata fail\n");
243 return FALSE;
244 }
245 sl_sco = dfile->data;
246 sl_page = page;
247 sl_index = address;
248 return TRUE;
249 }
250
sl_callNear(int address)251 void sl_callNear(int address) {
252 int val[1];
253 val[0] = sl_index;
254 sl_push(STACK_NEARJMP, val, 1);
255 sl_jmpNear(address);
256
257 labelCallCnt++;
258 labelCallCnt_afterPageCall++;
259 }
260
sl_retNear()261 void sl_retNear() {
262 int *tmp = sl_pop();
263 int index;
264
265 while (*tmp != STACK_NEARJMP) {
266 if (*tmp == STACK_FARJMP) {
267 SYSERROR("Stack buffer is illegal\n");
268 } else if (*tmp == STACK_VARIABLE) {
269 popVars(tmp);
270 } else {
271 SYSERROR("Stack buffer is illegal\n");
272 }
273 free(tmp);
274 tmp = sl_pop();
275 }
276 index = *(tmp + 2);
277 free(tmp);
278 sl_jmpNear(index);
279
280 labelCallCnt--;
281 labelCallCnt_afterPageCall--;
282 }
283
sl_callFar(int page)284 void sl_callFar(int page) {
285 int val[2];
286 boolean bool;
287
288 val[0] = sl_page;
289 val[1] = sl_index;
290 sl_push(STACK_FARJMP, val, 2);
291 bool = sl_jmpFar(page);
292 pageCallCnt++;
293 labelCallCnt_afterPageCall = 0;
294 if (!bool) {
295 sl_retFar();
296 }
297 }
298
sl_callFar2(int page,int address)299 void sl_callFar2(int page, int address) {
300 int val[2];
301 boolean bool;
302
303 val[0] = sl_page;
304 val[1] = sl_index;
305 sl_push(STACK_FARJMP, val, 2);
306 bool = sl_jmpFar2(page, address);
307 labelCallCnt_afterPageCall = 0;
308 pageCallCnt++;
309 if (!bool) {
310 sl_retFar();
311 }
312 }
313
sl_retFar()314 void sl_retFar() {
315 int *tmp = sl_pop();
316 int page, index;
317
318 while (*tmp != STACK_FARJMP) {
319 if (*tmp == STACK_NEARJMP) {
320 WARNING("Stack buffer is illegal\n");
321 } else if (*tmp == STACK_DATA) {
322 popDatas(tmp);
323 } else if (*tmp == STACK_VARIABLE) {
324 popVars(tmp);
325 } else {
326 SYSERROR("Stack buffer is illegal\n");
327 }
328 free(tmp);
329 tmp = sl_pop();
330 }
331 page = *(tmp + 2);
332 index = *(tmp + 3);
333 free(tmp);
334 sl_jmpFar2(page, index);
335
336 labelCallCnt_afterPageCall = 0;
337 pageCallCnt--;
338 }
339
340 /* UD 1 */
sl_retFar2()341 void sl_retFar2() {
342 int *tmp = sl_pop();
343 int page, index;
344
345 while (*tmp != STACK_FARJMP) {
346 if (*tmp == STACK_NEARJMP) {
347 labelCallCnt--;
348 } else if (*tmp == STACK_DATA) {
349 popDatas(tmp);
350 } else if (*tmp == STACK_VARIABLE) {
351 popVars(tmp);
352 } else {
353 SYSERROR("Stack buffer is illegal\n");
354 }
355 free(tmp);
356 tmp = sl_pop();
357 }
358 page = *(tmp + 2);
359 index = *(tmp + 3);
360 free(tmp);
361 sl_jmpFar2(page, index);
362
363 pageCallCnt--;
364 labelCallCnt_afterPageCall = 0;
365 }
366
367 /* UC0 */
sl_stackClear_allCall()368 void sl_stackClear_allCall() {
369 free(sco_stackbuf);
370 sco_stackbuf = calloc(sco_stacksize, sizeof(int));
371 if (sco_stackbuf == NULL)
372 NOMEMERR();
373
374 sco_stackindex = sco_stackbuf;
375 }
376
377 /* UC 2 */
sl_stackClear_pageCall(int cnt)378 void sl_stackClear_pageCall(int cnt) {
379 int *tmp;
380
381 while(cnt--) {
382 tmp = sl_pop();
383 if (*tmp == STACK_NEARJMP) {
384 labelCallCnt--;
385 } else if (*tmp == STACK_FARJMP) {
386 pageCallCnt--;
387 } else if (*tmp == STACK_VARIABLE) {
388 popVars(tmp);
389 } else {
390 SYSERROR("Stack buffer is illegal\n");
391 }
392 free(tmp);
393 }
394 labelCallCnt_afterPageCall = 0;
395 }
396
397 /* UC 1 */
sl_stackClear_labelCall(int cnt)398 void sl_stackClear_labelCall(int cnt) {
399 int *tmp;
400
401 if (labelCallCnt_afterPageCall == 0) return;
402
403 tmp = sl_pop();
404 while(cnt--) {
405 if (*tmp == STACK_NEARJMP) {
406 labelCallCnt--;
407 labelCallCnt_afterPageCall--;
408 } else if (*tmp == STACK_VARIABLE) {
409 popVars(tmp);
410 } else {
411 SYSERROR("Stack buffer is illegal\n");
412 }
413 free(tmp);
414 if (labelCallCnt_afterPageCall == 0) break;
415
416 tmp = sl_pop();
417 }
418 }
419
420 /* US */
sl_pushVar(int * topVar,int cnt)421 void sl_pushVar(int *topVar, int cnt) {
422 int *tmp = malloc(sizeof(int) * (cnt + 2));
423
424 if (tmp == NULL) {
425 NOMEMERR();
426 }
427
428 *tmp = preVarPage;
429 *(tmp+1) = preVarIndex;
430 memcpy(tmp + 2, topVar, sizeof(int) * cnt);
431 sl_push(STACK_VARIABLE, tmp, cnt + 2);
432 free(tmp);
433 }
434
435 /* UG */
sl_popVar(int * topvar,int cnt)436 void sl_popVar(int *topvar, int cnt) {
437 int *tmp = sl_pop();
438
439 if (*tmp != STACK_VARIABLE) {
440 SYSERROR("Stack buffer is illegal\n");
441 }
442 if (*(tmp + 2) != preVarPage){
443 WARNING("Variable is not match with stacked variable\n");
444 }
445 if (*(tmp + 3) != preVarIndex) {
446 WARNING("Variable is not match with stacked variable\n");
447 }
448 if (*(tmp + 1) != cnt + 2) {
449 WARNING("Variable count is not match with stacked variable\n");
450 }
451 memcpy(topvar, tmp + 4, sizeof(int) * cnt);
452 free(tmp);
453 }
454
popVars(int * tmp)455 static void popVars(int *tmp) {
456 int cnt, page, index;
457 int *topVar;
458
459 cnt = *(tmp + 1) - 2;
460 page = *(tmp + 2);
461 index = *(tmp + 3);
462
463 if (page == 0) {
464 topVar = sysVar + index;
465 } else {
466 if ((arrayVarBuffer + page - 1) -> value == NULL) {
467 WARNING("Illegal Variable pop\n");
468 return;
469 }
470 topVar = ((arrayVarBuffer + page - 1) -> value) + index;
471 }
472
473 memcpy(topVar, tmp + 4, sizeof(int) * cnt);
474 }
475
sl_getIndex()476 int sl_getIndex() {
477 return sl_index;
478 }
479
sl_getPage()480 int sl_getPage() {
481 return sl_page;
482 }
483
sl_getStackInfo(int * size)484 int *sl_getStackInfo(int *size) {
485 *size = sco_stackindex - sco_stackbuf;
486 // printf("get stack size = %d\n", *size);
487 return sco_stackbuf;
488 }
489
sl_putStackInfo(int * data,int size)490 void sl_putStackInfo(int *data, int size) {
491 if (size > sco_stacksize) {
492 sco_stacksize = size << 1;
493 sco_stackbuf = calloc(sco_stacksize, sizeof(int));
494 }
495 if (sco_stackbuf == NULL)
496 NOMEMERR();
497 memcpy(sco_stackbuf, data, size * sizeof(int));
498 sco_stackindex = sco_stackbuf + size;
499 }
500
501
502 /* TPx */
sl_pushData(int * data,int cnt)503 void sl_pushData(int *data, int cnt) {
504 dataPushCnt++;
505 sl_push(STACK_DATA, data, cnt);
506 }
507
508 /* TOx */
sl_popData(int * data,int cnt)509 void sl_popData(int *data, int cnt) {
510 int *tmp;
511 if (dataPushCnt == 0) return;
512
513 tmp = sl_pop();
514 dataPushCnt--;
515
516 if (*tmp != STACK_DATA)
517 SYSERROR("Stack buffer is illegal\n");
518 if (*(tmp + 1) != cnt)
519 WARNING("Variable count is not match with stacked variable\n");
520
521 memcpy(data, tmp + 2, sizeof(int) * cnt);
522 free(tmp);
523 }
524
popDatas(int * tmp)525 static void popDatas(int *tmp) {
526 int d1 = *(tmp + 2);
527 int d2 = *(tmp + 3);
528 int d3 = *(tmp + 4);
529
530 if (*(tmp + 1) != 3)
531 WARNING("Variable count is not match with stacked variable\n");
532
533 switch(d1) {
534 case TxxTEXTCOLOR:
535 if (d2 == 0) {
536 nact->msg.MsgFontColor = d3;
537 } else {
538 nact->sel.MsgFontColor = d3;
539 }
540 break;
541 case TxxTEXTSIZE:
542 if (d2 == 0) {
543 nact->msg.MsgFontSize = d3;
544 } else {
545 nact->sel.MsgFontSize = d3;
546 }
547 break;
548 case TxxTEXTLOC:
549 msg_setMessageLocation(d2, d3);
550 break;
551 }
552 dataPushCnt--;
553 }
554
555 static dridata *datatbl;
556
sl_setDataTable(int page,int index)557 void *sl_setDataTable(int page, int index) {
558 if (datatbl) {
559 ald_freedata(datatbl);
560 }
561 datatbl = ald_getdata(DRIFILE_SCO, page);
562 return (void *)(datatbl->data + index);
563 }
564
sl_returnGoto(int address)565 void sl_returnGoto(int address) {
566 int *tmp = sl_pop();
567 int page;
568
569 while (TRUE) {
570 if (*tmp != STACK_FARJMP || *tmp != STACK_NEARJMP) break;
571 if (*tmp == STACK_DATA) {
572 popDatas(tmp);
573 } else if (*tmp == STACK_VARIABLE) {
574 popVars(tmp);
575 } else {
576 fprintf(stderr, "%d \n", *tmp);
577 SYSERROR("Stack buffer is illegal\n");
578 }
579 free(tmp);
580 tmp = sl_pop();
581 }
582
583 if (*tmp == STACK_FARJMP) {
584 page = *(tmp + 2);
585 // index = *(tmp + 3);
586 free(tmp);
587 sl_jmpFar2(page, address);
588 labelCallCnt_afterPageCall = 0;
589 pageCallCnt--;
590 } else {
591 // index = *(tmp + 2);
592 free(tmp);
593 sl_jmpNear(address);
594
595 labelCallCnt--;
596 labelCallCnt_afterPageCall--;
597 }
598 }
599