Mercurial > hg > Game > Cerium
changeset 974:6e6d5a2ffe52 draft
add OSC demo
author | kazz <kazz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 01 Oct 2010 18:52:13 +0900 |
parents | 811cdd0fd418 |
children | c48e3866f85f |
files | Renderer/Test/Makefile.macosx Renderer/Test/network.cc Renderer/Test/network.h Renderer/Test/protobuf/network_game.proto |
diffstat | 4 files changed, 328 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Test/Makefile.macosx Fri Aug 27 06:39:16 2010 +0900 +++ b/Renderer/Test/Makefile.macosx Fri Oct 01 18:52:13 2010 +0900 @@ -13,7 +13,7 @@ %.pb.cc: $(PROTODIR)/%.proto $(PROTO) $(PROTOFLAGS) $< -ALL = ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum property_test send_linda dynamic writer chain_old SgRootChange viewer aquarium init_aquarium test_linda +ALL = ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum property_test send_linda dynamic writer chain_old SgRootChange viewer aquarium network init_aquarium test_linda oFLAGS=-g -O2 CFLAGt=-g -O2 @@ -91,6 +91,10 @@ aquarium : $(AQUARIUM_OBJ) $(CC) -o $@ $? $(LIBS) $(PROTOLIBS) +NETWORK_OBJ = network_game.pb.o network.o +network : $(NETWORK_OBJ) + $(CC) -o $@ $? $(LIBS) $(PROTOLIBS) + INIT_AQUARIUM_OBJ = aquarium.pb.o init_aquarium.o init_aquarium : $(INIT_AQUARIUM_OBJ) $(CC) -o $@ $? $(LIBS) $(PROTOLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Test/network.cc Fri Oct 01 18:52:13 2010 +0900 @@ -0,0 +1,286 @@ +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> +#include "SceneGraphRoot.h" +#include "lindaapi.h" +#include "network.h" +#include "network_game.pb.h" + +#define GET_SERIAL_ID 65535 + +int NetworkGame::last_player_id = 0; + +Viewer *NetworkGame::sgroot; +linda_t NetworkGame::linda_addr = { "localhost", 10000 }; +int NetworkGame::linda; +int NetworkGame::serial_id; +int NetworkGame::width; +int NetworkGame::start_x; +char *NetworkGame::xml_file_name; + +const char *usr_help_str = "Usage: ./network -linda LINDA_SERVER_NAME\n"; +void TMend(TaskManager *manager); + +extern void task_initialize(); +extern int init(TaskManager *manager, int argc, char *argv[]); +extern Application * +application() { + return new NetworkGame(); +} + +static void +null_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ +} +static void +null_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree) +{ +} + +void +NetworkGame::update_last_player_id() { + last_player_id++; + if (last_player_id == serial_id) + last_player_id++; +} + +void +NetworkGame::set_position(SceneGraphPtr node, unsigned char *reply) { + network_game::Position *pos = new network_game::Position(); + pos->ParseFromArray(reply + LINDA_HEADER_SIZE, psx_get_datalength(reply)); + node->xyz[0] = pos->x(); + node->xyz[1] = pos->y(); + node->angle[0] = pos->angle_x(); + node->angle[1] = pos->angle_y(); + delete pos; +} + +static void +update_position_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ + // LindaServerから座標データを取得してオブジェクトに反映させる。 + if (!node->resend_flag || node->seq_rd != node->seq) { + unsigned char *reply_rd = psx_reply(node->seq_rd); + if (reply_rd != NULL) { + NetworkGame::set_position(node, reply_rd); + psx_free(reply_rd); + return; + } + } + unsigned char *reply = psx_reply(node->seq); + if (reply != NULL) { +// NetworkGame::set_position(node, reply); + psx_free(reply); + node->seq = psx_wait_rd(NetworkGame::linda, node->id * 10 + 1); + node->resend_flag = true; + } else if (node->resend_flag) { + node->seq_rd = psx_rd(NetworkGame::linda, node->id * 10 + 1); + node->resend_flag = false; + } +} + +SceneGraphPtr +create_sg(Viewer *viewer, SceneGraphPtr par, unsigned char *data, int len, int serial_id) +{ + SceneGraphPtr child = viewer->sgroot->createSceneGraph(); + viewer->sgroot->createFromXMLmemory(viewer->sgroot->tmanager, child, (char *)data, len); + child->set_move_collision(update_position_move, null_collision); + child->id = serial_id; + child->seq = psx_wait_rd(NetworkGame::linda, serial_id * 10 + 1); + child->seq_rd = psx_rd(NetworkGame::linda, serial_id * 10 + 1); + child->resend_flag = false; + par->addChild(child); + return child; +} + +static void +check_new_player_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ + unsigned char *reply_rd = psx_reply(node->seq_rd); + if (reply_rd != NULL) { + unsigned char *xml_data = reply_rd + LINDA_HEADER_SIZE; + int xml_len = psx_get_datalength(reply_rd); + create_sg(NetworkGame::sgroot, node, xml_data, xml_len, NetworkGame::last_player_id); + psx_free(reply_rd); + NetworkGame::update_last_player_id(); + int tuple_id = NetworkGame::last_player_id * 10; + node->seq_rd = psx_rd(NetworkGame::linda, tuple_id); + } + // printf("rd id: %d\n", NetworkGame::last_player_id); +} + +void * +file_map(const char *filename, int *size) { + int fd; + void *addr; + struct stat sb; + + if ((fd = open(filename, O_RDONLY)) == -1) { + fprintf(stderr, "Can't open %s\n", filename); + perror(NULL); + } + if (fstat(fd, &sb) == -1) { + fprintf(stderr, "Can't fstat %s\n", filename); + perror(NULL); + } + *size = sb.st_size; + addr = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) { + perror("mmap error\n"); + exit(EXIT_FAILURE); + } + close(fd); + + return addr; +} + +void callback_free(unsigned char *tuple, void *arg) { + psx_free(tuple); +} + +void +NetworkGame::send_position(SceneGraphPtr node) { + int pos_id = serial_id * 10 + 1; + psx_callback_in(linda, pos_id, callback_free, NULL); + network_game::Position *pos = new network_game::Position(); + pos->set_x(node->xyz[0]); + pos->set_y(node->xyz[1]); + pos->set_angle_x(node->angle[0]); + pos->set_angle_y(node->angle[1]); + int size = pos->ByteSize(); + unsigned char *msg = (unsigned char *) sgroot->manager->allocate(sizeof(char) * size); + pos->SerializeToArray(msg, size); // 更新したデータを再度シリアライズ + delete pos; + psx_out(linda, pos_id, msg, size); +} + +void +my_move(SceneGraphPtr node, void *sgroot_, int w, int h) +{ + SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_; + Pad *pad = sgroot->getController(); + int flag = 0; + if (pad->right.isHold() || pad->left.isHold()) { + if (pad->right.isHold()) { + node->xyz[0] += 5.0f; +// node->angle[1] = 0.0f; + flag = 1; + } else if (pad->left.isHold()) { + node->xyz[0] -= 5.0f; +// node->angle[1] = 180.0f; + flag = 1; + } + } + + if (pad->down.isHold() || pad->up.isHold() ) { + if (pad->down.isHold()) { + node->xyz[1] += 5.0f; + flag = 1; + } else if (pad->up.isHold()) { + node->xyz[1] -= 5.0f; + flag = 1; + } + } + + /* ここで座標を送信 */ + if (flag || node->resend_flag) { + NetworkGame::send_position(node); + } +} + +void +NetworkGame::create_my_sg(Viewer *viewer, SceneGraphPtr par, int screen_w, int screen_h) +{ + int size; + void *addr = file_map(xml_file_name, &size); + SceneGraphPtr sgp = viewer->createSceneGraph(); + viewer->createFromXMLmemory(sgp, (char *)addr, size); + sgp->set_move_collision(my_move, null_collision); + + par->addChild(sgp); + sgp->c_xyz[0] = 0.0f; + sgp->c_xyz[1] = 0.0f; + sgp->c_xyz[2] = 0.0f; + + int xml_id = serial_id * 10; + psx_out(linda, xml_id, (unsigned char *)addr, size); + int pos_id = serial_id * 10 + 1; + + network_game::Position *pos = new network_game::Position(); + pos->set_x(0.0f); + pos->set_y(0.0f); + pos->set_angle_x(0.0f); + pos->set_angle_y(0.0f); + unsigned char *msg = (unsigned char *) viewer->manager->allocate(sizeof(unsigned char *) * size); + pos->SerializeToArray(msg, size); + psx_out(linda, pos_id, (unsigned char *)msg, pos->ByteSize()); + delete pos; + sgp->seq = 0; + sgp->resend_flag = 0; +} + +MainLoopPtr +NetworkGame::init(Viewer *sgroot, int screen_w, int screen_h) +{ + this->sgroot = sgroot; + width = screen_w; + linda_connect(); // 接続に合わせて serial_id も取得 +// update_screen_scope(); + SceneGraphPtr parent = sgroot->createSceneGraph(); + parent->set_move_collision(check_new_player_move, null_collision); + + create_my_sg(sgroot, parent, screen_w, screen_h); + update_last_player_id(); + + int tuple_id = NetworkGame::last_player_id * 10; + parent->seq_rd = psx_rd(linda, tuple_id); + sgroot->setSceneData(parent); + return sgroot; +} + +void +NetworkGame::linda_connect() { + init_linda(); // セレクタの初期化 + linda = open_linda_java(linda_addr.hostname, linda_addr.port); + // serial_id の取得 + int seq = psx_in(linda, GET_SERIAL_ID); + unsigned char *data = NULL; + do { + psx_sync_n(); + data = psx_reply(seq); + } while (data == NULL); +// data[LINDA_HEADER_SIZE + psx_get_datalength(data)] = '\0'; + serial_id = atoi((char *)data + LINDA_HEADER_SIZE); + psx_free(data); + printf("Get serial_id: %d\n", serial_id); +} + +int +TMmain(TaskManager *manager, int argc, char *argv[]) +{ + task_initialize(); + manager->set_TMend(TMend); + + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i],"-linda") == 0 && i + 1 <= argc) { + NetworkGame::linda_addr.hostname = argv[i+1]; + } else if (strcmp(argv[i],"-port") == 0 && i + 1 <= argc) { + NetworkGame::linda_addr.port = atoi(argv[i+1]); + } else if (strcmp(argv[i],"-xml") == 0 && i + 1 <= argc) { + NetworkGame::xml_file_name = argv[i+1]; + } + } + return init(manager, argc, argv); +} + +void +TMend(TaskManager *manager) +{ + printf("NetworkGame end\n"); +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Test/network.h Fri Oct 01 18:52:13 2010 +0900 @@ -0,0 +1,29 @@ +#include <math.h> +#include <stdlib.h> +#include "SceneGraphRoot.h" +#include "Application.h" +#include "MainLoop.h" +typedef struct { + const char *hostname; + int port; +} linda_t; + +class NetworkGame : public Application { +public: + static int last_player_id; + + static Viewer *sgroot; + static linda_t linda_addr; + static int linda; + static int serial_id; + static int start_x; + static int width; + static char *xml_file_name; + static void linda_connect(); + static void update_screen_scope(); + static void send_position(SceneGraphPtr node); + static void set_position(SceneGraphPtr node, unsigned char *reply); + static void update_last_player_id(); + void create_my_sg(Viewer *sgroot, SceneGraphPtr parent, int screen_w, int screen_h); + MainLoopPtr init(Viewer *viewer, int screen_w, int screen_h); +};