Mercurial > hg > old > magoroku_racing
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; +}