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 "Time.h"
#include "network.h"
#include "Network.h"
#include <iostream>
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() {
std::cout << "[Application] start" << std::endl;
running = true;
}
void Application::stop() {
std::cout << "[Application] stop" << std::endl;
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();
// setup game
game_setup(&game);
game_reset(&game);
// setup schedules
gameUpdateSchudule.setExact(true);
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();
}
void Application::shutdown() {
shutdown_network();
std::cout << "[Application] shutdown" << std::endl;
network.shutdown();
}
void Application::update() {
// Get time and mouse position
// update time values
time = PerformanceTimer::get();
dt = time - lastTime;
lastTime = time;
service_network(&game);
// network stuff
network.service(master ? 1 : 0);
game_update(&game, dt);
if (master && gameUpdateSchudule.next(time)) {
send_game_updates(&game);
network.sendGameUpdates();
}
}
void Application::setMaster(bool master) {
std::cout << "[Application] setMaster = " << master << std::endl;
this->master = master;
game_set_master(&game, master ? 1 : 0);
}

View File

@ -11,12 +11,14 @@
#include "game.h"
#include "Schedule.h"
#include "Arguments.h"
#include "Network.h"
class Application {
public:
Application();
virtual ~Application();
virtual void initialize(int argc, char ** argv);
virtual void initialize(Arguments &arg);
virtual void update();
virtual void shutdown();
@ -41,6 +43,7 @@ private:
protected:
game_t game;
Network network;
double dt;
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)
# find external software
# 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/glfw/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/spark/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include)
include_directories (${GREMLIN_SOURCE_DIR}/src)
# define executable
add_executable( gremlin
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 (MSVC)
add_definitions(/D_USE_MATH_DEFINES)
endif(MSVC)
if (WIN32)
set(PLATFORM_LIBRARIES ws2_32 winmm)
@ -47,10 +15,44 @@ if(UNIX)
set(PLATFORM_LIBRARIES pthread)
endif(UNIX)
target_link_libraries(gremlin
if (OPENGL_FOUND)
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
enet ${PLATFORM_LIBRARIES}
)

View File

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

View File

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

View File

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

View File

@ -5,23 +5,22 @@
* Author: gmueller
*/
#include "network.h"
#include "Network.h"
#include <enet/enet.h>
#include <iostream>
#include <cmath>
#include <stdio.h>
#include <math.h>
Network::Network(game_t *game) :
game(game) {
}
ENetHost *host = 0;
ENetPeer *client_peer = 0;
void setup_network(const char *remote) {
void Network::initialize(const std::string &hostname) {
if (enet_initialize() != 0) {
throw "failed to initialize enet";
}
if (remote == NULL) {
fprintf(stdout, "Start server.\n");
if (hostname.empty()) {
std::cout << "[Network] Start server." << std::endl;
ENetAddress address;
address.host = ENET_HOST_ANY;
@ -29,56 +28,51 @@ void setup_network(const char *remote) {
host = enet_host_create(&address, 32, 2, 0, 0);
if (host == NULL) {
fprintf(stderr,
"An error occurred while trying to create an ENet server host.\n");
exit( EXIT_FAILURE);
throw "An error occurred while trying to create an ENet server host.";
}
} else {
fprintf(stdout, "Start client.\n");
std::cout << "[Network] Start client." << std::endl;
ENetAddress address;
ENetEvent event;
host = enet_host_create(NULL, 1, 2, 57600 / 8, 14400 / 8);
if (host == NULL) {
fprintf(stderr,
"An error occurred while trying to create an ENet client host.\n");
exit( EXIT_FAILURE);
throw "An error occurred while trying to create an ENet client host.";
}
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;
/* Initiate the connection, allocating the two channels 0 and 1. */
client_peer = enet_host_connect(host, &address, 2, 0);
if (client_peer == NULL) {
fprintf(stderr,
"No available peers for initiating an ENet connection.\n");
exit( EXIT_FAILURE);
throw "No available peers for initiating an ENet connection.";
}
/* 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) {
puts("Connection succeeded.");
std::cout << "[Network] connected" << host << std::endl;
} else {
/* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */
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_deinitialize();
}
void send_game_updates(game_t *game) {
void Network::sendGameUpdates() {
size_t i;
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
if (game->player[i].status == 0)
@ -109,7 +103,7 @@ void send_game_updates(game_t *game) {
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;
switch (msg->msg_id) {
case MESSAGE_PLAYER_SPAWN: {
@ -128,8 +122,6 @@ void dispatch_message(enet_uint8 *data, size_t length, game_t *game) {
case MESSAGE_ACCEPT: {
accept_message_t *am = (accept_message_t *) data;
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;
}
case MESSAGE_PLAYER_UPDATE: {
@ -213,16 +205,20 @@ 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;
if (host == 0)
throw "not connected";
/* 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) {
case ENET_EVENT_TYPE_CONNECT:
printf("A new client connected from %x:%u.\n",
event.peer->address.host, event.peer->address.port);
{
case ENET_EVENT_TYPE_CONNECT: {
std::cout << "A new client connected from "
<< 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++) {
@ -255,7 +251,6 @@ void service_network(game_t *game) {
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;
// send player spawn message
@ -280,12 +275,12 @@ void service_network(game_t *game) {
break;
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);
break;
}
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. */
player_t *player = (player_t *) event.peer->data;
@ -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) {
ENetPacket * packet = enet_packet_create(data, length,
ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(client_peer, 0, packet);
} else {
dispatch_message(data, length, game);
dispatch(data, length);
}
}

View File

@ -11,6 +11,10 @@
#include "game.h"
#include "common.h"
#include <enet/enet.h>
#include <string>
#define MESSAGE_PLAYER_SPAWN 0
#define MESSAGE_PLAYER_KILL 1
#define MESSAGE_ACCEPT 2
@ -85,11 +89,19 @@ struct team_update_message_t {
uint16_t wins;
};
void setup_network(const char *remote);
void shutdown_network();
void dispatch_message(uint8_t *data, size_t length, game_t *game);
void service_network(game_t *game);
void send_game_updates(game_t *game);
void send_message(uint8_t *data, size_t length, game_t *game);
class Network {
public:
Network(game_t *game);
void initialize(const std::string &host);
void shutdown();
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_ */

View File

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

View File

@ -1,12 +1,20 @@
#include "Application.h"
#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 {
Application app;
::signal(SIGTERM, terminate);
app.setMaster(true);
app.initialize(argc, argv);
app.initialize(args);
while (app.isRunning())
app.update();
app.shutdown();