summaryrefslogtreecommitdiff
path: root/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game.cpp')
-rw-r--r--game.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/game.cpp b/game.cpp
new file mode 100644
index 0000000..5bc1a8d
--- /dev/null
+++ b/game.cpp
@@ -0,0 +1,108 @@
+#include "game.h"
+#include "video.h"
+#include "messages.h"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+
+Game* Game::game = NULL;
+
+Game::Game() : socket(io_service) {
+ scene = new Scene();
+}
+
+Game::~Game() {
+ delete scene;
+}
+
+void Game::run(const std::string host, const unsigned int port) {
+ run(host, boost::lexical_cast<std::string>(port));
+}
+
+void Game::run(const std::string host, const std::string port) {
+ SDL_WarpMouse(video::width/2, video::height/2);
+ scene->last_time = SDL_GetTicks();
+ scene->update();
+
+ {
+ boost::asio::ip::tcp::resolver resolver(io_service);
+ boost::asio::ip::tcp::resolver::query query(host, port);
+ boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
+ socket.connect(boost::asio::ip::tcp::endpoint(*iterator));
+
+ message::Hello h(1);
+ h.send(socket);
+ }
+
+ async_read();
+
+ unsigned int last = SDL_GetTicks();
+ while(scene->running) {
+ if(SDL_GetTicks() - last >= 1000) {
+ message::Pos pos(scene->pos.x, scene->pos.y, scene->pos.z);
+ pos.send(socket);
+ last = SDL_GetTicks();
+ }
+ io_service.poll_one();
+ scene->events();
+ scene->render();
+
+ SDL_Delay(1);
+ }
+}
+
+void Game::async_read() {
+ uint8_t *t = new uint8_t;
+ boost::asio::async_read(socket, boost::asio::buffer(t, sizeof(uint8_t)),
+ boost::asio::transfer_all(),
+ boost::bind(&Game::handle_message, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, t));
+}
+
+void Game::handle_message(const boost::system::error_code& error, std::size_t bytes_transferred, uint8_t *type) {
+ if(error) {
+ std::cerr << error << std::endl;
+ delete type;
+ scene->running = false;
+ return;
+ }
+
+ switch(*type) {
+ case message::MSG_TYPE_CHUNK:
+ handle_chunk();
+ break;
+ default:
+ std::cout << "unknown type: " << (int)*type << std::endl;
+ }
+
+ delete type;
+ async_read();
+}
+
+void Game::handle_chunk() {
+ message::Chunk m;
+
+ // coords
+ m.read(socket);
+ int64_t x, y;
+ m.get_coords(x, y);
+
+ // data
+ m.read(socket);
+ float *data = m.get_data();
+ scene->terrain->tc->add_chunk(data, x, y, Terrain::chunk_size_total, Terrain::chunk_size_total);
+
+ Terrain::Chunk *chunk = NULL;
+ try {
+ chunk = new Terrain::Chunk(scene->terrain, x, y);
+ } catch(...) {
+ }
+ if(chunk)
+ scene->terrain->chunks.push_back(chunk);
+}
+
+Game& Game::get_instance() {
+ if(!game)
+ game = new Game();
+ return *game;
+}