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