changeset 974:d1700a13513f

add OSC demo
author kazz <kazz@cr.ie.u-ryukyu.ac.jp>
date Fri, 01 Oct 2010 18:52:13 +0900
parents d093d601fc14
children 4b59f003e3ce
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);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Test/protobuf/network_game.proto	Fri Oct 01 18:52:13 2010 +0900
@@ -0,0 +1,8 @@
+package network_game;
+
+message Position {
+  required float x = 1;
+  required float y = 2;
+  required float angle_x = 3;
+  required float angle_y = 4;
+}