more structure changes

This commit is contained in:
gmueller 2011-01-16 23:02:40 +01:00
parent 54f2f3c4f6
commit 8278db04b9
11 changed files with 330 additions and 203 deletions

View File

@ -7,10 +7,12 @@
#include "Application.h" #include "Application.h"
#include "Time.h" #include "Time.h"
#include "network.h" #include "Network.h"
#include <iostream>
Application::Application() : Application::Application() :
running(false), master(false), time(0.0) { running(false), master(false), time(0.0), network(&game) {
} }
@ -23,40 +25,67 @@ bool Application::isRunning() {
} }
void Application::start() { void Application::start() {
std::cout << "[Application] start" << std::endl;
running = true; running = true;
} }
void Application::stop() { void Application::stop() {
std::cout << "[Application] stop" << std::endl;
running = false; running = false;
} }
void Application::initialize(int argc, char ** argv) { void Application::initialize(Arguments &arg) {
std::cout << "[Application] initialize" << std::endl;
// setup time
PerformanceTimer::set(0.0);
time = PerformanceTimer::get(); time = PerformanceTimer::get();
// setup game
game_setup(&game); game_setup(&game);
game_reset(&game); game_reset(&game);
// setup schedules
gameUpdateSchudule.setExact(true); gameUpdateSchudule.setExact(true);
gameUpdateSchudule.setInterval(0.05); gameUpdateSchudule.setInterval(0.05);
std::string host = arg.getString("-h", std::string());
network.initialize(host);
// setup network
if (host.empty()) {
setMaster(true);
} else {
setMaster(true);
}
// start
start(); start();
} }
void Application::shutdown() { void Application::shutdown() {
shutdown_network(); std::cout << "[Application] shutdown" << std::endl;
network.shutdown();
} }
void Application::update() { void Application::update() {
// Get time and mouse position // update time values
time = PerformanceTimer::get(); time = PerformanceTimer::get();
dt = time - lastTime; dt = time - lastTime;
lastTime = time; lastTime = time;
service_network(&game); // network stuff
network.service(master ? 1 : 0);
game_update(&game, dt); game_update(&game, dt);
if (master && gameUpdateSchudule.next(time)) { if (master && gameUpdateSchudule.next(time)) {
send_game_updates(&game); network.sendGameUpdates();
} }
} }
void Application::setMaster(bool master) { void Application::setMaster(bool master) {
std::cout << "[Application] setMaster = " << master << std::endl;
this->master = master; this->master = master;
game_set_master(&game, master ? 1 : 0); game_set_master(&game, master ? 1 : 0);
} }

View File

@ -11,12 +11,14 @@
#include "game.h" #include "game.h"
#include "Schedule.h" #include "Schedule.h"
#include "Arguments.h"
#include "Network.h"
class Application { class Application {
public: public:
Application(); Application();
virtual ~Application(); virtual ~Application();
virtual void initialize(int argc, char ** argv); virtual void initialize(Arguments &arg);
virtual void update(); virtual void update();
virtual void shutdown(); virtual void shutdown();
@ -41,6 +43,7 @@ private:
protected: protected:
game_t game; game_t game;
Network network;
double dt; double dt;
double time; double time;
}; };

96
src/Arguments.h Normal file
View File

@ -0,0 +1,96 @@
/*
* arguments.hpp
*
* Created on: 06.05.2010
* Author: gmueller
*/
#include <cstdlib>
#include <string>
#include <vector>
#include <stdexcept>
class Arguments {
std::vector<std::string> arguments;
public:
Arguments() {
}
Arguments(size_t c, const char **v) {
for (size_t i = 0; i < c; i++)
arguments.push_back(v[i]);
}
void add(const std::string &argument) {
arguments.push_back(argument);
}
int getCount() {
return arguments.size();
}
bool hasFlag(const std::string &flag) {
size_t i;
for (i = 0; i < arguments.size(); i++) {
if (flag == arguments[i])
return true;
}
return false;
}
int getInt(const std::string &flag, int def) {
size_t i;
for (i = 0; i < arguments.size(); i++) {
if (flag == arguments[i] && (i + 1 < arguments.size()))
return std::atoi(arguments[i + 1].c_str());
}
return def;
}
float getFloat(const std::string &flag, float def) {
size_t i;
for (i = 0; i < arguments.size(); i++) {
if (flag == arguments[i] && (i + 1 < arguments.size()))
return std::atof(arguments[i + 1].c_str());
}
return def;
}
std::string getString(const std::string &flag, const std::string &def) {
size_t i;
for (i = 0; i < arguments.size(); i++) {
if (flag == arguments[i] && (i + 1 < arguments.size()))
return std::string(arguments[i + 1]);
}
return def;
}
std::string getString(const std::string &flag) {
size_t i;
for (i = 0; i < arguments.size(); i++) {
if (flag == arguments[i] && (i + 1 < arguments.size()))
return std::string(arguments[i + 1]);
}
throw std::runtime_error("Arguments: flag " + flag + " not found");
}
void getVector(const std::string &flag, std::vector<std::string> &v) {
size_t i;
// find flag
for (i = 0; i < arguments.size(); i++) {
if (flag == arguments[i])
break;
}
for (i++; i < arguments.size(); i++) {
if (arguments[i][0] != '-')
v.push_back(arguments[i]);
}
}
};

View File

@ -1,43 +1,11 @@
if (OPENGL_FOUND) include_directories (${GREMLIN_SOURCE_DIR}/libs/glfw/include)
# find external software include_directories (${GREMLIN_SOURCE_DIR}/libs/spark/include)
# set includes
include_directories (${GREMLIN_SOURCE_DIR}/libs/glfw/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/spark/include)
SET(VIDEO_SOURCES Explosion oglfont Client)
endif(OPENGL_FOUND)
include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include) include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include)
include_directories (${GREMLIN_SOURCE_DIR}/src) include_directories (${GREMLIN_SOURCE_DIR}/src)
if (MSVC)
# define executable add_definitions(/D_USE_MATH_DEFINES)
add_executable( gremlin endif(MSVC)
Application
main
game
Time
network
${VIDEO_SOURCES}
)
# define executable
add_executable( gremlin_dedicated
Application
server
game
Time
network
)
add_dependencies( gremlin
enet
)
add_dependencies( gremlin_dedicated
enet
)
if (WIN32) if (WIN32)
set(PLATFORM_LIBRARIES ws2_32 winmm) set(PLATFORM_LIBRARIES ws2_32 winmm)
@ -47,10 +15,44 @@ if(UNIX)
set(PLATFORM_LIBRARIES pthread) set(PLATFORM_LIBRARIES pthread)
endif(UNIX) endif(UNIX)
target_link_libraries(gremlin if (OPENGL_FOUND)
enet ${PLATFORM_LIBRARIES}
SET(VIDEO_SOURCES Explosion oglfont Client)
# define executable
add_executable( gremlin
Application
main
game
Time
Network
${VIDEO_SOURCES}
)
add_dependencies( gremlin
enet
)
target_link_libraries(gremlin
enet ${PLATFORM_LIBRARIES}
)
endif(OPENGL_FOUND)
# define executable
add_executable( gremlin_dedicated
Application
server
game
Time
Network
) )
add_dependencies( gremlin_dedicated
enet
)
target_link_libraries(gremlin_dedicated target_link_libraries(gremlin_dedicated
enet ${PLATFORM_LIBRARIES} enet ${PLATFORM_LIBRARIES}
) )

View File

@ -6,7 +6,7 @@
*/ */
#include "Client.h" #include "Client.h"
#include "network.h" #include "Network.h"
#include "Explosion.h" #include "Explosion.h"
#include "Time.h" #include "Time.h"
@ -30,9 +30,9 @@ void setup_light() {
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glEnable(GL_LIGHT0); glEnable( GL_LIGHT0);
glEnable(GL_LIGHTING); glEnable( GL_LIGHTING);
} }
void setup_opengl() { void setup_opengl() {
@ -49,14 +49,14 @@ void setup_opengl() {
glfwEnable(GLFW_STICKY_KEYS); glfwEnable(GLFW_STICKY_KEYS);
// general settings // general settings
glShadeModel(GL_SMOOTH); glShadeModel( GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_CULL_FACE); glEnable( GL_CULL_FACE);
// setup depth buffer // setup depth buffer
glClearDepth(1.0f); glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST); glEnable( GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc( GL_LEQUAL);
// Enable vertical sync (on cards that support it) // Enable vertical sync (on cards that support it)
glfwSwapInterval(0); glfwSwapInterval(0);
@ -65,7 +65,7 @@ void setup_opengl() {
void draw_team(team_t *team) { void draw_team(team_t *team) {
size_t i = 0; size_t i = 0;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, team->color); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, team->color);
glMatrixMode(GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(team->x, team->y, team->z); glTranslated(team->x, team->y, team->z);
gluSphere(quadratic, 50.f, 32, 32); gluSphere(quadratic, 50.f, 32, 32);
@ -76,7 +76,7 @@ void draw_player(player_t *player) {
if (player->status == 0) if (player->status == 0)
return; return;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, player->team->color); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, player->team->color);
glMatrixMode(GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(player->x, player->y, player->z); glTranslated(player->x, player->y, player->z);
gluSphere(quadratic, 10.f, 32, 32); gluSphere(quadratic, 10.f, 32, 32);
@ -88,7 +88,7 @@ void draw_bomb(bomb_t *bomb) {
return; return;
GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f }; GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
glMatrixMode(GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(bomb->x, bomb->y, bomb->z); glTranslated(bomb->x, bomb->y, bomb->z);
gluSphere(quadratic, 3.f, 4, 4); gluSphere(quadratic, 3.f, 4, 4);
@ -99,7 +99,7 @@ void draw_point(point_t *point) {
return; return;
GLfloat red[] = { 0.0f, 0.0f, 1.0f, 1.0f }; GLfloat red[] = { 0.0f, 0.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
glMatrixMode(GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(point->x, point->y, point->z); glTranslated(point->x, point->y, point->z);
gluSphere(quadratic, 3.f, 12, 12); gluSphere(quadratic, 3.f, 12, 12);
@ -163,7 +163,7 @@ void draw_box() {
if (wallTex == 0) { if (wallTex == 0) {
glGenTextures(1, &wallTex); glGenTextures(1, &wallTex);
glBindTexture(GL_TEXTURE_2D, wallTex); glBindTexture(GL_TEXTURE_2D, wallTex);
glEnable(GL_TEXTURE_2D); glEnable( GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -172,19 +172,19 @@ void draw_box() {
glfwLoadTexture2D("data/wall.tga", GLFW_BUILD_MIPMAPS_BIT); glfwLoadTexture2D("data/wall.tga", GLFW_BUILD_MIPMAPS_BIT);
} else { } else {
glBindTexture(GL_TEXTURE_2D, wallTex); glBindTexture(GL_TEXTURE_2D, wallTex);
glEnable(GL_TEXTURE_2D); glEnable( GL_TEXTURE_2D);
} }
GLfloat red[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat red[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
// Enable/Disable features // Enable/Disable features
glPushAttrib(GL_ENABLE_BIT); glPushAttrib( GL_ENABLE_BIT);
glEnable(GL_TEXTURE_2D); glEnable( GL_TEXTURE_2D);
//glDisable( GL_DEPTH_TEST); //glDisable( GL_DEPTH_TEST);
// glEnable( GL_LIGHTING); // glEnable( GL_LIGHTING);
// glDisable( GL_BLEND); // glDisable( GL_BLEND);
glMatrixMode(GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(2000.0, 0.0, 0.0); glTranslated(2000.0, 0.0, 0.0);
//glScaled(5000.0f, 5000.0f, 5000.0f); //glScaled(5000.0f, 5000.0f, 5000.0f);
@ -193,7 +193,7 @@ void draw_box() {
glColor4f(1, 1, 1, 1); glColor4f(1, 1, 1, 1);
// Render the front quad // Render the front quad
glBegin(GL_QUADS); glBegin( GL_QUADS);
glTexCoord2f(0, t); glTexCoord2f(0, t);
glNormal3f(0.0, 0.0, 1.0); glNormal3f(0.0, 0.0, 1.0);
glVertex3f(-s, s, -s); glVertex3f(-s, s, -s);
@ -297,7 +297,7 @@ void Client::accelerate(double x, double y, double z) {
msg.x = x; msg.x = x;
msg.y = y; msg.y = y;
msg.z = z; msg.z = z;
send_message((uint8_t*) &msg, sizeof(msg), &game); network.sendMessage((uint8_t*) &msg, sizeof(msg));
} }
void Client::drop_bomb(double rx, double ry, double rz, double ttl) { void Client::drop_bomb(double rx, double ry, double rz, double ttl) {
@ -310,7 +310,7 @@ void Client::drop_bomb(double rx, double ry, double rz, double ttl) {
msg.vy = game.local_player->vy + ry * 100; msg.vy = game.local_player->vy + ry * 100;
msg.vz = game.local_player->vz + rz * 100; msg.vz = game.local_player->vz + rz * 100;
msg.ttl = ttl; msg.ttl = ttl;
send_message((uint8_t*) &msg, sizeof(msg), &game); network.sendMessage((uint8_t*) &msg, sizeof(msg));
} }
void Client::loadConsoleFont() { void Client::loadConsoleFont() {
@ -343,33 +343,20 @@ void Client::prepareFrame(double rx, double ry, double rz) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Select and setup the projection matrix // Select and setup the projection matrix
glMatrixMode(GL_PROJECTION); glMatrixMode( GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(60.0f, (GLfloat) width / (GLfloat) height, 1.0f, 10000.0f); gluPerspective(60.0f, (GLfloat) width / (GLfloat) height, 1.0f, 10000.0f);
// Select and setup the modelview matrix // Select and setup the modelview matrix
glMatrixMode(GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
gluLookAt(camX, camY, camZ, camX + rx * 10.0f, camY + ry * 10.0f, camZ + rz gluLookAt(camX, camY, camZ, camX + rx * 10.0f, camY + ry * 10.0f, camZ + rz
* 10.0f, 0.0f, 1.0f, 0.0f); * 10.0f, 0.0f, 1.0f, 0.0f);
} }
void Client::initialize(int argc, char ** argv) { void Client::initialize(Arguments &arg) {
Application::initialize(argc, argv); Application::initialize(arg);
std::string arg1;
if (argc > 1) {
arg1 = argv[1];
if (arg1 == "server") {
setMaster(true);
} else {
setMaster(false);
}
} else {
setMaster(false);
arg1 = "forge.camijo.de";
}
// Initialise GLFW // Initialise GLFW
if (!glfwInit()) { if (!glfwInit()) {
@ -377,7 +364,6 @@ void Client::initialize(int argc, char ** argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
game_setup_explosion_callback(&game, explosion_callback, 0); game_setup_explosion_callback(&game, explosion_callback, 0);
setup_opengl(); setup_opengl();
setup_explosion(); setup_explosion();
@ -386,11 +372,8 @@ void Client::initialize(int argc, char ** argv) {
gluQuadricTexture(quadratic, GL_TRUE); gluQuadricTexture(quadratic, GL_TRUE);
if (isMaster()) { if (isMaster()) {
setup_network(NULL);
team_t *team = game_team(&game, 0); team_t *team = game_team(&game, 0);
game.local_player = game_spawn_player(&game, team); game.local_player = game_spawn_player(&game, team);
} else {
setup_network(arg1.c_str());
} }
size_t i; size_t i;
@ -461,10 +444,10 @@ void Client::update() {
} }
prepareFrame(rx, ry, rz); prepareFrame(rx, ry, rz);
setup_light(); setup_light();
glEnable(GL_LIGHT0); glEnable( GL_LIGHT0);
glEnable(GL_LIGHTING); glEnable( GL_LIGHTING);
glEnable(GL_CULL_FACE); glEnable( GL_CULL_FACE);
glDisable(GL_TEXTURE_2D); glDisable( GL_TEXTURE_2D);
for (size_t i = 0; i < GAME_TEAM_COUNT; i++) for (size_t i = 0; i < GAME_TEAM_COUNT; i++)
draw_team(&game.team[i]); draw_team(&game.team[i]);
@ -505,8 +488,8 @@ void Client::update() {
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << "FPS: " << (int) (1 / dt) << " Time: " << floor(dt * 10000.0 + 0.5) sstr << "FPS: " << (int) (1 / dt) << " Time: " << floor(dt * 10000.0
/ 10.0; + 0.5) / 10.0;
oglf_print(&font, 10, 25 * fy++, sstr.str().c_str()); oglf_print(&font, 10, 25 * fy++, sstr.str().c_str());
} }

View File

@ -15,7 +15,7 @@
class Client: public Application { class Client: public Application {
public: public:
void initialize(int argc, char ** argv); void initialize(Arguments &arg);
void update(); void update();
void shutdown(); void shutdown();
private: private:

View File

@ -10,8 +10,6 @@
using namespace SPK; using namespace SPK;
using namespace SPK::GL; using namespace SPK::GL;
#define M_PI 3.126
Explosion::~Explosion() { Explosion::~Explosion() {
SPKFactory::getInstance().destroyAll(); SPKFactory::getInstance().destroyAll();
} }

View File

@ -5,23 +5,22 @@
* Author: gmueller * Author: gmueller
*/ */
#include "network.h" #include "Network.h"
#include <enet/enet.h> #include <iostream>
#include <cmath>
#include <stdio.h> Network::Network(game_t *game) :
#include <math.h> game(game) {
}
ENetHost *host = 0; void Network::initialize(const std::string &hostname) {
ENetPeer *client_peer = 0;
void setup_network(const char *remote) {
if (enet_initialize() != 0) { if (enet_initialize() != 0) {
throw "failed to initialize enet"; throw "failed to initialize enet";
} }
if (remote == NULL) { if (hostname.empty()) {
fprintf(stdout, "Start server.\n"); std::cout << "[Network] Start server." << std::endl;
ENetAddress address; ENetAddress address;
address.host = ENET_HOST_ANY; address.host = ENET_HOST_ANY;
@ -29,56 +28,51 @@ void setup_network(const char *remote) {
host = enet_host_create(&address, 32, 2, 0, 0); host = enet_host_create(&address, 32, 2, 0, 0);
if (host == NULL) { if (host == NULL) {
fprintf(stderr, throw "An error occurred while trying to create an ENet server host.";
"An error occurred while trying to create an ENet server host.\n");
exit( EXIT_FAILURE);
} }
} else { } else {
fprintf(stdout, "Start client.\n"); std::cout << "[Network] Start client." << std::endl;
ENetAddress address; ENetAddress address;
ENetEvent event; ENetEvent event;
host = enet_host_create(NULL, 1, 2, 57600 / 8, 14400 / 8); host = enet_host_create(NULL, 1, 2, 57600 / 8, 14400 / 8);
if (host == NULL) { if (host == NULL) {
fprintf(stderr, throw "An error occurred while trying to create an ENet client host.";
"An error occurred while trying to create an ENet client host.\n");
exit( EXIT_FAILURE);
} }
enet_address_set_host(&address, remote); std::cout << "[Network] connect to " << host << std::endl;
enet_address_set_host(&address, hostname.c_str());
address.port = 1234; address.port = 1234;
/* Initiate the connection, allocating the two channels 0 and 1. */ /* Initiate the connection, allocating the two channels 0 and 1. */
client_peer = enet_host_connect(host, &address, 2, 0); client_peer = enet_host_connect(host, &address, 2, 0);
if (client_peer == NULL) { if (client_peer == NULL) {
fprintf(stderr, throw "No available peers for initiating an ENet connection.";
"No available peers for initiating an ENet connection.\n");
exit( EXIT_FAILURE);
} }
/* Wait up to 5 seconds for the connection attempt to succeed. */ /* Wait up to 5 seconds for the connection attempt to succeed. */
if (enet_host_service(host, &event, 5000) > 0 && event.type if (enet_host_service(host, &event, 2000) > 0 && event.type
== ENET_EVENT_TYPE_CONNECT) { == ENET_EVENT_TYPE_CONNECT) {
puts("Connection succeeded."); std::cout << "[Network] connected" << host << std::endl;
} else { } else {
/* Either the 5 seconds are up or a disconnect event was */ /* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */ /* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */ /* had run out without any significant event. */
enet_peer_reset(client_peer); enet_peer_reset(client_peer);
fprintf(stderr, "Connection to %s failed.", remote); throw "[Network] connection failed.";
} }
} }
} }
void shutdown_network() { void Network::shutdown() {
enet_host_destroy(host); enet_host_destroy(host);
enet_deinitialize(); enet_deinitialize();
} }
void send_game_updates(game_t *game) { void Network::sendGameUpdates() {
size_t i; size_t i;
for (i = 0; i < GAME_PLAYER_COUNT; i++) { for (i = 0; i < GAME_PLAYER_COUNT; i++) {
if (game->player[i].status == 0) if (game->player[i].status == 0)
@ -109,7 +103,7 @@ void send_game_updates(game_t *game) {
enet_host_flush(host); enet_host_flush(host);
} }
void dispatch_message(enet_uint8 *data, size_t length, game_t *game) { void Network::dispatch(enet_uint8 *data, size_t length) {
message_t *msg = (message_t *) data; message_t *msg = (message_t *) data;
switch (msg->msg_id) { switch (msg->msg_id) {
case MESSAGE_PLAYER_SPAWN: { case MESSAGE_PLAYER_SPAWN: {
@ -128,8 +122,6 @@ void dispatch_message(enet_uint8 *data, size_t length, game_t *game) {
case MESSAGE_ACCEPT: { case MESSAGE_ACCEPT: {
accept_message_t *am = (accept_message_t *) data; accept_message_t *am = (accept_message_t *) data;
game->local_player = game_player(game, am->player_id); game->local_player = game_player(game, am->player_id);
printf("Spwan as %d.%d\n", game->local_player->team->id,
game->local_player->id);
break; break;
} }
case MESSAGE_PLAYER_UPDATE: { case MESSAGE_PLAYER_UPDATE: {
@ -213,93 +205,96 @@ void dispatch_message(enet_uint8 *data, size_t length, game_t *game) {
}; };
} }
void service_network(game_t *game) { void Network::service(uint32_t timeout) {
ENetEvent event; ENetEvent event;
if (host == 0)
throw "not connected";
/* Wait up to 1000 milliseconds for an event. */ /* Wait up to 1000 milliseconds for an event. */
while (enet_host_service(host, &event, 0) > 0) { while (enet_host_service(host, &event, timeout) > 0) {
switch (event.type) { switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: case ENET_EVENT_TYPE_CONNECT: {
printf("A new client connected from %x:%u.\n", std::cout << "A new client connected from "
event.peer->address.host, event.peer->address.port); << event.peer->address.host << " "
{ << event.peer->address.port << std::endl;
// bring new client up to date
size_t i;
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
if (game->player[i].status == 0)
continue;
// send player spawn message
player_spawn_message_t spwan_msg;
spwan_msg.msg_id = MESSAGE_PLAYER_SPAWN;
spwan_msg.team_id = game->player[i].team->id;
spwan_msg.player_id = game->player[i].id;
ENetPacket * packet = enet_packet_create(&spwan_msg,
sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(event.peer, 0, packet);
}
for (i = 0; i < GAME_POINT_COUNT; i++) {
if (game->point[i].status == 0)
continue;
point_update_mesage_t msg;
msg.msg_id = MESSAGE_POINT_UPDATE;
msg.point_index = i;
msg.status = game->point[i].status;
msg.x = game->point[i].x;
msg.y = game->point[i].y;
msg.z = game->point[i].z;
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(event.peer, 0, packet);
}
team_t *team = game_team_with_least_players(game);
player_t *player = game_spawn_player(game, team);
printf("Spwan as %d.%d\n", team->id, player->id);
event.peer->data = player;
// bring new client up to date
size_t i;
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
if (game->player[i].status == 0)
continue;
// send player spawn message // send player spawn message
player_spawn_message_t spwan_msg; player_spawn_message_t spwan_msg;
spwan_msg.msg_id = MESSAGE_PLAYER_SPAWN; spwan_msg.msg_id = MESSAGE_PLAYER_SPAWN;
spwan_msg.team_id = team->id; spwan_msg.team_id = game->player[i].team->id;
spwan_msg.player_id = player->id; spwan_msg.player_id = game->player[i].id;
ENetPacket * packet = enet_packet_create(&spwan_msg, ENetPacket * packet = enet_packet_create(&spwan_msg,
sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE); sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(host, 0, packet); enet_peer_send(event.peer, 0, packet);
}
// send team and player for (i = 0; i < GAME_POINT_COUNT; i++) {
accept_message_t msg; if (game->point[i].status == 0)
msg.msg_id = MESSAGE_ACCEPT; continue;
msg.player_id = player->id; point_update_mesage_t msg;
packet = enet_packet_create(&msg, sizeof(msg), msg.msg_id = MESSAGE_POINT_UPDATE;
msg.point_index = i;
msg.status = game->point[i].status;
msg.x = game->point[i].x;
msg.y = game->point[i].y;
msg.z = game->point[i].z;
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(event.peer, 0, packet); enet_peer_send(event.peer, 0, packet);
// send state
} }
team_t *team = game_team_with_least_players(game);
player_t *player = game_spawn_player(game, team);
event.peer->data = player;
// send player spawn message
player_spawn_message_t spwan_msg;
spwan_msg.msg_id = MESSAGE_PLAYER_SPAWN;
spwan_msg.team_id = team->id;
spwan_msg.player_id = player->id;
ENetPacket * packet = enet_packet_create(&spwan_msg,
sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(host, 0, packet);
// send team and player
accept_message_t msg;
msg.msg_id = MESSAGE_ACCEPT;
msg.player_id = player->id;
packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(event.peer, 0, packet);
// send state
}
break; break;
case ENET_EVENT_TYPE_RECEIVE: { case ENET_EVENT_TYPE_RECEIVE: {
dispatch_message(event.packet->data, event.packet->dataLength, game); dispatch(event.packet->data, event.packet->dataLength);
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
break; break;
} }
case ENET_EVENT_TYPE_DISCONNECT: case ENET_EVENT_TYPE_DISCONNECT:
printf("%s disconected.\n", event.peer -> data); //printf("%s disconected.\n", event.peer -> data);
{ {
/* Reset the peer's client information. */ /* Reset the peer's client information. */
player_t *player = (player_t *) event.peer->data; player_t *player = (player_t *) event.peer->data;
player->status = 0; player->status = 0;
player->team = 0; player->team = 0;
// send player spawn message // send player spawn message
player_kill_message_t msg; player_kill_message_t msg;
msg.msg_id = MESSAGE_PLAYER_KILL; msg.msg_id = MESSAGE_PLAYER_KILL;
msg.player_id = player->id; msg.player_id = player->id;
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg), ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(host, 0, packet); enet_host_broadcast(host, 0, packet);
} }
event.peer->data = NULL; event.peer->data = NULL;
break; break;
} }
@ -307,12 +302,12 @@ void service_network(game_t *game) {
} }
void send_message(uint8_t *data, size_t length, game_t *game) { void Network::sendMessage(uint8_t *data, size_t length) {
if (client_peer) { if (client_peer) {
ENetPacket * packet = enet_packet_create(data, length, ENetPacket * packet = enet_packet_create(data, length,
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(client_peer, 0, packet); enet_peer_send(client_peer, 0, packet);
} else { } else {
dispatch_message(data, length, game); dispatch(data, length);
} }
} }

View File

@ -11,6 +11,10 @@
#include "game.h" #include "game.h"
#include "common.h" #include "common.h"
#include <enet/enet.h>
#include <string>
#define MESSAGE_PLAYER_SPAWN 0 #define MESSAGE_PLAYER_SPAWN 0
#define MESSAGE_PLAYER_KILL 1 #define MESSAGE_PLAYER_KILL 1
#define MESSAGE_ACCEPT 2 #define MESSAGE_ACCEPT 2
@ -85,11 +89,19 @@ struct team_update_message_t {
uint16_t wins; uint16_t wins;
}; };
void setup_network(const char *remote); class Network {
void shutdown_network(); public:
void dispatch_message(uint8_t *data, size_t length, game_t *game); Network(game_t *game);
void service_network(game_t *game); void initialize(const std::string &host);
void send_game_updates(game_t *game); void shutdown();
void send_message(uint8_t *data, size_t length, game_t *game); void dispatch(uint8_t *data, size_t length);
void service(uint32_t timeout);
void sendGameUpdates();
void sendMessage(uint8_t *data, size_t length);
protected:
game_t *game;
ENetHost *host;
ENetPeer *client_peer;
};
#endif /* NETWORK_H_ */ #endif /* NETWORK_H_ */

View File

@ -2,10 +2,11 @@
#include <iostream> #include <iostream>
int main(int argc, char ** argv) { int main(int argc, const char **argv) {
try { try {
Client app; Client app;
app.initialize(argc, argv); Arguments args(argc, argv);
app.initialize(args);
while (app.isRunning()) while (app.isRunning())
app.update(); app.update();
app.shutdown(); app.shutdown();

View File

@ -1,12 +1,20 @@
#include "Application.h" #include "Application.h"
#include <iostream> #include <iostream>
#include <csignal>
int main(int argc, char ** argv) { Application app;
void terminate(int param) {
app.stop();
}
int main(int argc, const char **argv) {
Arguments args(argc, argv);
try { try {
Application app; ::signal(SIGTERM, terminate);
app.setMaster(true); app.setMaster(true);
app.initialize(argc, argv); app.initialize(args);
while (app.isRunning()) while (app.isRunning())
app.update(); app.update();
app.shutdown(); app.shutdown();