diff linda.c @ 0:0fae5658fb0b

Initial revision
author gongo
date Thu, 02 Nov 2006 08:55:19 +0000
parents
children 6910aeb52843
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linda.c	Thu Nov 02 08:55:19 2006 +0000
@@ -0,0 +1,289 @@
+/*
+ * 2006/07/24 16:22:23 sugiyama
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <libps2.h>
+#include <ps2util.h>
+
+#include "car.h"
+#include "game.h"
+#include "lindaapi.h"
+
+#define CLIENT_MAX 2
+#define LINDA_ASK_ID 65535
+#define LINDA_HOST "firefly.cr.ie.u-ryukyu.ac.jp"
+
+extern CarPtr car_init(int);
+extern void gFont_SetString(char *, int, int);
+extern void gFont_SetStringInt(int, int, int);
+extern void carNode_append(CarPtr);
+extern Game game;
+extern FILE *main_fp;
+
+static GAME_STATE common_state = GAME_WAIT;
+static  int my_id;
+
+typedef struct car_info {
+    GAME_STATE state;
+    FMATRIX position;
+    int car_id;
+    int course_id;
+    int create_flg;
+} CarInfo, *CarInfoPtr;
+
+static CarPtr linda_carlist[CLIENT_MAX+1];
+static CarInfo jiki;
+static int linda_seq[CLIENT_MAX+1];
+
+static void
+linda_enemy_update(int id, CarPtr enemy, CarInfoPtr tpl)
+{
+    int i,j;
+
+    if (id == 1 || tpl->state == GAME_GOAL) {
+	common_state = tpl->state;
+	game.course_id = tpl->course_id;
+    }
+
+    if (enemy && (common_state == GAME_MAIN || common_state == GAME_GOAL)) {
+	for (i=0; i<4; i++) {
+	    for (j=0; j<4; j++) {
+		enemy->body->transfer[i][j] = tpl->position[i][j];
+	    }
+	}
+
+	/* 敵は相対位置で */
+	enemy->body->transfer[3][0] -= game.jiki->location[0];
+	enemy->body->transfer[3][1] -= game.jiki->location[1];
+	enemy->body->transfer[3][2] -= game.jiki->location[2];
+	enemy->body->transfer[3][3] = 1;
+    }
+}
+
+/*
+ * 位置が同じなら1を返す。
+ * もっと良い比較方法があるんでは...
+ */
+static int
+linda_jiki_compareLocation()
+{
+    float x,y,z;
+    double d;
+
+    if (common_state == GAME_MAIN || common_state == GAME_GOAL) {
+	x = jiki.position[3][0] - game.jiki->location[0];
+	y = jiki.position[3][1] - game.jiki->location[1];
+	z = jiki.position[3][2] - game.jiki->location[2];
+	d = sqrt(x*x+y*y+z*z);
+
+	if (d < 1.0) {
+	    return 1;
+	} else {
+	    return 0;
+	}
+    } else {
+	return 1;
+    }
+}
+
+/*
+ * 自機情報が更新されていなければ
+ * 0を返す(psx_outしない)
+ */
+static int
+linda_jiki_compare()
+{
+    if ((jiki.car_id == game.car_id) &&
+	(jiki.course_id == game.course_id) &&
+	(jiki.create_flg == ((game.jiki) ? 1:0)) &&
+	(jiki.state == common_state) &&
+	(linda_jiki_compareLocation())) {
+	return 0;
+    } else {
+	return 1;
+    }
+}
+
+static void
+linda_jiki_update()
+{
+    int i,j;
+
+    jiki.car_id     = game.car_id;
+    jiki.course_id  = game.course_id;
+    jiki.create_flg = (game.jiki) ? 1 : 0;
+    jiki.state      = common_state;
+
+    if (common_state == GAME_MAIN || common_state == GAME_GOAL) {
+	for (i=0; i<3; i++) {
+	    for (j=0; j<4; j++) {
+		jiki.position[i][j]
+		    = game.jiki->body->transfer[i][j];
+	    }
+	}
+	jiki.position[3][0] = game.jiki->location[0];
+	jiki.position[3][1] = game.jiki->location[1];
+	jiki.position[3][2] = game.jiki->location[2];
+	jiki.position[3][3] = 1;
+    }
+}
+
+void
+linda_update()
+{
+    int i;
+    int barrier = 1; // バリア同期(?)用
+    int connect = 1;
+    char* reply;
+    CarInfoPtr p = NULL;
+    CarPtr car = NULL;
+
+    for (i=1; i<=CLIENT_MAX; i++) {
+	reply = psx_reply(linda_seq[i]);
+	if (reply) {
+	    p = (CarInfoPtr)(reply+LINDA_HEADER_SIZE);
+
+	    if (i != game.play_id) {
+		connect++;
+		
+		car = linda_carlist[i];
+		if (common_state == GAME_MAIN && !car && p->create_flg == 1) {
+		    car = car_init(p->car_id);
+		    carNode_append(car);
+		    linda_carlist[i] = car;
+		}
+		linda_enemy_update(i, car, p);
+		if (common_state == p->state) {
+		    barrier++;
+		}
+	    }
+	    psx_free(reply);
+	    linda_seq[i] = psx_rd(i);
+	}
+    }
+
+    if (connect == CLIENT_MAX) {
+	if (game.state == GAME_WAIT) {
+	    gFont_SetString("CONNECT OK!!", 170, 300);
+	    if (game.play_id == 1)
+		gFont_SetString(" PUSH START ", 170, 400);
+	}
+
+	// ごちゃごちゃしてる...
+	// なんか無駄な処理がありそうだ
+	if (game.play_id == 1) {
+	    // 全員のフラグ成立
+	    if (common_state == GAME_GOAL) {
+		if (game.state == GAME_FINISH) {
+		    common_state = game.state;
+		} else {
+		    game.state = common_state;
+		}
+	    } else if (barrier == CLIENT_MAX) {
+		common_state = game.state;
+	    } else {
+		game.state = common_state;
+	    }
+	} else {
+	    if (game.state == GAME_GOAL) {
+		if (common_state != GAME_FINISH) {
+		    common_state = game.state;
+		} else {
+		    game.state = common_state;
+		}
+	    } else {
+		game.state = common_state;
+	    }
+	}
+    } else {
+	if (game.state == GAME_WAIT) {
+	    gFont_SetString("WAITING...", 200, 100);
+	}
+	game.state = common_state;
+    }
+
+    if (linda_jiki_compare()) {
+#ifdef DEBUG
+	// どのタイミングでoutされてるか見る
+	// 必要なときだけoutしないと重いですね当然だけど
+	//fprintf(main_fp, "psx_out() jiki\n");
+#endif
+	linda_jiki_update();
+	// 無理矢理
+	// 古いものを消すだけなんだけど
+	// 正しいやり方が他に有るのかな?
+	// 実行し続けてると最終的に激重になるので
+	// ここら辺に問題が有るのだろうか。
+	//	psx_free(psx_reply(psx_in(game.play_id)));
+	linda_seq[my_id]=psx_in(game.play_id);
+	psx_out(game.play_id, (char*)&jiki, sizeof(CarInfo));
+    }
+}
+
+static int
+get_id()
+{
+    unsigned char * reply;
+    int seq;
+    int id;
+
+    //ユーザIDが格納されているTUPLE SpaceのIDへアクセス
+    seq = psx_in(LINDA_ASK_ID);
+
+    // IDが取得できるまでループ
+    while((reply = psx_reply(seq)) == 0) psx_sync_n();
+
+    id = atoi(reply+LINDA_HEADER_SIZE);
+    psx_free(reply);
+    return id;
+}
+
+void
+linda_jikiInfo_init()
+{
+    int i, j;
+
+    jiki.car_id     = 1;
+    jiki.course_id  = 1;
+    jiki.create_flg = 0;
+    jiki.state      = game.state;
+
+    // malloc16で生成してないからBus errorに
+    // ps2_vu0_unit_matrix(jiki.position);
+    for (i=0; i<4; i++) {
+	for (j=0; j<4; j++) {
+	    if (i==j)
+		jiki.position[i][j] = 1;
+	    else
+		jiki.position[i][j] = 0;
+	}
+    }
+
+    for (i=0; i<CLIENT_MAX+1; i++) {
+	linda_carlist[i] = NULL;
+    }
+}
+
+
+
+int
+linda_init()
+{
+
+    int i;
+
+    start_linda(LINDA_HOST);
+    my_id = get_id();
+
+    for (i=1; i<=CLIENT_MAX; i++) {
+	if (i == my_id) {
+	    psx_out(i, (char*)&jiki, sizeof(CarInfo));
+	}
+	linda_seq[i] = psx_rd(i);
+    }
+    psx_sync_n();
+
+    return my_id;
+}