--- a/src/proto2/Application.cc Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/Application.cc Sun Nov 09 21:51:13 2008 +0000
@@ -23,25 +23,29 @@
private:
// arguments
CL_CommandLine args;
-
+
+ bool arg_graphics;
std::string arg_port;
- bool arg_dedicated;
+ bool arg_server;
std::string arg_connect;
void parse_args (int argc, char **argv) {
// set up the options
args.add_option('p', "port", "PORT", "set network port used", true);
- args.add_option('D', "dedicated", "", "act as a network server", true);
- args.add_option('c', "connect", "SERVERHOST", "act as a network client", true);
+ args.add_option('s', "server", "", "act as a network server", true);
+ args.add_option('c', "client", "SERVERHOST", "act as a network client", true);
+ args.add_option('g', "graphics", "", "run graphics/local input. Implied with --connect", true);
// set defaults
+ arg_graphics = false;
arg_port = NETWORK_PORT_STR;
- arg_dedicated = false;
+ arg_server = false;
arg_connect = "";
try {
// parse args
args.parse_args(argc, argv);
+
} catch (CL_Error &e) {
throw ArgumentError(e.message);
}
@@ -52,12 +56,17 @@
arg_port = args.get_argument();
break;
- case 'D':
- arg_dedicated = true;
+ case 's':
+ arg_server = true;
break;
case 'c':
arg_connect = args.get_argument();
+ arg_graphics = true;
+ break;
+
+ case 'g':
+ arg_graphics = true;
break;
case CL_CommandLine::REST_ARG:
@@ -70,31 +79,41 @@
}
// check for valid combinations of arugments
- if (arg_dedicated && !arg_connect.empty())
- throw ArgumentError("-D and -c are mutually exclusive");
-
- if (!arg_dedicated && arg_connect.empty())
- throw ArgumentError("nothing to do");
+ if (!(arg_server xor !arg_connect.empty()))
+ throw ArgumentError("must supply *exactly* one of --server/--client");
}
public:
virtual int main (int argc, char **argv) {
- // initialize core
+ // initialize the ClanLib components that we use
CL_SetupCore setup_core;
-
+ CL_SetupNetwork setup_network;
+ CL_SetupDisplay setup_disp;
+ CL_SetupGL setup_gl;
+
try {
// parse arugments
parse_args(argc, argv);
+
+ // our engine
+ Engine engine;
- // run engine based on args
- if (arg_dedicated) {
- Engine::runNetworkServer(arg_port);
+ // setup graphics
+ if (arg_graphics)
+ engine.setupGraphics();
+
+ // setup either network server or client
+ if (arg_server) {
+ engine.setupNetworkServer(arg_port);
} else if (!arg_connect.empty()) {
- Engine::runNetworkClient(arg_connect, arg_port);
+ engine.setupNetworkClient(arg_connect, arg_port);
} else
assert(false);
+
+ // run the main loop
+ engine.run();
// succesful return
return 0;
--- a/src/proto2/Dimension.hh Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/Dimension.hh Sun Nov 09 21:51:13 2008 +0000
@@ -5,18 +5,18 @@
class Dimension {
public:
- uint32_t width;
- uint32_t height;
+ uint32_t w;
+ uint32_t h;
- Dimension (uint32_t width, uint32_t height) : width(width), height(height) { }
+ Dimension (uint32_t w, uint32_t h) : w(w), h(h) { }
};
class PositionDelta {
public:
- uint32_t dx;
- uint32_t dy;
+ int32_t dx;
+ int32_t dy;
- PositionDelta (uint32_t dx, uint32_t dy) : dx(dx), dy(dy) { }
+ PositionDelta (int32_t dx, int32_t dy) : dx(dx), dy(dy) { }
};
class Coordinate {
@@ -33,15 +33,14 @@
return *this;
}
- uint32_t scaledX() {
- // Scale the coordinate so that it
- // matches the pixel resolution
- return this->x/1;
+ Coordinate operator+ (const PositionDelta &d) {
+ return Coordinate(x + d.dx, y + d.dy);
}
- uint32_t scaledY() {
- return this->y/1;
- }
+ // Scale the coordinate so that it matches the pixel resolution
+ uint32_t scaledX() { return x; }
+
+ uint32_t scaledY() { return y; }
};
std::ostream& operator<< (std::ostream &s, const Coordinate &c);
--- a/src/proto2/Drawer.cc.disabled Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/Drawer.cc.disabled Sun Nov 09 21:51:13 2008 +0000
@@ -7,70 +7,70 @@
class CL_Game : public CL_ClanApplication {
private:
- bool keep_going;
- void check_input() {
- if(CL_Keyboard::get_keycode(CL_KEY_ESCAPE))
- keep_going = false;
-
+ bool keep_going;
+ void check_input() {
+ if(CL_Keyboard::get_keycode(CL_KEY_ESCAPE))
+ keep_going = false;
+
LocalPlayer& lp = gs.getLocalPlayer();
- if(CL_Keyboard::get_keycode(CL_KEY_UP)) {
- lp.doMovement(PositionDelta(0,3));
- }
- if(CL_Keyboard::get_keycode(CL_KEY_DOWN)) {
- lp.doMovement(PositionDelta(0,-3));
- }
- if(CL_Keyboard::get_keycode(CL_KEY_LEFT)) {
- lp.doMovement(PositionDelta(-3,0));
- }
- if(CL_Keyboard::get_keycode(CL_KEY_RIGHT)) {
- lp.doMovement(PositionDelta(3,0));
- }
- }
+ if(CL_Keyboard::get_keycode(CL_KEY_UP)) {
+ lp.doMovement(PositionDelta(0,3));
+ }
+ if(CL_Keyboard::get_keycode(CL_KEY_DOWN)) {
+ lp.doMovement(PositionDelta(0,-3));
+ }
+ if(CL_Keyboard::get_keycode(CL_KEY_LEFT)) {
+ lp.doMovement(PositionDelta(-3,0));
+ }
+ if(CL_Keyboard::get_keycode(CL_KEY_RIGHT)) {
+ lp.doMovement(PositionDelta(3,0));
+ }
+ }
public:
- GameState gs;
-
- CL_Game() : keep_going(true) {}
- virtual int main(int argc, char **argv) {
- CL_SetupCore setup_init;
- CL_SetupDisplay setup_disp;
- CL_SetupGL setup_gl;
-
- //gs.player_list.push(Player(Coordinate()));
+ GameState gs;
- CL_DisplayWindow win("ikkuna", 640, 480);
-// CL_Surface bg(CL_PNGProvider("image.png");
+ CL_Game() : keep_going(true) {}
+ virtual int main(int argc, char **argv) {
+ CL_SetupCore setup_init;
+ CL_SetupDisplay setup_disp;
+ CL_SetupGL setup_gl;
+
+ //gs.player_list.push(Player(Coordinate()));
- unsigned int last_draw = CL_System::get_time();
- int r = 100, g = 100, b = 100;
- unsigned int frame_count = 0;
- bool R = false, G = false, B = false;
+ CL_DisplayWindow win("ikkuna", 640, 480);
+// CL_Surface bg(CL_PNGProvider("image.png");
- while(keep_going) { //not good idea to put infinite loop
- CL_Display::clear(CL_Color(r, g, b));
+ unsigned int last_draw = CL_System::get_time();
+ int r = 100, g = 100, b = 100;
+ unsigned int frame_count = 0;
+ bool R = false, G = false, B = false;
+
+ while(keep_going) { //not good idea to put infinite loop
+ CL_Display::clear(CL_Color(r, g, b));
- int colorIdx = 0;
- for(std::list<Player>::iterator it = gs.player_list.begin(); it != gs.player_list.end(); ++it) {
-
- CL_Display::fill_rect(CL_Rect(it->getPosition().scaledX()-10, it->getPosition().scaledY()-10,
- it->getPosition().scaledX()+10, it->getPosition().scaledY()+10), CL_Color((colorIdx*30)%255, (colorIdx*30)%255, (colorIdx*30)%255));
+ int colorIdx = 0;
+ for(std::list<Player>::iterator it = gs.player_list.begin(); it != gs.player_list.end(); ++it) {
- colorIdx++;
- }
-
- CL_Display::flip(1);
- frame_count++;
- unsigned int cur_draw = CL_System::get_time();
-
- check_input();
+ CL_Display::fill_rect(CL_Rect(it->getPosition().scaledX()-10, it->getPosition().scaledY()-10,
+ it->getPosition().scaledX()+10, it->getPosition().scaledY()+10), CL_Color((colorIdx*30)%255, (colorIdx*30)%255, (colorIdx*30)%255));
- last_draw = cur_draw;
- CL_System::keep_alive();
-// sleep(10); //flip already wait a short amount of time
- }
- return 0;
- }
+ colorIdx++;
+ }
+
+ CL_Display::flip(1);
+ frame_count++;
+ unsigned int cur_draw = CL_System::get_time();
+
+ check_input();
+
+ last_draw = cur_draw;
+ CL_System::keep_alive();
+// sleep(10); //flip already wait a short amount of time
+ }
+ return 0;
+ }
};
CL_Game inst;
--- a/src/proto2/Engine.cc Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/Engine.cc Sun Nov 09 21:51:13 2008 +0000
@@ -1,6 +1,5 @@
#include "Engine.hh"
-#include "GameState.hh"
#include "NetworkServer.hh"
#include "NetworkClient.hh"
@@ -10,53 +9,29 @@
}
-void Engine::runNetworkServer (const std::string &listen_port) {
- // the engine
- Engine engine;
-
- // setup network
- CL_SetupNetwork setup_network;
-
- try {
- // create the server
- engine.net_server = new NetworkServer(engine.game_state, listen_port);
-
- // run the main loop
- engine.main_loop();
-
- } catch (CL_Error &e) {
- std::cerr << "NetworkServer::main: CL_Error:" << e.message << std::endl;
-
- throw;
- }
+void Engine::setupGraphics (void) {
+ // create the graphics
+ graphics = new Graphics(*this, game_state);
}
-void Engine::runNetworkClient (const std::string &connect_host, const std::string &connect_port) {
- // the engine
- Engine engine;
-
- // setup network
- CL_SetupNetwork setup_network;
+void Engine::setupNetworkServer (const std::string &listen_port) {
+ // create the server
+ net_server = new NetworkServer(game_state, listen_port);
+}
+void Engine::setupNetworkClient (const std::string &connect_host, const std::string &connect_port) {
// connect_to
CL_IPAddress connect_addr(connect_host, connect_port);
- try {
- // create the server
- engine.net_client = new NetworkClient(engine.game_state, connect_addr);
-
- // run the main loop
- engine.main_loop();
-
- } catch (CL_Error &e) {
- std::cerr << "NetworkServer::main: CL_Error:" << e.message << std::endl;
-
- throw;
- }
-
+ // create the client
+ net_client = new NetworkClient(game_state, connect_addr);
}
-void Engine::main_loop (void) {
+void Engine::stop (void) {
+ is_running = false;
+}
+
+void Engine::run (void) {
while (is_running) {
// this does.... magical things
CL_System::keep_alive();
@@ -65,7 +40,6 @@
// ideally, we should be able to have a main loop that does timed waits on I/O, fufilling some set of timers
// but as far as I can tell, ClanLib doesn't have anything like that
CL_System::sleep(100);
-
}
}
--- a/src/proto2/Engine.hh Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/Engine.hh Sun Nov 09 21:51:13 2008 +0000
@@ -1,4 +1,11 @@
+#ifndef ENGINE_HH
+#define ENGINE_HH
+// XXX: forward-declare Engine for other components
+class Engine;
+
+#include "GameState.hh"
+#include "Graphics.hh"
#include "NetworkServer.hh"
#include "NetworkClient.hh"
@@ -9,25 +16,38 @@
// game state
GameState game_state;
+ // Graphics/Input
+ Graphics *graphics;
+
// network server/client
NetworkServer *net_server;
NetworkClient *net_client;
// to exit the mainloop
bool is_running;
-
+
+ public:
// default constructor
Engine (void);
- public:
- static void runNetworkServer (const std::string &listen_port);
- static void runNetworkClient (const std::string &connect_host, const std::string &connect_port);
+ // setup graphics
+ void setupGraphics (void);
- // logging utility
+ // set up network server/client
+ // setting up both of these will lead to odd behaviour :)
+ void setupNetworkServer (const std::string &listen_port);
+ void setupNetworkClient (const std::string &connect_host, const std::string &connect_port);
+
+ // run the main loop
+ void run (void);
+
+ // terminate the main loop
+ void stop (void);
+
+ public:
+ // logging utility
static Logger log (enum LogLevel level, const char *type);
- private:
- void main_loop (void);
-
};
+#endif /* ENGINE_HH */
--- a/src/proto2/GameState.hh Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/GameState.hh Sun Nov 09 21:51:13 2008 +0000
@@ -29,12 +29,26 @@
bool visible;
Coordinate getPosition (void) const {
- return this->position;
+ return position;
}
protected:
- void updatePosition (Coordinate p) {
- this->position = p;
+ /*
+ * Update position to the given value.
+ *
+ * Returns true if valid move (not out of bounds), false otherwise (doesn't change position)
+ */
+ bool updatePosition (Coordinate p) {
+ // unsigned...
+ if (p.x > dimensions.w || p.y > dimensions.h) {
+ // out-of-bounds
+ return false;
+ }
+
+ // valid
+ position = p;
+
+ return true;
}
};
@@ -44,8 +58,10 @@
LocalPlayer (Coordinate c, bool visible) : Player(c, visible) { }
public:
- virtual void move (PositionDelta d) {
- this->position += d;
+ virtual bool move (PositionDelta d) {
+ return true;
+
+ //return updatePosition(position + d);
}
};
@@ -66,12 +82,12 @@
GameState (void) : map_dimensions(MAP_DIM_W, MAP_DIM_H), local_player(NULL) {
}
-
- LocalPlayer &getLocalPlayer (void) {
- if (!local_player)
- throw std::logic_error("getLocalPlayer called with no local player");
-
- return *local_player;
+
+ /*
+ * This will return NULL if we don't have a local player - yet
+ */
+ LocalPlayer *getLocalPlayer (void) {
+ return local_player;
}
void newLocalPlayer (LocalPlayer *player) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto2/Graphics.cc Sun Nov 09 21:51:13 2008 +0000
@@ -0,0 +1,80 @@
+
+#include "Graphics.hh"
+
+Graphics::Graphics (Engine &engine, GameState &state) :
+ engine(engine),
+ state(state),
+ update_timer(GRAPHICS_UPDATE_INTERVAL_MS),
+ win(GRAPHICS_WINDOW_TITLE, MAP_DIM_W, MAP_DIM_H),
+ keyboard(win.get_ic()->get_keyboard()) {
+
+ // connect timer signal
+ slots.connect(update_timer.sig_timer(), this, &Graphics::on_update);
+
+ // enable
+ update_timer.enable();
+}
+
+void Graphics::check_input (void) {
+ LocalPlayer *player;
+ int dx = 0, dy = 0;
+
+ // stop on escape
+ if (keyboard.get_keycode(CL_KEY_ESCAPE)) {
+ engine.stop();
+
+ return;
+ }
+
+ // ignore if we don't have a local player
+ if ((player = state.getLocalPlayer()) == NULL)
+ return;
+
+ // handle up/down/left/right
+ if (keyboard.get_keycode(CL_KEY_UP))
+ dy -= 3;
+
+ if (keyboard.get_keycode(CL_KEY_DOWN))
+ dy += 3;
+
+ if (keyboard.get_keycode(CL_KEY_LEFT))
+ dx -= 3;
+
+ if (keyboard.get_keycode(CL_KEY_RIGHT))
+ dx += 3;
+
+ // apply movement if applicable
+ if (dx || dy)
+ player->move(PositionDelta(dx, dy));
+}
+
+void Graphics::do_redraw (void) {
+ CL_GraphicContext *gc = win.get_gc();
+
+ // white background
+ gc->clear(CL_Color::white);
+
+ // draw players
+ for (std::list<Player*>::iterator it = state.player_list.begin(); it != state.player_list.end(); it++) {
+ Player *p = *it;
+
+ // draw square
+ gc->fill_rect(
+ CL_Rect(
+ p->getPosition().x - 5, p->getPosition().y - 5,
+ p->getPosition().x + 5, p->getPosition().y + 5
+ ), CL_Color::black
+ );
+ }
+
+ // flip window buffer, LIEK NAO
+ win.flip(0);
+}
+
+void Graphics::on_update (void) {
+ // check keyboard input
+ check_input();
+
+ // redraw display
+ do_redraw();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto2/Graphics.hh Sun Nov 09 21:51:13 2008 +0000
@@ -0,0 +1,40 @@
+#ifndef GRAPHICS_HH
+#define GRAPHICS_HH
+
+// XXX: forward-declare for Engine
+class Graphics;
+
+#include "GameState.hh"
+#include "Engine.hh"
+
+#include <ClanLib/core.h>
+#include <ClanLib/gl.h>
+#include <ClanLib/display.h>
+
+#define GRAPHICS_WINDOW_TITLE "Kisna Glista"
+#define GRAPHICS_UPDATE_INTERVAL_MS 100
+
+class Graphics {
+ private:
+ Engine &engine;
+ GameState &state;
+
+ CL_SlotContainer slots;
+
+ CL_Timer update_timer;
+
+ CL_DisplayWindow win;
+ CL_InputDevice &keyboard;
+
+ public:
+ Graphics (Engine &engine, GameState &state);
+
+ private:
+ void check_input (void);
+ void do_redraw (void);
+
+ void on_update (void);
+
+};
+
+#endif /* GRAPHICS_HH */
--- a/src/proto2/Network.hh Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/Network.hh Sun Nov 09 21:51:13 2008 +0000
@@ -48,8 +48,8 @@
/*
* Client has moved
*
- * uint32_t dx
- * uint32_t dy
+ * int32_t dx
+ * int32_t dy
*/
NETMSG_CLIENT_MOVE = 0x0201,
--- a/src/proto2/NetworkClient.cc Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/NetworkClient.cc Sun Nov 09 21:51:13 2008 +0000
@@ -3,6 +3,8 @@
#include "Engine.hh"
#include "Logger.hh"
+#include <cassert>
+
NetworkClient::NetworkClient (GameState &state, const CL_IPAddress &connect_to) :
NetworkCore(state), server(netsession.connect(connect_to)) {
@@ -99,12 +101,16 @@
slots.connect(obj.sig_received_message(NETMSG_PLAYER_POSITION), this, &NetworkClientLocalPlayer::on_position);
}
-void NetworkClientLocalPlayer::move (PositionDelta d) {
+bool NetworkClientLocalPlayer::move (PositionDelta d) {
+ // always send move, in all cases
CL_NetPacket pkt;
- pkt.output.write_uint32(d.dx);
- pkt.output.write_uint32(d.dy);
+ pkt.output.write_int32(d.dx);
+ pkt.output.write_int32(d.dy);
obj.send(NETMSG_CLIENT_MOVE, pkt, false);
+
+ // return validity
+ return LocalPlayer::move(d);
}
void NetworkClientLocalPlayer::on_position (CL_NetPacket &pkt) {
@@ -134,7 +140,7 @@
Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", pos=" << pos;
- updatePosition(pos);
+ assert(updatePosition(pos));
}
void NetworkClientRemotePlayer::on_quit (CL_NetPacket &pkt) {
--- a/src/proto2/NetworkClient.hh Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/NetworkClient.hh Sun Nov 09 21:51:13 2008 +0000
@@ -36,7 +36,7 @@
public:
NetworkClientLocalPlayer (NetworkClient &client, CL_NetObject_Client &obj, Coordinate initial_position);
- virtual void move (PositionDelta d);
+ virtual bool move (PositionDelta d);
private:
void on_position (CL_NetPacket &pkt);
--- a/src/proto2/NetworkServer.cc Sun Nov 09 20:40:46 2008 +0000
+++ b/src/proto2/NetworkServer.cc Sun Nov 09 21:51:13 2008 +0000
@@ -48,7 +48,7 @@
}
NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, CL_NetComputer &computer, uint16_t pid) :
- RemotePlayer(Coordinate(0, 0), true), server(server), computer(computer), obj(&server.netobjs), pid(pid) {
+ RemotePlayer(Coordinate(100, 100), true), server(server), computer(computer), obj(&server.netobjs), pid(pid) {
// log
Engine::log(INFO, "server_player.connected") << "computer=" << computer << ", obj=" << obj;
@@ -96,8 +96,8 @@
return;
// read packet
- uint32_t dx = pkt.input.read_uint32();
- uint32_t dy = pkt.input.read_uint32();
+ int32_t dx = pkt.input.read_int32();
+ int32_t dy = pkt.input.read_int32();
// movement delta
PositionDelta delta(dx, dy);