0
|
1 /*
|
17
|
2 * $Id$
|
0
|
3 */
|
|
4 #include <stdio.h>
|
|
5 #include <stdlib.h>
|
|
6 #include <math.h>
|
46
|
7 #include <arpa/inet.h>
|
0
|
8 #include <libps2.h>
|
|
9 #include <ps2util.h>
|
|
10
|
|
11 #include "car.h"
|
|
12 #include "game.h"
|
|
13 #include "lindaapi.h"
|
44
|
14 #include "linda.h"
|
0
|
15
|
|
16 extern void carNode_append(CarPtr);
|
|
17 extern FILE *main_fp;
|
43
|
18 static int my_id;
|
0
|
19 static CarPtr linda_carlist[CLIENT_MAX+1];
|
|
20 static int linda_seq[CLIENT_MAX+1];
|
|
21
|
|
22 static void
|
44
|
23 set_header(unsigned int data, char *pkt, int offset)
|
|
24 {
|
|
25 int *ipkt;
|
|
26 int ndata = htonl(data);
|
|
27
|
|
28 ipkt = (int*)pkt;
|
|
29 ipkt[offset/4] = ndata;
|
|
30 }
|
|
31
|
|
32 static unsigned int
|
|
33 get_header(char *pkt, int offset)
|
|
34 {
|
|
35 int *ipkt;
|
|
36 int data;
|
|
37 unsigned int header;
|
|
38
|
|
39 ipkt = (int *)pkt;
|
|
40 data = ipkt[offset/4];
|
|
41 header = (unsigned int)ntohl(data);
|
|
42
|
|
43 return header;
|
|
44 }
|
|
45
|
|
46 static char*
|
|
47 make_packet(unsigned int mode, unsigned int carid,
|
|
48 unsigned int courseid, char *data)
|
|
49 {
|
|
50 char *packet;
|
|
51 unsigned int len = 0;
|
|
52
|
|
53 if (data) len += sizeof(FMATRIX);
|
|
54
|
|
55 packet = (char*)malloc(PKT_HEADER_SIZE+len);
|
|
56
|
|
57 set_header(mode, packet, PKT_MODE_OFFSET);
|
|
58 set_header(carid, packet, PKT_CARID_OFFSET);
|
|
59 set_header(courseid, packet, PKT_COURSEID_OFFSET);
|
|
60
|
|
61 if (data)
|
|
62 memcpy(packet+PKT_DATA_OFFSET, data, len);
|
|
63
|
|
64 return packet;
|
|
65 }
|
|
66
|
|
67
|
|
68 static void
|
|
69 send_packet(unsigned int dest, unsigned int mode, unsigned int car,
|
|
70 unsigned int course, char *data)
|
|
71 {
|
|
72 char *pkt;
|
|
73 int len = PKT_HEADER_SIZE;
|
|
74
|
|
75 if (data) len += sizeof(FMATRIX);
|
|
76
|
|
77 pkt = make_packet(mode, car, course, data);
|
|
78 psx_out(dest, pkt, len);
|
|
79 free(pkt);
|
|
80 }
|
|
81
|
|
82 static void
|
|
83 get_packet(int id, int *flg, int *mode, int *car, int *course, char *data)
|
|
84 {
|
47
|
85 char *reply = NULL;
|
|
86 char *pkt = NULL;
|
44
|
87
|
|
88 reply = psx_reply(linda_seq[id]);
|
|
89 if (reply) {
|
|
90 pkt = reply+LINDA_HEADER_SIZE;
|
|
91
|
46
|
92 if (flg) *flg = 1;
|
|
93 if (mode) *mode = get_header(pkt, PKT_MODE_OFFSET);
|
|
94 if (car) *car = get_header(pkt, PKT_CARID_OFFSET);
|
|
95 if (course) *course = get_header(pkt, PKT_COURSEID_OFFSET);
|
56
|
96 if (data)
|
|
97 memcpy(data, pkt+PKT_DATA_OFFSET, sizeof(FMATRIX));
|
|
98
|
44
|
99 psx_free(reply);
|
|
100 linda_seq[id] = psx_rd(id);
|
|
101 }
|
|
102 }
|
|
103
|
|
104 static void
|
|
105 linda_set_schedule(void *func, int mode)
|
|
106 {
|
|
107 linda_seq[game.play_id] = psx_in(game.play_id);
|
|
108 game.linda_exec = func;
|
|
109 send_packet(game.play_id, mode, 1, 1, NULL);
|
|
110 }
|
|
111
|
|
112 static Bool
|
|
113 linda_sche_wait0()
|
|
114 {
|
|
115 int i, flg=0;
|
46
|
116 int id = game.play_id;
|
44
|
117 int connect = 1; // 接続済みユーザ数
|
|
118
|
47
|
119 for (i=1; i<=CLIENT_MAX; i++) {
|
50
|
120 get_packet(i, &flg, NULL, NULL, NULL, NULL);
|
51
|
121 if (i == id) {
|
|
122 flg = 0;
|
|
123 continue;
|
|
124 }
|
|
125 if (flg == 1) {
|
|
126 connect++;
|
|
127 flg = 0;
|
|
128 }
|
44
|
129 }
|
|
130
|
|
131 if (connect == CLIENT_MAX) {
|
|
132 linda_set_schedule(linda_sche_wait_ready0, MODE_WAIT_READY);
|
|
133 return TRUE;
|
|
134 } else {
|
|
135 return FALSE;
|
|
136 }
|
|
137
|
|
138 }
|
|
139
|
|
140 static Bool
|
|
141 linda_sche_wait1()
|
|
142 {
|
|
143 int mode;
|
|
144
|
|
145 get_packet(PLAYER_1P, NULL, &mode, NULL, NULL, NULL);
|
|
146
|
|
147 if (mode == MODE_WAIT_READY) {
|
|
148 linda_set_schedule(linda_sche_wait_ready1, MODE_WAIT_READY);
|
|
149 return TRUE;
|
|
150 } else {
|
|
151 return FALSE;
|
|
152 }
|
|
153 }
|
|
154
|
|
155 static Bool
|
|
156 linda_sche_wait_ready0()
|
|
157 {
|
|
158 int i, flg, mode;
|
46
|
159 int id = game.play_id;
|
44
|
160 int connect = 1;
|
|
161
|
49
|
162 for (i=1; i<=CLIENT_MAX; i++) {
|
50
|
163 get_packet(i, &flg, &mode, NULL, NULL, NULL);
|
51
|
164 if (i == id) {
|
|
165 flg = 0;
|
|
166 continue;
|
|
167 }
|
|
168 if (flg == 1 && mode == MODE_WAIT_READY) {
|
44
|
169 connect++;
|
51
|
170 flg = 0;
|
|
171 }
|
44
|
172 }
|
|
173
|
|
174 if (connect == CLIENT_MAX) {
|
|
175 linda_set_schedule(linda_sche_opening0, MODE_OPENING);
|
|
176 return TRUE;
|
|
177 } else {
|
|
178 return FALSE;
|
|
179 }
|
|
180
|
|
181 }
|
|
182
|
46
|
183 static Bool
|
44
|
184 linda_sche_wait_ready1()
|
|
185 {
|
|
186 int mode;
|
|
187
|
|
188 get_packet(PLAYER_1P, NULL, &mode, NULL, NULL, NULL);
|
|
189
|
|
190 if (mode == MODE_OPENING) {
|
|
191 linda_set_schedule(linda_sche_opening1, MODE_OPENING);
|
|
192 return TRUE;
|
|
193 } else {
|
|
194 return FALSE;
|
|
195 }
|
|
196 }
|
|
197
|
46
|
198 static Bool
|
44
|
199 linda_sche_opening0()
|
|
200 {
|
|
201 int i, flg, mode;
|
46
|
202 int id = game.play_id;
|
44
|
203 int connect = 1;
|
|
204
|
49
|
205 for (i=1; i<=CLIENT_MAX; i++) {
|
50
|
206 get_packet(i, &flg, &mode, NULL, NULL, NULL);
|
51
|
207 if (i == id) {
|
|
208 flg = 0;
|
|
209 continue;
|
|
210 }
|
|
211 if (flg == 1 && mode == MODE_OPENING) {
|
44
|
212 connect++;
|
51
|
213 flg = 0;
|
|
214 }
|
44
|
215 }
|
|
216
|
|
217 if (connect == CLIENT_MAX) {
|
|
218 linda_set_schedule(linda_sche_select_car0, MODE_SELECT_CAR);
|
|
219 return TRUE;
|
|
220 } else {
|
|
221 return FALSE;
|
|
222 }
|
|
223 }
|
|
224
|
46
|
225 static Bool
|
44
|
226 linda_sche_opening1()
|
|
227 {
|
|
228 int mode;
|
|
229
|
|
230 get_packet(PLAYER_1P, NULL, &mode, NULL, NULL, NULL);
|
|
231
|
|
232 if (mode == MODE_SELECT_CAR) {
|
|
233 linda_set_schedule(linda_sche_select_car1, MODE_SELECT_CAR);
|
|
234 return TRUE;
|
|
235 } else {
|
|
236 return FALSE;
|
|
237 }
|
|
238 }
|
|
239
|
|
240 static Bool
|
|
241 linda_sche_select_car0()
|
|
242 {
|
|
243 int i, flg, mode;
|
46
|
244 int id = game.play_id;
|
44
|
245 int connect = 1;
|
|
246
|
49
|
247 for (i=1; i<=CLIENT_MAX; i++) {
|
50
|
248 get_packet(i, &flg, &mode, NULL, NULL, NULL);
|
51
|
249 if (i == id) {
|
|
250 flg = 0;
|
|
251 continue;
|
|
252 }
|
|
253 if (flg == 1 && mode == MODE_SELECT_CAR) {
|
44
|
254 connect++;
|
51
|
255 flg = 0;
|
|
256 }
|
44
|
257 }
|
|
258
|
|
259 if (connect == CLIENT_MAX) {
|
|
260 linda_set_schedule(linda_sche_select_course0, MODE_SELECT_COURSE);
|
|
261 return TRUE;
|
|
262 } else {
|
|
263 return FALSE;
|
|
264 }
|
|
265 }
|
|
266
|
|
267 static Bool
|
|
268 linda_sche_select_car1()
|
|
269 {
|
|
270 int mode;
|
|
271
|
|
272 get_packet(PLAYER_1P, NULL, &mode, NULL, NULL, NULL);
|
|
273
|
|
274 if (mode == MODE_SELECT_COURSE) {
|
|
275 linda_set_schedule(linda_sche_select_course1, MODE_SELECT_COURSE);
|
|
276 return TRUE;
|
|
277 } else {
|
|
278 return FALSE;
|
|
279 }
|
|
280 }
|
|
281
|
|
282 static Bool
|
|
283 linda_sche_select_course0()
|
|
284 {
|
46
|
285 int i;
|
|
286 int flg, mode;
|
50
|
287 int connect = 1;
|
46
|
288 int id = game.play_id;
|
44
|
289 static int course_id = 1;
|
|
290
|
|
291 if (course_id != game.course_id) {
|
|
292 course_id = game.course_id;
|
50
|
293 linda_seq[game.play_id] = psx_in(game.play_id);
|
46
|
294 send_packet(game.play_id, MODE_SELECT_COURSE, 0, course_id, NULL);
|
50
|
295 return FALSE;
|
44
|
296 }
|
|
297
|
49
|
298 for (i=1; i<=CLIENT_MAX; i++) {
|
50
|
299 get_packet(i, &flg, &mode, NULL, NULL, NULL);
|
51
|
300 if (i == id) {
|
|
301 flg = 0;
|
|
302 continue;
|
|
303 }
|
|
304 if (flg == 1 && mode == MODE_SELECT_COURSE) {
|
44
|
305 connect++;
|
51
|
306 flg = 0;
|
|
307 }
|
|
308
|
44
|
309 }
|
|
310
|
|
311 if (connect == CLIENT_MAX) {
|
|
312 linda_set_schedule(linda_sche_ready0, MODE_READY);
|
|
313 return TRUE;
|
|
314 } else {
|
|
315 return FALSE;
|
|
316 }
|
|
317 }
|
|
318
|
|
319 static Bool
|
|
320 linda_sche_select_course1()
|
|
321 {
|
|
322 int mode, course_id;
|
|
323
|
|
324 get_packet(PLAYER_1P, NULL, &mode, NULL, &course_id, NULL);
|
|
325
|
|
326 if (mode == MODE_SELECT_COURSE) {
|
|
327 game.course_id = course_id;
|
|
328 return FALSE;
|
|
329 } else if (mode == MODE_READY) {
|
|
330 linda_set_schedule(linda_sche_ready1, MODE_READY);
|
|
331 return TRUE;
|
|
332 } else {
|
|
333 return FALSE;
|
|
334 }
|
|
335 }
|
|
336
|
|
337
|
|
338 static Bool
|
|
339 linda_sche_ready0()
|
|
340 {
|
52
|
341 linda_set_schedule(linda_sche_main0, MODE_MAIN);
|
44
|
342 return TRUE;
|
|
343 }
|
|
344
|
|
345 static Bool
|
|
346 linda_sche_ready1()
|
|
347 {
|
52
|
348 linda_set_schedule(linda_sche_main1, MODE_MAIN);
|
|
349 return TRUE;
|
|
350 }
|
|
351
|
|
352 static Bool
|
|
353 linda_sche_main0()
|
|
354 {
|
53
|
355 FMATRIX data;
|
|
356
|
|
357 ps2_vu0_unit_matrix(data);
|
|
358 ps2_vu0_copy_matrix(data, game.jiki->body->transfer);
|
|
359 ps2_vu0_copy_vector(data[3], game.jiki->location);
|
|
360
|
54
|
361 linda_seq[game.play_id] = psx_in(game.play_id);
|
|
362 send_packet(game.play_id, MODE_MAIN, 1, 1, (char*)data);
|
52
|
363 return FALSE;
|
|
364 }
|
|
365
|
|
366 static Bool
|
|
367 linda_sche_main1()
|
|
368 {
|
|
369 int mode;
|
|
370 FMATRIX po;
|
|
371
|
|
372 ps2_vu0_unit_matrix(po);
|
55
|
373
|
56
|
374 get_packet(PLAYER_1P, NULL, &mode, NULL, NULL, (char*)po);
|
52
|
375
|
|
376 if (mode == MODE_MAIN) {
|
|
377 ps2_vu0_copy_matrix(game.jiki->body->transfer, po);
|
|
378 }
|
|
379
|
44
|
380 return FALSE;
|
|
381 }
|
|
382
|
|
383 #if 0
|
|
384 static void
|
0
|
385 linda_enemy_update(int id, CarPtr enemy, CarInfoPtr tpl)
|
|
386 {
|
|
387 int i,j;
|
|
388
|
|
389 if (id == 1 || tpl->state == GAME_GOAL) {
|
|
390 common_state = tpl->state;
|
|
391 game.course_id = tpl->course_id;
|
|
392 }
|
|
393
|
|
394 if (enemy && (common_state == GAME_MAIN || common_state == GAME_GOAL)) {
|
|
395 for (i=0; i<4; i++) {
|
|
396 for (j=0; j<4; j++) {
|
|
397 enemy->body->transfer[i][j] = tpl->position[i][j];
|
|
398 }
|
|
399 }
|
|
400
|
|
401 /* 敵は相対位置で */
|
|
402 enemy->body->transfer[3][0] -= game.jiki->location[0];
|
|
403 enemy->body->transfer[3][1] -= game.jiki->location[1];
|
|
404 enemy->body->transfer[3][2] -= game.jiki->location[2];
|
|
405 enemy->body->transfer[3][3] = 1;
|
|
406 }
|
|
407 }
|
|
408
|
|
409 /*
|
|
410 * 位置が同じなら1を返す。
|
|
411 * もっと良い比較方法があるんでは...
|
|
412 */
|
|
413 static int
|
|
414 linda_jiki_compareLocation()
|
|
415 {
|
|
416 float x,y,z;
|
|
417 double d;
|
|
418
|
|
419 if (common_state == GAME_MAIN || common_state == GAME_GOAL) {
|
|
420 x = jiki.position[3][0] - game.jiki->location[0];
|
|
421 y = jiki.position[3][1] - game.jiki->location[1];
|
|
422 z = jiki.position[3][2] - game.jiki->location[2];
|
|
423 d = sqrt(x*x+y*y+z*z);
|
|
424
|
|
425 if (d < 1.0) {
|
|
426 return 1;
|
|
427 } else {
|
|
428 return 0;
|
|
429 }
|
|
430 } else {
|
|
431 return 1;
|
|
432 }
|
|
433 }
|
|
434
|
44
|
435
|
0
|
436 /*
|
|
437 * 自機情報が更新されていなければ
|
|
438 * 0を返す(psx_outしない)
|
|
439 */
|
|
440 static int
|
|
441 linda_jiki_compare()
|
|
442 {
|
|
443 if ((jiki.car_id == game.car_id) &&
|
|
444 (jiki.course_id == game.course_id) &&
|
|
445 (jiki.create_flg == ((game.jiki) ? 1:0)) &&
|
|
446 (jiki.state == common_state) &&
|
|
447 (linda_jiki_compareLocation())) {
|
|
448 return 0;
|
|
449 } else {
|
|
450 return 1;
|
|
451 }
|
|
452 }
|
|
453
|
|
454 static void
|
|
455 linda_jiki_update()
|
|
456 {
|
|
457 int i,j;
|
44
|
458
|
0
|
459
|
|
460 jiki.car_id = game.car_id;
|
|
461 jiki.course_id = game.course_id;
|
|
462 jiki.create_flg = (game.jiki) ? 1 : 0;
|
|
463 jiki.state = common_state;
|
|
464
|
|
465 if (common_state == GAME_MAIN || common_state == GAME_GOAL) {
|
|
466 for (i=0; i<3; i++) {
|
|
467 for (j=0; j<4; j++) {
|
|
468 jiki.position[i][j]
|
|
469 = game.jiki->body->transfer[i][j];
|
|
470 }
|
|
471 }
|
|
472 jiki.position[3][0] = game.jiki->location[0];
|
|
473 jiki.position[3][1] = game.jiki->location[1];
|
|
474 jiki.position[3][2] = game.jiki->location[2];
|
|
475 jiki.position[3][3] = 1;
|
|
476 }
|
|
477 }
|
|
478
|
|
479 void
|
|
480 linda_update()
|
|
481 {
|
|
482 int i;
|
|
483 int barrier = 1; // バリア同期(?)用
|
|
484 int connect = 1;
|
44
|
485 int mode, id, flg;
|
0
|
486 char* reply;
|
44
|
487 char* pkt;
|
0
|
488 CarPtr car = NULL;
|
|
489
|
|
490 for (i=1; i<=CLIENT_MAX; i++) {
|
|
491 reply = psx_reply(linda_seq[i]);
|
|
492 if (reply) {
|
44
|
493 pkt = reply+LINDA_HEADER_SIZE;
|
|
494 mode = get_header(pkt, PKT_MODE_OFFSET);
|
|
495 id = get_header(pkt, PKT_ID_OFFSET);
|
|
496 flg = get_header(pkt, PKT_FLG_OFFSET);
|
|
497
|
0
|
498 if (i != game.play_id) {
|
|
499 connect++;
|
|
500
|
|
501 car = linda_carlist[i];
|
|
502 if (common_state == GAME_MAIN && !car && p->create_flg == 1) {
|
|
503 car = car_init(p->car_id);
|
|
504 carNode_append(car);
|
|
505 linda_carlist[i] = car;
|
|
506 }
|
|
507 linda_enemy_update(i, car, p);
|
|
508 if (common_state == p->state) {
|
|
509 barrier++;
|
|
510 }
|
|
511 }
|
|
512 psx_free(reply);
|
|
513 linda_seq[i] = psx_rd(i);
|
|
514 }
|
|
515 }
|
|
516
|
|
517 if (connect == CLIENT_MAX) {
|
|
518 if (game.state == GAME_WAIT) {
|
|
519 gFont_SetString("CONNECT OK!!", 170, 300);
|
|
520 if (game.play_id == 1)
|
|
521 gFont_SetString(" PUSH START ", 170, 400);
|
|
522 }
|
|
523
|
|
524 // ごちゃごちゃしてる...
|
|
525 // なんか無駄な処理がありそうだ
|
|
526 if (game.play_id == 1) {
|
|
527 // 全員のフラグ成立
|
|
528 if (common_state == GAME_GOAL) {
|
|
529 if (game.state == GAME_FINISH) {
|
|
530 common_state = game.state;
|
|
531 } else {
|
|
532 game.state = common_state;
|
|
533 }
|
|
534 } else if (barrier == CLIENT_MAX) {
|
|
535 common_state = game.state;
|
|
536 } else {
|
|
537 game.state = common_state;
|
|
538 }
|
|
539 } else {
|
|
540 if (game.state == GAME_GOAL) {
|
|
541 if (common_state != GAME_FINISH) {
|
|
542 common_state = game.state;
|
|
543 } else {
|
|
544 game.state = common_state;
|
|
545 }
|
|
546 } else {
|
|
547 game.state = common_state;
|
|
548 }
|
|
549 }
|
|
550 } else {
|
|
551 if (game.state == GAME_WAIT) {
|
|
552 gFont_SetString("WAITING...", 200, 100);
|
|
553 }
|
|
554 game.state = common_state;
|
|
555 }
|
|
556
|
|
557 if (linda_jiki_compare()) {
|
|
558 #ifdef DEBUG
|
|
559 // どのタイミングでoutされてるか見る
|
|
560 // 必要なときだけoutしないと重いですね当然だけど
|
|
561 //fprintf(main_fp, "psx_out() jiki\n");
|
|
562 #endif
|
|
563 linda_jiki_update();
|
|
564 // 無理矢理
|
|
565 // 古いものを消すだけなんだけど
|
|
566 // 正しいやり方が他に有るのかな?
|
|
567 // 実行し続けてると最終的に激重になるので
|
|
568 // ここら辺に問題が有るのだろうか。
|
|
569 // psx_free(psx_reply(psx_in(game.play_id)));
|
|
570 linda_seq[my_id]=psx_in(game.play_id);
|
|
571 psx_out(game.play_id, (char*)&jiki, sizeof(CarInfo));
|
|
572 }
|
|
573 }
|
44
|
574 #endif
|
0
|
575
|
|
576 static int
|
|
577 get_id()
|
|
578 {
|
|
579 unsigned char * reply;
|
|
580 int seq;
|
|
581 int id;
|
|
582
|
|
583 //ユーザIDが格納されているTUPLE SpaceのIDへアクセス
|
|
584 seq = psx_in(LINDA_ASK_ID);
|
|
585
|
|
586 // IDが取得できるまでループ
|
|
587 while((reply = psx_reply(seq)) == 0) psx_sync_n();
|
|
588
|
|
589 id = atoi(reply+LINDA_HEADER_SIZE);
|
|
590 psx_free(reply);
|
|
591 return id;
|
|
592 }
|
|
593
|
|
594 void
|
43
|
595 linda_env_init()
|
0
|
596 {
|
43
|
597 int i;
|
0
|
598
|
|
599 for (i=0; i<CLIENT_MAX+1; i++) {
|
|
600 linda_carlist[i] = NULL;
|
|
601 }
|
43
|
602
|
0
|
603 }
|
|
604
|
|
605
|
|
606
|
|
607 int
|
|
608 linda_init()
|
|
609 {
|
|
610 int i;
|
|
611
|
|
612 start_linda(LINDA_HOST);
|
|
613 my_id = get_id();
|
|
614
|
|
615 for (i=1; i<=CLIENT_MAX; i++) {
|
|
616 if (i == my_id) {
|
44
|
617 send_packet(i, MODE_WAIT, i, 0, NULL);
|
0
|
618 }
|
|
619 linda_seq[i] = psx_rd(i);
|
|
620 }
|
|
621 psx_sync_n();
|
|
622
|
48
|
623 if (my_id == PLAYER_1P) {
|
|
624 game.linda_exec = &linda_sche_wait0;
|
|
625 send_packet(game.play_id, MODE_WAIT, 1, 1, NULL);
|
|
626 } else {
|
|
627 game.linda_exec = &linda_sche_wait1;
|
|
628 send_packet(game.play_id, MODE_WAIT, 1, 1, NULL);
|
|
629 }
|
0
|
630 return my_id;
|
|
631 }
|