that's not a prototype anymore... at least it shouldn't be
authorterom
Wed, 03 Dec 2008 19:16:32 +0000
changeset 185 25becd2cb026
parent 184 561892e2a30e
child 186 0738f2949a2b
that's not a prototype anymore... at least it shouldn't be
src/Application.cc
src/CMakeLists.txt
src/Config.hh
src/Engine.cc
src/Engine.hh
src/Error.hh
src/GameState.cc
src/GameState.hh
src/Graphics.cc
src/Graphics.hh
src/Input.hh
src/Logger.cc
src/Logger.hh
src/Network.cc
src/Network.hh
src/NetworkAddress.hh
src/NetworkClient.cc
src/NetworkClient.hh
src/NetworkConfig.hh
src/NetworkNode.cc
src/NetworkNode.hh
src/NetworkObject.cc
src/NetworkObject.hh
src/NetworkPacket.cc
src/NetworkPacket.hh
src/NetworkServer.cc
src/NetworkServer.hh
src/NetworkSession.cc
src/NetworkSession.hh
src/NetworkSocket.hh
src/NetworkTCP.cc
src/NetworkTCP.hh
src/NetworkUDP.cc
src/NetworkUDP.hh
src/Physics.cc
src/Physics.hh
src/SinglePlayer.hh
src/Terrain.cc
src/Terrain.hh
src/Vector.hh
src/proto2/Application.cc
src/proto2/CMakeLists.txt
src/proto2/Config.hh
src/proto2/Engine.cc
src/proto2/Engine.hh
src/proto2/Error.hh
src/proto2/GameState.cc
src/proto2/GameState.hh
src/proto2/Graphics.cc
src/proto2/Graphics.hh
src/proto2/Input.hh
src/proto2/Logger.cc
src/proto2/Logger.hh
src/proto2/Network.cc
src/proto2/Network.hh
src/proto2/NetworkAddress.hh
src/proto2/NetworkClient.cc
src/proto2/NetworkClient.hh
src/proto2/NetworkConfig.hh
src/proto2/NetworkNode.cc
src/proto2/NetworkNode.hh
src/proto2/NetworkObject.cc
src/proto2/NetworkObject.hh
src/proto2/NetworkPacket.cc
src/proto2/NetworkPacket.hh
src/proto2/NetworkServer.cc
src/proto2/NetworkServer.hh
src/proto2/NetworkSession.cc
src/proto2/NetworkSession.hh
src/proto2/NetworkSocket.hh
src/proto2/NetworkTCP.cc
src/proto2/NetworkTCP.hh
src/proto2/NetworkUDP.cc
src/proto2/NetworkUDP.hh
src/proto2/Physics.cc
src/proto2/Physics.hh
src/proto2/SinglePlayer.hh
src/proto2/Terrain.cc
src/proto2/Terrain.hh
src/proto2/Vector.hh
src/proto2/config.h.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Application.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,134 @@
+
+#include "Engine.hh"
+#include "Error.hh"
+
+#include <stdexcept>
+#include <cassert>
+
+#include <ClanLib/core.h>
+#include <ClanLib/application.h>
+
+class ArgumentError : public Error {
+    public:
+        ArgumentError (const std::string &message) : Error(message) { }
+};
+
+class Main : public CL_ClanApplication {
+    private:
+        // arguments
+        CL_CommandLine args;
+        
+        bool arg_graphics;
+        std::string arg_port;
+        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('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_server = false;
+            arg_connect = "";
+            
+            try {
+                // parse args
+                args.parse_args(argc, argv);
+
+            } catch (CL_Error &e) {
+                throw ArgumentError(e.message);
+            }
+
+            while (args.next()) {
+                switch (args.get_key()) {
+                    case 'p':
+                        arg_port = args.get_argument();
+                        break;
+
+                    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:
+                        throw ArgumentError(args.get_argument());
+
+                    default:
+                        throw ArgumentError(std::string(1, (char) args.get_key()));
+
+                }
+            }
+            
+            // check for invalid combinations of arugments
+            if (arg_server and !arg_connect.empty())
+                throw ArgumentError("cannot be both server and client");
+        }
+
+    public:
+        virtual int main (int argc, char **argv) {
+            // 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;
+                
+                // setup graphics
+                if (arg_graphics)
+                    engine.setupGraphics();
+
+                // setup either network server, client or singleplayer
+                if (arg_server) {
+                    engine.setupNetworkServer(arg_port);
+
+                } else if (!arg_connect.empty()) {
+                    engine.setupNetworkClient(arg_connect, arg_port);
+                
+                } else {
+                    engine.setupSinglePlayer();
+                }
+
+                // run the main loop
+                engine.run();
+                
+                // succesful return
+                return 0;
+            
+            } catch (ArgumentError &e) {
+                std::cerr << e.what() << std::endl;
+                args.print_help();
+
+                // XXX: handle --help
+                return 1;
+            } catch (CL_Error &e) {
+                std::cerr << "main: CL_Error:" << e.message << std::endl;
+
+                return 1;
+
+            } catch (std::exception &e) {
+                std::cerr << "FATAL [uncaught_exception] " << e.what() << std::endl;
+
+                return 1;
+            }
+        }
+} app;
+
--- a/src/CMakeLists.txt	Wed Dec 03 18:59:10 2008 +0000
+++ b/src/CMakeLists.txt	Wed Dec 03 19:16:32 2008 +0000
@@ -3,23 +3,16 @@
 
 set(SOURCES ${SOURCE_FILES} ${HEADER_FILES})
 
-# Set default compile flags for GCC
-if(CMAKE_COMPILER_IS_GNUCXX)
-	message(STATUS "GCC detected, enabling pedantic mode and warnings")
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -Wall -Wextra")
-endif(CMAKE_COMPILER_IS_GNUCXX)
-
 # Generate config.h
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
 include_directories("${CMAKE_CURRENT_BINARY_DIR}")
 
 # Libraries
 
-# An example of how to use a library. You'll need FindExampleLibrary.cmake for this to work
-# Put that file in trunk/cmake/Modules/ and also look inside the file for further instructions.
-#find_package(ExampleLibrary REQUIRED)
-#include_directories(${ExampleLibrary_INCLUDE_DIRS})
-#set(LIBS ${LIBS} ${ExampleLibrary_LIBRARIES})
+# ClanLib 0.8
+find_package(ClanLib 0.8 REQUIRED COMPONENTS Core App Signals Display GL Sound Network)
+include_directories(${ClanLib_INCLUDE_DIRS})
+set(LIBS ${LIBS} ${ClanLib_LIBRARIES})
 
 # Assumes the project generates only one executable. If you need more, you'll need to alter
 # the script and replace ${PROJECT_SHORT_NAME} by executable name.
@@ -27,6 +20,4 @@
 target_link_libraries("${PROJECT_SHORT_NAME}" ${LIBS})
 install(TARGETS "${PROJECT_SHORT_NAME}" DESTINATION bin)
 
-# prototype
-add_subdirectory(proto2)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Config.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,44 @@
+#ifndef CONFIG_HH
+#define CONFIG_HH
+
+#include <ClanLib/display.h>
+
+// This is a temporary way to declare different constants. Maybe we
+// should do somekind of resource manager? Do we have time?
+
+// Mathematical constants
+const float KG_PI = 3.14159265;
+
+// Physics simulation
+// Physics resolution
+const uint16_t MAP_WIDTH = 800;
+const uint16_t MAP_HEIGHT = 600;
+const float MAP_SCALE = 1; // One "pixel" in "real" units
+// Simulation
+const uint16_t PHYSICS_TICK_MS = 10;
+
+// Constants affecting physics
+const float MAP_GRAVITY = 1200.0;
+const float PLAYER_COLLISION_ELASTICITY = 0.3; // TODO: This could be
+                                        // different for different
+                                        // objects
+
+// Player properties
+const float PLAYER_MASS = 10.0;
+const float PLAYER_MOVE_FORCE = 5000.0;
+const float PLAYER_MIN_SPEED = 30.0;
+const float PLAYER_JUMP_MIN_DISTANCE = 5.0;
+const float PLAYER_AIM_MIN = -KG_PI/4; 
+const float PLAYER_AIM_MAX = KG_PI/2;
+const float PLAYER_INITIAL_X = 400.0;
+const float PLAYER_INITIAL_Y = 300.0;
+const float CROSSHAIR_ANGLE_SPEED = PI/40;
+
+const float PLAYER_MAX_SPEED = 70;
+
+// Graphical properties
+const CL_Color COLOR_EMPTY(86, 41, 0);
+const CL_Color COLOR_DIRT(144, 82, 23);
+const CL_Color COLOR_ROCK(132, 136, 135);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Engine.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,58 @@
+
+#include "Engine.hh"
+#include "NetworkServer.hh"
+#include "NetworkClient.hh"
+#include "SinglePlayer.hh"
+
+#include <iostream>
+
+Engine::Engine (void) : is_running(true) {
+
+}
+
+void Engine::setupGraphics (void) {
+    // create the graphics
+    graphics = new Graphics(*this, game_state);
+}
+
+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);
+
+    // create the client
+    net_client = new NetworkClient(game_state, connect_addr);
+}
+
+void Engine::setupSinglePlayer (void) {
+    // create player directly
+ 	LocalPlayer* lp = new SinglePlayer(game_state);
+
+    // add to gamestate
+	game_state.newLocalPlayer(lp);
+}
+
+void Engine::stop (void) {
+    is_running = false;
+}
+
+void Engine::run (void) {
+    while (is_running) {
+        // this does.... magical things
+        CL_System::keep_alive();
+
+        // if I can't find some better way to do this in ClanLib by next thursday, then it f*%!ing sucks
+        // 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(10);
+    }
+}
+
+Logger Engine::log (enum LogLevel level, const char *type) {
+    return Logger(level <= WARN ? std::cerr : std::cout, level, type);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Engine.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,54 @@
+#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"
+
+#include "Logger.hh"
+
+class Engine {
+    private:
+        // 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);
+
+        // setup graphics
+        void setupGraphics (void);
+        
+        // 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);
+		void setupSinglePlayer (void);
+        
+        // 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);
+
+};
+
+#endif /* ENGINE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Error.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,19 @@
+#ifndef ERROR_HH
+#define ERROR_HH
+
+#include <stdexcept>
+#include <string>
+
+class Error : public std::exception {
+    private:
+        const char *message;
+    
+    public:
+        Error (const std::string &message) : message(message.c_str()) { }
+
+        virtual const char* what() const throw() {
+            return message;
+        }
+};
+
+#endif /* ERROR_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GameState.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,113 @@
+
+#include "GameState.hh"
+#include "Engine.hh"
+#include "Config.hh"
+
+/**
+ * shoots the selected weapon.
+ * TODO: selection and weapon information
+ */
+void Player::shoot (void) {
+    // here should be somehow considered which projectile it is
+    if(!canShoot())
+        return;
+    reloadTimer += 0;
+    Vector unitVectorAim = facingRight ? Vector(std::cos(aim), -std::sin(aim)) : 
+            Vector(-std::cos(aim), -std::sin(aim));
+    float shotspeed = 100*PHYSICS_TICK_MS;
+    Vector shotRelativeVelocity = unitVectorAim * shotspeed;
+    Vector shotVelocity = this->velocity + shotRelativeVelocity;
+    this->state.addProjectile(new Shot(this->state, this->position, shotVelocity, true));
+}
+
+void Player::handleMove (PlayerInput_Move input) {
+    float fx = 0; // Force in x-direction
+    float da = 0; // Crosshair angle
+
+    // handle left/right
+    if ((input & INPUT_MOVE_LEFT) && (velocity.x > -PLAYER_MAX_SPEED))
+        fx -= PLAYER_MOVE_FORCE;
+
+    if ((input & INPUT_MOVE_RIGHT) && (velocity.x < PLAYER_MAX_SPEED))
+        fx += PLAYER_MOVE_FORCE;
+
+    if (input & INPUT_MOVE_UP)
+        da += CROSSHAIR_ANGLE_SPEED;
+
+    if (input & INPUT_MOVE_DOWN)
+        da -= CROSSHAIR_ANGLE_SPEED;
+
+    if (input & INPUT_MOVE_JUMP) {
+        if ((input & INPUT_MOVE_LEFT))
+            jump(-1);
+        else if ((input & INPUT_MOVE_RIGHT))
+            jump(1);
+        else
+            jump(0);
+    }
+
+    if (input & INPUT_MOVE_DIG) {
+        // Should create Shot which destroys ground, but also should be destroyed then,
+        // but it doesn't.
+        // But this now just segfaults
+//        world.addObject(new Shot(state, position, true));
+
+        world.removeGround(position, 15);
+    }
+
+    if (input & INPUT_SHOOT) {
+        this->shoot();
+    }
+
+
+
+    // Player facing
+    if (fx < 0) setFacing(false);
+    else if (fx > 0) setFacing(true);
+
+
+    this->changeAim(da); // Move crosshair
+
+    // Apply force
+    applyForce(Vector(fx, 0));
+
+}
+
+void Player::debugInfo (void) {
+    Engine::log(DEBUG, "Player.debugInfo") << "In air: " << this->inAir;
+}
+
+void Shot::onCollision() {
+    world.removeGround(position, 20);
+}
+
+void Shot::draw(CL_GraphicContext *gc) {
+
+
+    CL_Quad player(
+                   (position).x+1, (position).y+1,
+                   (position).x-1, (position).y+1,
+                   (position).x+1, (position).y-1,
+                   (position).x-1, (position).y-1
+                   );
+
+    gc->fill_quad(player, CL_Color::green);
+
+    const uint16_t chlen = 10;
+    uint16_t x = player.center().x;
+    uint16_t y = player.center().y;
+    if(target_visible) {
+        if (facingRight) {
+            gc->draw_line(x, y,
+                          x + std::cos(aim)*chlen,
+                          y - std::sin(aim)*chlen,
+                          CL_Color::black);
+        } else {
+            gc->draw_line(x, y,
+                          x - std::cos(aim)*chlen,
+                          y - std::sin(aim)*chlen,
+                          CL_Color::black);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GameState.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,113 @@
+#ifndef GAMESTATE_HH
+#define GAMESTATE_HH
+
+#include "Physics.hh"
+#include "Input.hh"
+#include "Config.hh"
+
+#include <list>
+#include <stdexcept>
+#include <cmath>
+
+// forward-declare GameState
+class GameState;
+
+class Player : public PhysicsObject {
+protected:
+    GameState &state;
+    bool visible;
+    
+public:
+    Player(GameState &state, Vector position, bool visible) : 
+        PhysicsObject((PhysicsWorld &) state, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible) {
+            
+        std::vector<Vector> shape(4);
+        shape[0] = Vector(0,-9);
+        shape[1] = Vector(6,0);
+        shape[2] = Vector(0,9); 
+        shape[3] = Vector(-6,0);
+        // Initialize the shape of the player (salmiakki shape)
+        setShape(shape);
+        collision_elasticity = PLAYER_COLLISION_ELASTICITY;
+        world.addPlayerObject(this);
+    }
+    
+    void debugInfo ();
+    virtual void handleMove (PlayerInput_Move input);
+    void shoot (void);
+
+};
+
+class Shot : public PhysicsObject {
+protected:
+    GameState &state;
+    bool visible;
+    uint32_t birth_tick;
+    uint32_t death_tick;
+    bool target_visible;
+public:
+    Shot(GameState &state, Vector position, Vector velocity, bool visible) :
+        PhysicsObject((PhysicsWorld &) state, PLAYER_MASS, position, velocity), state(state), visible(visible) {
+        // Looks kind of dumb, for ammunition to have shape
+        std::vector<Vector> shape(4);
+        shape[0] = Vector(-1, -1);
+        shape[1] = Vector(-1, 1);
+        shape[2] = Vector(1, 1);
+        shape[3] = Vector(1, -1);
+        setShape(shape);
+        target_visible = false;
+        collision_elasticity = 0.9; // = shotType.elasticity
+        world.addProjectile(this);
+    }
+private:
+    virtual void onCollision();
+    virtual void draw(CL_GraphicContext *gc);
+};
+
+class LocalPlayer : public Player {
+protected:
+    LocalPlayer (GameState &state, Vector pos, bool visible) : Player(state, pos, visible) { }
+};
+
+class RemotePlayer : public Player {
+protected:
+    RemotePlayer (GameState &state, Vector pos, bool visible) : Player(state, pos, visible) { }
+};
+
+class GameState : public PhysicsWorld {
+public:
+    std::list<Player*> player_list;
+
+    // only one local player is supported
+    LocalPlayer *local_player;
+
+    GameState (void) : PhysicsWorld(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT)), local_player(NULL) {
+
+    }
+       
+    /*
+     * This will return NULL if we don't have a local player - yet
+     */
+    LocalPlayer *getLocalPlayer (void) {
+        return local_player;
+    }
+        
+    void newLocalPlayer (LocalPlayer *player) {
+        if (local_player)
+            throw std::logic_error("newLocalPlayer called even though we already have a local player");
+
+        player_list.push_back(player);
+
+        local_player = player;
+    }
+
+    void newRemotePlayer (RemotePlayer *player) {
+        player_list.push_back(player);
+    }
+
+    void removePlayer (Player *player) {
+        player_list.remove(player);
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,87 @@
+
+#include "Graphics.hh"
+#include "Physics.hh"
+#include "GameState.hh"
+#include <cmath>
+
+Graphics::Graphics (Engine &engine, GameState &state) :
+    engine(engine), 
+    state(state), 
+    update_timer(GRAPHICS_UPDATE_INTERVAL_MS),
+    win(GRAPHICS_WINDOW_TITLE, GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT),
+    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;
+    PlayerInput_Move input_move = 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 movement
+    if (keyboard.get_keycode(CL_KEY_LEFT))
+        input_move |= INPUT_MOVE_LEFT;
+
+    if (keyboard.get_keycode(CL_KEY_RIGHT))
+        input_move |= INPUT_MOVE_RIGHT;
+
+    if (keyboard.get_keycode(CL_KEY_UP))
+        input_move |= INPUT_MOVE_UP;
+
+    if (keyboard.get_keycode(CL_KEY_DOWN))
+        input_move |= INPUT_MOVE_DOWN;
+
+    if (keyboard.get_keycode(CL_KEY_RSHIFT))
+        input_move |= INPUT_MOVE_JUMP;
+
+    if (keyboard.get_keycode(CL_KEY_I))
+        player->debugInfo();
+    
+    if (keyboard.get_keycode(CL_KEY_F)) {
+        Engine::log(DEBUG, "Graphics.check_input") << "Fire!";
+        input_move |= INPUT_SHOOT;
+    }
+   
+    if (keyboard.get_keycode(CL_KEY_M))
+        input_move |= INPUT_MOVE_DIG;
+ 
+    // apply movement if applicable
+    if (input_move)
+        player->handleMove(input_move);
+}
+
+void Graphics::do_redraw (void) {
+    CL_GraphicContext *gc = win.get_gc();
+    
+    // White background
+    gc->clear(CL_Color::white);
+
+    // Draw terrain
+    state.draw(gc);
+
+    // Flip window buffer, sync
+    win.flip(1);
+}
+
+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/Graphics.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,42 @@
+#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>
+
+const std::string GRAPHICS_WINDOW_TITLE = "Kisna Glista";
+const uint32_t GRAPHICS_RESOLUTION_WIDTH = 800;
+const uint32_t GRAPHICS_RESOLUTION_HEIGHT = 600;
+const uint16_t GRAPHICS_UPDATE_INTERVAL_MS = 20;
+
+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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Input.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,21 @@
+#ifndef INPUT_HH
+#define INPUT_HH
+
+const uint16_t INPUT_INTERVAL_MS = 20;
+
+enum {
+    // XXX: aiming is not movement?
+    INPUT_MOVE_UP       = 0x0001,
+    INPUT_MOVE_DOWN     = 0x0002,
+
+    INPUT_MOVE_LEFT     = 0x0004,
+    INPUT_MOVE_RIGHT    = 0x0008,
+
+    INPUT_MOVE_JUMP     = 0x0010,
+    INPUT_MOVE_DIG      = 0x0020,
+    INPUT_SHOOT         = 0x0040,
+};
+
+typedef uint16_t PlayerInput_Move;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Logger.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,40 @@
+
+#include "Logger.hh"
+
+Logger::Logger (std::ostream &stream, enum LogLevel level, const char *module) : stream(stream), level(level), module(module) {
+    const char *l;
+
+    switch (level) {
+        case FATAL: l = "FATAL"; break;
+        case ERROR: l = "ERROR"; break;
+        case WARN: l = "WARN"; break;
+        case INFO: l = "INFO"; break;
+        case DEBUG: l = "DEBUG"; break;
+        default: l = "???"; break;
+    };
+
+    stream << l << " [" << module << "] ";
+}
+
+Logger::~Logger (void) {
+    stream << std::endl;
+}
+
+std::ostream& operator<< (std::ostream &s, CL_NetComputer &c) {
+    s << "[" << c.get_address().get_address() << ":" << c.get_address().get_port() << "]";
+
+    return s;
+}
+
+std::ostream& operator<< (std::ostream &s, CL_NetObject_Server &obj) {
+    s << "%" << obj.get_obj_id();
+
+    return s;
+}
+
+std::ostream& operator<< (std::ostream &s, CL_NetObject_Client &obj) {
+    s << "%" << obj.get_obj_id();
+
+    return s;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Logger.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,39 @@
+#ifndef LOGGER_HH
+#define LOGGER_HH
+
+#include <ClanLib/network.h>
+
+#include <iostream>
+
+enum LogLevel {
+    FATAL,
+    ERROR,
+    WARN,
+    INFO,
+    DEBUG,
+};
+
+class Logger {
+    private:
+        std::ostream &stream;
+        enum LogLevel level;
+        const char *module;
+
+    public:
+        Logger (std::ostream &stream, enum LogLevel level, const char *module);
+
+        template <typename T> Logger& operator<< (T &val) {
+            stream << val;
+
+            return *this;
+        }
+
+
+        ~Logger (void);
+};
+
+std::ostream& operator<< (std::ostream &s, CL_NetComputer &c);
+std::ostream& operator<< (std::ostream &s, CL_NetObject_Server &obj);
+std::ostream& operator<< (std::ostream &s, CL_NetObject_Client &obj);
+
+#endif /* LOGGER_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Network.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,29 @@
+#include "Network.hh"
+#include "NetworkAddress.hh"
+#include "NetworkSocket.hh"
+#include "Engine.hh"
+
+#include <sstream>
+#include <cstring>
+
+std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr) {
+    s << "[" << addr.get_address() << ":" << addr.get_port() << "]";
+
+    return s;
+
+}
+        
+std::string NetworkSocketError::build_str (const NetworkSocket &socket, const char *op, const char *err) {
+    std::stringstream ss;
+
+    ss << "socket #" << socket.get_socket() << " " << op << ": " << err;
+
+    return ss.str();
+}
+
+NetworkSocketError::NetworkSocketError (const NetworkSocket &socket, const char *op, const char *err) :
+    Error(build_str(socket, op, err)) {
+    
+    // nothing
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Network.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,83 @@
+#ifndef NETWORK_HH
+#define NETWORK_HH
+
+#include "NetworkConfig.hh"
+#include "GameState.hh"
+
+#include <ClanLib/network.h>
+
+const int32_t COORDINATE_MAX = 1 << 30;
+
+class NetworkCore {
+    protected:
+        GameState &state;
+
+        CL_SlotContainer slots;
+
+        // constructor
+        NetworkCore (GameState &state) : state(state) { }
+
+
+
+
+};
+
+enum NetworkChannel {
+    /*
+     * Core channel used for NetworkSession
+     */
+    NETCHAN_CORE            = 0x01,
+};
+
+enum NetworkPhysicsFlags {
+    NETWORK_PHYSICS_INAIR      = 0x01,
+};
+
+enum NetworkMessage {
+    NETMSG_PACKET_INVALID   = 0x00,
+
+    /*
+     * You have joined the game:
+     *
+     *  Vector      initial_position
+     */
+    NETMSG_SERVER_HELLO = 0x0100,
+
+    /*
+     * New client has connected to server:
+     *  
+     *  Vector      initial_position
+     */
+    NETMSG_PLAYER_JOIN  = 0x0101,
+
+    /*
+     * Client has left server:
+     *
+     */
+    NETMSG_PLAYER_QUIT  = 0x0102,
+
+    /*
+     * Client has moved
+     *
+     *  uint16_t    PlayerInput_Move
+     */
+    NETMSG_CLIENT_MOVE  = 0x0201,
+    
+    /*
+     * Initial player info
+     *
+     *  Vector      initial_position
+     */
+    NETMSG_PLAYER_INFO  = 0x0300,
+
+    /*
+     * Player position update
+     *
+     * Vector   position
+     * Vector   velocity
+     * uint8_t  NetworkPhysicsFlags
+     */
+    NETMSG_PLAYER_POSITION  = 0x0301,
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkAddress.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,11 @@
+#ifndef NETWORK_ADDRESS_HH
+#define NETWORK_ADDRESS_HH
+
+#include <ClanLib/Network/Socket/ip_address.h>
+
+typedef CL_IPAddress NetworkAddress;
+
+// Network.cc
+std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr);
+
+#endif /* NETWORK_ADDRESS_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkClient.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,143 @@
+
+#include "NetworkClient.hh"
+#include "Engine.hh"
+#include "Logger.hh"
+
+#include <cassert>
+
+NetworkClient::NetworkClient (GameState &state, const NetworkAddress &connect_to) : 
+    NetworkCore(state), netsession(NETWORK_MAGIC_ID), server(netsession.connect(connect_to)), netobjs(netsession, NETCHAN_CORE, server) {
+    
+    // connect slots
+    slots.connect(netobjs.sig_create(), this, &NetworkClient::on_create);
+
+    // XXX: sig_disconnected
+}
+
+void NetworkClient::on_create (NetworkObject_Client *obj, NetworkMessageID msg_id, NetworkPacket &pkt) {
+    switch (msg_id) {
+        case NETMSG_SERVER_HELLO:
+            on_server_hello(obj, pkt);
+
+            break;
+        
+        case NETMSG_PLAYER_INFO:
+            on_player_info(obj, pkt);
+
+            break;
+        
+        case NETMSG_PLAYER_JOIN:
+            on_player_join(obj, pkt);
+
+            break;
+
+        default:
+            Engine::log(WARN, "client.on_create_object") << "unknown msg_id=" << msg_id << " for obj=" << obj;
+    }
+}
+        
+void NetworkClient::on_server_hello (NetworkObject_Client *obj, NetworkPacket &pkt) {
+    // read the packet
+    Vector position = pkt.read_vector();
+    
+    Engine::log(INFO, "client.on_server_hello") << "obj=" << obj << ", pos=" << position;
+
+    // create the LocalPlayer object
+    NetworkClientLocalPlayer *player = new NetworkClientLocalPlayer(*this, obj, position);
+
+    // inform state
+    state.newLocalPlayer(player);
+}
+        
+void NetworkClient::on_player_info (NetworkObject_Client *obj, NetworkPacket &pkt) {
+    // read the packet
+    Vector position = pkt.read_vector();
+    
+    Engine::log(INFO, "client.on_player_info") << "obj=" << obj << ", pos=" << position;
+
+    // create the LocalPlayer object
+    NetworkClientRemotePlayer *player = new NetworkClientRemotePlayer(*this, obj, position);
+
+    // inform state
+    state.newRemotePlayer(player);
+
+}
+        
+void NetworkClient::on_player_join (NetworkObject_Client *obj, NetworkPacket &pkt) {
+    // read the packet
+    Vector position = pkt.read_vector();
+    
+    Engine::log(INFO, "client.on_player_join") << "obj=" << obj << ", pos=" << position;
+    
+    // create the RemotePlayer object
+    NetworkClientRemotePlayer *player = new NetworkClientRemotePlayer(*this, obj, position);
+
+    // inform state
+    state.newRemotePlayer(player);
+}
+        
+void NetworkClient::player_quit (NetworkClientRemotePlayer *player) {
+    // inform state
+    state.removePlayer(player);
+
+    // delete
+    // XXX: leak because deleting the slot while it's being called breaks ClanLib
+    //  delete player;
+}
+
+NetworkClientLocalPlayer::NetworkClientLocalPlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position) :
+    LocalPlayer(client.state, position, true), client(client), obj(obj) {
+    
+    // receive messages
+    slots.connect(obj->sig_message(NETMSG_PLAYER_POSITION), this, &NetworkClientLocalPlayer::on_position);
+}
+        
+void NetworkClientLocalPlayer::handleMove (PlayerInput_Move input) {
+    // always send move, in all cases
+    NetworkPacket pkt;
+    pkt.write_uint16(input);
+
+    obj->send(NETMSG_CLIENT_MOVE, pkt, false);
+    
+    // do not handle locally
+}
+        
+void NetworkClientLocalPlayer::on_position (NetworkPacket &pkt) {
+    Vector position = pkt.read_vector();
+    Vector velocity = pkt.read_vector();
+    uint8_t flags = pkt.read_uint8();
+
+    Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", position=" << position << ", velocity=" << velocity;
+    
+    // just update... 
+    updatePhysics(position, velocity, flags & NETWORK_PHYSICS_INAIR);
+}
+        
+NetworkClientRemotePlayer::NetworkClientRemotePlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position) :
+    RemotePlayer(client.state, position, true), client(client), obj(obj) {
+    
+    // receive messages
+    slots.connect(obj->sig_message(NETMSG_PLAYER_POSITION), this, &NetworkClientRemotePlayer::on_position);
+    slots.connect(obj->sig_message(NETMSG_PLAYER_QUIT), this, &NetworkClientRemotePlayer::on_quit);
+}
+
+void NetworkClientRemotePlayer::on_position (NetworkPacket &pkt) {
+    Vector position = pkt.read_vector();
+    Vector velocity = pkt.read_vector();
+    uint8_t flags = pkt.read_uint8();
+
+    Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", position=" << position << ", velocity=" << velocity;
+    
+    // just update... 
+    updatePhysics(position, velocity, flags & NETWORK_PHYSICS_INAIR);
+}
+
+void NetworkClientRemotePlayer::on_quit (NetworkPacket &pkt) {
+    // pkt is empty
+    (void) pkt;
+
+    Engine::log(INFO, "client_player.on_quit") << "obj=" << obj;
+
+    client.player_quit(this);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkClient.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,71 @@
+#ifndef NETWORKCLIENT_HH
+#define NETWORKCLIENT_HH
+
+#include "Network.hh"
+#include "GameState.hh"
+#include "NetworkSession.hh"
+#include "NetworkObject.hh"
+
+// forward-declare
+class NetworkClientLocalPlayer;
+class NetworkClientRemotePlayer;
+
+class NetworkClient : public NetworkCore {
+    friend class NetworkClientLocalPlayer;
+    friend class NetworkClientRemotePlayer;
+
+    private:
+        NetworkSession netsession;
+        NetworkNode *server;
+
+        NetworkObject_ClientController netobjs;
+        
+    public:
+        NetworkClient (GameState &state, const NetworkAddress &connect_to);
+
+    private:
+        void on_create (NetworkObject_Client *obj, NetworkMessageID msg_id, NetworkPacket &pkt);
+
+        void on_server_hello (NetworkObject_Client *obj, NetworkPacket &pkt);
+        void on_player_info (NetworkObject_Client *obj, NetworkPacket &pkt);
+        void on_player_join (NetworkObject_Client *obj, NetworkPacket &pkt);
+    
+    public:
+        void player_quit (NetworkClientRemotePlayer *player);
+};
+
+class NetworkClientLocalPlayer : public LocalPlayer {
+    private:
+        NetworkClient &client;
+
+        CL_SlotContainer slots;
+        
+        NetworkObject_Client *obj;
+
+    public:
+        NetworkClientLocalPlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position);
+        
+        virtual void handleMove (PlayerInput_Move input);
+    
+    private:
+        void on_position (NetworkPacket &pkt);
+};
+
+class NetworkClientRemotePlayer : public RemotePlayer {
+    private:
+        NetworkClient &client;
+        
+        CL_SlotContainer slots;
+
+        NetworkObject_Client *obj;
+
+    public:
+        NetworkClientRemotePlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position);
+    
+    private:
+        void on_position (NetworkPacket &pkt);
+
+        void on_quit (NetworkPacket &pkt);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkConfig.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,29 @@
+#ifndef NETWORK_CONFIG_HH
+#define NETWORK_CONFIG_HH
+
+// socket-related includes
+// copied from clanlib code, so should be relatively OS-safe
+#ifndef WIN32
+        #include <sys/socket.h>
+        #include <netinet/in.h>
+        #include <arpa/inet.h>
+        #include <netdb.h>
+        #include <sys/time.h>
+        #include <unistd.h> 
+#else
+        #include <winsock2.h>
+        #include <windows.h>
+        typedef int socklen_t;
+#endif
+
+#include <string>
+
+const std::string NETWORK_PORT_STR = "9338";
+
+const size_t NETWORK_PACKET_SIZE = 1280;
+const int NETWORK_LISTEN_BACKLOG = 5;
+
+const char NETWORK_MAGIC_STR[8+1] = "KISNGLIS";
+const uint64_t NETWORK_MAGIC_ID = * ((const uint64_t *) NETWORK_MAGIC_STR);
+
+#endif /* NETWORK_CONFIG_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkNode.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,51 @@
+
+#include <cassert>
+
+#include "NetworkNode.hh"
+
+NetworkNode::NetworkNode (NetworkSession &session, NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &address) :
+    session(session), tcp(tcp), udp(udp), address(address) {
+    
+    // connect signals
+    slots.connect(tcp->sig_disconnect(), this, &NetworkNode::on_disconnect);
+    slots.connect(tcp->sig_packet(), &session, &NetworkSession::handle_message, this);
+    
+}
+
+NetworkNode::~NetworkNode (void) {
+    delete tcp;
+}
+
+void NetworkNode::on_disconnect (void) {
+    // tell session
+    session.handle_disconnect(this);
+
+    // fire signal
+    _sig_disconnected();
+    
+    // delete
+//    delete this;
+}
+
+void NetworkNode::send (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable) {
+    assert(channel_id > 0);
+    
+    // add our header
+    NetworkPacket pkt2;
+    pkt2.write_uint16(channel_id);
+    pkt2.write_packet(pkt);
+    
+    // either tcp or udp
+    if (reliable) {
+        assert(tcp);
+
+        tcp->write_packet(pkt2);
+
+    } else {
+        udp->sendto(pkt2, address);
+    }
+}
+        
+const NetworkAddress& NetworkNode::getRemoteAddress (void) {
+    return address;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkNode.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,45 @@
+#ifndef NETWORK_NODE_HH
+#define NETWORK_NODE_HH
+
+// forward-declare
+class NetworkNode;
+
+enum NetworkNodeType {
+    NETWORK_NODE_SERVER_CLIENT,
+    NETWORK_NODE_CLIENT_SERVER
+};
+
+#include "NetworkTCP.hh"
+#include "NetworkUDP.hh"
+#include "NetworkSession.hh"
+
+class NetworkNode {
+    private:
+        NetworkSession &session;
+        NetworkTCPTransport *tcp;
+        NetworkUDP *udp;
+        const NetworkAddress address;
+
+        CL_SlotContainer slots;
+    
+    public:
+        NetworkNode (NetworkSession &session, NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &address);
+        
+    private:
+        NetworkNode (const NetworkNode &copy);
+        ~NetworkNode (void);
+        NetworkNode& operator= (const NetworkNode &copy);
+        
+        void on_disconnect (void);
+         
+        CL_Signal_v0 _sig_disconnected;
+
+    public:
+        void send (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable = true);
+
+        const NetworkAddress& getRemoteAddress (void);
+        
+        CL_Signal_v0& sig_disconnected (void) { return _sig_disconnected; }
+};
+
+#endif /* NETWORK_NODE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkObject.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,148 @@
+
+#include <cassert>
+
+#include "NetworkObject.hh"
+
+/* 
+ * NetworkObject_Controller 
+ */
+NetworkObjectController::NetworkObjectController (NetworkSession &session, NetworkChannelID channel_id) :
+    session(session), channel_id(channel_id) {
+    
+    // setup signals
+    slot_message = session.sig_chan_message(channel_id).connect(this, &NetworkObjectController::on_message);
+}
+
+void NetworkObjectController::on_message (NetworkPacket &pkt, NetworkNode *node) {
+    uint32_t obj_id = pkt.read_uint32();
+    uint16_t msg_id = pkt.read_uint16();
+    
+    // lookup object
+    NetworkObject *obj = objects[obj_id];
+
+    if (obj) {
+        obj->handle_packet(node, msg_id, pkt);
+
+    } else {
+        handle_create(obj_id, msg_id, pkt, node);
+    }
+}
+
+/* 
+ * NetworkObject_ServerController 
+ */
+NetworkObject_ServerController::NetworkObject_ServerController (NetworkSession &session, NetworkChannelID channel_id) :
+    NetworkObjectController(session, channel_id), id_pool(0) {
+
+}
+
+NetworkObjectID NetworkObject_ServerController::getObjectID (void) {
+    return ++id_pool;
+}
+        
+void NetworkObject_ServerController::handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node) {
+    (void) obj_id;
+    (void) msg_id;
+    (void) pkt;
+    (void) node;
+
+    // XXX: fail
+    throw CL_Error("clients cannot create objects");
+}
+        
+/* 
+ * NetworkObject_ClientController *
+ */
+NetworkObject_ClientController::NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server) :
+    NetworkObjectController(session, channel_id), server(server) {
+
+
+}
+        
+void NetworkObject_ClientController::handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node) {
+    // we only communicate with the server
+    assert(node == server);
+    
+    // create new object
+    NetworkObject_Client *obj = new NetworkObject_Client(*this, obj_id);
+    
+    // signal
+   _sig_create(obj, msg_id, pkt); 
+}
+
+/* 
+ * NetworkObject 
+ */
+NetworkObject::NetworkObject (NetworkObjectController &controller, NetworkObjectID obj_id) :
+    obj_id(obj_id) {
+    
+    assert(obj_id);
+
+    controller.objects[obj_id] = this;
+}
+        
+void NetworkObject::buildPacket (NetworkPacket &pkt, NetworkMessageID msg_id, const NetworkPacket &payload) {
+    pkt.write_uint32(obj_id);
+    pkt.write_uint16(msg_id);
+    pkt.write_packet(payload);
+}
+
+std::ostream& operator<< (std::ostream &s, const NetworkObject &obj) {
+    return s << "<NetworkObject #" << obj.obj_id << ">";
+}
+
+/* 
+ * NetworkObject_Server 
+ */
+NetworkObject_Server::NetworkObject_Server (NetworkObject_ServerController &controller) :
+    NetworkObject(controller, controller.getObjectID()), controller(controller) {
+    
+}
+
+void NetworkObject_Server::handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt) {
+    _map_sig_message[msg_id](node, pkt);
+}
+
+void NetworkObject_Server::send_to (NetworkNode *dst, NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable) {
+    NetworkPacket pkt_out;
+
+    buildPacket(pkt_out, msg_id, pkt);
+
+    dst->send(controller.channel_id, pkt_out, reliable);
+}
+
+void NetworkObject_Server::send_all (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable) {
+    send_all_except(msg_id, pkt, NULL, reliable);
+}
+
+void NetworkObject_Server::send_all_except (NetworkMessageID msg_id, const NetworkPacket &pkt, NetworkNode *black_sheep, bool reliable) {
+    NetworkPacket pkt_out;
+
+    buildPacket(pkt_out, msg_id, pkt);
+    
+    controller.session.send_all_except(controller.channel_id, pkt_out, black_sheep, reliable);
+}
+ 
+/* 
+ * NetworkObject_Client 
+ */
+NetworkObject_Client::NetworkObject_Client (NetworkObject_ClientController &controller, NetworkObjectID id) :
+    NetworkObject(controller, id), controller(controller) { 
+    
+    // nothing
+}
+
+void NetworkObject_Client::handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt) {
+    assert(node == controller.server);
+
+    _map_sig_message[msg_id](pkt);
+}
+       
+void NetworkObject_Client::send (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable) {
+    NetworkPacket pkt_out;
+
+    buildPacket(pkt_out, msg_id, pkt);
+
+    controller.server->send(controller.channel_id, pkt_out, reliable);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkObject.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,132 @@
+#ifndef NETWORK_OBJECT_HH
+#define NETWORK_OBJECT_HH
+
+#include "NetworkSession.hh"
+#include "NetworkNode.hh"
+#include "Logger.hh"
+
+#include <map>
+
+typedef uint32_t NetworkObjectID;
+typedef uint16_t NetworkMessageID;
+
+// forward-declare
+class NetworkObject;
+class NetworkObject_Client;
+class NetworkObject_Server;
+
+class NetworkObjectController {
+    friend class NetworkObject;
+    friend class NetworkObject_Server;
+    friend class NetworkObject_Client;
+
+    private:
+        NetworkSession &session;
+        NetworkChannelID channel_id;
+
+        std::map<NetworkObjectID, NetworkObject*> objects;
+
+        CL_Slot slot_message;
+    
+    protected:
+        NetworkObjectController (NetworkSession &session, NetworkChannelID channel_id);
+    
+    private:
+        void on_message (NetworkPacket &pkt, NetworkNode *node);
+
+    protected:
+        virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node) = 0; 
+};
+
+class NetworkObject_ServerController : public NetworkObjectController {
+    friend class NetworkObject_Server;
+
+    private:
+        NetworkObjectID id_pool;
+    
+    public:
+        NetworkObject_ServerController (NetworkSession &session, NetworkChannelID channel_id);
+
+    protected:
+        NetworkObjectID getObjectID (void);
+
+        virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node);
+};
+
+class NetworkObject_ClientController : public NetworkObjectController {
+    friend class NetworkObject_Client;
+
+    private:
+        NetworkNode *server;
+
+        CL_Signal_v3<NetworkObject_Client*, NetworkMessageID, NetworkPacket&> _sig_create;
+    
+    public:
+        NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server);
+
+    protected:
+        virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node);
+    
+    public:  
+        CL_Signal_v3<NetworkObject_Client*, NetworkMessageID, NetworkPacket&>& sig_create (void) { return _sig_create; }
+};
+
+class NetworkObject {
+    friend class NetworkObjectController;
+    friend std::ostream& operator<< (std::ostream &s, const NetworkObject &obj);
+
+    protected:
+        NetworkObjectID obj_id;
+
+    protected:
+        NetworkObject (NetworkObjectController &controller, NetworkObjectID obj_id);
+        
+        virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt) = 0;
+
+        void buildPacket (NetworkPacket &pkt, NetworkMessageID msg_id, const NetworkPacket &payload);
+};
+
+std::ostream& operator<< (std::ostream &s, const NetworkObject &obj);
+
+class NetworkObject_Server : public NetworkObject {
+    friend class NetworkObject_ServerController;
+
+    private:
+        NetworkObject_ServerController &controller;
+
+        std::map<NetworkMessageID, CL_Signal_v2<NetworkNode*, NetworkPacket&> > _map_sig_message;
+
+    public:
+        NetworkObject_Server (NetworkObject_ServerController &controller);
+    
+    protected:
+        virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt);
+
+    public:
+        void send_to (NetworkNode *dst, NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable = true);
+        void send_all (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable = true);
+        void send_all_except (NetworkMessageID msg_id, const NetworkPacket &pkt, NetworkNode *black_sheep, bool reliable = true);
+    
+        CL_Signal_v2<NetworkNode*, NetworkPacket&>& sig_message (NetworkMessageID msg_id) { return _map_sig_message[msg_id]; }
+};
+
+class NetworkObject_Client : public NetworkObject {
+    friend class NetworkObject_ClientController;
+
+    private:
+        NetworkObject_ClientController &controller;
+
+        std::map<NetworkMessageID, CL_Signal_v1<NetworkPacket&> > _map_sig_message;
+
+    protected:
+        NetworkObject_Client (NetworkObject_ClientController &controller, NetworkObjectID id);
+        
+        virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt);
+
+    public:
+        void send (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable = true);
+        
+        CL_Signal_v1<NetworkPacket&>& sig_message (NetworkMessageID msg_id) { return _map_sig_message[msg_id]; }
+};
+
+#endif /* NETWORK_OBJECT_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkPacket.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,144 @@
+
+#include <cassert>
+#include <cstring>
+
+#include "NetworkPacket.hh"
+
+
+NetworkPacket::NetworkPacket (void) :
+    buf_size(NETWORK_PACKET_SIZE), data_size(0), offset(0) {
+    
+    // nothing
+}
+
+void NetworkPacket::check_write_size (size_t item_size) {
+     if (offset + item_size > buf_size)
+        throw NetworkPacketError("not enough space to write");
+
+}
+        
+void NetworkPacket::check_read_size (size_t item_size) {
+    if (offset + item_size > data_size)
+        throw NetworkPacketError("not enough data to read");
+}
+
+void NetworkPacket::write (const void *ptr, size_t len) {
+    // check buffer overflow
+    check_write_size(len);
+
+    // set value
+    memcpy(buf + offset, ptr, len);
+
+    // update offset and size
+    offset += len;
+    data_size += len;
+}
+
+void NetworkPacket::read (void *ptr, size_t len) {
+    // check buffer underflow
+    check_read_size(len);
+
+    // set value
+    memcpy(ptr, buf + offset, len);
+
+    // update offset
+    offset += len;
+}
+
+template <typename T> T NetworkPacket::read_val (void) {
+    T val;
+
+    // read
+    read(&val, sizeof(T));
+
+    // return
+    return val;
+}
+
+template <typename T> void NetworkPacket::write_val (const T &val) {
+    // write
+    write(&val, sizeof(T));
+}
+
+uint32_t NetworkPacket::read_uint32 (void) {
+    return ntohl(read_val<uint32_t>());
+}
+
+uint16_t NetworkPacket::read_uint16 (void) {
+    return ntohs(read_val<uint16_t>());
+}
+
+uint8_t NetworkPacket::read_uint8 (void) {
+    return read_val<uint8_t>();
+}
+
+int32_t NetworkPacket::read_int32 (void) {
+    return ntohl(read_val<int32_t>());
+}
+
+int16_t NetworkPacket::read_int16 (void) {
+    return ntohs(read_val<int16_t>());
+}
+
+int8_t NetworkPacket::read_int8 (void) {
+    return read_val<int8_t>();
+}
+        
+float NetworkPacket::read_float32 (void) {
+    int32_t ival = read_int32();
+
+    return *((float *) &ival);
+}
+
+Vector NetworkPacket::read_vector (void) {
+    float fx = read_float32();
+    float fy = read_float32();
+
+    return Vector(fx, fy);
+}
+
+void NetworkPacket::write_uint32 (uint32_t val) {
+    write_val<uint32_t>(htonl(val));
+}
+
+void NetworkPacket::write_uint16 (uint16_t val) {
+    write_val<uint16_t>(htons(val));
+}
+
+void NetworkPacket::write_uint8 (uint8_t val) {
+    write_val<uint8_t>(val);
+}
+
+void NetworkPacket::write_int32 (int32_t val) {
+    write_val<int32_t>(htonl(val));
+}
+
+void NetworkPacket::write_int16 (int16_t val) {
+    write_val<int16_t>(htons(val));
+}
+
+void NetworkPacket::write_int8 (int8_t val) {
+    write_val<int8_t>(val);
+}
+        
+void NetworkPacket::write_float32 (float val) {
+    write_int32(*((int32_t *) &val));
+}
+
+void NetworkPacket::write_vector (const Vector &vec) {
+    write_float32(vec.x);
+    write_float32(vec.y);
+}
+
+void NetworkPacket::write_packet (const NetworkPacket &pkt) {
+    // check buffer size
+    check_write_size(pkt.get_data_size());
+
+    // copy
+    memcpy(buf + offset, pkt.get_buf(), pkt.get_data_size());
+
+    // update offset/data_size
+    offset += pkt.get_data_size();
+    data_size += pkt.get_data_size();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkPacket.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,66 @@
+#ifndef NETWORK_PACKET_HH
+#define NETWORK_PACKET_HH
+
+#include "NetworkConfig.hh"
+#include "Vector.hh"
+#include "Error.hh"
+
+class NetworkPacketError : public Error {
+    public:
+        NetworkPacketError (const std::string &message) : Error(message) { }
+};
+
+class NetworkPacket {
+    private:
+        char buf[NETWORK_PACKET_SIZE];
+        size_t buf_size, data_size, offset;
+        
+        void check_write_size (size_t item_size);
+        void check_read_size (size_t item_size);
+
+        template <typename T> T read_val (void);
+        template <typename T> void write_val (const T &val);
+ 
+    public:
+        NetworkPacket (void);
+        
+        char* get_buf (void) { return buf; }
+        const char* get_buf (void) const { return buf; }
+        size_t get_data_size (void) const { return data_size; }
+        size_t get_buf_size (void) const { return buf_size; }
+
+        void set_data_size (size_t size) { offset = 0; data_size = size; }
+
+        // raw
+        void write (const void *ptr, size_t len);
+        void read (void *ptr, size_t len);
+       
+        // type-reads, handle network-endianlness
+        uint32_t read_uint32 (void);
+        uint16_t read_uint16 (void);
+        uint8_t read_uint8 (void);
+
+        int32_t read_int32 (void);
+        int16_t read_int16 (void);
+        int8_t read_int8 (void);
+        
+        float read_float32 (void);
+
+
+        void write_uint32 (uint32_t val);
+        void write_uint16 (uint16_t val);
+        void write_uint8 (uint8_t val);
+
+        void write_int32 (int32_t val);
+        void write_int16 (int16_t val);
+        void write_int8 (int8_t val);
+        
+        void write_float32 (float val);
+
+        // complex
+        Vector read_vector (void);
+        void write_vector (const Vector &vec);
+        void write_packet (const NetworkPacket &pkt);
+};
+
+#endif /* NETWORK_PACKET_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkServer.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,114 @@
+#include "NetworkServer.hh"
+#include "Engine.hh"
+#include "Logger.hh"
+
+#include <cassert>
+
+NetworkServer::NetworkServer (GameState &state, const NetworkAddress &listen_addr) : 
+    NetworkCore(state), netsession(NETWORK_MAGIC_ID), netobjs(netsession, NETCHAN_CORE) {
+    
+    // connect slots
+    slots.connect(netsession.sig_node_connected(), this, &NetworkServer::on_node_connected);
+    
+    // and then we listen
+    netsession.listen(listen_addr);
+
+    Engine::log(INFO, "server") << "running, listen_addr=" << listen_addr;
+}
+
+void NetworkServer::on_node_connected (NetworkNode *node) {
+    // create the player object (it logs it)
+    NetworkServerPlayer *player = new NetworkServerPlayer(*this, node);
+
+    // add to players
+    players.push_back(player);
+    
+    // add to GameState
+    state.newRemotePlayer(player);
+}
+        
+void NetworkServer::handle_disconnect (NetworkServerPlayer *player) {
+    // remove from state
+    state.removePlayer(player);
+
+    // remove from list
+    players.remove(player);
+}
+        
+NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, NetworkNode *node) : 
+    RemotePlayer(server.state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true), server(server), obj(server.netobjs), node(node) {
+    
+    // log
+    Engine::log(INFO, "server_player.connected") << "node=" << node << ", obj=" << obj;
+
+    // messages
+    slots.connect(node->sig_disconnected(), this, &NetworkServerPlayer::on_disconnected);
+    slots.connect(obj.sig_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move);
+
+    // the initial NETMSG_PLAYER_HELLO
+    NetworkPacket hello_pkt;
+    hello_pkt.write_vector(position);
+
+    obj.send_to(node, NETMSG_SERVER_HELLO, hello_pkt, true);
+
+    // send other player objects
+    for (std::list<NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) {
+        NetworkServerPlayer *player = *it;
+        NetworkPacket player_pkt;
+        
+        // player is not in players list yet
+        assert(player != this);
+        
+        player_pkt.write_vector(player->position);
+
+        player->obj.send_to(node, NETMSG_PLAYER_INFO, player_pkt, true);
+    }
+
+    // broadcast NETMSG_PLAYER_JOIN to all clients except current
+    obj.send_all_except(NETMSG_PLAYER_JOIN, hello_pkt, node, true);
+}
+
+void NetworkServerPlayer::on_disconnected (void) {
+    NetworkPacket pkt;
+    
+    Engine::log(INFO, "server_player.disconnected") << "node=" << node << ", obj=" << obj;
+    
+    // remove from server
+    server.handle_disconnect(this);
+    
+    // tell other clients
+    obj.send_all(NETMSG_PLAYER_QUIT, pkt, true);
+
+    // free
+//    delete this;
+}
+
+void NetworkServerPlayer::on_move (NetworkNode *src, NetworkPacket &pkt) {
+    // sanity-check, other players shouldn't move
+    if (src != node) {
+        Engine::log(WARN, "server_player.on_move") << "packet from wrong src=" << src << ", node=" << node;
+        return;
+    }
+    
+    PlayerInput_Move input = pkt.read_uint16();
+
+    Engine::log(INFO, "server_player.on_move") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
+    
+    // apply input
+    handleMove(input);  
+
+    // send position update
+    send_position_update();
+}
+        
+void NetworkServerPlayer::send_position_update (void) {
+    NetworkPacket pkt;
+    pkt.write_vector(position);
+    pkt.write_vector(velocity);
+    pkt.write_uint8(inAir & NETWORK_PHYSICS_INAIR);
+
+    Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity;
+
+    obj.send_all(NETMSG_PLAYER_POSITION, pkt, false);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkServer.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,52 @@
+#ifndef NETWORKSERVER_HH
+#define NETWORKSERVER_HH
+
+#include "Network.hh"
+#include "GameState.hh"
+#include "NetworkSession.hh"
+#include "NetworkObject.hh"
+
+#include <list>
+#include <map>
+#include <ClanLib/core.h>
+
+// forward-declare
+class NetworkServerPlayer;
+
+class NetworkServer : public NetworkCore {
+    friend class NetworkServerPlayer;
+
+    protected:
+        NetworkSession netsession;
+        NetworkObject_ServerController netobjs;
+        std::list<NetworkServerPlayer *> players;
+
+    public:
+        NetworkServer (GameState &state, const NetworkAddress &listen_addr);
+    
+    protected:
+        void handle_disconnect (NetworkServerPlayer *player);
+
+    private:
+        void on_node_connected (NetworkNode *node);
+};
+
+class NetworkServerPlayer : public RemotePlayer {
+    private:
+        NetworkServer &server;
+        NetworkObject_Server obj;
+        NetworkNode *node;
+
+        CL_SlotContainer slots;
+        
+    public:
+        NetworkServerPlayer (NetworkServer &server, NetworkNode *node);
+
+    private:
+        void on_disconnected (void);
+        void on_move (NetworkNode *node, NetworkPacket &pkt);
+
+        void send_position_update (void);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkSession.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,107 @@
+
+#include "NetworkSession.hh"
+#include "Engine.hh"
+
+#include <cassert>
+
+NetworkSession::NetworkSession (uint64_t magic) :
+    magic(magic), tcp_srv(NULL), udp_srv(NULL), udp_client(NULL) {
+   
+    // nothing
+}
+        
+void NetworkSession::listen (const NetworkAddress &addr) {
+    assert(tcp_srv == NULL && udp_srv == NULL);
+    
+    // create TCP/UDP servers
+    tcp_srv = new NetworkTCPServer(addr);
+    udp_srv = new NetworkUDP(addr);
+    
+    // connect signals
+    slots.connect(tcp_srv->sig_client(), this, &NetworkSession::on_tcp_client);
+    slots.connect(udp_srv->sig_packet(), this, &NetworkSession::on_udp_packet);
+}
+        
+NetworkNode *NetworkSession::build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type) {
+    // XXX: unused
+    (void) type;
+
+    // create node
+    return new NetworkNode(*this, tcp, udp, addr);
+}
+
+NetworkNode* NetworkSession::connect (const NetworkAddress &addr) {
+    // XXX: only one connect
+    assert(!udp_client);
+
+    // connect TCP
+    NetworkTCPClient *tcp_client = new NetworkTCPClient(addr);
+        
+    // create UDP socket on same address
+    udp_client = new NetworkUDP(tcp_client->getLocalAddress());
+    
+    // build client
+    NetworkNode *client_node = build_node(tcp_client, udp_client, addr, NETWORK_NODE_CLIENT_SERVER);
+
+    // add to nodes
+    nodes[addr] = client_node;
+
+    // connect signals
+    slots.connect(udp_client->sig_packet(), this, &NetworkSession::on_udp_packet);
+        
+    // return the "server" node
+    return client_node;
+}
+                
+void NetworkSession::handle_disconnect (NetworkNode *node) {
+    // remove from nodes
+    nodes.erase(node->getRemoteAddress());
+}
+        
+void NetworkSession::handle_message (NetworkPacket &pkt, NetworkNode *node) {
+    // read the channel id
+    NetworkChannelID channel_id = pkt.read_uint16();
+
+    // fire signal
+    _map_sig_chan_message[channel_id](pkt, node);
+}
+ 
+void NetworkSession::on_tcp_client (NetworkTCPTransport *tcp_client) {
+    // get remote address manually, because NetworkTCPServer doesn't pass it in to us
+    NetworkAddress addr = tcp_client->getRemoteAddress();
+
+    // build client
+    NetworkNode *client_node = build_node(tcp_client, udp_srv, addr, NETWORK_NODE_SERVER_CLIENT);
+
+    // add to nodes
+    nodes[addr] = client_node;
+    
+    // fire signals
+    _sig_node_connected(client_node);
+}
+        
+void NetworkSession::on_udp_packet (NetworkPacket &pkt, const NetworkAddress &addr) {
+    NetworkNode *node = nodes[addr];
+    
+    // drop from unknown sources
+    if (!node) {
+        Engine::log(WARN, "net_session.on_udp_packet") << "dropping unsolicted UDP packet from " << addr;
+        return;
+    }
+
+    // handle
+    handle_message(pkt, node);
+}
+       
+void NetworkSession::send_all (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable) {
+    send_all_except(channel_id, pkt, NULL, reliable);
+}
+        
+void NetworkSession::send_all_except (NetworkChannelID channel_id, const NetworkPacket &pkt, const NetworkNode *node, bool reliable) {
+    for (std::map<NetworkAddress, NetworkNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
+        if (it->second == node)
+            continue;
+
+        it->second->send(channel_id, pkt, reliable);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkSession.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,58 @@
+#ifndef NETWORK_SESSION_HH
+#define NETWORK_SESSION_HH
+
+#include <map>
+#include <stdint.h>
+
+// forward-declare
+class NetworkSession;
+
+/*
+ * Used to separate packets, ID zero is reserved for NetworkSession use
+ */
+typedef uint16_t NetworkChannelID;
+
+#include "NetworkTCP.hh"
+#include "NetworkUDP.hh"
+#include "NetworkNode.hh"
+
+class NetworkSession {
+    friend class NetworkNode;
+
+    private:
+        uint64_t magic;
+        NetworkTCPServer *tcp_srv;
+        NetworkUDP *udp_srv, *udp_client;
+
+        CL_SlotContainer slots;
+
+        std::map<NetworkAddress, NetworkNode*> nodes;
+        std::map<NetworkChannelID, CL_Signal_v2<NetworkPacket&, NetworkNode *> > _map_sig_chan_message;
+    
+    public:
+        NetworkSession (uint64_t magic);
+
+        void listen (const NetworkAddress &addr);
+        NetworkNode* connect (const NetworkAddress &addr);
+    
+    protected:
+        virtual NetworkNode *build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type);
+        
+        void handle_disconnect (NetworkNode *node);
+        void handle_message (NetworkPacket &pkt, NetworkNode *node);
+
+    private:
+        void on_tcp_client (NetworkTCPTransport *client);
+        void on_udp_packet (NetworkPacket &pkt, const NetworkAddress &addr);
+
+        CL_Signal_v1<NetworkNode*> _sig_node_connected;
+
+    public:
+        void send_all (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable = true);
+        void send_all_except (NetworkChannelID channel_id, const NetworkPacket &pkt, const NetworkNode *node, bool reliable = true);
+
+        CL_Signal_v1<NetworkNode*>& sig_node_connected (void) { return _sig_node_connected; }
+        CL_Signal_v2<NetworkPacket&, NetworkNode *>& sig_chan_message (NetworkChannelID cid) { return _map_sig_chan_message[cid]; }
+};
+
+#endif /* NETWORK_SESSION_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkSocket.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,32 @@
+#ifndef NETWORK_SOCKET_HH
+#define NETWORK_SOCKET_HH
+
+#include "Error.hh"
+
+#include <ClanLib/Network/Socket/socket.h>
+#include <cerrno>
+#include <cstring>
+
+typedef CL_Socket NetworkSocket;
+
+// Network.cc
+class NetworkSocketError : public Error {
+    protected:
+        std::string build_str (const NetworkSocket &socket, const char *op, const char *err);
+
+        NetworkSocketError (const NetworkSocket &socket, const char *op, const char *err);
+};
+
+class NetworkSocketOSError : public NetworkSocketError {
+    public:
+        NetworkSocketOSError (const NetworkSocket &socket, const char *op) :
+            NetworkSocketError(socket, op, strerror(errno)) { }
+};
+
+class NetworkSocketEOFError : public NetworkSocketError {
+    public:
+        NetworkSocketEOFError (const NetworkSocket &socket, const char *op) :
+            NetworkSocketError(socket, op, "EOF") { }
+};
+
+#endif /* NETWORK_SOCKET_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkTCP.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,325 @@
+
+#include "NetworkTCP.hh"
+#include "Engine.hh"
+
+#include <cstdlib>
+#include <cassert>
+
+NetworkBuffer::NetworkBuffer (NetworkSocket &socket, size_t size_hint) :
+    socket(socket), buf(0), size(0), offset(0) {
+    
+    // allocate initial buffer
+    if ((buf = (char *) malloc(size_hint)) == NULL)
+       throw NetworkBufferError("malloc failed");
+    
+    // remember size
+    size = size_hint;
+}
+        
+NetworkBuffer::~NetworkBuffer (void) {
+    free(buf);
+}
+
+void NetworkBuffer::resize (size_t item_size) {
+    size_t new_size = size;
+
+    // grow new_size until item_size fits
+    while (offset + item_size > new_size)
+        new_size *= 2;
+    
+    // grow if needed
+    if (new_size != size) {
+        // realloc buffer
+        if ((buf = (char *) realloc((void *) buf, new_size)) == NULL)
+            throw NetworkBufferError("realloc failed");
+
+        // update size
+        size = new_size;
+
+    } else if (new_size > (offset + item_size) * 4) {
+        // XXX: shrink?
+    }
+}
+        
+void NetworkBuffer::trim (size_t prefix_size) {
+    // update offset
+    offset -= prefix_size;
+
+    // shift the buffer forwards from (buf + prefix) -> (buf), copying (old_offset - prefix) bytes
+    memmove(buf, buf + prefix_size, offset);
+}
+     
+bool NetworkBuffer::try_read (size_t item_size) {
+    int ret;
+    size_t to_read = item_size;
+
+    // keept reads at at least NETWORK_CHUNK_SIZE bytes
+    if (to_read < NETWORK_TCP_CHUNK_SIZE)
+        to_read = NETWORK_TCP_CHUNK_SIZE;
+
+    // resize buffer if needed
+    resize(to_read);
+
+    // read once
+    try {
+        ret = socket.recv(buf + offset, to_read);
+
+    } catch (CL_Error &e) {
+        if (errno == EAGAIN)
+            return false;
+
+        else
+            throw NetworkSocketOSError(socket, "recv");
+    }
+    
+    // handle EOF
+    if (ret == 0)
+        throw NetworkSocketEOFError(socket, "recv");
+
+    assert(ret >= 0);
+
+    // update offset
+    offset += ret;
+
+    // did we get enough?
+    if ((unsigned int) ret < item_size)
+        return false;
+    else
+        return true;
+} 
+        
+bool NetworkBuffer::peek_prefix (uint16_t &ref) {
+    if (offset < sizeof(uint16_t))
+        return false;
+
+    ref = ntohs(*((uint16_t *) (buf)));
+
+    return true;
+}
+    
+bool NetworkBuffer::peek_prefix (uint32_t &ref) {
+    if (offset < sizeof(uint32_t))
+        return false;
+
+    ref = ntohl(*((uint32_t *) (buf)));
+
+    return true;
+}
+
+template <typename PrefixType> PrefixType NetworkBuffer::read_prefix (char *buf_ptr, size_t buf_max) {
+    PrefixType prefix = 0;
+    size_t missing = 0;
+    
+    do {    
+        // do we have the prefix?
+        if (peek_prefix(prefix)) {
+            // do we already have the payload?
+            if (offset >= sizeof(PrefixType) + prefix) {
+                break;
+
+            } else {
+                missing = (sizeof(PrefixType) + prefix) - offset;
+            }
+
+        } else {
+            missing = sizeof(PrefixType);
+        }
+
+        // sanity-check
+        assert(missing);
+        
+        // try and read the missing data
+        if (try_read(missing) == false) {
+            // if unable to read what we need, return zero.
+            return 0;
+        }
+        
+        // assess the situation again
+    } while (true);
+    
+    // copy the data over, unless it's too large
+    if (prefix <= buf_max) {
+        // ...don't copy the prefix, though
+        memcpy(buf_ptr, buf + sizeof(PrefixType), prefix);
+    
+        // trim the bytes out
+        trim(sizeof(PrefixType) + prefix);
+        
+        // return
+        return prefix;
+
+    } else {
+        // trim the bytes out
+        trim(sizeof(PrefixType) + prefix);
+        
+        throw NetworkBufferError("recv prefix overflow");   
+    }
+}
+   
+void NetworkBuffer::push_write (char *buf_ptr, size_t buf_size) {
+    int ret;
+
+    // try and short-circuit writes unless we have already buffered data
+    if (offset == 0) {
+        try {
+            // attempt to send something
+            ret = socket.send(buf_ptr, buf_size);
+
+        } catch (CL_Error &e) {
+            // ignore EAGAIN, detect this by setting ret to -1
+            if (errno != EAGAIN)
+                throw NetworkSocketOSError(socket, "send");
+
+            ret = -1;
+        }
+        
+        // if we managed to send something, adjust buf/size and buffer
+        if (ret > 0) {
+            // sanity-check
+            assert(buf_size >= (unsigned int) ret);
+
+            buf_ptr += ret;
+            buf_size -= ret;
+
+            // if that was all, we're done
+            if (buf_size == 0)
+                return;
+        }
+    }
+    
+    // resize to fit buf_size more bytes
+    resize(buf_size);
+    
+    // copy into our internal buffer
+    memcpy(buf + offset, buf_ptr, buf_size);
+}
+        
+void NetworkBuffer::flush_write (void) {
+    int ret;
+
+    // ignore if we don't have any data buffered
+    if (offset == 0)
+        return;
+    
+    // attempt to write as much as possible
+    try {
+        ret = socket.send(buf, offset);
+
+    } catch (CL_Error &e) {
+        // ignore EAGAIN and just return
+        if (errno == EAGAIN)
+            return;
+
+        else
+            throw NetworkSocketOSError(socket, "send");
+    }
+
+    // trim the buffer
+    trim(ret);
+}
+        
+void NetworkBuffer::write_prefix (char *buf, uint16_t prefix) {
+    uint16_t nval = htons(prefix);
+
+    push_write((char*) &nval, sizeof(uint16_t)); 
+    push_write(buf, prefix);
+}
+
+void NetworkBuffer::write_prefix (char *buf, uint32_t prefix) {
+    uint32_t nval = htonl(prefix);
+
+    push_write((char*) &nval, sizeof(uint32_t)); 
+    push_write(buf, prefix);
+}
+
+NetworkTCPTransport::NetworkTCPTransport (NetworkSocket socket) :
+    socket(socket), in(socket, NETWORK_TCP_INITIAL_IN_BUF), out(socket, NETWORK_TCP_INITIAL_OUT_BUF) {
+    
+    // connect signals
+    slots.connect(socket.sig_read_triggered(), this, &NetworkTCPTransport::on_read);
+    slots.connect(socket.sig_write_triggered(), this, &NetworkTCPTransport::on_write);
+    slots.connect(socket.sig_disconnected(), this, &NetworkTCPTransport::on_disconnected);
+}
+
+
+void NetworkTCPTransport::on_read (void) {
+    uint16_t prefix;
+    NetworkPacket packet;
+    
+    // let the in stream read length-prefixed packets and pass them on to handle_packet
+    while ((prefix = in.read_prefix<uint16_t>(packet.get_buf(), packet.get_buf_size())) > 0) {
+        packet.set_data_size(prefix);
+        _sig_packet(packet);
+    }
+}
+
+void NetworkTCPTransport::on_write (void) {
+    // just flush the output buffer
+    out.flush_write();
+}
+
+void NetworkTCPTransport::on_disconnected (void) {
+    // pass right through
+    _sig_disconnect();
+}
+        
+void NetworkTCPTransport::write_packet (const NetworkPacket &packet) {
+    uint16_t prefix = packet.get_data_size();
+    
+    if (prefix != packet.get_data_size())
+        throw CL_Error("send prefix overflow");
+    
+    try {
+        // just write to the output buffer
+        out.write_prefix((char *) packet.get_buf(), prefix);
+
+    } catch (Error &e) {
+        const char *err = e.what();
+
+        Engine::log(ERROR, "tcp.write_packet") << err;
+        
+        throw;    
+    }
+}
+
+NetworkTCPServer::NetworkTCPServer (const NetworkAddress &listen_addr) :
+    socket(CL_Socket::tcp, CL_Socket::ipv4) {
+    
+    // bind
+    socket.bind(listen_addr);
+
+    // assign slots
+    slots.connect(socket.sig_read_triggered(), this, &NetworkTCPServer::on_accept);
+
+    // listen
+    socket.listen(NETWORK_LISTEN_BACKLOG);
+    
+    // use nonblocking sockets
+    socket.set_nonblocking(true);
+}
+
+
+void NetworkTCPServer::on_accept (void) {
+    // accept a new socket
+    NetworkSocket client_sock = socket.accept();
+
+    // create a new NetworkTCPTransport
+    NetworkTCPTransport *client = buildTransport(client_sock);
+        
+    // let our user handle it
+    _sig_client(client);
+}
+        
+NetworkTCPTransport* NetworkTCPServer::buildTransport (CL_Socket &socket) {
+    return new NetworkTCPTransport(socket);
+}
+        
+NetworkTCPClient::NetworkTCPClient (const NetworkAddress &connect_addr) :
+    NetworkTCPTransport(NetworkSocket(CL_Socket::tcp, CL_Socket::ipv4)) {
+
+    // connect
+    socket.connect(connect_addr);
+    
+    // use nonblocking sockets
+    socket.set_nonblocking(true);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkTCP.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,105 @@
+#ifndef NETWORK_TCP_HH
+#define NETWORK_TCP_HH
+
+#include <ClanLib/core.h>
+
+#include "NetworkSocket.hh"
+#include "NetworkAddress.hh"
+#include "NetworkPacket.hh"
+#include "Error.hh"
+
+const size_t NETWORK_TCP_CHUNK_SIZE = 1024;
+const size_t NETWORK_TCP_INITIAL_IN_BUF = 4096;
+const size_t NETWORK_TCP_INITIAL_OUT_BUF = 0;
+
+class NetworkBufferError : public Error {
+    public:
+        NetworkBufferError (const std::string &message) : Error(message) { }
+};
+
+class NetworkBuffer {
+    private:
+        NetworkSocket socket;
+
+        char *buf;
+        size_t size, offset;
+    
+    public:
+        NetworkBuffer (NetworkSocket &socket, size_t size_hint);
+        ~NetworkBuffer (void);
+    
+    private:
+        NetworkBuffer (const NetworkBuffer &copy);
+        NetworkBuffer& operator= (const NetworkBuffer &copy);
+
+        void resize (size_t item_size);
+        void trim (size_t prefix_size);
+
+    public:    
+        void push_write (char *buf_ptr, size_t buf_size);
+        void flush_write (void);
+        void write_prefix (char *buf, uint16_t prefix);
+        void write_prefix (char *buf, uint32_t prefix);
+        
+        bool try_read (size_t item_size);
+        bool peek_prefix (uint16_t &ref);
+        bool peek_prefix (uint32_t &ref);
+        template <typename PrefixType> PrefixType read_prefix (char *buf_ptr, size_t buf_max);
+};
+
+class NetworkTCPTransport {
+    protected:
+        NetworkSocket socket;
+
+        NetworkBuffer in, out;
+    
+        CL_SlotContainer slots; 
+    
+    public:
+        NetworkTCPTransport (NetworkSocket socket);
+
+    private:
+        void on_read (void);
+        void on_write (void);
+        void on_disconnected (void);
+
+        CL_Signal_v1<NetworkPacket &> _sig_packet;
+        CL_Signal_v0 _sig_disconnect;
+
+    public:
+        NetworkAddress getLocalAddress (void) { return socket.get_source_address(); }
+        NetworkAddress getRemoteAddress (void) { return socket.get_dest_address(); }
+
+        void write_packet (const NetworkPacket &packet);
+        
+        CL_Signal_v1<NetworkPacket&>& sig_packet (void) { return _sig_packet; }
+        CL_Signal_v0& sig_disconnect (void) { return _sig_disconnect; }
+};
+
+class NetworkTCPServer {
+    private:
+        NetworkSocket socket;
+
+        CL_SlotContainer slots; 
+
+    public:
+        NetworkTCPServer (const NetworkAddress &listen_addr);
+
+    private:
+        void on_accept (void);
+
+        CL_Signal_v1<NetworkTCPTransport *> _sig_client;
+
+    protected:
+        virtual NetworkTCPTransport* buildTransport (CL_Socket &socket);
+
+    public:
+        CL_Signal_v1<NetworkTCPTransport *>& sig_client (void) { return _sig_client; }
+};
+
+class NetworkTCPClient : public NetworkTCPTransport {
+    public:
+        NetworkTCPClient (const NetworkAddress &connect_addr);
+};
+
+#endif /* NETWORK_TCP_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkUDP.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,79 @@
+
+#include "NetworkUDP.hh"
+
+#include <ClanLib/core.h>
+#include <cassert>
+
+NetworkUDP::NetworkUDP (void) : 
+    socket(CL_Socket::udp, CL_Socket::ipv4) {
+    
+    // do not bind
+
+    // connect signal
+    slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);
+
+    // nonblocking
+    socket.set_nonblocking(true);
+}
+
+NetworkUDP::NetworkUDP (const NetworkAddress &bind_addr) :
+    socket(CL_Socket::udp, CL_Socket::ipv4) {
+    
+    // bind socket
+    socket.bind(bind_addr);
+
+    // connect signal
+    slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);
+
+    // nonblocking
+    socket.set_nonblocking(true);
+}
+        
+void NetworkUDP::on_recv (void) {
+    int ret;
+    NetworkPacket pkt;
+    NetworkAddress src;
+    
+    // receieve as many packets as possible
+    do {    
+        // attempt to recv a packet
+        try {
+            ret = socket.recv(pkt.get_buf(), pkt.get_buf_size(), src);
+
+        } catch (CL_Error &e) {
+            if (errno == EAGAIN)
+                return;
+            else
+                throw;
+        }
+        
+        // set packet data size
+        pkt.set_data_size(ret);
+
+        // handle packet
+        _sig_packet(pkt, src);
+
+    } while (true);
+}
+        
+bool NetworkUDP::sendto (const NetworkPacket &packet, const NetworkAddress &dst) {
+    int ret;
+
+    // XXX: shouldn't get trimmed
+    try {
+        ret = socket.send(packet.get_buf(), packet.get_data_size(), dst);
+
+    } catch (CL_Error &e) {
+        // XXX: catch some errors, but not others?
+        return false;
+    }
+
+    assert(ret > 0);
+    
+    // UDP shouldn't trim packets
+    assert((unsigned int) ret == packet.get_data_size());
+    
+    // good
+    return true;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NetworkUDP.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,29 @@
+#ifndef NETWORK_UDP_HH
+#define NETWORK_UDP_HH
+
+#include "NetworkSocket.hh"
+#include "NetworkAddress.hh"
+#include "NetworkPacket.hh"
+
+class NetworkUDP {
+    private:
+        NetworkSocket socket;
+
+        CL_SlotContainer slots;
+
+    public:
+        NetworkUDP (void);
+        NetworkUDP (const NetworkAddress &bind_addr);
+
+    private:
+        void on_recv (void);
+
+        CL_Signal_v2<NetworkPacket &, const NetworkAddress&> _sig_packet;
+
+    public:
+        bool sendto (const NetworkPacket &packet, const NetworkAddress &dst);
+        
+        CL_Signal_v2<NetworkPacket &, const NetworkAddress&>& sig_packet (void) { return _sig_packet; }
+};
+
+#endif /* NETWORK_UDP_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Physics.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,409 @@
+#include "Physics.hh"
+#include "Engine.hh"
+#include "GameState.hh"
+#include "Terrain.hh"
+
+#include <algorithm>
+#include <functional>
+#include <cmath>
+#include <assert.h>
+
+PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
+    : Terrain(1337), tick_timer(PHYSICS_TICK_MS), tick_counter(0), dimensions(dimensions),
+      gravity(gravity) {
+    slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
+    tick_timer.enable();
+}
+
+void PhysicsWorld::addPlayerObject (PhysicsObject *object) {
+    players.push_back(object);
+}
+
+void PhysicsWorld::addProjectile (PhysicsObject *projectile) {
+    projectiles.push_back(projectile);
+}
+
+void PhysicsWorld::tick () {
+    //    Engine::log(DEBUG, "physics.apply_force") << "*tick*";
+
+    for (std::list<PhysicsObject*>::iterator i = players.begin(); i != players.end(); i++) {
+        (*i)->tick(); 
+    }
+
+    for (std::list<PhysicsObject*>::iterator i = projectiles.begin(); i != projectiles.end(); i++) {
+        (*i)->tick();
+    }
+
+    tick_counter++;
+}
+
+uint32_t PhysicsWorld::getTick (void) {
+    return tick_counter;
+}
+
+void PhysicsWorld::draw(CL_GraphicContext *gc) {
+    Terrain::draw(gc);
+   
+    // Draw players
+    for (std::list<PhysicsObject*>::iterator it = players.begin(); it != players.end(); it++) {
+        (*it)->draw(gc);
+    }
+    // Draw projectiles
+    for (std::list<PhysicsObject*>::iterator it = projectiles.begin(); it != projectiles.end(); it++) {
+        (*it)->draw(gc);
+    }
+}
+
+PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, 
+                              Vector position, Vector velocity)
+    : world(world), position(position), velocity(velocity),
+      mass(mass), inAir(true), aim(0), facingRight(true), reloadTimer(0) {
+    // TODO: Is thir the right way to do this?
+    //world.addPlayerObject(this);
+}
+
+/**
+ * Player walks on floor.
+ */
+Vector PhysicsObject::walk (TimeMS dt, bool right) {
+    // TODO: that dt should affect to something
+    float velocity = 100;
+    // which way we are walking
+    float deltaX = right ? (velocity*dt)/1000 : -(velocity*dt)/1000;
+    Vector reached = this->position;
+   
+    // Is there upward ramp
+    if(!possibleLocation(position+Vector(deltaX, 0))) {
+        // Yes. Then we check n pixels up
+        for(int i = 1; i < 3; i++) {
+            if(possibleLocation(position+Vector(deltaX, -i))) {
+                // and when there is finally EMPTY, we can walk
+                reached = position+Vector(deltaX, -i);
+                break;
+            }
+        }
+    } else {
+        // Or downward ramp or flat
+        for(int i = 0; 1; i++) {
+
+            // And when there is finally ground we can step on
+            // it. If there is no gound we still step there,
+            // but will fall one pixel down
+            if(possibleLocation(position+Vector(deltaX, i))) {
+                reached = position+Vector(deltaX, i);
+            } else {
+                break;
+            }
+            
+            // If the fall is big enough, set the worm in the air
+            if (i >= 2) {
+                Vector back = walk(dt, !right);
+                this->inAir = true;
+                this->velocity.x = right ? velocity : -velocity;
+                // Avoid stepping two pixels down when it starts to free fall
+                reached.y -= 2;
+                this->velocity = (reached-back)*1000/dt;
+                break;
+            }
+        }
+    }
+    // And we return where we got
+    return reached;
+
+}
+
+/**
+ * Makes the player jump in the air.
+ * @param direction -1: jump left, 0: jump up, 1: jump right
+ */
+void PhysicsObject::jump (int direction) {
+    // Jump only if player is "on the ground"
+    if (!this->inAir) {
+ 	    velocity.y = -100;
+        switch (direction) {
+            case 1:
+                velocity.x += 20;
+                break;
+            case -1:
+                velocity.x -= 20;
+                break;
+            case 0:
+                break;
+            default:
+                throw std::logic_error("Invalid jump direction");
+        }
+	    inAir = true;
+    }
+}
+
+bool PhysicsObject::possibleLocation (Vector loc) {
+    for(unsigned int i = 0; i < this->shape.size(); i++) {
+        if(world.collides(loc+shape[i]))
+            return false;
+    }
+    return true;
+}
+
+void func1() {
+
+}
+
+/**
+ * Updates object speed and position. This function organises force
+ * integration and collision detection.
+ */   
+void PhysicsObject::updatePosition () {
+
+    // Reloads weapon if not reloaded
+    reloadTimer -= PHYSICS_TICK_MS;
+    if(reloadTimer < 0)
+        reloadTimer = 0;
+
+    // Add gravity to the force queue
+    forceq.push(world.gravity);
+    
+    // Go trough every force in the queue
+    Force total;
+    while (!forceq.empty()) {
+        total += forceq.front();
+        forceq.pop();
+    }
+
+    // If the player has stopped and there's some ground under some of the 3 some of the 3t
+    // set inAir false
+    if (this->velocity == Vector(0,0)) {
+        this->inAir = !world.collides(this->position+shape[1]+Vector(0, 1))
+                      && !world.collides(this->position+shape[2]+Vector(0, 1))
+                      && !world.collides(this->position+shape[3]+Vector(0, 1));
+        // If, however, there's a force caused by a bomb, e.g., set it in air.
+        // Still, we have to be able to separate forces caused by walking attempts
+        // and bombs etc (+0.1 because float comparison can be dangerous)
+        if (total.y < 0 || abs(total.x) > PLAYER_MOVE_FORCE + 0.1)
+            this->inAir = true;
+    }
+
+    if(!possibleLocation(position)) {
+        //if we are trapped in ground form dirtball or something
+        //we might want to just return and set velocity to some value
+        //return;
+    }
+
+    // If the worm is not in the air make it walk,
+    // otherwise integrate the new position and velocity
+    if (!this->inAir) {
+        //std::cout << "Tryin to walk" << std::endl;
+        // It walks only if there's some vertical force
+        if (total.x != 0) {
+            std::cout << "Succeeding to walk" << std::endl;
+            this->position = walk(PHYSICS_TICK_MS, total.x > 0);
+            this->velocity = Vector(0,0);
+        }
+    }
+
+    if(!possibleLocation(position)) {
+        Engine::log(DEBUG, "great failure") << "great failure";
+        func1();
+    }
+    Vector newPosition;
+    Vector velAfterTick;
+    // Calculate new position and velocity to the given references
+    integrate(total, PHYSICS_TICK_MS, newPosition, velAfterTick);
+    this->velocity = velAfterTick;
+
+   
+    // Collision detection
+    bool collided = false;
+   
+    const Vector diffVec = newPosition-position;
+    const Vector unitVector = diffVec / diffVec.length();
+    Vector reached = position;
+
+    while ((position-reached).sqrLength() < diffVec.sqrLength()) {
+        reached += unitVector;
+        // Check if any of the shapes points collide
+        for (uint64_t i = 0; i < shape.size(); i++) {
+            if (world.collides(reached+shape[i])) {  // Collision
+                if (inAir) {
+                    //                    Engine::log(DEBUG, "Here");
+                    this->bounce(world.getNormal(reached+shape[i], 
+                                                 reached-unitVector+shape[i]));
+                    //this->velocity *= COLLISION_ELASTICITY;
+                }
+                reached = reached - unitVector; // Return to last point
+                collided = true;
+                if (this->velocity.sqrLength() < PLAYER_MIN_SPEED * PLAYER_MIN_SPEED) {
+                    this->velocity = Vector(0,0);
+                }
+                break;
+            }
+        }
+        if (collided)
+            break;
+//        reached += unitVector;
+    }
+   
+    
+    if(!possibleLocation(reached)) {
+        Engine::log(DEBUG, "PhysicsObject.updatePosition") << "logic error reached should not be possible to be impossible.. diffVec: " << diffVec;
+        func1();
+    }
+
+    // In case of some float error check the final coordinate
+    if(!collided) {
+        if(!possibleLocation(newPosition)) {
+            newPosition = reached;
+        } else {
+            // This means everything was ok, so no need to do anything
+        }
+    } else {
+        newPosition = reached;
+        onCollision();
+        //this->velocity = Vector(0, 0);
+        //TODO: it shouldn't just stop on collision
+    }
+    if(!possibleLocation(newPosition)) {
+        Engine::log(DEBUG, "great failure") << "great failure";
+        func1();
+    }
+    this->position = newPosition;
+    if(!possibleLocation(position)) {
+        Engine::log(DEBUG, "great failure") << "great failure";
+        func1();
+    }
+//    Engine::log(DEBUG, "PhysicsObject.updatePosition") << "Pos: " << this->position;
+}
+
+/**
+ * Bounces from straight wall in any direction.
+ * Direction given as normal of that wall
+ */
+void PhysicsObject::bounce (Vector normal) {
+    // normal.sqrLength can't be 0 when got from getNormal()
+    if (normal.sqrLength() != 0) {
+        Vector nvel = velocity;
+        // We project the velocity on normal and remove twice that much from velocity
+        nvel = nvel - ((2)*((nvel*normal)/(normal*normal))*normal);
+        velocity = nvel;
+        // We lose some of our speed on collision
+        this->velocity *= this->collision_elasticity;
+    }
+}
+
+/**
+ * Integrates given force over time and stores new position to
+ * posAfterTick and new velocity to velAfterTick.
+ * @param force Force vector.
+ * @param dt The time the force is applied (<=PHYSICS_TICK_MS)
+ */
+void PhysicsObject::integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick) {
+    posAfterTick = position;
+    velAfterTick = velocity;
+    Derivative tmpd;
+    Derivative k1 = evaluate(force, 0, tmpd, posAfterTick, velAfterTick);
+    Derivative k2 = evaluate(force, 0.5f*dt, k1, posAfterTick, velAfterTick);
+    Derivative k3 = evaluate(force, 0.5f*dt, k2, posAfterTick, velAfterTick);
+    Derivative k4 = evaluate(force, dt, k3, posAfterTick, velAfterTick);
+    
+
+    const Vector dxdt = (k1.dx + (k2.dx + k3.dx) * 2.0f + k4.dx) * 1.0f/6.0f;
+    const Vector dvdt = (k1.dv + (k2.dv + k3.dv) * 2.0f + k4.dv) * 1.0f/6.0f;
+    
+    //    Engine::log(DEBUG, "PhysicsObject.integrate") << "Changes: "<< dxdt << " " << dvdt << " Time: " <<dt;
+    posAfterTick = posAfterTick + (dxdt * dt)/1000;
+    velAfterTick = velAfterTick + (dvdt * dt)/1000;
+    //Engine::log(DEBUG, "PhysicsObject.integrate") << "velAfterTick: " << velAfterTick;
+}
+
+Derivative PhysicsObject::evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick) {
+    Vector curPos = posAfterTick + (d.dx*dt)/1000;
+    Vector curVel = velAfterTick + (d.dv*dt)/1000;
+
+    Derivative out;
+    out.dx = curVel;
+    out.dv = acceleration(force);
+    //Engine::log(DEBUG, "PhysicsObject.evaluate") << "Out.dx: " << out.dx;
+    return out;
+}
+
+Vector PhysicsObject::acceleration(const Force &force) {
+    return (force/mass);
+}
+
+void PhysicsObject::applyForce (Force force) {
+    // Add applied force to the queue
+    forceq.push(force);
+}
+
+void PhysicsObject::changeAim(float da) {
+    this->aim += da;
+
+    if (this->aim > PLAYER_AIM_MAX) this->aim = PLAYER_AIM_MAX;
+    if (this->aim < PLAYER_AIM_MIN) this->aim = PLAYER_AIM_MIN;
+    //Engine::log(DEBUG, "PhysicsObject.changeAim") << "Player aim: " << this->aim;
+}
+
+void PhysicsObject::setFacing(bool facingRight) {
+    //Engine::log(DEBUG, "PhysicsObject.setFacing") << "Facing: " << right;
+    this->facingRight = facingRight;
+}
+
+void PhysicsObject::updatePhysics (Vector position, Vector velocity, bool inAir) {
+    this->position = position;
+    this->velocity = velocity;
+    this->inAir = inAir;
+}
+    
+Vector PhysicsObject::getPosition () {
+    return this->position;
+}
+
+bool PhysicsObject::getFacing() {
+    return this->facingRight;
+}
+
+float PhysicsObject::getAim() {
+    return this->aim;
+}
+
+std::vector<Vector>& PhysicsObject::getShape () {
+    return this->shape;
+}
+
+void PhysicsObject::setShape (std::vector<Vector> shape) {
+    this->shape = shape;
+}
+
+void PhysicsObject::tick () {
+    this->updatePosition();
+}
+
+bool PhysicsObject::canShoot() {
+    return this->reloadTimer <= 0;
+}
+
+void PhysicsObject::draw(CL_GraphicContext *gc) {
+    CL_Quad player(
+                   (position+shape[0]).x, (position+shape[0]).y,
+                   (position+shape[1]).x, (position+shape[1]).y,
+                   (position+shape[2]).x, (position+shape[2]).y,
+                   (position+shape[3]).x, (position+shape[3]).y
+                   );
+    
+    gc->fill_quad(player, CL_Color::green);
+    
+    const uint16_t chlen = 10;
+    uint16_t x = player.center().x;
+    uint16_t y = player.center().y;
+    if (facingRight) {
+        gc->draw_line(x, y,
+                      x + std::cos(aim)*chlen,
+                      y - std::sin(aim)*chlen,
+                      CL_Color::black);
+    } else {
+        gc->draw_line(x, y,
+                      x - std::cos(aim)*chlen,
+                      y - std::sin(aim)*chlen,
+                      CL_Color::black);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Physics.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,297 @@
+#ifndef PHYSICS_HH
+#define PHYSICS_HH
+
+#include <vector>
+#include <queue>
+#include <list>
+#include <ClanLib/core.h>
+#include <ClanLib/display.h>
+
+#include "Vector.hh"
+#include "Config.hh"
+#include "Terrain.hh"
+
+// Forward declares
+class PhysicsWorld;
+class PhysicsObject;
+class PlayerObject;
+class ProjectileObject;
+class Shape;
+struct Derivative;
+
+// Type definitions
+typedef uint16_t TimeMS;
+typedef Vector Force;
+
+/**
+ * PhysicsWorld class. PhysicsWorld contains PhysicsObjects that are
+ * simulated in the PhysicsWorld.
+ */
+class PhysicsWorld : public Terrain {
+    friend class PhysicsObject;
+
+private:
+    CL_Timer tick_timer;
+    uint32_t tick_counter;
+
+    //    Terrain terrain;
+
+protected:
+    std::list<PhysicsObject*> players;
+    std::list<PhysicsObject*> projectiles;
+//    std::vector<PhysicsObject*> objects;
+
+    // Contains connections between signals and slots
+    CL_SlotContainer slots;
+
+    PhysicsWorld(Vector gravity, Vector dimensions);
+
+    // TODO: Should these be somewhere else?
+    Vector dimensions;
+    Vector gravity;
+
+
+
+public:
+    // TODO: Replace addObject with these?
+    //void addPlayerObject(PlayerObject *object);
+    //void addProjectileObject(ProjectileObject *object);
+    
+    /**
+     * Add object to the PhysicsWorld.
+     *
+     * @param object Pointer to the PhysicsObject to add.
+     */
+    void addPlayerObject(PhysicsObject *object);
+    
+    void addProjectile(PhysicsObject *projectile);
+
+    /**
+     * Advance one time step in physics simulation.
+     */
+    void tick();
+
+    /**
+     * Get current tick in physics simulation.
+     *
+     * @return tick Current simulation tick.
+     */
+    uint32_t getTick();
+
+    virtual void draw(CL_GraphicContext *gc);
+
+    // TODO This should probably be protected or in GameStat or in GameStatee
+};
+
+/**
+ * PhysicObject class. A basic PhysicsObject class.
+ */
+class PhysicsObject {
+protected:
+    // This probably shouldn't be done this way.
+    PhysicsWorld &world;
+
+    Vector position;
+    Vector velocity;
+    float mass;
+    bool inAir; // Is the object "on the ground"
+    float collision_elasticity;
+
+    // Attributes for players
+    float aim; // Aim direction (half circle)
+    bool facingRight; // Player facing
+
+    //
+    int reloadTimer;
+
+    PhysicsObject(PhysicsWorld &world, float mass, Vector position, 
+                  Vector velocity);
+    ~PhysicsObject() {}
+
+
+    /**
+     * Add force to the force queue to be applied on next tick.
+     *
+     * @param force Force vector
+     */
+    void applyForce(Force force);
+
+    /**
+     * Change player aim
+     *
+     * @param da Aim angle change
+     */
+    void changeAim(float da);
+   
+    /**
+     * Set player facing.
+     *
+     * @param facingRight True if player is facing right.
+     */
+    void setFacing(bool facingRight);
+
+    /**
+     * Makes the player jump in the air.
+     * @param direction -1: jump left, 0: jump up, 1: jump right
+     */
+    void jump(int direction);
+
+    /** 
+     * Handle ground-bounce
+     *
+     * @param normal Normal vector relative to which to bounce
+     */
+    void bounce(Vector normal);
+
+    /**
+     * Called on network clients to sync state from server
+     *
+     * @param position New position
+     * @param velocity New velocity
+     * @param inAir New inAir value
+     */
+    void updatePhysics(Vector position, Vector velocity, bool inAir);
+
+private:
+    // TODO: I'd be tempted to use some already made ClanLib structure
+    // here.  
+    // Shape of the object. Edge points of the shape polygon.
+    std::vector<Vector> shape;
+
+    // TODO: Should these operations be moved to PhysicsWorld?
+    // Force queue that is emptied on every tick
+    std::queue<Force> forceq;
+
+    /**
+     * Handle player movement and apply forces.
+     */
+    void updatePosition();
+
+    // TODO: Should these be moved to PhysicsWorld?
+    /**
+     * Use RK4 to integrate the effects of force over a time interwall.
+     *
+     * @param force Force to integrate
+     * @param dt Time intervall
+     */
+    void integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick);
+
+    /**
+     * Evaluate the value of the derivative at given time
+     *
+     * @param force Force
+     * @param dt Time
+     * @param d Previous derivative
+     */
+    Derivative evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick);
+
+    /**
+     * Return object acceleration with given force.
+     *
+     * @param force Force
+     * @return Acceleration
+     */
+    Vector acceleration(const Force &force);
+
+    // TODO: If integration is moved to PhysicsWorld then this should
+    // also move there.
+    /**
+     * Handle ground movement.
+     *
+     * @param right Boolean describing the movement direction.
+     * @return New position
+     */
+    Vector walk(TimeMS, bool right);
+
+    /*
+     * Handle collision. TODO: This is not used. It probably should
+     * be?
+     */
+    virtual void onCollision() {}
+
+    /*
+     * TODO: This probably does some kind of collision
+     * detection. Could be named/documented better.
+     */
+    bool possibleLocation(Vector loc);
+
+public:
+    /**
+     * Get current object position.
+     *
+     * @return Position vector
+     */
+    Vector getPosition();
+
+    /**
+     * Return object shape.
+     *
+     * @return Polygon points
+     */
+    std::vector<Vector>& getShape();
+
+    /**
+     * Set object shape.
+     *
+     * @param shape Vector containing polygon poinst
+     */
+    void setShape(std::vector<Vector> shape);
+
+    /**
+     * Return object facing.
+     *
+     * @return Object facing (true if facing right)
+     */
+    bool getFacing();
+
+    /**
+     * Return object aim angle.
+     *
+     * @return Object aim angle
+     */
+    float getAim();
+
+    /**
+     * Update object in physics simulation.
+     */
+    void tick();
+
+    /**
+     * @return whether this PhysicsObject can shoot or not
+     * This is in PhysicsObject for larpa-like shots
+     */
+    bool canShoot();
+
+    /**
+     * Draw object
+     *
+     * @param gc CL_GraphicContext
+     */
+    virtual void draw(CL_GraphicContext *gc);
+};
+
+// TODO: This could probably be moved somewhere else or removed
+// completely.
+struct Derivative {
+    Vector dx; // Velocity
+    Vector dv; // Acceleration
+};
+
+
+// TODO: These are drafts
+/**
+ * PlayerObject class. Represents a player in the physics engine.
+ */
+//class PlayerObject : public PhysicsObject {
+
+//};
+
+/**
+ * ProjectileObject class. Represents different projectiles in the
+ * physics (i.e. not players) in the physics engine.
+ */
+//class ProjectileObject : public PhysicsObject {
+
+//};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SinglePlayer.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,11 @@
+#ifndef SINGLE_PLAYER_HH
+#define SINGLE_PLAYER_HH
+
+#include "GameState.hh"
+
+class SinglePlayer : public LocalPlayer {
+    public:
+        SinglePlayer (GameState &state) : LocalPlayer(state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true) { }
+};
+
+#endif /* SINGLE_PLAYER_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Terrain.cc	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,283 @@
+#include "Terrain.hh"
+#include "Engine.hh"
+
+#include <cmath>
+#include <cassert>
+#include <algorithm>
+#include <ClanLib/display.h>
+
+Terrain::Terrain() {}
+Terrain::Terrain(const int &seed) 
+    : terrain(MAP_WIDTH, std::vector<TerrainType>(MAP_HEIGHT, DIRT)){
+    this->generateTerrain(seed);
+}
+Terrain::Terrain(const Terrain &t) {
+    this->terrain = t.getTerrain();
+    this->generatePixelBuffer();
+}
+
+void Terrain::generatePixelBuffer() {
+    this->pixbuf = CL_PixelBuffer(MAP_WIDTH, MAP_HEIGHT, 4*MAP_WIDTH, 
+                                  CL_PixelFormat::rgba8888);
+
+    CL_Color color;
+    for (uint16_t i = 0; i < MAP_WIDTH; i++) {
+        for (uint16_t j = 0; j < MAP_HEIGHT; j++) {
+            switch(terrain[i][j]) {
+            case EMPTY:
+                color = COLOR_EMPTY;
+                break;
+            case DIRT:
+                color = COLOR_DIRT;
+                break;
+            case ROCK:
+                color = COLOR_ROCK;
+                break;
+            default: // TODO: Shouldn't be here.
+                break; 
+            }
+            this->pixbuf.draw_pixel(i, j, color);
+        }
+    }
+}
+
+Vector Terrain::getPixelLocation(Vector point) const{
+    return Vector(scale(point.x), 
+                  scale(point.y));
+}
+
+uint16_t Terrain::scale(float x) const {
+    return (uint16_t)(x/MAP_SCALE);
+}
+
+TerrainType Terrain::getType(int32_t x, int32_t y) const {
+    if ((x < 0) || (y < 0) ||(x >= MAP_WIDTH) || (y >= MAP_HEIGHT)) {
+        return ROCK;
+    }
+    return terrain[x][y];
+}
+TerrainType Terrain::getType(Vector point) const {
+    return getType((int32_t)point.x, (int32_t)point.y);
+}
+
+bool Terrain::collides(const Vector &point) const {
+    Vector coor = getPixelLocation(point);
+    return (getType(coor.x, coor.y) != EMPTY);
+}
+
+bool Terrain::collides(const Vector &begin, const Vector &end) const {
+    // TODO: Maybe we should have another function prototype that also
+    // returns the point where we collided.
+
+    // We'll use Bresenhams line algorithm to go trough all the
+    // "pixels" of the line.
+    Vector b = getPixelLocation(begin);
+    Vector e = getPixelLocation(end);
+
+    bool steep = (abs(e.y - b.y) > abs(e.x - b.x)); // k > 1
+    if (steep) { // Line is steep -> swap x and y coordinates
+        std::swap(b.x, b.y);
+        std::swap(e.x, e.y);
+    }
+    if (b.x > e.x) { // Line goes down -> make it go up
+        std::swap(b, e);
+    }
+    uint16_t dx = e.x - b.x;
+    uint16_t dy = abs(e.y - b.y);
+    int32_t err = dx/2;
+    uint16_t ystep;
+    uint16_t y = b.y;
+    // Is the line ascending or descending
+    if (b.y < e.y) ystep = 1;
+    else ystep = -1;
+    // Go trough the line
+    for (uint16_t x =  b.x; x <= e.x; x++) {
+        if (steep) { // X and Y coordinates must be switched if steep
+            if (getType(y,x) != EMPTY) { // Collision!
+                return true;
+            }
+        } else {
+            if (getType(x,y) != EMPTY) { // Collision!
+                return true;
+            }
+        }
+        err = err - dy;
+        if (err < 0) { // Check if we want to make an ystep
+            y = y + ystep;
+            err = err + dx;
+        }
+    }
+    return false; // No Collision
+}
+
+void Terrain::removeGround(const Vector &pos, const float &radius) {
+    // TODO: Implement. Some circle algoritmh should be usefull here,
+    // though the current impelementation doesn't seem too bad either.
+
+    Vector mid = getPixelLocation(pos);
+    uint16_t r = scale(radius);
+    for (uint16_t i = mid.x-r; i < mid.x+r; i++) {
+        for (uint16_t j = mid.y-r; j < mid.y+r; j++) {
+            if (getType(i, j) != ROCK) { // getType returns ROCK if
+                                         // out of bounds
+                if ((i-mid.x)*(i-mid.x)+(j-mid.y)*(j-mid.y) < r*r) {
+                    terrain[i][j] = EMPTY;
+                    pixbuf.draw_pixel(i, j, COLOR_EMPTY);
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Gets the index of the given coordinate direction
+ * referring to the DIRECTIONS table in Physics.hh
+ */
+int getDirectionIndex (Vector direction) {
+    Vector dir = direction.roundToInt();
+    if(dir.x == 0 && dir.y == -1) {
+        return 0;
+    } else if(dir.x == 1 && dir.y == -1) {
+        return 1;
+    } else if(dir.x == 1 && dir.y == 0) {
+        return 2;
+    } else if(dir.x == 1 && dir.y == 1) {
+        return 3;
+    } else if(dir.x == 0 && dir.y == 1) {
+        return 4;
+    } else if(dir.x == -1 && dir.y == 1) {
+        return 5;
+    } else if(dir.x == -1 && dir.y == 0) {
+        return 6;
+    } else if(dir.x == -1 && dir.y == -1) {
+        return 7;
+    }
+    Engine::log(DEBUG, "Terrain.getDirectionIndex ") << "invalid direction: " << direction;
+    return 0;
+}
+
+/**
+ * point should be ground and prevPoint air, but it's easy to assure that
+ * @param point - pixel on ground to which was collided
+ * @param prevPoint - pixel where we are when we collide
+ */
+Vector Terrain::getNormal(Vector point, Vector prevPoint) const {
+    Vector p = getPixelLocation(point);
+
+    assert(point != prevPoint);
+
+    Vector normal(0,0);
+
+    // These two must be rounded separately
+    int dirIdx = getDirectionIndex(prevPoint.roundToInt() - point.roundToInt());
+//    dirIdx = (dirIdx+4)%8;
+
+    std::cout << (prevPoint.roundToInt()) - (point.roundToInt()) << prevPoint-point << std::endl;
+
+    normal += DIRECTIONS[dirIdx];
+    for(int i = 1; i <= 2; i++) {
+        if(getType(point + DIRECTIONS[(dirIdx+i+8)%8]) == EMPTY) {
+            normal += DIRECTIONS[(dirIdx+i+8)%8];
+        }
+    }
+    for(int i = 1; i <= 2; i++) {
+        if(getType(point + DIRECTIONS[(dirIdx-i+8)%8]) == EMPTY) {
+            normal += DIRECTIONS[(dirIdx-i+8)%8];
+        }
+    }
+
+    Engine::log(DEBUG, "Physics.getNormal ") << "normal: " << normal << "   dirIdx: " << dirIdx;
+
+    if(getType(point) == EMPTY || getType(prevPoint) != EMPTY) {
+        Engine::log(DEBUG, "Physics.getNormal ") << "logic ground error";
+    }
+    
+
+//    for (int i = 0; i < 8; i++) {
+//        if (getType(p.x+DIRECTIONS[i].x, p.y+DIRECTIONS[i].y) == EMPTY) {
+//            normal += DIRECTIONS[i];
+//        }
+//    }
+
+   
+    // Special cases
+    /*    Vector tmp = direction(direction(prevPoint-point) + direction(normal));
+    Engine::log(DEBUG, "Terrain.getNormal") << "tmp: " << tmp;
+    if (normal.length() == 0 || (tmp.x != 0 && tmp.y != 0 && getType(tmp.x, tmp.y) != EMPTY)) 
+        normal = prevPoint - point; // Direct hit
+    */
+//    Engine::log(DEBUG, "Terrain.getNormal") << "Normal: " << normal;
+    return normal;
+    return Vector(0,-1);
+}
+
+Vector direction(const Vector &v) {
+    Vector tmp(v);
+    if (tmp.length() > 0) tmp /= tmp.length();
+    tmp.x = (uint16_t)(tmp.x);
+    tmp.y = (uint16_t)(tmp.y);
+    return tmp;
+}
+
+// TODO: This could better :)
+// TODO: And this need some cleaning :)
+void Terrain::generateTerrain(int seed) {
+    srand(seed); // Set random number generator seed.
+
+    // Some constants to control random generation
+    const int min_range = 25;
+    const int max_range = 80;
+    const int num = 50;
+    const int rock_rarity = 4;
+
+    // Generate circles (or whatever)
+    for (int i = 0; i < num; i++) {
+        // Random generate circle attributes
+        int midx = rand()%MAP_WIDTH;
+        int midy = rand()%MAP_HEIGHT;
+        int range = rand()%(max_range-min_range)+min_range;
+
+        // Make sure that there's a circle in the midle of the cave
+        if (i == 0) {
+            midx = MAP_WIDTH/2;
+            midy = MAP_WIDTH/2;
+            range = 150;
+        }
+
+        TerrainType type = EMPTY;
+        if (rand()%rock_rarity == 0) {
+            type = ROCK;
+        }
+
+        // Loops for every pixel of the cirlcle (or square as it seems
+        // now)
+        for (int x = std::max(0, midx-range); 
+             x < std::min((int32_t)MAP_WIDTH, midx+range); 
+             x++) {
+            for (int y = std::max(0, midy-range);
+                    y < std::min((int32_t)MAP_HEIGHT, midy+range);
+                    y++) {
+                
+                //terrain[x][y] = type;
+
+                if ((x-midx)*(x-midx)+(y-midy)*(y-midy) < range*range) {
+                    terrain[x][y] = type;
+                }
+            }
+            
+        } 
+        
+    }
+    
+    this->generatePixelBuffer();
+}
+
+void Terrain::draw(CL_GraphicContext *gc) {
+    CL_Surface surf(this->pixbuf);
+    surf.draw(0,0,gc);
+}
+
+std::vector<std::vector<TerrainType> > Terrain::getTerrain() const {
+    return terrain;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Terrain.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,169 @@
+#ifndef TERRAIN_HH
+#define TERRAIN_HH
+
+#include <vector>
+
+#include "Vector.hh"
+#include "Config.hh"
+
+enum TerrainType {EMPTY, DIRT, ROCK};
+
+const Vector DIRECTIONS[] = {
+    Vector(0,-1),
+    Vector(1,-1),
+    Vector(1,0),
+    Vector(1,1),
+    Vector(0,1),
+    Vector(-1,1),
+    Vector(-1,0),
+    Vector(-1,-1)
+};
+
+/**
+ * Terrain class. Represents game terrain and contains member
+ * functions to manipulate terrain and get info about it.
+ * 
+ * Terrain resolution is a constant that is defined in
+ * configuration. Terrain has a scale (i.e. the width and height in
+ * "real" units. Scaling is needed because physics simulation uses
+ * "real" units. The idea is that this class is used with "real" units
+ * and it uses pixelcoordinates internally.
+ */ 
+class Terrain {
+private:
+    std::vector<std::vector<TerrainType> > terrain;
+
+    // Terrain graphic
+    CL_PixelBuffer pixbuf;
+
+    /**
+     * Generates pixelbuffer from terrain. Should be used only on
+     * constructors because this is expected to be slow.
+     */
+    void generatePixelBuffer();
+
+    /**
+     * Get pixel location of a point that is in "real" units.
+     *
+     * @param point Point in "real" units
+     * @return Int vector
+     */
+    Vector getPixelLocation(Vector point) const;
+
+    /**
+     * Scale parameter to "pixels"
+     *
+     * @param x Scaled value
+     * @return Corresponding value in pixels
+     */
+    uint16_t scale(float x) const;
+
+ public:
+
+    // TODO: This should be private.
+    /**
+     * Return the type of terrain at given position. Returns ROCK if
+     * given point is not inside terrain area.
+     *
+     * @param x X coordinate
+     * @param y Y coordinate
+     * @return Terrain type
+     */
+    TerrainType getType(int32_t x, int32_t y) const;
+    //point is just rounded and redirected to that above
+    TerrainType getType(Vector point) const;
+
+    /**
+     * Constructor.
+     *
+     * @param scale The "real" width and height of the terrain.
+     */
+    Terrain();
+    /**
+     * Constructor.
+     *
+     * @param scale The "real" width and height of the terrain.
+     * @param seed Random number generator seed used to create the
+     * terrain.
+     */
+    Terrain(const int &seed);
+    /**
+     * Copy constructor.
+     *
+     * @param t Terrain to be copied.
+     */
+    Terrain(const Terrain &t);
+    /**
+     * Destructor
+     */
+    ~Terrain() {}
+
+    /**
+     * Check if given point has some terrain.
+     *
+     * @param point Point that is in scaled units.
+     */
+    bool collides(const Vector &point) const;
+    /**
+     * Check if given line collides with terrain.
+     *
+     * @param begin Line begin point in scaled units.
+     * @param end Line end point in scaled units.
+     */
+    bool collides(const Vector &begin, const Vector &end) const;
+    
+    /**
+     * Remove a circular area from terrain.
+     *
+     * @param pos Circle center
+     * @param r Circle radius
+     */ 
+    void removeGround(const Vector &pos, const float &r);
+
+    /**
+     * Return normal for the given point.
+     *
+     * @param point Point for which the normal is calculated.
+     * @return Normal vector ((0,0) if there's no terrain)
+     */
+    Vector getNormal(Vector point, Vector prevPoint) const;
+
+    /**
+     * Generate random terrain.
+     *
+     * @param seed Seed for the randomnumber generator.
+     */
+    void generateTerrain(int seed);
+
+    /**
+     * Draw the terrain for given graphicscontext.
+     *
+     * @param gc CL_GraphicContext
+     */
+    virtual void draw(CL_GraphicContext *gc);
+    /**
+     * Draw part of the terrain for given graphiscontext.
+     *
+     * @param gc CL_GraphicContext
+     * @param center Center of the rectangle drawn.
+     * @param dimension Dimensions of the rectangle.
+     */
+    //void draw(CL_GraphicContext &gc, Vector center, Vector dimensions);
+
+    /**
+     * Set terrain.
+     *
+     * @param terrain Terrain.
+     */
+    void setTerrain(const std::vector<std::vector<TerrainType> > &terrain);
+    /**
+     * Get terrain.
+     *
+     * @return Terrain.
+     */
+    std::vector<std::vector<TerrainType> > getTerrain() const;
+};
+
+Vector direction(const Vector &v);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Vector.hh	Wed Dec 03 19:16:32 2008 +0000
@@ -0,0 +1,106 @@
+#ifndef VECTOR_HH
+#define VECTOR_HH
+
+#include <iostream>
+#include <cmath>
+
+/**
+ * A 2D Vector class. Implements standard vector operations.
+ */
+template <typename T>
+class _Vector {
+public:
+    T x;
+    T y;
+
+    /**
+     * Default constructor.
+     */
+    _Vector() : x(0), y(0) {}
+    
+    /**
+     * Constuctor.
+     *
+     * @param x Initial x-coordinate
+     * @param y Initial y-coordinate
+     */
+    _Vector(T x, T y) : x(x), y(y) {}
+
+    /**
+     * Copy constructor.
+     *
+     * @param v Vector to be copied.
+     */
+    _Vector(const _Vector &v) : x(v.x), y(v.y) {}
+
+    // Operator declarations
+    void operator=(const _Vector &v) {
+        this->x = v.x;
+        this->y = v.y;
+    }
+    _Vector operator+(const _Vector &v) const {
+        return _Vector(this->x+v.x, this->y+v.y);
+    }
+    _Vector operator-(const _Vector &v) const {
+        return _Vector(this->x-v.x, this->y-v.y);
+    }
+    _Vector operator*(const T &scalar) const {
+        return _Vector(this->x*scalar, this->y*scalar);
+    }
+    T operator*(const _Vector &v) const {
+        return (this->x*v.x + this->y*v.y);
+    }
+    _Vector operator/(const T &d) const {
+        return _Vector(this->x/d, this->y/d);
+    }
+    void operator+=(const _Vector &v) {
+        *this = *this + v;
+    }
+    void operator-=(const _Vector &v) {
+        *this = *this - v;
+    }
+    void operator*=(const T &scalar) {
+        *this = *this * scalar;
+    }
+    void operator/=(const T &scalar) {
+        *this = *this / scalar;
+    }
+
+    // Other operations
+    T length() const {
+        return sqrt(sqrLength());
+    }
+    T sqrLength() const {
+        return (this->x * this->x) + (this->y * this->y);
+    }
+    _Vector roundToInt() const {
+        return _Vector((int)(x), (int)(y));
+    }
+};
+
+// Unary operators
+template<typename T>
+_Vector<T> operator*(const T &scalar, const _Vector<T> v) {
+    return (v * scalar);
+} 
+
+// Comparison operators
+template<typename T>
+bool operator==(const _Vector<T> &v1, const _Vector<T> &v2) {
+    return ((v1.x == v2.x) && (v1.y == v2.y));
+}
+template<typename T>
+bool operator!=(const _Vector<T> &v1, const _Vector<T> &v2) {
+    return !(v1 == v2);
+}
+
+// Output operator
+template<typename T>
+std::ostream& operator<<(std::ostream &s, const _Vector<T> &v) {
+    return s<<"("<<v.x<<", "<<v.y<<")";
+}
+
+// Standard vector
+typedef _Vector<float> Vector;
+
+#endif
--- a/src/proto2/Application.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-
-#include "Engine.hh"
-#include "Error.hh"
-
-#include <stdexcept>
-#include <cassert>
-
-#include <ClanLib/core.h>
-#include <ClanLib/application.h>
-
-class ArgumentError : public Error {
-    public:
-        ArgumentError (const std::string &message) : Error(message) { }
-};
-
-class Main : public CL_ClanApplication {
-    private:
-        // arguments
-        CL_CommandLine args;
-        
-        bool arg_graphics;
-        std::string arg_port;
-        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('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_server = false;
-            arg_connect = "";
-            
-            try {
-                // parse args
-                args.parse_args(argc, argv);
-
-            } catch (CL_Error &e) {
-                throw ArgumentError(e.message);
-            }
-
-            while (args.next()) {
-                switch (args.get_key()) {
-                    case 'p':
-                        arg_port = args.get_argument();
-                        break;
-
-                    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:
-                        throw ArgumentError(args.get_argument());
-
-                    default:
-                        throw ArgumentError(std::string(1, (char) args.get_key()));
-
-                }
-            }
-            
-            // check for invalid combinations of arugments
-            if (arg_server and !arg_connect.empty())
-                throw ArgumentError("cannot be both server and client");
-        }
-
-    public:
-        virtual int main (int argc, char **argv) {
-            // 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;
-                
-                // setup graphics
-                if (arg_graphics)
-                    engine.setupGraphics();
-
-                // setup either network server, client or singleplayer
-                if (arg_server) {
-                    engine.setupNetworkServer(arg_port);
-
-                } else if (!arg_connect.empty()) {
-                    engine.setupNetworkClient(arg_connect, arg_port);
-                
-                } else {
-                    engine.setupSinglePlayer();
-                }
-
-                // run the main loop
-                engine.run();
-                
-                // succesful return
-                return 0;
-            
-            } catch (ArgumentError &e) {
-                std::cerr << e.what() << std::endl;
-                args.print_help();
-
-                // XXX: handle --help
-                return 1;
-            } catch (CL_Error &e) {
-                std::cerr << "main: CL_Error:" << e.message << std::endl;
-
-                return 1;
-
-            } catch (std::exception &e) {
-                std::cerr << "FATAL [uncaught_exception] " << e.what() << std::endl;
-
-                return 1;
-            }
-        }
-} app;
-
--- a/src/proto2/CMakeLists.txt	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-FILE(GLOB SOURCE_FILES "*.cc")
-FILE(GLOB HEADER_FILES "*.hh")
-
-set(SOURCES ${SOURCE_FILES} ${HEADER_FILES})
-
-# Generate config.h
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
-include_directories("${CMAKE_CURRENT_BINARY_DIR}")
-
-# Libraries
-
-# ClanLib 0.8
-find_package(ClanLib 0.8 REQUIRED COMPONENTS Core App Signals Display GL Sound Network)
-include_directories(${ClanLib_INCLUDE_DIRS})
-set(LIBS ${LIBS} ${ClanLib_LIBRARIES})
-
-message("DEBUG: ${LIBS}")
-
-# Assumes the project generates only one executable. If you need more, you'll need to alter
-# the script and replace ${PROJECT_SHORT_NAME} by executable name.
-add_executable("${PROJECT_SHORT_NAME}-p2" ${SOURCES})
-target_link_libraries("${PROJECT_SHORT_NAME}-p2" ${LIBS})
-install(TARGETS "${PROJECT_SHORT_NAME}-p2" DESTINATION bin)
-
-
--- a/src/proto2/Config.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#ifndef CONFIG_HH
-#define CONFIG_HH
-
-#include <ClanLib/display.h>
-
-// This is a temporary way to declare different constants. Maybe we
-// should do somekind of resource manager? Do we have time?
-
-// Mathematical constants
-const float KG_PI = 3.14159265;
-
-// Physics simulation
-// Physics resolution
-const uint16_t MAP_WIDTH = 800;
-const uint16_t MAP_HEIGHT = 600;
-const float MAP_SCALE = 1; // One "pixel" in "real" units
-// Simulation
-const uint16_t PHYSICS_TICK_MS = 10;
-
-// Constants affecting physics
-const float MAP_GRAVITY = 1200.0;
-const float PLAYER_COLLISION_ELASTICITY = 0.3; // TODO: This could be
-                                        // different for different
-                                        // objects
-
-// Player properties
-const float PLAYER_MASS = 10.0;
-const float PLAYER_MOVE_FORCE = 5000.0;
-const float PLAYER_MIN_SPEED = 30.0;
-const float PLAYER_JUMP_MIN_DISTANCE = 5.0;
-const float PLAYER_AIM_MIN = -KG_PI/4; 
-const float PLAYER_AIM_MAX = KG_PI/2;
-const float PLAYER_INITIAL_X = 400.0;
-const float PLAYER_INITIAL_Y = 300.0;
-const float CROSSHAIR_ANGLE_SPEED = PI/40;
-
-const float PLAYER_MAX_SPEED = 70;
-
-// Graphical properties
-const CL_Color COLOR_EMPTY(86, 41, 0);
-const CL_Color COLOR_DIRT(144, 82, 23);
-const CL_Color COLOR_ROCK(132, 136, 135);
-
-#endif
--- a/src/proto2/Engine.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-
-#include "Engine.hh"
-#include "NetworkServer.hh"
-#include "NetworkClient.hh"
-#include "SinglePlayer.hh"
-
-#include <iostream>
-
-Engine::Engine (void) : is_running(true) {
-
-}
-
-void Engine::setupGraphics (void) {
-    // create the graphics
-    graphics = new Graphics(*this, game_state);
-}
-
-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);
-
-    // create the client
-    net_client = new NetworkClient(game_state, connect_addr);
-}
-
-void Engine::setupSinglePlayer (void) {
-    // create player directly
- 	LocalPlayer* lp = new SinglePlayer(game_state);
-
-    // add to gamestate
-	game_state.newLocalPlayer(lp);
-}
-
-void Engine::stop (void) {
-    is_running = false;
-}
-
-void Engine::run (void) {
-    while (is_running) {
-        // this does.... magical things
-        CL_System::keep_alive();
-
-        // if I can't find some better way to do this in ClanLib by next thursday, then it f*%!ing sucks
-        // 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(10);
-    }
-}
-
-Logger Engine::log (enum LogLevel level, const char *type) {
-    return Logger(level <= WARN ? std::cerr : std::cout, level, type);
-}
-
--- a/src/proto2/Engine.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#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"
-
-#include "Logger.hh"
-
-class Engine {
-    private:
-        // 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);
-
-        // setup graphics
-        void setupGraphics (void);
-        
-        // 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);
-		void setupSinglePlayer (void);
-        
-        // 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);
-
-};
-
-#endif /* ENGINE_HH */
--- a/src/proto2/Error.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#ifndef ERROR_HH
-#define ERROR_HH
-
-#include <stdexcept>
-#include <string>
-
-class Error : public std::exception {
-    private:
-        const char *message;
-    
-    public:
-        Error (const std::string &message) : message(message.c_str()) { }
-
-        virtual const char* what() const throw() {
-            return message;
-        }
-};
-
-#endif /* ERROR_HH */
--- a/src/proto2/GameState.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-
-#include "GameState.hh"
-#include "Engine.hh"
-#include "Config.hh"
-
-/**
- * shoots the selected weapon.
- * TODO: selection and weapon information
- */
-void Player::shoot (void) {
-    // here should be somehow considered which projectile it is
-    if(!canShoot())
-        return;
-    reloadTimer += 0;
-    Vector unitVectorAim = facingRight ? Vector(std::cos(aim), -std::sin(aim)) : 
-            Vector(-std::cos(aim), -std::sin(aim));
-    float shotspeed = 100*PHYSICS_TICK_MS;
-    Vector shotRelativeVelocity = unitVectorAim * shotspeed;
-    Vector shotVelocity = this->velocity + shotRelativeVelocity;
-    this->state.addProjectile(new Shot(this->state, this->position, shotVelocity, true));
-}
-
-void Player::handleMove (PlayerInput_Move input) {
-    float fx = 0; // Force in x-direction
-    float da = 0; // Crosshair angle
-
-    // handle left/right
-    if ((input & INPUT_MOVE_LEFT) && (velocity.x > -PLAYER_MAX_SPEED))
-        fx -= PLAYER_MOVE_FORCE;
-
-    if ((input & INPUT_MOVE_RIGHT) && (velocity.x < PLAYER_MAX_SPEED))
-        fx += PLAYER_MOVE_FORCE;
-
-    if (input & INPUT_MOVE_UP)
-        da += CROSSHAIR_ANGLE_SPEED;
-
-    if (input & INPUT_MOVE_DOWN)
-        da -= CROSSHAIR_ANGLE_SPEED;
-
-    if (input & INPUT_MOVE_JUMP) {
-        if ((input & INPUT_MOVE_LEFT))
-            jump(-1);
-        else if ((input & INPUT_MOVE_RIGHT))
-            jump(1);
-        else
-            jump(0);
-    }
-
-    if (input & INPUT_MOVE_DIG) {
-        // Should create Shot which destroys ground, but also should be destroyed then,
-        // but it doesn't.
-        // But this now just segfaults
-//        world.addObject(new Shot(state, position, true));
-
-        world.removeGround(position, 15);
-    }
-
-    if (input & INPUT_SHOOT) {
-        this->shoot();
-    }
-
-
-
-    // Player facing
-    if (fx < 0) setFacing(false);
-    else if (fx > 0) setFacing(true);
-
-
-    this->changeAim(da); // Move crosshair
-
-    // Apply force
-    applyForce(Vector(fx, 0));
-
-}
-
-void Player::debugInfo (void) {
-    Engine::log(DEBUG, "Player.debugInfo") << "In air: " << this->inAir;
-}
-
-void Shot::onCollision() {
-    world.removeGround(position, 20);
-}
-
-void Shot::draw(CL_GraphicContext *gc) {
-
-
-    CL_Quad player(
-                   (position).x+1, (position).y+1,
-                   (position).x-1, (position).y+1,
-                   (position).x+1, (position).y-1,
-                   (position).x-1, (position).y-1
-                   );
-
-    gc->fill_quad(player, CL_Color::green);
-
-    const uint16_t chlen = 10;
-    uint16_t x = player.center().x;
-    uint16_t y = player.center().y;
-    if(target_visible) {
-        if (facingRight) {
-            gc->draw_line(x, y,
-                          x + std::cos(aim)*chlen,
-                          y - std::sin(aim)*chlen,
-                          CL_Color::black);
-        } else {
-            gc->draw_line(x, y,
-                          x - std::cos(aim)*chlen,
-                          y - std::sin(aim)*chlen,
-                          CL_Color::black);
-        }
-    }
-}
-
--- a/src/proto2/GameState.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-#ifndef GAMESTATE_HH
-#define GAMESTATE_HH
-
-#include "Physics.hh"
-#include "Input.hh"
-#include "Config.hh"
-
-#include <list>
-#include <stdexcept>
-#include <cmath>
-
-// forward-declare GameState
-class GameState;
-
-class Player : public PhysicsObject {
-protected:
-    GameState &state;
-    bool visible;
-    
-public:
-    Player(GameState &state, Vector position, bool visible) : 
-        PhysicsObject((PhysicsWorld &) state, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible) {
-            
-        std::vector<Vector> shape(4);
-        shape[0] = Vector(0,-9);
-        shape[1] = Vector(6,0);
-        shape[2] = Vector(0,9); 
-        shape[3] = Vector(-6,0);
-        // Initialize the shape of the player (salmiakki shape)
-        setShape(shape);
-        collision_elasticity = PLAYER_COLLISION_ELASTICITY;
-        world.addPlayerObject(this);
-    }
-    
-    void debugInfo ();
-    virtual void handleMove (PlayerInput_Move input);
-    void shoot (void);
-
-};
-
-class Shot : public PhysicsObject {
-protected:
-    GameState &state;
-    bool visible;
-    uint32_t birth_tick;
-    uint32_t death_tick;
-    bool target_visible;
-public:
-    Shot(GameState &state, Vector position, Vector velocity, bool visible) :
-        PhysicsObject((PhysicsWorld &) state, PLAYER_MASS, position, velocity), state(state), visible(visible) {
-        // Looks kind of dumb, for ammunition to have shape
-        std::vector<Vector> shape(4);
-        shape[0] = Vector(-1, -1);
-        shape[1] = Vector(-1, 1);
-        shape[2] = Vector(1, 1);
-        shape[3] = Vector(1, -1);
-        setShape(shape);
-        target_visible = false;
-        collision_elasticity = 0.9; // = shotType.elasticity
-        world.addProjectile(this);
-    }
-private:
-    virtual void onCollision();
-    virtual void draw(CL_GraphicContext *gc);
-};
-
-class LocalPlayer : public Player {
-protected:
-    LocalPlayer (GameState &state, Vector pos, bool visible) : Player(state, pos, visible) { }
-};
-
-class RemotePlayer : public Player {
-protected:
-    RemotePlayer (GameState &state, Vector pos, bool visible) : Player(state, pos, visible) { }
-};
-
-class GameState : public PhysicsWorld {
-public:
-    std::list<Player*> player_list;
-
-    // only one local player is supported
-    LocalPlayer *local_player;
-
-    GameState (void) : PhysicsWorld(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT)), local_player(NULL) {
-
-    }
-       
-    /*
-     * This will return NULL if we don't have a local player - yet
-     */
-    LocalPlayer *getLocalPlayer (void) {
-        return local_player;
-    }
-        
-    void newLocalPlayer (LocalPlayer *player) {
-        if (local_player)
-            throw std::logic_error("newLocalPlayer called even though we already have a local player");
-
-        player_list.push_back(player);
-
-        local_player = player;
-    }
-
-    void newRemotePlayer (RemotePlayer *player) {
-        player_list.push_back(player);
-    }
-
-    void removePlayer (Player *player) {
-        player_list.remove(player);
-    }
-};
-
-#endif
--- a/src/proto2/Graphics.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-
-#include "Graphics.hh"
-#include "Physics.hh"
-#include "GameState.hh"
-#include <cmath>
-
-Graphics::Graphics (Engine &engine, GameState &state) :
-    engine(engine), 
-    state(state), 
-    update_timer(GRAPHICS_UPDATE_INTERVAL_MS),
-    win(GRAPHICS_WINDOW_TITLE, GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT),
-    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;
-    PlayerInput_Move input_move = 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 movement
-    if (keyboard.get_keycode(CL_KEY_LEFT))
-        input_move |= INPUT_MOVE_LEFT;
-
-    if (keyboard.get_keycode(CL_KEY_RIGHT))
-        input_move |= INPUT_MOVE_RIGHT;
-
-    if (keyboard.get_keycode(CL_KEY_UP))
-        input_move |= INPUT_MOVE_UP;
-
-    if (keyboard.get_keycode(CL_KEY_DOWN))
-        input_move |= INPUT_MOVE_DOWN;
-
-    if (keyboard.get_keycode(CL_KEY_RSHIFT))
-        input_move |= INPUT_MOVE_JUMP;
-
-    if (keyboard.get_keycode(CL_KEY_I))
-        player->debugInfo();
-    
-    if (keyboard.get_keycode(CL_KEY_F)) {
-        Engine::log(DEBUG, "Graphics.check_input") << "Fire!";
-        input_move |= INPUT_SHOOT;
-    }
-   
-    if (keyboard.get_keycode(CL_KEY_M))
-        input_move |= INPUT_MOVE_DIG;
- 
-    // apply movement if applicable
-    if (input_move)
-        player->handleMove(input_move);
-}
-
-void Graphics::do_redraw (void) {
-    CL_GraphicContext *gc = win.get_gc();
-    
-    // White background
-    gc->clear(CL_Color::white);
-
-    // Draw terrain
-    state.draw(gc);
-
-    // Flip window buffer, sync
-    win.flip(1);
-}
-
-void Graphics::on_update (void) {
-    // check keyboard input
-    check_input();
-
-    // redraw display
-    do_redraw();
-}
--- a/src/proto2/Graphics.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#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>
-
-const std::string GRAPHICS_WINDOW_TITLE = "Kisna Glista";
-const uint32_t GRAPHICS_RESOLUTION_WIDTH = 800;
-const uint32_t GRAPHICS_RESOLUTION_HEIGHT = 600;
-const uint16_t GRAPHICS_UPDATE_INTERVAL_MS = 20;
-
-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/Input.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#ifndef INPUT_HH
-#define INPUT_HH
-
-const uint16_t INPUT_INTERVAL_MS = 20;
-
-enum {
-    // XXX: aiming is not movement?
-    INPUT_MOVE_UP       = 0x0001,
-    INPUT_MOVE_DOWN     = 0x0002,
-
-    INPUT_MOVE_LEFT     = 0x0004,
-    INPUT_MOVE_RIGHT    = 0x0008,
-
-    INPUT_MOVE_JUMP     = 0x0010,
-    INPUT_MOVE_DIG      = 0x0020,
-    INPUT_SHOOT         = 0x0040,
-};
-
-typedef uint16_t PlayerInput_Move;
-
-#endif
--- a/src/proto2/Logger.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-
-#include "Logger.hh"
-
-Logger::Logger (std::ostream &stream, enum LogLevel level, const char *module) : stream(stream), level(level), module(module) {
-    const char *l;
-
-    switch (level) {
-        case FATAL: l = "FATAL"; break;
-        case ERROR: l = "ERROR"; break;
-        case WARN: l = "WARN"; break;
-        case INFO: l = "INFO"; break;
-        case DEBUG: l = "DEBUG"; break;
-        default: l = "???"; break;
-    };
-
-    stream << l << " [" << module << "] ";
-}
-
-Logger::~Logger (void) {
-    stream << std::endl;
-}
-
-std::ostream& operator<< (std::ostream &s, CL_NetComputer &c) {
-    s << "[" << c.get_address().get_address() << ":" << c.get_address().get_port() << "]";
-
-    return s;
-}
-
-std::ostream& operator<< (std::ostream &s, CL_NetObject_Server &obj) {
-    s << "%" << obj.get_obj_id();
-
-    return s;
-}
-
-std::ostream& operator<< (std::ostream &s, CL_NetObject_Client &obj) {
-    s << "%" << obj.get_obj_id();
-
-    return s;
-}
-
--- a/src/proto2/Logger.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#ifndef LOGGER_HH
-#define LOGGER_HH
-
-#include <ClanLib/network.h>
-
-#include <iostream>
-
-enum LogLevel {
-    FATAL,
-    ERROR,
-    WARN,
-    INFO,
-    DEBUG,
-};
-
-class Logger {
-    private:
-        std::ostream &stream;
-        enum LogLevel level;
-        const char *module;
-
-    public:
-        Logger (std::ostream &stream, enum LogLevel level, const char *module);
-
-        template <typename T> Logger& operator<< (T &val) {
-            stream << val;
-
-            return *this;
-        }
-
-
-        ~Logger (void);
-};
-
-std::ostream& operator<< (std::ostream &s, CL_NetComputer &c);
-std::ostream& operator<< (std::ostream &s, CL_NetObject_Server &obj);
-std::ostream& operator<< (std::ostream &s, CL_NetObject_Client &obj);
-
-#endif /* LOGGER_HH */
--- a/src/proto2/Network.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#include "Network.hh"
-#include "NetworkAddress.hh"
-#include "NetworkSocket.hh"
-#include "Engine.hh"
-
-#include <sstream>
-#include <cstring>
-
-std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr) {
-    s << "[" << addr.get_address() << ":" << addr.get_port() << "]";
-
-    return s;
-
-}
-        
-std::string NetworkSocketError::build_str (const NetworkSocket &socket, const char *op, const char *err) {
-    std::stringstream ss;
-
-    ss << "socket #" << socket.get_socket() << " " << op << ": " << err;
-
-    return ss.str();
-}
-
-NetworkSocketError::NetworkSocketError (const NetworkSocket &socket, const char *op, const char *err) :
-    Error(build_str(socket, op, err)) {
-    
-    // nothing
-}
-
--- a/src/proto2/Network.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#ifndef NETWORK_HH
-#define NETWORK_HH
-
-#include "NetworkConfig.hh"
-#include "GameState.hh"
-
-#include <ClanLib/network.h>
-
-const int32_t COORDINATE_MAX = 1 << 30;
-
-class NetworkCore {
-    protected:
-        GameState &state;
-
-        CL_SlotContainer slots;
-
-        // constructor
-        NetworkCore (GameState &state) : state(state) { }
-
-
-
-
-};
-
-enum NetworkChannel {
-    /*
-     * Core channel used for NetworkSession
-     */
-    NETCHAN_CORE            = 0x01,
-};
-
-enum NetworkPhysicsFlags {
-    NETWORK_PHYSICS_INAIR      = 0x01,
-};
-
-enum NetworkMessage {
-    NETMSG_PACKET_INVALID   = 0x00,
-
-    /*
-     * You have joined the game:
-     *
-     *  Vector      initial_position
-     */
-    NETMSG_SERVER_HELLO = 0x0100,
-
-    /*
-     * New client has connected to server:
-     *  
-     *  Vector      initial_position
-     */
-    NETMSG_PLAYER_JOIN  = 0x0101,
-
-    /*
-     * Client has left server:
-     *
-     */
-    NETMSG_PLAYER_QUIT  = 0x0102,
-
-    /*
-     * Client has moved
-     *
-     *  uint16_t    PlayerInput_Move
-     */
-    NETMSG_CLIENT_MOVE  = 0x0201,
-    
-    /*
-     * Initial player info
-     *
-     *  Vector      initial_position
-     */
-    NETMSG_PLAYER_INFO  = 0x0300,
-
-    /*
-     * Player position update
-     *
-     * Vector   position
-     * Vector   velocity
-     * uint8_t  NetworkPhysicsFlags
-     */
-    NETMSG_PLAYER_POSITION  = 0x0301,
-};
-
-#endif
--- a/src/proto2/NetworkAddress.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef NETWORK_ADDRESS_HH
-#define NETWORK_ADDRESS_HH
-
-#include <ClanLib/Network/Socket/ip_address.h>
-
-typedef CL_IPAddress NetworkAddress;
-
-// Network.cc
-std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr);
-
-#endif /* NETWORK_ADDRESS_HH */
--- a/src/proto2/NetworkClient.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-
-#include "NetworkClient.hh"
-#include "Engine.hh"
-#include "Logger.hh"
-
-#include <cassert>
-
-NetworkClient::NetworkClient (GameState &state, const NetworkAddress &connect_to) : 
-    NetworkCore(state), netsession(NETWORK_MAGIC_ID), server(netsession.connect(connect_to)), netobjs(netsession, NETCHAN_CORE, server) {
-    
-    // connect slots
-    slots.connect(netobjs.sig_create(), this, &NetworkClient::on_create);
-
-    // XXX: sig_disconnected
-}
-
-void NetworkClient::on_create (NetworkObject_Client *obj, NetworkMessageID msg_id, NetworkPacket &pkt) {
-    switch (msg_id) {
-        case NETMSG_SERVER_HELLO:
-            on_server_hello(obj, pkt);
-
-            break;
-        
-        case NETMSG_PLAYER_INFO:
-            on_player_info(obj, pkt);
-
-            break;
-        
-        case NETMSG_PLAYER_JOIN:
-            on_player_join(obj, pkt);
-
-            break;
-
-        default:
-            Engine::log(WARN, "client.on_create_object") << "unknown msg_id=" << msg_id << " for obj=" << obj;
-    }
-}
-        
-void NetworkClient::on_server_hello (NetworkObject_Client *obj, NetworkPacket &pkt) {
-    // read the packet
-    Vector position = pkt.read_vector();
-    
-    Engine::log(INFO, "client.on_server_hello") << "obj=" << obj << ", pos=" << position;
-
-    // create the LocalPlayer object
-    NetworkClientLocalPlayer *player = new NetworkClientLocalPlayer(*this, obj, position);
-
-    // inform state
-    state.newLocalPlayer(player);
-}
-        
-void NetworkClient::on_player_info (NetworkObject_Client *obj, NetworkPacket &pkt) {
-    // read the packet
-    Vector position = pkt.read_vector();
-    
-    Engine::log(INFO, "client.on_player_info") << "obj=" << obj << ", pos=" << position;
-
-    // create the LocalPlayer object
-    NetworkClientRemotePlayer *player = new NetworkClientRemotePlayer(*this, obj, position);
-
-    // inform state
-    state.newRemotePlayer(player);
-
-}
-        
-void NetworkClient::on_player_join (NetworkObject_Client *obj, NetworkPacket &pkt) {
-    // read the packet
-    Vector position = pkt.read_vector();
-    
-    Engine::log(INFO, "client.on_player_join") << "obj=" << obj << ", pos=" << position;
-    
-    // create the RemotePlayer object
-    NetworkClientRemotePlayer *player = new NetworkClientRemotePlayer(*this, obj, position);
-
-    // inform state
-    state.newRemotePlayer(player);
-}
-        
-void NetworkClient::player_quit (NetworkClientRemotePlayer *player) {
-    // inform state
-    state.removePlayer(player);
-
-    // delete
-    // XXX: leak because deleting the slot while it's being called breaks ClanLib
-    //  delete player;
-}
-
-NetworkClientLocalPlayer::NetworkClientLocalPlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position) :
-    LocalPlayer(client.state, position, true), client(client), obj(obj) {
-    
-    // receive messages
-    slots.connect(obj->sig_message(NETMSG_PLAYER_POSITION), this, &NetworkClientLocalPlayer::on_position);
-}
-        
-void NetworkClientLocalPlayer::handleMove (PlayerInput_Move input) {
-    // always send move, in all cases
-    NetworkPacket pkt;
-    pkt.write_uint16(input);
-
-    obj->send(NETMSG_CLIENT_MOVE, pkt, false);
-    
-    // do not handle locally
-}
-        
-void NetworkClientLocalPlayer::on_position (NetworkPacket &pkt) {
-    Vector position = pkt.read_vector();
-    Vector velocity = pkt.read_vector();
-    uint8_t flags = pkt.read_uint8();
-
-    Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", position=" << position << ", velocity=" << velocity;
-    
-    // just update... 
-    updatePhysics(position, velocity, flags & NETWORK_PHYSICS_INAIR);
-}
-        
-NetworkClientRemotePlayer::NetworkClientRemotePlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position) :
-    RemotePlayer(client.state, position, true), client(client), obj(obj) {
-    
-    // receive messages
-    slots.connect(obj->sig_message(NETMSG_PLAYER_POSITION), this, &NetworkClientRemotePlayer::on_position);
-    slots.connect(obj->sig_message(NETMSG_PLAYER_QUIT), this, &NetworkClientRemotePlayer::on_quit);
-}
-
-void NetworkClientRemotePlayer::on_position (NetworkPacket &pkt) {
-    Vector position = pkt.read_vector();
-    Vector velocity = pkt.read_vector();
-    uint8_t flags = pkt.read_uint8();
-
-    Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", position=" << position << ", velocity=" << velocity;
-    
-    // just update... 
-    updatePhysics(position, velocity, flags & NETWORK_PHYSICS_INAIR);
-}
-
-void NetworkClientRemotePlayer::on_quit (NetworkPacket &pkt) {
-    // pkt is empty
-    (void) pkt;
-
-    Engine::log(INFO, "client_player.on_quit") << "obj=" << obj;
-
-    client.player_quit(this);
-}
-
--- a/src/proto2/NetworkClient.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#ifndef NETWORKCLIENT_HH
-#define NETWORKCLIENT_HH
-
-#include "Network.hh"
-#include "GameState.hh"
-#include "NetworkSession.hh"
-#include "NetworkObject.hh"
-
-// forward-declare
-class NetworkClientLocalPlayer;
-class NetworkClientRemotePlayer;
-
-class NetworkClient : public NetworkCore {
-    friend class NetworkClientLocalPlayer;
-    friend class NetworkClientRemotePlayer;
-
-    private:
-        NetworkSession netsession;
-        NetworkNode *server;
-
-        NetworkObject_ClientController netobjs;
-        
-    public:
-        NetworkClient (GameState &state, const NetworkAddress &connect_to);
-
-    private:
-        void on_create (NetworkObject_Client *obj, NetworkMessageID msg_id, NetworkPacket &pkt);
-
-        void on_server_hello (NetworkObject_Client *obj, NetworkPacket &pkt);
-        void on_player_info (NetworkObject_Client *obj, NetworkPacket &pkt);
-        void on_player_join (NetworkObject_Client *obj, NetworkPacket &pkt);
-    
-    public:
-        void player_quit (NetworkClientRemotePlayer *player);
-};
-
-class NetworkClientLocalPlayer : public LocalPlayer {
-    private:
-        NetworkClient &client;
-
-        CL_SlotContainer slots;
-        
-        NetworkObject_Client *obj;
-
-    public:
-        NetworkClientLocalPlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position);
-        
-        virtual void handleMove (PlayerInput_Move input);
-    
-    private:
-        void on_position (NetworkPacket &pkt);
-};
-
-class NetworkClientRemotePlayer : public RemotePlayer {
-    private:
-        NetworkClient &client;
-        
-        CL_SlotContainer slots;
-
-        NetworkObject_Client *obj;
-
-    public:
-        NetworkClientRemotePlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position);
-    
-    private:
-        void on_position (NetworkPacket &pkt);
-
-        void on_quit (NetworkPacket &pkt);
-};
-
-#endif
--- a/src/proto2/NetworkConfig.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#ifndef NETWORK_CONFIG_HH
-#define NETWORK_CONFIG_HH
-
-// socket-related includes
-// copied from clanlib code, so should be relatively OS-safe
-#ifndef WIN32
-        #include <sys/socket.h>
-        #include <netinet/in.h>
-        #include <arpa/inet.h>
-        #include <netdb.h>
-        #include <sys/time.h>
-        #include <unistd.h> 
-#else
-        #include <winsock2.h>
-        #include <windows.h>
-        typedef int socklen_t;
-#endif
-
-#include <string>
-
-const std::string NETWORK_PORT_STR = "9338";
-
-const size_t NETWORK_PACKET_SIZE = 1280;
-const int NETWORK_LISTEN_BACKLOG = 5;
-
-const char NETWORK_MAGIC_STR[8+1] = "KISNGLIS";
-const uint64_t NETWORK_MAGIC_ID = * ((const uint64_t *) NETWORK_MAGIC_STR);
-
-#endif /* NETWORK_CONFIG_HH */
--- a/src/proto2/NetworkNode.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-
-#include <cassert>
-
-#include "NetworkNode.hh"
-
-NetworkNode::NetworkNode (NetworkSession &session, NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &address) :
-    session(session), tcp(tcp), udp(udp), address(address) {
-    
-    // connect signals
-    slots.connect(tcp->sig_disconnect(), this, &NetworkNode::on_disconnect);
-    slots.connect(tcp->sig_packet(), &session, &NetworkSession::handle_message, this);
-    
-}
-
-NetworkNode::~NetworkNode (void) {
-    delete tcp;
-}
-
-void NetworkNode::on_disconnect (void) {
-    // tell session
-    session.handle_disconnect(this);
-
-    // fire signal
-    _sig_disconnected();
-    
-    // delete
-//    delete this;
-}
-
-void NetworkNode::send (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable) {
-    assert(channel_id > 0);
-    
-    // add our header
-    NetworkPacket pkt2;
-    pkt2.write_uint16(channel_id);
-    pkt2.write_packet(pkt);
-    
-    // either tcp or udp
-    if (reliable) {
-        assert(tcp);
-
-        tcp->write_packet(pkt2);
-
-    } else {
-        udp->sendto(pkt2, address);
-    }
-}
-        
-const NetworkAddress& NetworkNode::getRemoteAddress (void) {
-    return address;
-}
--- a/src/proto2/NetworkNode.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#ifndef NETWORK_NODE_HH
-#define NETWORK_NODE_HH
-
-// forward-declare
-class NetworkNode;
-
-enum NetworkNodeType {
-    NETWORK_NODE_SERVER_CLIENT,
-    NETWORK_NODE_CLIENT_SERVER
-};
-
-#include "NetworkTCP.hh"
-#include "NetworkUDP.hh"
-#include "NetworkSession.hh"
-
-class NetworkNode {
-    private:
-        NetworkSession &session;
-        NetworkTCPTransport *tcp;
-        NetworkUDP *udp;
-        const NetworkAddress address;
-
-        CL_SlotContainer slots;
-    
-    public:
-        NetworkNode (NetworkSession &session, NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &address);
-        
-    private:
-        NetworkNode (const NetworkNode &copy);
-        ~NetworkNode (void);
-        NetworkNode& operator= (const NetworkNode &copy);
-        
-        void on_disconnect (void);
-         
-        CL_Signal_v0 _sig_disconnected;
-
-    public:
-        void send (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable = true);
-
-        const NetworkAddress& getRemoteAddress (void);
-        
-        CL_Signal_v0& sig_disconnected (void) { return _sig_disconnected; }
-};
-
-#endif /* NETWORK_NODE_HH */
--- a/src/proto2/NetworkObject.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-
-#include <cassert>
-
-#include "NetworkObject.hh"
-
-/* 
- * NetworkObject_Controller 
- */
-NetworkObjectController::NetworkObjectController (NetworkSession &session, NetworkChannelID channel_id) :
-    session(session), channel_id(channel_id) {
-    
-    // setup signals
-    slot_message = session.sig_chan_message(channel_id).connect(this, &NetworkObjectController::on_message);
-}
-
-void NetworkObjectController::on_message (NetworkPacket &pkt, NetworkNode *node) {
-    uint32_t obj_id = pkt.read_uint32();
-    uint16_t msg_id = pkt.read_uint16();
-    
-    // lookup object
-    NetworkObject *obj = objects[obj_id];
-
-    if (obj) {
-        obj->handle_packet(node, msg_id, pkt);
-
-    } else {
-        handle_create(obj_id, msg_id, pkt, node);
-    }
-}
-
-/* 
- * NetworkObject_ServerController 
- */
-NetworkObject_ServerController::NetworkObject_ServerController (NetworkSession &session, NetworkChannelID channel_id) :
-    NetworkObjectController(session, channel_id), id_pool(0) {
-
-}
-
-NetworkObjectID NetworkObject_ServerController::getObjectID (void) {
-    return ++id_pool;
-}
-        
-void NetworkObject_ServerController::handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node) {
-    (void) obj_id;
-    (void) msg_id;
-    (void) pkt;
-    (void) node;
-
-    // XXX: fail
-    throw CL_Error("clients cannot create objects");
-}
-        
-/* 
- * NetworkObject_ClientController *
- */
-NetworkObject_ClientController::NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server) :
-    NetworkObjectController(session, channel_id), server(server) {
-
-
-}
-        
-void NetworkObject_ClientController::handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node) {
-    // we only communicate with the server
-    assert(node == server);
-    
-    // create new object
-    NetworkObject_Client *obj = new NetworkObject_Client(*this, obj_id);
-    
-    // signal
-   _sig_create(obj, msg_id, pkt); 
-}
-
-/* 
- * NetworkObject 
- */
-NetworkObject::NetworkObject (NetworkObjectController &controller, NetworkObjectID obj_id) :
-    obj_id(obj_id) {
-    
-    assert(obj_id);
-
-    controller.objects[obj_id] = this;
-}
-        
-void NetworkObject::buildPacket (NetworkPacket &pkt, NetworkMessageID msg_id, const NetworkPacket &payload) {
-    pkt.write_uint32(obj_id);
-    pkt.write_uint16(msg_id);
-    pkt.write_packet(payload);
-}
-
-std::ostream& operator<< (std::ostream &s, const NetworkObject &obj) {
-    return s << "<NetworkObject #" << obj.obj_id << ">";
-}
-
-/* 
- * NetworkObject_Server 
- */
-NetworkObject_Server::NetworkObject_Server (NetworkObject_ServerController &controller) :
-    NetworkObject(controller, controller.getObjectID()), controller(controller) {
-    
-}
-
-void NetworkObject_Server::handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt) {
-    _map_sig_message[msg_id](node, pkt);
-}
-
-void NetworkObject_Server::send_to (NetworkNode *dst, NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable) {
-    NetworkPacket pkt_out;
-
-    buildPacket(pkt_out, msg_id, pkt);
-
-    dst->send(controller.channel_id, pkt_out, reliable);
-}
-
-void NetworkObject_Server::send_all (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable) {
-    send_all_except(msg_id, pkt, NULL, reliable);
-}
-
-void NetworkObject_Server::send_all_except (NetworkMessageID msg_id, const NetworkPacket &pkt, NetworkNode *black_sheep, bool reliable) {
-    NetworkPacket pkt_out;
-
-    buildPacket(pkt_out, msg_id, pkt);
-    
-    controller.session.send_all_except(controller.channel_id, pkt_out, black_sheep, reliable);
-}
- 
-/* 
- * NetworkObject_Client 
- */
-NetworkObject_Client::NetworkObject_Client (NetworkObject_ClientController &controller, NetworkObjectID id) :
-    NetworkObject(controller, id), controller(controller) { 
-    
-    // nothing
-}
-
-void NetworkObject_Client::handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt) {
-    assert(node == controller.server);
-
-    _map_sig_message[msg_id](pkt);
-}
-       
-void NetworkObject_Client::send (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable) {
-    NetworkPacket pkt_out;
-
-    buildPacket(pkt_out, msg_id, pkt);
-
-    controller.server->send(controller.channel_id, pkt_out, reliable);
-}
-
--- a/src/proto2/NetworkObject.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-#ifndef NETWORK_OBJECT_HH
-#define NETWORK_OBJECT_HH
-
-#include "NetworkSession.hh"
-#include "NetworkNode.hh"
-#include "Logger.hh"
-
-#include <map>
-
-typedef uint32_t NetworkObjectID;
-typedef uint16_t NetworkMessageID;
-
-// forward-declare
-class NetworkObject;
-class NetworkObject_Client;
-class NetworkObject_Server;
-
-class NetworkObjectController {
-    friend class NetworkObject;
-    friend class NetworkObject_Server;
-    friend class NetworkObject_Client;
-
-    private:
-        NetworkSession &session;
-        NetworkChannelID channel_id;
-
-        std::map<NetworkObjectID, NetworkObject*> objects;
-
-        CL_Slot slot_message;
-    
-    protected:
-        NetworkObjectController (NetworkSession &session, NetworkChannelID channel_id);
-    
-    private:
-        void on_message (NetworkPacket &pkt, NetworkNode *node);
-
-    protected:
-        virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node) = 0; 
-};
-
-class NetworkObject_ServerController : public NetworkObjectController {
-    friend class NetworkObject_Server;
-
-    private:
-        NetworkObjectID id_pool;
-    
-    public:
-        NetworkObject_ServerController (NetworkSession &session, NetworkChannelID channel_id);
-
-    protected:
-        NetworkObjectID getObjectID (void);
-
-        virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node);
-};
-
-class NetworkObject_ClientController : public NetworkObjectController {
-    friend class NetworkObject_Client;
-
-    private:
-        NetworkNode *server;
-
-        CL_Signal_v3<NetworkObject_Client*, NetworkMessageID, NetworkPacket&> _sig_create;
-    
-    public:
-        NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server);
-
-    protected:
-        virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacket &pkt, NetworkNode *node);
-    
-    public:  
-        CL_Signal_v3<NetworkObject_Client*, NetworkMessageID, NetworkPacket&>& sig_create (void) { return _sig_create; }
-};
-
-class NetworkObject {
-    friend class NetworkObjectController;
-    friend std::ostream& operator<< (std::ostream &s, const NetworkObject &obj);
-
-    protected:
-        NetworkObjectID obj_id;
-
-    protected:
-        NetworkObject (NetworkObjectController &controller, NetworkObjectID obj_id);
-        
-        virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt) = 0;
-
-        void buildPacket (NetworkPacket &pkt, NetworkMessageID msg_id, const NetworkPacket &payload);
-};
-
-std::ostream& operator<< (std::ostream &s, const NetworkObject &obj);
-
-class NetworkObject_Server : public NetworkObject {
-    friend class NetworkObject_ServerController;
-
-    private:
-        NetworkObject_ServerController &controller;
-
-        std::map<NetworkMessageID, CL_Signal_v2<NetworkNode*, NetworkPacket&> > _map_sig_message;
-
-    public:
-        NetworkObject_Server (NetworkObject_ServerController &controller);
-    
-    protected:
-        virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt);
-
-    public:
-        void send_to (NetworkNode *dst, NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable = true);
-        void send_all (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable = true);
-        void send_all_except (NetworkMessageID msg_id, const NetworkPacket &pkt, NetworkNode *black_sheep, bool reliable = true);
-    
-        CL_Signal_v2<NetworkNode*, NetworkPacket&>& sig_message (NetworkMessageID msg_id) { return _map_sig_message[msg_id]; }
-};
-
-class NetworkObject_Client : public NetworkObject {
-    friend class NetworkObject_ClientController;
-
-    private:
-        NetworkObject_ClientController &controller;
-
-        std::map<NetworkMessageID, CL_Signal_v1<NetworkPacket&> > _map_sig_message;
-
-    protected:
-        NetworkObject_Client (NetworkObject_ClientController &controller, NetworkObjectID id);
-        
-        virtual void handle_packet (NetworkNode *node, NetworkMessageID msg_id, NetworkPacket &pkt);
-
-    public:
-        void send (NetworkMessageID msg_id, const NetworkPacket &pkt, bool reliable = true);
-        
-        CL_Signal_v1<NetworkPacket&>& sig_message (NetworkMessageID msg_id) { return _map_sig_message[msg_id]; }
-};
-
-#endif /* NETWORK_OBJECT_HH */
--- a/src/proto2/NetworkPacket.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-
-#include <cassert>
-#include <cstring>
-
-#include "NetworkPacket.hh"
-
-
-NetworkPacket::NetworkPacket (void) :
-    buf_size(NETWORK_PACKET_SIZE), data_size(0), offset(0) {
-    
-    // nothing
-}
-
-void NetworkPacket::check_write_size (size_t item_size) {
-     if (offset + item_size > buf_size)
-        throw NetworkPacketError("not enough space to write");
-
-}
-        
-void NetworkPacket::check_read_size (size_t item_size) {
-    if (offset + item_size > data_size)
-        throw NetworkPacketError("not enough data to read");
-}
-
-void NetworkPacket::write (const void *ptr, size_t len) {
-    // check buffer overflow
-    check_write_size(len);
-
-    // set value
-    memcpy(buf + offset, ptr, len);
-
-    // update offset and size
-    offset += len;
-    data_size += len;
-}
-
-void NetworkPacket::read (void *ptr, size_t len) {
-    // check buffer underflow
-    check_read_size(len);
-
-    // set value
-    memcpy(ptr, buf + offset, len);
-
-    // update offset
-    offset += len;
-}
-
-template <typename T> T NetworkPacket::read_val (void) {
-    T val;
-
-    // read
-    read(&val, sizeof(T));
-
-    // return
-    return val;
-}
-
-template <typename T> void NetworkPacket::write_val (const T &val) {
-    // write
-    write(&val, sizeof(T));
-}
-
-uint32_t NetworkPacket::read_uint32 (void) {
-    return ntohl(read_val<uint32_t>());
-}
-
-uint16_t NetworkPacket::read_uint16 (void) {
-    return ntohs(read_val<uint16_t>());
-}
-
-uint8_t NetworkPacket::read_uint8 (void) {
-    return read_val<uint8_t>();
-}
-
-int32_t NetworkPacket::read_int32 (void) {
-    return ntohl(read_val<int32_t>());
-}
-
-int16_t NetworkPacket::read_int16 (void) {
-    return ntohs(read_val<int16_t>());
-}
-
-int8_t NetworkPacket::read_int8 (void) {
-    return read_val<int8_t>();
-}
-        
-float NetworkPacket::read_float32 (void) {
-    int32_t ival = read_int32();
-
-    return *((float *) &ival);
-}
-
-Vector NetworkPacket::read_vector (void) {
-    float fx = read_float32();
-    float fy = read_float32();
-
-    return Vector(fx, fy);
-}
-
-void NetworkPacket::write_uint32 (uint32_t val) {
-    write_val<uint32_t>(htonl(val));
-}
-
-void NetworkPacket::write_uint16 (uint16_t val) {
-    write_val<uint16_t>(htons(val));
-}
-
-void NetworkPacket::write_uint8 (uint8_t val) {
-    write_val<uint8_t>(val);
-}
-
-void NetworkPacket::write_int32 (int32_t val) {
-    write_val<int32_t>(htonl(val));
-}
-
-void NetworkPacket::write_int16 (int16_t val) {
-    write_val<int16_t>(htons(val));
-}
-
-void NetworkPacket::write_int8 (int8_t val) {
-    write_val<int8_t>(val);
-}
-        
-void NetworkPacket::write_float32 (float val) {
-    write_int32(*((int32_t *) &val));
-}
-
-void NetworkPacket::write_vector (const Vector &vec) {
-    write_float32(vec.x);
-    write_float32(vec.y);
-}
-
-void NetworkPacket::write_packet (const NetworkPacket &pkt) {
-    // check buffer size
-    check_write_size(pkt.get_data_size());
-
-    // copy
-    memcpy(buf + offset, pkt.get_buf(), pkt.get_data_size());
-
-    // update offset/data_size
-    offset += pkt.get_data_size();
-    data_size += pkt.get_data_size();
-}
-
--- a/src/proto2/NetworkPacket.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#ifndef NETWORK_PACKET_HH
-#define NETWORK_PACKET_HH
-
-#include "NetworkConfig.hh"
-#include "Vector.hh"
-#include "Error.hh"
-
-class NetworkPacketError : public Error {
-    public:
-        NetworkPacketError (const std::string &message) : Error(message) { }
-};
-
-class NetworkPacket {
-    private:
-        char buf[NETWORK_PACKET_SIZE];
-        size_t buf_size, data_size, offset;
-        
-        void check_write_size (size_t item_size);
-        void check_read_size (size_t item_size);
-
-        template <typename T> T read_val (void);
-        template <typename T> void write_val (const T &val);
- 
-    public:
-        NetworkPacket (void);
-        
-        char* get_buf (void) { return buf; }
-        const char* get_buf (void) const { return buf; }
-        size_t get_data_size (void) const { return data_size; }
-        size_t get_buf_size (void) const { return buf_size; }
-
-        void set_data_size (size_t size) { offset = 0; data_size = size; }
-
-        // raw
-        void write (const void *ptr, size_t len);
-        void read (void *ptr, size_t len);
-       
-        // type-reads, handle network-endianlness
-        uint32_t read_uint32 (void);
-        uint16_t read_uint16 (void);
-        uint8_t read_uint8 (void);
-
-        int32_t read_int32 (void);
-        int16_t read_int16 (void);
-        int8_t read_int8 (void);
-        
-        float read_float32 (void);
-
-
-        void write_uint32 (uint32_t val);
-        void write_uint16 (uint16_t val);
-        void write_uint8 (uint8_t val);
-
-        void write_int32 (int32_t val);
-        void write_int16 (int16_t val);
-        void write_int8 (int8_t val);
-        
-        void write_float32 (float val);
-
-        // complex
-        Vector read_vector (void);
-        void write_vector (const Vector &vec);
-        void write_packet (const NetworkPacket &pkt);
-};
-
-#endif /* NETWORK_PACKET_HH */
--- a/src/proto2/NetworkServer.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-#include "NetworkServer.hh"
-#include "Engine.hh"
-#include "Logger.hh"
-
-#include <cassert>
-
-NetworkServer::NetworkServer (GameState &state, const NetworkAddress &listen_addr) : 
-    NetworkCore(state), netsession(NETWORK_MAGIC_ID), netobjs(netsession, NETCHAN_CORE) {
-    
-    // connect slots
-    slots.connect(netsession.sig_node_connected(), this, &NetworkServer::on_node_connected);
-    
-    // and then we listen
-    netsession.listen(listen_addr);
-
-    Engine::log(INFO, "server") << "running, listen_addr=" << listen_addr;
-}
-
-void NetworkServer::on_node_connected (NetworkNode *node) {
-    // create the player object (it logs it)
-    NetworkServerPlayer *player = new NetworkServerPlayer(*this, node);
-
-    // add to players
-    players.push_back(player);
-    
-    // add to GameState
-    state.newRemotePlayer(player);
-}
-        
-void NetworkServer::handle_disconnect (NetworkServerPlayer *player) {
-    // remove from state
-    state.removePlayer(player);
-
-    // remove from list
-    players.remove(player);
-}
-        
-NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, NetworkNode *node) : 
-    RemotePlayer(server.state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true), server(server), obj(server.netobjs), node(node) {
-    
-    // log
-    Engine::log(INFO, "server_player.connected") << "node=" << node << ", obj=" << obj;
-
-    // messages
-    slots.connect(node->sig_disconnected(), this, &NetworkServerPlayer::on_disconnected);
-    slots.connect(obj.sig_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move);
-
-    // the initial NETMSG_PLAYER_HELLO
-    NetworkPacket hello_pkt;
-    hello_pkt.write_vector(position);
-
-    obj.send_to(node, NETMSG_SERVER_HELLO, hello_pkt, true);
-
-    // send other player objects
-    for (std::list<NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) {
-        NetworkServerPlayer *player = *it;
-        NetworkPacket player_pkt;
-        
-        // player is not in players list yet
-        assert(player != this);
-        
-        player_pkt.write_vector(player->position);
-
-        player->obj.send_to(node, NETMSG_PLAYER_INFO, player_pkt, true);
-    }
-
-    // broadcast NETMSG_PLAYER_JOIN to all clients except current
-    obj.send_all_except(NETMSG_PLAYER_JOIN, hello_pkt, node, true);
-}
-
-void NetworkServerPlayer::on_disconnected (void) {
-    NetworkPacket pkt;
-    
-    Engine::log(INFO, "server_player.disconnected") << "node=" << node << ", obj=" << obj;
-    
-    // remove from server
-    server.handle_disconnect(this);
-    
-    // tell other clients
-    obj.send_all(NETMSG_PLAYER_QUIT, pkt, true);
-
-    // free
-//    delete this;
-}
-
-void NetworkServerPlayer::on_move (NetworkNode *src, NetworkPacket &pkt) {
-    // sanity-check, other players shouldn't move
-    if (src != node) {
-        Engine::log(WARN, "server_player.on_move") << "packet from wrong src=" << src << ", node=" << node;
-        return;
-    }
-    
-    PlayerInput_Move input = pkt.read_uint16();
-
-    Engine::log(INFO, "server_player.on_move") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
-    
-    // apply input
-    handleMove(input);  
-
-    // send position update
-    send_position_update();
-}
-        
-void NetworkServerPlayer::send_position_update (void) {
-    NetworkPacket pkt;
-    pkt.write_vector(position);
-    pkt.write_vector(velocity);
-    pkt.write_uint8(inAir & NETWORK_PHYSICS_INAIR);
-
-    Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity;
-
-    obj.send_all(NETMSG_PLAYER_POSITION, pkt, false);
-}
-
--- a/src/proto2/NetworkServer.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#ifndef NETWORKSERVER_HH
-#define NETWORKSERVER_HH
-
-#include "Network.hh"
-#include "GameState.hh"
-#include "NetworkSession.hh"
-#include "NetworkObject.hh"
-
-#include <list>
-#include <map>
-#include <ClanLib/core.h>
-
-// forward-declare
-class NetworkServerPlayer;
-
-class NetworkServer : public NetworkCore {
-    friend class NetworkServerPlayer;
-
-    protected:
-        NetworkSession netsession;
-        NetworkObject_ServerController netobjs;
-        std::list<NetworkServerPlayer *> players;
-
-    public:
-        NetworkServer (GameState &state, const NetworkAddress &listen_addr);
-    
-    protected:
-        void handle_disconnect (NetworkServerPlayer *player);
-
-    private:
-        void on_node_connected (NetworkNode *node);
-};
-
-class NetworkServerPlayer : public RemotePlayer {
-    private:
-        NetworkServer &server;
-        NetworkObject_Server obj;
-        NetworkNode *node;
-
-        CL_SlotContainer slots;
-        
-    public:
-        NetworkServerPlayer (NetworkServer &server, NetworkNode *node);
-
-    private:
-        void on_disconnected (void);
-        void on_move (NetworkNode *node, NetworkPacket &pkt);
-
-        void send_position_update (void);
-};
-
-#endif
--- a/src/proto2/NetworkSession.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-
-#include "NetworkSession.hh"
-#include "Engine.hh"
-
-#include <cassert>
-
-NetworkSession::NetworkSession (uint64_t magic) :
-    magic(magic), tcp_srv(NULL), udp_srv(NULL), udp_client(NULL) {
-   
-    // nothing
-}
-        
-void NetworkSession::listen (const NetworkAddress &addr) {
-    assert(tcp_srv == NULL && udp_srv == NULL);
-    
-    // create TCP/UDP servers
-    tcp_srv = new NetworkTCPServer(addr);
-    udp_srv = new NetworkUDP(addr);
-    
-    // connect signals
-    slots.connect(tcp_srv->sig_client(), this, &NetworkSession::on_tcp_client);
-    slots.connect(udp_srv->sig_packet(), this, &NetworkSession::on_udp_packet);
-}
-        
-NetworkNode *NetworkSession::build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type) {
-    // XXX: unused
-    (void) type;
-
-    // create node
-    return new NetworkNode(*this, tcp, udp, addr);
-}
-
-NetworkNode* NetworkSession::connect (const NetworkAddress &addr) {
-    // XXX: only one connect
-    assert(!udp_client);
-
-    // connect TCP
-    NetworkTCPClient *tcp_client = new NetworkTCPClient(addr);
-        
-    // create UDP socket on same address
-    udp_client = new NetworkUDP(tcp_client->getLocalAddress());
-    
-    // build client
-    NetworkNode *client_node = build_node(tcp_client, udp_client, addr, NETWORK_NODE_CLIENT_SERVER);
-
-    // add to nodes
-    nodes[addr] = client_node;
-
-    // connect signals
-    slots.connect(udp_client->sig_packet(), this, &NetworkSession::on_udp_packet);
-        
-    // return the "server" node
-    return client_node;
-}
-                
-void NetworkSession::handle_disconnect (NetworkNode *node) {
-    // remove from nodes
-    nodes.erase(node->getRemoteAddress());
-}
-        
-void NetworkSession::handle_message (NetworkPacket &pkt, NetworkNode *node) {
-    // read the channel id
-    NetworkChannelID channel_id = pkt.read_uint16();
-
-    // fire signal
-    _map_sig_chan_message[channel_id](pkt, node);
-}
- 
-void NetworkSession::on_tcp_client (NetworkTCPTransport *tcp_client) {
-    // get remote address manually, because NetworkTCPServer doesn't pass it in to us
-    NetworkAddress addr = tcp_client->getRemoteAddress();
-
-    // build client
-    NetworkNode *client_node = build_node(tcp_client, udp_srv, addr, NETWORK_NODE_SERVER_CLIENT);
-
-    // add to nodes
-    nodes[addr] = client_node;
-    
-    // fire signals
-    _sig_node_connected(client_node);
-}
-        
-void NetworkSession::on_udp_packet (NetworkPacket &pkt, const NetworkAddress &addr) {
-    NetworkNode *node = nodes[addr];
-    
-    // drop from unknown sources
-    if (!node) {
-        Engine::log(WARN, "net_session.on_udp_packet") << "dropping unsolicted UDP packet from " << addr;
-        return;
-    }
-
-    // handle
-    handle_message(pkt, node);
-}
-       
-void NetworkSession::send_all (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable) {
-    send_all_except(channel_id, pkt, NULL, reliable);
-}
-        
-void NetworkSession::send_all_except (NetworkChannelID channel_id, const NetworkPacket &pkt, const NetworkNode *node, bool reliable) {
-    for (std::map<NetworkAddress, NetworkNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
-        if (it->second == node)
-            continue;
-
-        it->second->send(channel_id, pkt, reliable);
-    }
-}
--- a/src/proto2/NetworkSession.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#ifndef NETWORK_SESSION_HH
-#define NETWORK_SESSION_HH
-
-#include <map>
-#include <stdint.h>
-
-// forward-declare
-class NetworkSession;
-
-/*
- * Used to separate packets, ID zero is reserved for NetworkSession use
- */
-typedef uint16_t NetworkChannelID;
-
-#include "NetworkTCP.hh"
-#include "NetworkUDP.hh"
-#include "NetworkNode.hh"
-
-class NetworkSession {
-    friend class NetworkNode;
-
-    private:
-        uint64_t magic;
-        NetworkTCPServer *tcp_srv;
-        NetworkUDP *udp_srv, *udp_client;
-
-        CL_SlotContainer slots;
-
-        std::map<NetworkAddress, NetworkNode*> nodes;
-        std::map<NetworkChannelID, CL_Signal_v2<NetworkPacket&, NetworkNode *> > _map_sig_chan_message;
-    
-    public:
-        NetworkSession (uint64_t magic);
-
-        void listen (const NetworkAddress &addr);
-        NetworkNode* connect (const NetworkAddress &addr);
-    
-    protected:
-        virtual NetworkNode *build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type);
-        
-        void handle_disconnect (NetworkNode *node);
-        void handle_message (NetworkPacket &pkt, NetworkNode *node);
-
-    private:
-        void on_tcp_client (NetworkTCPTransport *client);
-        void on_udp_packet (NetworkPacket &pkt, const NetworkAddress &addr);
-
-        CL_Signal_v1<NetworkNode*> _sig_node_connected;
-
-    public:
-        void send_all (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable = true);
-        void send_all_except (NetworkChannelID channel_id, const NetworkPacket &pkt, const NetworkNode *node, bool reliable = true);
-
-        CL_Signal_v1<NetworkNode*>& sig_node_connected (void) { return _sig_node_connected; }
-        CL_Signal_v2<NetworkPacket&, NetworkNode *>& sig_chan_message (NetworkChannelID cid) { return _map_sig_chan_message[cid]; }
-};
-
-#endif /* NETWORK_SESSION_HH */
--- a/src/proto2/NetworkSocket.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#ifndef NETWORK_SOCKET_HH
-#define NETWORK_SOCKET_HH
-
-#include "Error.hh"
-
-#include <ClanLib/Network/Socket/socket.h>
-#include <cerrno>
-#include <cstring>
-
-typedef CL_Socket NetworkSocket;
-
-// Network.cc
-class NetworkSocketError : public Error {
-    protected:
-        std::string build_str (const NetworkSocket &socket, const char *op, const char *err);
-
-        NetworkSocketError (const NetworkSocket &socket, const char *op, const char *err);
-};
-
-class NetworkSocketOSError : public NetworkSocketError {
-    public:
-        NetworkSocketOSError (const NetworkSocket &socket, const char *op) :
-            NetworkSocketError(socket, op, strerror(errno)) { }
-};
-
-class NetworkSocketEOFError : public NetworkSocketError {
-    public:
-        NetworkSocketEOFError (const NetworkSocket &socket, const char *op) :
-            NetworkSocketError(socket, op, "EOF") { }
-};
-
-#endif /* NETWORK_SOCKET_HH */
--- a/src/proto2/NetworkTCP.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,325 +0,0 @@
-
-#include "NetworkTCP.hh"
-#include "Engine.hh"
-
-#include <cstdlib>
-#include <cassert>
-
-NetworkBuffer::NetworkBuffer (NetworkSocket &socket, size_t size_hint) :
-    socket(socket), buf(0), size(0), offset(0) {
-    
-    // allocate initial buffer
-    if ((buf = (char *) malloc(size_hint)) == NULL)
-       throw NetworkBufferError("malloc failed");
-    
-    // remember size
-    size = size_hint;
-}
-        
-NetworkBuffer::~NetworkBuffer (void) {
-    free(buf);
-}
-
-void NetworkBuffer::resize (size_t item_size) {
-    size_t new_size = size;
-
-    // grow new_size until item_size fits
-    while (offset + item_size > new_size)
-        new_size *= 2;
-    
-    // grow if needed
-    if (new_size != size) {
-        // realloc buffer
-        if ((buf = (char *) realloc((void *) buf, new_size)) == NULL)
-            throw NetworkBufferError("realloc failed");
-
-        // update size
-        size = new_size;
-
-    } else if (new_size > (offset + item_size) * 4) {
-        // XXX: shrink?
-    }
-}
-        
-void NetworkBuffer::trim (size_t prefix_size) {
-    // update offset
-    offset -= prefix_size;
-
-    // shift the buffer forwards from (buf + prefix) -> (buf), copying (old_offset - prefix) bytes
-    memmove(buf, buf + prefix_size, offset);
-}
-     
-bool NetworkBuffer::try_read (size_t item_size) {
-    int ret;
-    size_t to_read = item_size;
-
-    // keept reads at at least NETWORK_CHUNK_SIZE bytes
-    if (to_read < NETWORK_TCP_CHUNK_SIZE)
-        to_read = NETWORK_TCP_CHUNK_SIZE;
-
-    // resize buffer if needed
-    resize(to_read);
-
-    // read once
-    try {
-        ret = socket.recv(buf + offset, to_read);
-
-    } catch (CL_Error &e) {
-        if (errno == EAGAIN)
-            return false;
-
-        else
-            throw NetworkSocketOSError(socket, "recv");
-    }
-    
-    // handle EOF
-    if (ret == 0)
-        throw NetworkSocketEOFError(socket, "recv");
-
-    assert(ret >= 0);
-
-    // update offset
-    offset += ret;
-
-    // did we get enough?
-    if ((unsigned int) ret < item_size)
-        return false;
-    else
-        return true;
-} 
-        
-bool NetworkBuffer::peek_prefix (uint16_t &ref) {
-    if (offset < sizeof(uint16_t))
-        return false;
-
-    ref = ntohs(*((uint16_t *) (buf)));
-
-    return true;
-}
-    
-bool NetworkBuffer::peek_prefix (uint32_t &ref) {
-    if (offset < sizeof(uint32_t))
-        return false;
-
-    ref = ntohl(*((uint32_t *) (buf)));
-
-    return true;
-}
-
-template <typename PrefixType> PrefixType NetworkBuffer::read_prefix (char *buf_ptr, size_t buf_max) {
-    PrefixType prefix = 0;
-    size_t missing = 0;
-    
-    do {    
-        // do we have the prefix?
-        if (peek_prefix(prefix)) {
-            // do we already have the payload?
-            if (offset >= sizeof(PrefixType) + prefix) {
-                break;
-
-            } else {
-                missing = (sizeof(PrefixType) + prefix) - offset;
-            }
-
-        } else {
-            missing = sizeof(PrefixType);
-        }
-
-        // sanity-check
-        assert(missing);
-        
-        // try and read the missing data
-        if (try_read(missing) == false) {
-            // if unable to read what we need, return zero.
-            return 0;
-        }
-        
-        // assess the situation again
-    } while (true);
-    
-    // copy the data over, unless it's too large
-    if (prefix <= buf_max) {
-        // ...don't copy the prefix, though
-        memcpy(buf_ptr, buf + sizeof(PrefixType), prefix);
-    
-        // trim the bytes out
-        trim(sizeof(PrefixType) + prefix);
-        
-        // return
-        return prefix;
-
-    } else {
-        // trim the bytes out
-        trim(sizeof(PrefixType) + prefix);
-        
-        throw NetworkBufferError("recv prefix overflow");   
-    }
-}
-   
-void NetworkBuffer::push_write (char *buf_ptr, size_t buf_size) {
-    int ret;
-
-    // try and short-circuit writes unless we have already buffered data
-    if (offset == 0) {
-        try {
-            // attempt to send something
-            ret = socket.send(buf_ptr, buf_size);
-
-        } catch (CL_Error &e) {
-            // ignore EAGAIN, detect this by setting ret to -1
-            if (errno != EAGAIN)
-                throw NetworkSocketOSError(socket, "send");
-
-            ret = -1;
-        }
-        
-        // if we managed to send something, adjust buf/size and buffer
-        if (ret > 0) {
-            // sanity-check
-            assert(buf_size >= (unsigned int) ret);
-
-            buf_ptr += ret;
-            buf_size -= ret;
-
-            // if that was all, we're done
-            if (buf_size == 0)
-                return;
-        }
-    }
-    
-    // resize to fit buf_size more bytes
-    resize(buf_size);
-    
-    // copy into our internal buffer
-    memcpy(buf + offset, buf_ptr, buf_size);
-}
-        
-void NetworkBuffer::flush_write (void) {
-    int ret;
-
-    // ignore if we don't have any data buffered
-    if (offset == 0)
-        return;
-    
-    // attempt to write as much as possible
-    try {
-        ret = socket.send(buf, offset);
-
-    } catch (CL_Error &e) {
-        // ignore EAGAIN and just return
-        if (errno == EAGAIN)
-            return;
-
-        else
-            throw NetworkSocketOSError(socket, "send");
-    }
-
-    // trim the buffer
-    trim(ret);
-}
-        
-void NetworkBuffer::write_prefix (char *buf, uint16_t prefix) {
-    uint16_t nval = htons(prefix);
-
-    push_write((char*) &nval, sizeof(uint16_t)); 
-    push_write(buf, prefix);
-}
-
-void NetworkBuffer::write_prefix (char *buf, uint32_t prefix) {
-    uint32_t nval = htonl(prefix);
-
-    push_write((char*) &nval, sizeof(uint32_t)); 
-    push_write(buf, prefix);
-}
-
-NetworkTCPTransport::NetworkTCPTransport (NetworkSocket socket) :
-    socket(socket), in(socket, NETWORK_TCP_INITIAL_IN_BUF), out(socket, NETWORK_TCP_INITIAL_OUT_BUF) {
-    
-    // connect signals
-    slots.connect(socket.sig_read_triggered(), this, &NetworkTCPTransport::on_read);
-    slots.connect(socket.sig_write_triggered(), this, &NetworkTCPTransport::on_write);
-    slots.connect(socket.sig_disconnected(), this, &NetworkTCPTransport::on_disconnected);
-}
-
-
-void NetworkTCPTransport::on_read (void) {
-    uint16_t prefix;
-    NetworkPacket packet;
-    
-    // let the in stream read length-prefixed packets and pass them on to handle_packet
-    while ((prefix = in.read_prefix<uint16_t>(packet.get_buf(), packet.get_buf_size())) > 0) {
-        packet.set_data_size(prefix);
-        _sig_packet(packet);
-    }
-}
-
-void NetworkTCPTransport::on_write (void) {
-    // just flush the output buffer
-    out.flush_write();
-}
-
-void NetworkTCPTransport::on_disconnected (void) {
-    // pass right through
-    _sig_disconnect();
-}
-        
-void NetworkTCPTransport::write_packet (const NetworkPacket &packet) {
-    uint16_t prefix = packet.get_data_size();
-    
-    if (prefix != packet.get_data_size())
-        throw CL_Error("send prefix overflow");
-    
-    try {
-        // just write to the output buffer
-        out.write_prefix((char *) packet.get_buf(), prefix);
-
-    } catch (Error &e) {
-        const char *err = e.what();
-
-        Engine::log(ERROR, "tcp.write_packet") << err;
-        
-        throw;    
-    }
-}
-
-NetworkTCPServer::NetworkTCPServer (const NetworkAddress &listen_addr) :
-    socket(CL_Socket::tcp, CL_Socket::ipv4) {
-    
-    // bind
-    socket.bind(listen_addr);
-
-    // assign slots
-    slots.connect(socket.sig_read_triggered(), this, &NetworkTCPServer::on_accept);
-
-    // listen
-    socket.listen(NETWORK_LISTEN_BACKLOG);
-    
-    // use nonblocking sockets
-    socket.set_nonblocking(true);
-}
-
-
-void NetworkTCPServer::on_accept (void) {
-    // accept a new socket
-    NetworkSocket client_sock = socket.accept();
-
-    // create a new NetworkTCPTransport
-    NetworkTCPTransport *client = buildTransport(client_sock);
-        
-    // let our user handle it
-    _sig_client(client);
-}
-        
-NetworkTCPTransport* NetworkTCPServer::buildTransport (CL_Socket &socket) {
-    return new NetworkTCPTransport(socket);
-}
-        
-NetworkTCPClient::NetworkTCPClient (const NetworkAddress &connect_addr) :
-    NetworkTCPTransport(NetworkSocket(CL_Socket::tcp, CL_Socket::ipv4)) {
-
-    // connect
-    socket.connect(connect_addr);
-    
-    // use nonblocking sockets
-    socket.set_nonblocking(true);
-}
--- a/src/proto2/NetworkTCP.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-#ifndef NETWORK_TCP_HH
-#define NETWORK_TCP_HH
-
-#include <ClanLib/core.h>
-
-#include "NetworkSocket.hh"
-#include "NetworkAddress.hh"
-#include "NetworkPacket.hh"
-#include "Error.hh"
-
-const size_t NETWORK_TCP_CHUNK_SIZE = 1024;
-const size_t NETWORK_TCP_INITIAL_IN_BUF = 4096;
-const size_t NETWORK_TCP_INITIAL_OUT_BUF = 0;
-
-class NetworkBufferError : public Error {
-    public:
-        NetworkBufferError (const std::string &message) : Error(message) { }
-};
-
-class NetworkBuffer {
-    private:
-        NetworkSocket socket;
-
-        char *buf;
-        size_t size, offset;
-    
-    public:
-        NetworkBuffer (NetworkSocket &socket, size_t size_hint);
-        ~NetworkBuffer (void);
-    
-    private:
-        NetworkBuffer (const NetworkBuffer &copy);
-        NetworkBuffer& operator= (const NetworkBuffer &copy);
-
-        void resize (size_t item_size);
-        void trim (size_t prefix_size);
-
-    public:    
-        void push_write (char *buf_ptr, size_t buf_size);
-        void flush_write (void);
-        void write_prefix (char *buf, uint16_t prefix);
-        void write_prefix (char *buf, uint32_t prefix);
-        
-        bool try_read (size_t item_size);
-        bool peek_prefix (uint16_t &ref);
-        bool peek_prefix (uint32_t &ref);
-        template <typename PrefixType> PrefixType read_prefix (char *buf_ptr, size_t buf_max);
-};
-
-class NetworkTCPTransport {
-    protected:
-        NetworkSocket socket;
-
-        NetworkBuffer in, out;
-    
-        CL_SlotContainer slots; 
-    
-    public:
-        NetworkTCPTransport (NetworkSocket socket);
-
-    private:
-        void on_read (void);
-        void on_write (void);
-        void on_disconnected (void);
-
-        CL_Signal_v1<NetworkPacket &> _sig_packet;
-        CL_Signal_v0 _sig_disconnect;
-
-    public:
-        NetworkAddress getLocalAddress (void) { return socket.get_source_address(); }
-        NetworkAddress getRemoteAddress (void) { return socket.get_dest_address(); }
-
-        void write_packet (const NetworkPacket &packet);
-        
-        CL_Signal_v1<NetworkPacket&>& sig_packet (void) { return _sig_packet; }
-        CL_Signal_v0& sig_disconnect (void) { return _sig_disconnect; }
-};
-
-class NetworkTCPServer {
-    private:
-        NetworkSocket socket;
-
-        CL_SlotContainer slots; 
-
-    public:
-        NetworkTCPServer (const NetworkAddress &listen_addr);
-
-    private:
-        void on_accept (void);
-
-        CL_Signal_v1<NetworkTCPTransport *> _sig_client;
-
-    protected:
-        virtual NetworkTCPTransport* buildTransport (CL_Socket &socket);
-
-    public:
-        CL_Signal_v1<NetworkTCPTransport *>& sig_client (void) { return _sig_client; }
-};
-
-class NetworkTCPClient : public NetworkTCPTransport {
-    public:
-        NetworkTCPClient (const NetworkAddress &connect_addr);
-};
-
-#endif /* NETWORK_TCP_HH */
--- a/src/proto2/NetworkUDP.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-
-#include "NetworkUDP.hh"
-
-#include <ClanLib/core.h>
-#include <cassert>
-
-NetworkUDP::NetworkUDP (void) : 
-    socket(CL_Socket::udp, CL_Socket::ipv4) {
-    
-    // do not bind
-
-    // connect signal
-    slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);
-
-    // nonblocking
-    socket.set_nonblocking(true);
-}
-
-NetworkUDP::NetworkUDP (const NetworkAddress &bind_addr) :
-    socket(CL_Socket::udp, CL_Socket::ipv4) {
-    
-    // bind socket
-    socket.bind(bind_addr);
-
-    // connect signal
-    slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);
-
-    // nonblocking
-    socket.set_nonblocking(true);
-}
-        
-void NetworkUDP::on_recv (void) {
-    int ret;
-    NetworkPacket pkt;
-    NetworkAddress src;
-    
-    // receieve as many packets as possible
-    do {    
-        // attempt to recv a packet
-        try {
-            ret = socket.recv(pkt.get_buf(), pkt.get_buf_size(), src);
-
-        } catch (CL_Error &e) {
-            if (errno == EAGAIN)
-                return;
-            else
-                throw;
-        }
-        
-        // set packet data size
-        pkt.set_data_size(ret);
-
-        // handle packet
-        _sig_packet(pkt, src);
-
-    } while (true);
-}
-        
-bool NetworkUDP::sendto (const NetworkPacket &packet, const NetworkAddress &dst) {
-    int ret;
-
-    // XXX: shouldn't get trimmed
-    try {
-        ret = socket.send(packet.get_buf(), packet.get_data_size(), dst);
-
-    } catch (CL_Error &e) {
-        // XXX: catch some errors, but not others?
-        return false;
-    }
-
-    assert(ret > 0);
-    
-    // UDP shouldn't trim packets
-    assert((unsigned int) ret == packet.get_data_size());
-    
-    // good
-    return true;
-}
-
--- a/src/proto2/NetworkUDP.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#ifndef NETWORK_UDP_HH
-#define NETWORK_UDP_HH
-
-#include "NetworkSocket.hh"
-#include "NetworkAddress.hh"
-#include "NetworkPacket.hh"
-
-class NetworkUDP {
-    private:
-        NetworkSocket socket;
-
-        CL_SlotContainer slots;
-
-    public:
-        NetworkUDP (void);
-        NetworkUDP (const NetworkAddress &bind_addr);
-
-    private:
-        void on_recv (void);
-
-        CL_Signal_v2<NetworkPacket &, const NetworkAddress&> _sig_packet;
-
-    public:
-        bool sendto (const NetworkPacket &packet, const NetworkAddress &dst);
-        
-        CL_Signal_v2<NetworkPacket &, const NetworkAddress&>& sig_packet (void) { return _sig_packet; }
-};
-
-#endif /* NETWORK_UDP_HH */
--- a/src/proto2/Physics.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,409 +0,0 @@
-#include "Physics.hh"
-#include "Engine.hh"
-#include "GameState.hh"
-#include "Terrain.hh"
-
-#include <algorithm>
-#include <functional>
-#include <cmath>
-#include <assert.h>
-
-PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
-    : Terrain(1337), tick_timer(PHYSICS_TICK_MS), tick_counter(0), dimensions(dimensions),
-      gravity(gravity) {
-    slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
-    tick_timer.enable();
-}
-
-void PhysicsWorld::addPlayerObject (PhysicsObject *object) {
-    players.push_back(object);
-}
-
-void PhysicsWorld::addProjectile (PhysicsObject *projectile) {
-    projectiles.push_back(projectile);
-}
-
-void PhysicsWorld::tick () {
-    //    Engine::log(DEBUG, "physics.apply_force") << "*tick*";
-
-    for (std::list<PhysicsObject*>::iterator i = players.begin(); i != players.end(); i++) {
-        (*i)->tick(); 
-    }
-
-    for (std::list<PhysicsObject*>::iterator i = projectiles.begin(); i != projectiles.end(); i++) {
-        (*i)->tick();
-    }
-
-    tick_counter++;
-}
-
-uint32_t PhysicsWorld::getTick (void) {
-    return tick_counter;
-}
-
-void PhysicsWorld::draw(CL_GraphicContext *gc) {
-    Terrain::draw(gc);
-   
-    // Draw players
-    for (std::list<PhysicsObject*>::iterator it = players.begin(); it != players.end(); it++) {
-        (*it)->draw(gc);
-    }
-    // Draw projectiles
-    for (std::list<PhysicsObject*>::iterator it = projectiles.begin(); it != projectiles.end(); it++) {
-        (*it)->draw(gc);
-    }
-}
-
-PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, 
-                              Vector position, Vector velocity)
-    : world(world), position(position), velocity(velocity),
-      mass(mass), inAir(true), aim(0), facingRight(true), reloadTimer(0) {
-    // TODO: Is thir the right way to do this?
-    //world.addPlayerObject(this);
-}
-
-/**
- * Player walks on floor.
- */
-Vector PhysicsObject::walk (TimeMS dt, bool right) {
-    // TODO: that dt should affect to something
-    float velocity = 100;
-    // which way we are walking
-    float deltaX = right ? (velocity*dt)/1000 : -(velocity*dt)/1000;
-    Vector reached = this->position;
-   
-    // Is there upward ramp
-    if(!possibleLocation(position+Vector(deltaX, 0))) {
-        // Yes. Then we check n pixels up
-        for(int i = 1; i < 3; i++) {
-            if(possibleLocation(position+Vector(deltaX, -i))) {
-                // and when there is finally EMPTY, we can walk
-                reached = position+Vector(deltaX, -i);
-                break;
-            }
-        }
-    } else {
-        // Or downward ramp or flat
-        for(int i = 0; 1; i++) {
-
-            // And when there is finally ground we can step on
-            // it. If there is no gound we still step there,
-            // but will fall one pixel down
-            if(possibleLocation(position+Vector(deltaX, i))) {
-                reached = position+Vector(deltaX, i);
-            } else {
-                break;
-            }
-            
-            // If the fall is big enough, set the worm in the air
-            if (i >= 2) {
-                Vector back = walk(dt, !right);
-                this->inAir = true;
-                this->velocity.x = right ? velocity : -velocity;
-                // Avoid stepping two pixels down when it starts to free fall
-                reached.y -= 2;
-                this->velocity = (reached-back)*1000/dt;
-                break;
-            }
-        }
-    }
-    // And we return where we got
-    return reached;
-
-}
-
-/**
- * Makes the player jump in the air.
- * @param direction -1: jump left, 0: jump up, 1: jump right
- */
-void PhysicsObject::jump (int direction) {
-    // Jump only if player is "on the ground"
-    if (!this->inAir) {
- 	    velocity.y = -100;
-        switch (direction) {
-            case 1:
-                velocity.x += 20;
-                break;
-            case -1:
-                velocity.x -= 20;
-                break;
-            case 0:
-                break;
-            default:
-                throw std::logic_error("Invalid jump direction");
-        }
-	    inAir = true;
-    }
-}
-
-bool PhysicsObject::possibleLocation (Vector loc) {
-    for(unsigned int i = 0; i < this->shape.size(); i++) {
-        if(world.collides(loc+shape[i]))
-            return false;
-    }
-    return true;
-}
-
-void func1() {
-
-}
-
-/**
- * Updates object speed and position. This function organises force
- * integration and collision detection.
- */   
-void PhysicsObject::updatePosition () {
-
-    // Reloads weapon if not reloaded
-    reloadTimer -= PHYSICS_TICK_MS;
-    if(reloadTimer < 0)
-        reloadTimer = 0;
-
-    // Add gravity to the force queue
-    forceq.push(world.gravity);
-    
-    // Go trough every force in the queue
-    Force total;
-    while (!forceq.empty()) {
-        total += forceq.front();
-        forceq.pop();
-    }
-
-    // If the player has stopped and there's some ground under some of the 3 some of the 3t
-    // set inAir false
-    if (this->velocity == Vector(0,0)) {
-        this->inAir = !world.collides(this->position+shape[1]+Vector(0, 1))
-                      && !world.collides(this->position+shape[2]+Vector(0, 1))
-                      && !world.collides(this->position+shape[3]+Vector(0, 1));
-        // If, however, there's a force caused by a bomb, e.g., set it in air.
-        // Still, we have to be able to separate forces caused by walking attempts
-        // and bombs etc (+0.1 because float comparison can be dangerous)
-        if (total.y < 0 || abs(total.x) > PLAYER_MOVE_FORCE + 0.1)
-            this->inAir = true;
-    }
-
-    if(!possibleLocation(position)) {
-        //if we are trapped in ground form dirtball or something
-        //we might want to just return and set velocity to some value
-        //return;
-    }
-
-    // If the worm is not in the air make it walk,
-    // otherwise integrate the new position and velocity
-    if (!this->inAir) {
-        //std::cout << "Tryin to walk" << std::endl;
-        // It walks only if there's some vertical force
-        if (total.x != 0) {
-            std::cout << "Succeeding to walk" << std::endl;
-            this->position = walk(PHYSICS_TICK_MS, total.x > 0);
-            this->velocity = Vector(0,0);
-        }
-    }
-
-    if(!possibleLocation(position)) {
-        Engine::log(DEBUG, "great failure") << "great failure";
-        func1();
-    }
-    Vector newPosition;
-    Vector velAfterTick;
-    // Calculate new position and velocity to the given references
-    integrate(total, PHYSICS_TICK_MS, newPosition, velAfterTick);
-    this->velocity = velAfterTick;
-
-   
-    // Collision detection
-    bool collided = false;
-   
-    const Vector diffVec = newPosition-position;
-    const Vector unitVector = diffVec / diffVec.length();
-    Vector reached = position;
-
-    while ((position-reached).sqrLength() < diffVec.sqrLength()) {
-        reached += unitVector;
-        // Check if any of the shapes points collide
-        for (uint64_t i = 0; i < shape.size(); i++) {
-            if (world.collides(reached+shape[i])) {  // Collision
-                if (inAir) {
-                    //                    Engine::log(DEBUG, "Here");
-                    this->bounce(world.getNormal(reached+shape[i], 
-                                                 reached-unitVector+shape[i]));
-                    //this->velocity *= COLLISION_ELASTICITY;
-                }
-                reached = reached - unitVector; // Return to last point
-                collided = true;
-                if (this->velocity.sqrLength() < PLAYER_MIN_SPEED * PLAYER_MIN_SPEED) {
-                    this->velocity = Vector(0,0);
-                }
-                break;
-            }
-        }
-        if (collided)
-            break;
-//        reached += unitVector;
-    }
-   
-    
-    if(!possibleLocation(reached)) {
-        Engine::log(DEBUG, "PhysicsObject.updatePosition") << "logic error reached should not be possible to be impossible.. diffVec: " << diffVec;
-        func1();
-    }
-
-    // In case of some float error check the final coordinate
-    if(!collided) {
-        if(!possibleLocation(newPosition)) {
-            newPosition = reached;
-        } else {
-            // This means everything was ok, so no need to do anything
-        }
-    } else {
-        newPosition = reached;
-        onCollision();
-        //this->velocity = Vector(0, 0);
-        //TODO: it shouldn't just stop on collision
-    }
-    if(!possibleLocation(newPosition)) {
-        Engine::log(DEBUG, "great failure") << "great failure";
-        func1();
-    }
-    this->position = newPosition;
-    if(!possibleLocation(position)) {
-        Engine::log(DEBUG, "great failure") << "great failure";
-        func1();
-    }
-//    Engine::log(DEBUG, "PhysicsObject.updatePosition") << "Pos: " << this->position;
-}
-
-/**
- * Bounces from straight wall in any direction.
- * Direction given as normal of that wall
- */
-void PhysicsObject::bounce (Vector normal) {
-    // normal.sqrLength can't be 0 when got from getNormal()
-    if (normal.sqrLength() != 0) {
-        Vector nvel = velocity;
-        // We project the velocity on normal and remove twice that much from velocity
-        nvel = nvel - ((2)*((nvel*normal)/(normal*normal))*normal);
-        velocity = nvel;
-        // We lose some of our speed on collision
-        this->velocity *= this->collision_elasticity;
-    }
-}
-
-/**
- * Integrates given force over time and stores new position to
- * posAfterTick and new velocity to velAfterTick.
- * @param force Force vector.
- * @param dt The time the force is applied (<=PHYSICS_TICK_MS)
- */
-void PhysicsObject::integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick) {
-    posAfterTick = position;
-    velAfterTick = velocity;
-    Derivative tmpd;
-    Derivative k1 = evaluate(force, 0, tmpd, posAfterTick, velAfterTick);
-    Derivative k2 = evaluate(force, 0.5f*dt, k1, posAfterTick, velAfterTick);
-    Derivative k3 = evaluate(force, 0.5f*dt, k2, posAfterTick, velAfterTick);
-    Derivative k4 = evaluate(force, dt, k3, posAfterTick, velAfterTick);
-    
-
-    const Vector dxdt = (k1.dx + (k2.dx + k3.dx) * 2.0f + k4.dx) * 1.0f/6.0f;
-    const Vector dvdt = (k1.dv + (k2.dv + k3.dv) * 2.0f + k4.dv) * 1.0f/6.0f;
-    
-    //    Engine::log(DEBUG, "PhysicsObject.integrate") << "Changes: "<< dxdt << " " << dvdt << " Time: " <<dt;
-    posAfterTick = posAfterTick + (dxdt * dt)/1000;
-    velAfterTick = velAfterTick + (dvdt * dt)/1000;
-    //Engine::log(DEBUG, "PhysicsObject.integrate") << "velAfterTick: " << velAfterTick;
-}
-
-Derivative PhysicsObject::evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick) {
-    Vector curPos = posAfterTick + (d.dx*dt)/1000;
-    Vector curVel = velAfterTick + (d.dv*dt)/1000;
-
-    Derivative out;
-    out.dx = curVel;
-    out.dv = acceleration(force);
-    //Engine::log(DEBUG, "PhysicsObject.evaluate") << "Out.dx: " << out.dx;
-    return out;
-}
-
-Vector PhysicsObject::acceleration(const Force &force) {
-    return (force/mass);
-}
-
-void PhysicsObject::applyForce (Force force) {
-    // Add applied force to the queue
-    forceq.push(force);
-}
-
-void PhysicsObject::changeAim(float da) {
-    this->aim += da;
-
-    if (this->aim > PLAYER_AIM_MAX) this->aim = PLAYER_AIM_MAX;
-    if (this->aim < PLAYER_AIM_MIN) this->aim = PLAYER_AIM_MIN;
-    //Engine::log(DEBUG, "PhysicsObject.changeAim") << "Player aim: " << this->aim;
-}
-
-void PhysicsObject::setFacing(bool facingRight) {
-    //Engine::log(DEBUG, "PhysicsObject.setFacing") << "Facing: " << right;
-    this->facingRight = facingRight;
-}
-
-void PhysicsObject::updatePhysics (Vector position, Vector velocity, bool inAir) {
-    this->position = position;
-    this->velocity = velocity;
-    this->inAir = inAir;
-}
-    
-Vector PhysicsObject::getPosition () {
-    return this->position;
-}
-
-bool PhysicsObject::getFacing() {
-    return this->facingRight;
-}
-
-float PhysicsObject::getAim() {
-    return this->aim;
-}
-
-std::vector<Vector>& PhysicsObject::getShape () {
-    return this->shape;
-}
-
-void PhysicsObject::setShape (std::vector<Vector> shape) {
-    this->shape = shape;
-}
-
-void PhysicsObject::tick () {
-    this->updatePosition();
-}
-
-bool PhysicsObject::canShoot() {
-    return this->reloadTimer <= 0;
-}
-
-void PhysicsObject::draw(CL_GraphicContext *gc) {
-    CL_Quad player(
-                   (position+shape[0]).x, (position+shape[0]).y,
-                   (position+shape[1]).x, (position+shape[1]).y,
-                   (position+shape[2]).x, (position+shape[2]).y,
-                   (position+shape[3]).x, (position+shape[3]).y
-                   );
-    
-    gc->fill_quad(player, CL_Color::green);
-    
-    const uint16_t chlen = 10;
-    uint16_t x = player.center().x;
-    uint16_t y = player.center().y;
-    if (facingRight) {
-        gc->draw_line(x, y,
-                      x + std::cos(aim)*chlen,
-                      y - std::sin(aim)*chlen,
-                      CL_Color::black);
-    } else {
-        gc->draw_line(x, y,
-                      x - std::cos(aim)*chlen,
-                      y - std::sin(aim)*chlen,
-                      CL_Color::black);
-    }
-}
-
--- a/src/proto2/Physics.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,297 +0,0 @@
-#ifndef PHYSICS_HH
-#define PHYSICS_HH
-
-#include <vector>
-#include <queue>
-#include <list>
-#include <ClanLib/core.h>
-#include <ClanLib/display.h>
-
-#include "Vector.hh"
-#include "Config.hh"
-#include "Terrain.hh"
-
-// Forward declares
-class PhysicsWorld;
-class PhysicsObject;
-class PlayerObject;
-class ProjectileObject;
-class Shape;
-struct Derivative;
-
-// Type definitions
-typedef uint16_t TimeMS;
-typedef Vector Force;
-
-/**
- * PhysicsWorld class. PhysicsWorld contains PhysicsObjects that are
- * simulated in the PhysicsWorld.
- */
-class PhysicsWorld : public Terrain {
-    friend class PhysicsObject;
-
-private:
-    CL_Timer tick_timer;
-    uint32_t tick_counter;
-
-    //    Terrain terrain;
-
-protected:
-    std::list<PhysicsObject*> players;
-    std::list<PhysicsObject*> projectiles;
-//    std::vector<PhysicsObject*> objects;
-
-    // Contains connections between signals and slots
-    CL_SlotContainer slots;
-
-    PhysicsWorld(Vector gravity, Vector dimensions);
-
-    // TODO: Should these be somewhere else?
-    Vector dimensions;
-    Vector gravity;
-
-
-
-public:
-    // TODO: Replace addObject with these?
-    //void addPlayerObject(PlayerObject *object);
-    //void addProjectileObject(ProjectileObject *object);
-    
-    /**
-     * Add object to the PhysicsWorld.
-     *
-     * @param object Pointer to the PhysicsObject to add.
-     */
-    void addPlayerObject(PhysicsObject *object);
-    
-    void addProjectile(PhysicsObject *projectile);
-
-    /**
-     * Advance one time step in physics simulation.
-     */
-    void tick();
-
-    /**
-     * Get current tick in physics simulation.
-     *
-     * @return tick Current simulation tick.
-     */
-    uint32_t getTick();
-
-    virtual void draw(CL_GraphicContext *gc);
-
-    // TODO This should probably be protected or in GameStat or in GameStatee
-};
-
-/**
- * PhysicObject class. A basic PhysicsObject class.
- */
-class PhysicsObject {
-protected:
-    // This probably shouldn't be done this way.
-    PhysicsWorld &world;
-
-    Vector position;
-    Vector velocity;
-    float mass;
-    bool inAir; // Is the object "on the ground"
-    float collision_elasticity;
-
-    // Attributes for players
-    float aim; // Aim direction (half circle)
-    bool facingRight; // Player facing
-
-    //
-    int reloadTimer;
-
-    PhysicsObject(PhysicsWorld &world, float mass, Vector position, 
-                  Vector velocity);
-    ~PhysicsObject() {}
-
-
-    /**
-     * Add force to the force queue to be applied on next tick.
-     *
-     * @param force Force vector
-     */
-    void applyForce(Force force);
-
-    /**
-     * Change player aim
-     *
-     * @param da Aim angle change
-     */
-    void changeAim(float da);
-   
-    /**
-     * Set player facing.
-     *
-     * @param facingRight True if player is facing right.
-     */
-    void setFacing(bool facingRight);
-
-    /**
-     * Makes the player jump in the air.
-     * @param direction -1: jump left, 0: jump up, 1: jump right
-     */
-    void jump(int direction);
-
-    /** 
-     * Handle ground-bounce
-     *
-     * @param normal Normal vector relative to which to bounce
-     */
-    void bounce(Vector normal);
-
-    /**
-     * Called on network clients to sync state from server
-     *
-     * @param position New position
-     * @param velocity New velocity
-     * @param inAir New inAir value
-     */
-    void updatePhysics(Vector position, Vector velocity, bool inAir);
-
-private:
-    // TODO: I'd be tempted to use some already made ClanLib structure
-    // here.  
-    // Shape of the object. Edge points of the shape polygon.
-    std::vector<Vector> shape;
-
-    // TODO: Should these operations be moved to PhysicsWorld?
-    // Force queue that is emptied on every tick
-    std::queue<Force> forceq;
-
-    /**
-     * Handle player movement and apply forces.
-     */
-    void updatePosition();
-
-    // TODO: Should these be moved to PhysicsWorld?
-    /**
-     * Use RK4 to integrate the effects of force over a time interwall.
-     *
-     * @param force Force to integrate
-     * @param dt Time intervall
-     */
-    void integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick);
-
-    /**
-     * Evaluate the value of the derivative at given time
-     *
-     * @param force Force
-     * @param dt Time
-     * @param d Previous derivative
-     */
-    Derivative evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick);
-
-    /**
-     * Return object acceleration with given force.
-     *
-     * @param force Force
-     * @return Acceleration
-     */
-    Vector acceleration(const Force &force);
-
-    // TODO: If integration is moved to PhysicsWorld then this should
-    // also move there.
-    /**
-     * Handle ground movement.
-     *
-     * @param right Boolean describing the movement direction.
-     * @return New position
-     */
-    Vector walk(TimeMS, bool right);
-
-    /*
-     * Handle collision. TODO: This is not used. It probably should
-     * be?
-     */
-    virtual void onCollision() {}
-
-    /*
-     * TODO: This probably does some kind of collision
-     * detection. Could be named/documented better.
-     */
-    bool possibleLocation(Vector loc);
-
-public:
-    /**
-     * Get current object position.
-     *
-     * @return Position vector
-     */
-    Vector getPosition();
-
-    /**
-     * Return object shape.
-     *
-     * @return Polygon points
-     */
-    std::vector<Vector>& getShape();
-
-    /**
-     * Set object shape.
-     *
-     * @param shape Vector containing polygon poinst
-     */
-    void setShape(std::vector<Vector> shape);
-
-    /**
-     * Return object facing.
-     *
-     * @return Object facing (true if facing right)
-     */
-    bool getFacing();
-
-    /**
-     * Return object aim angle.
-     *
-     * @return Object aim angle
-     */
-    float getAim();
-
-    /**
-     * Update object in physics simulation.
-     */
-    void tick();
-
-    /**
-     * @return whether this PhysicsObject can shoot or not
-     * This is in PhysicsObject for larpa-like shots
-     */
-    bool canShoot();
-
-    /**
-     * Draw object
-     *
-     * @param gc CL_GraphicContext
-     */
-    virtual void draw(CL_GraphicContext *gc);
-};
-
-// TODO: This could probably be moved somewhere else or removed
-// completely.
-struct Derivative {
-    Vector dx; // Velocity
-    Vector dv; // Acceleration
-};
-
-
-// TODO: These are drafts
-/**
- * PlayerObject class. Represents a player in the physics engine.
- */
-//class PlayerObject : public PhysicsObject {
-
-//};
-
-/**
- * ProjectileObject class. Represents different projectiles in the
- * physics (i.e. not players) in the physics engine.
- */
-//class ProjectileObject : public PhysicsObject {
-
-//};
-
-#endif
--- a/src/proto2/SinglePlayer.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef SINGLE_PLAYER_HH
-#define SINGLE_PLAYER_HH
-
-#include "GameState.hh"
-
-class SinglePlayer : public LocalPlayer {
-    public:
-        SinglePlayer (GameState &state) : LocalPlayer(state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true) { }
-};
-
-#endif /* SINGLE_PLAYER_HH */
--- a/src/proto2/Terrain.cc	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-#include "Terrain.hh"
-#include "Engine.hh"
-
-#include <cmath>
-#include <cassert>
-#include <algorithm>
-#include <ClanLib/display.h>
-
-Terrain::Terrain() {}
-Terrain::Terrain(const int &seed) 
-    : terrain(MAP_WIDTH, std::vector<TerrainType>(MAP_HEIGHT, DIRT)){
-    this->generateTerrain(seed);
-}
-Terrain::Terrain(const Terrain &t) {
-    this->terrain = t.getTerrain();
-    this->generatePixelBuffer();
-}
-
-void Terrain::generatePixelBuffer() {
-    this->pixbuf = CL_PixelBuffer(MAP_WIDTH, MAP_HEIGHT, 4*MAP_WIDTH, 
-                                  CL_PixelFormat::rgba8888);
-
-    CL_Color color;
-    for (uint16_t i = 0; i < MAP_WIDTH; i++) {
-        for (uint16_t j = 0; j < MAP_HEIGHT; j++) {
-            switch(terrain[i][j]) {
-            case EMPTY:
-                color = COLOR_EMPTY;
-                break;
-            case DIRT:
-                color = COLOR_DIRT;
-                break;
-            case ROCK:
-                color = COLOR_ROCK;
-                break;
-            default: // TODO: Shouldn't be here.
-                break; 
-            }
-            this->pixbuf.draw_pixel(i, j, color);
-        }
-    }
-}
-
-Vector Terrain::getPixelLocation(Vector point) const{
-    return Vector(scale(point.x), 
-                  scale(point.y));
-}
-
-uint16_t Terrain::scale(float x) const {
-    return (uint16_t)(x/MAP_SCALE);
-}
-
-TerrainType Terrain::getType(int32_t x, int32_t y) const {
-    if ((x < 0) || (y < 0) ||(x >= MAP_WIDTH) || (y >= MAP_HEIGHT)) {
-        return ROCK;
-    }
-    return terrain[x][y];
-}
-TerrainType Terrain::getType(Vector point) const {
-    return getType((int32_t)point.x, (int32_t)point.y);
-}
-
-bool Terrain::collides(const Vector &point) const {
-    Vector coor = getPixelLocation(point);
-    return (getType(coor.x, coor.y) != EMPTY);
-}
-
-bool Terrain::collides(const Vector &begin, const Vector &end) const {
-    // TODO: Maybe we should have another function prototype that also
-    // returns the point where we collided.
-
-    // We'll use Bresenhams line algorithm to go trough all the
-    // "pixels" of the line.
-    Vector b = getPixelLocation(begin);
-    Vector e = getPixelLocation(end);
-
-    bool steep = (abs(e.y - b.y) > abs(e.x - b.x)); // k > 1
-    if (steep) { // Line is steep -> swap x and y coordinates
-        std::swap(b.x, b.y);
-        std::swap(e.x, e.y);
-    }
-    if (b.x > e.x) { // Line goes down -> make it go up
-        std::swap(b, e);
-    }
-    uint16_t dx = e.x - b.x;
-    uint16_t dy = abs(e.y - b.y);
-    int32_t err = dx/2;
-    uint16_t ystep;
-    uint16_t y = b.y;
-    // Is the line ascending or descending
-    if (b.y < e.y) ystep = 1;
-    else ystep = -1;
-    // Go trough the line
-    for (uint16_t x =  b.x; x <= e.x; x++) {
-        if (steep) { // X and Y coordinates must be switched if steep
-            if (getType(y,x) != EMPTY) { // Collision!
-                return true;
-            }
-        } else {
-            if (getType(x,y) != EMPTY) { // Collision!
-                return true;
-            }
-        }
-        err = err - dy;
-        if (err < 0) { // Check if we want to make an ystep
-            y = y + ystep;
-            err = err + dx;
-        }
-    }
-    return false; // No Collision
-}
-
-void Terrain::removeGround(const Vector &pos, const float &radius) {
-    // TODO: Implement. Some circle algoritmh should be usefull here,
-    // though the current impelementation doesn't seem too bad either.
-
-    Vector mid = getPixelLocation(pos);
-    uint16_t r = scale(radius);
-    for (uint16_t i = mid.x-r; i < mid.x+r; i++) {
-        for (uint16_t j = mid.y-r; j < mid.y+r; j++) {
-            if (getType(i, j) != ROCK) { // getType returns ROCK if
-                                         // out of bounds
-                if ((i-mid.x)*(i-mid.x)+(j-mid.y)*(j-mid.y) < r*r) {
-                    terrain[i][j] = EMPTY;
-                    pixbuf.draw_pixel(i, j, COLOR_EMPTY);
-                }
-            }
-        }
-    }
-}
-
-/**
- * Gets the index of the given coordinate direction
- * referring to the DIRECTIONS table in Physics.hh
- */
-int getDirectionIndex (Vector direction) {
-    Vector dir = direction.roundToInt();
-    if(dir.x == 0 && dir.y == -1) {
-        return 0;
-    } else if(dir.x == 1 && dir.y == -1) {
-        return 1;
-    } else if(dir.x == 1 && dir.y == 0) {
-        return 2;
-    } else if(dir.x == 1 && dir.y == 1) {
-        return 3;
-    } else if(dir.x == 0 && dir.y == 1) {
-        return 4;
-    } else if(dir.x == -1 && dir.y == 1) {
-        return 5;
-    } else if(dir.x == -1 && dir.y == 0) {
-        return 6;
-    } else if(dir.x == -1 && dir.y == -1) {
-        return 7;
-    }
-    Engine::log(DEBUG, "Terrain.getDirectionIndex ") << "invalid direction: " << direction;
-    return 0;
-}
-
-/**
- * point should be ground and prevPoint air, but it's easy to assure that
- * @param point - pixel on ground to which was collided
- * @param prevPoint - pixel where we are when we collide
- */
-Vector Terrain::getNormal(Vector point, Vector prevPoint) const {
-    Vector p = getPixelLocation(point);
-
-    assert(point != prevPoint);
-
-    Vector normal(0,0);
-
-    // These two must be rounded separately
-    int dirIdx = getDirectionIndex(prevPoint.roundToInt() - point.roundToInt());
-//    dirIdx = (dirIdx+4)%8;
-
-    std::cout << (prevPoint.roundToInt()) - (point.roundToInt()) << prevPoint-point << std::endl;
-
-    normal += DIRECTIONS[dirIdx];
-    for(int i = 1; i <= 2; i++) {
-        if(getType(point + DIRECTIONS[(dirIdx+i+8)%8]) == EMPTY) {
-            normal += DIRECTIONS[(dirIdx+i+8)%8];
-        }
-    }
-    for(int i = 1; i <= 2; i++) {
-        if(getType(point + DIRECTIONS[(dirIdx-i+8)%8]) == EMPTY) {
-            normal += DIRECTIONS[(dirIdx-i+8)%8];
-        }
-    }
-
-    Engine::log(DEBUG, "Physics.getNormal ") << "normal: " << normal << "   dirIdx: " << dirIdx;
-
-    if(getType(point) == EMPTY || getType(prevPoint) != EMPTY) {
-        Engine::log(DEBUG, "Physics.getNormal ") << "logic ground error";
-    }
-    
-
-//    for (int i = 0; i < 8; i++) {
-//        if (getType(p.x+DIRECTIONS[i].x, p.y+DIRECTIONS[i].y) == EMPTY) {
-//            normal += DIRECTIONS[i];
-//        }
-//    }
-
-   
-    // Special cases
-    /*    Vector tmp = direction(direction(prevPoint-point) + direction(normal));
-    Engine::log(DEBUG, "Terrain.getNormal") << "tmp: " << tmp;
-    if (normal.length() == 0 || (tmp.x != 0 && tmp.y != 0 && getType(tmp.x, tmp.y) != EMPTY)) 
-        normal = prevPoint - point; // Direct hit
-    */
-//    Engine::log(DEBUG, "Terrain.getNormal") << "Normal: " << normal;
-    return normal;
-    return Vector(0,-1);
-}
-
-Vector direction(const Vector &v) {
-    Vector tmp(v);
-    if (tmp.length() > 0) tmp /= tmp.length();
-    tmp.x = (uint16_t)(tmp.x);
-    tmp.y = (uint16_t)(tmp.y);
-    return tmp;
-}
-
-// TODO: This could better :)
-// TODO: And this need some cleaning :)
-void Terrain::generateTerrain(int seed) {
-    srand(seed); // Set random number generator seed.
-
-    // Some constants to control random generation
-    const int min_range = 25;
-    const int max_range = 80;
-    const int num = 50;
-    const int rock_rarity = 4;
-
-    // Generate circles (or whatever)
-    for (int i = 0; i < num; i++) {
-        // Random generate circle attributes
-        int midx = rand()%MAP_WIDTH;
-        int midy = rand()%MAP_HEIGHT;
-        int range = rand()%(max_range-min_range)+min_range;
-
-        // Make sure that there's a circle in the midle of the cave
-        if (i == 0) {
-            midx = MAP_WIDTH/2;
-            midy = MAP_WIDTH/2;
-            range = 150;
-        }
-
-        TerrainType type = EMPTY;
-        if (rand()%rock_rarity == 0) {
-            type = ROCK;
-        }
-
-        // Loops for every pixel of the cirlcle (or square as it seems
-        // now)
-        for (int x = std::max(0, midx-range); 
-             x < std::min((int32_t)MAP_WIDTH, midx+range); 
-             x++) {
-            for (int y = std::max(0, midy-range);
-                    y < std::min((int32_t)MAP_HEIGHT, midy+range);
-                    y++) {
-                
-                //terrain[x][y] = type;
-
-                if ((x-midx)*(x-midx)+(y-midy)*(y-midy) < range*range) {
-                    terrain[x][y] = type;
-                }
-            }
-            
-        } 
-        
-    }
-    
-    this->generatePixelBuffer();
-}
-
-void Terrain::draw(CL_GraphicContext *gc) {
-    CL_Surface surf(this->pixbuf);
-    surf.draw(0,0,gc);
-}
-
-std::vector<std::vector<TerrainType> > Terrain::getTerrain() const {
-    return terrain;
-}
-
--- a/src/proto2/Terrain.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-#ifndef TERRAIN_HH
-#define TERRAIN_HH
-
-#include <vector>
-
-#include "Vector.hh"
-#include "Config.hh"
-
-enum TerrainType {EMPTY, DIRT, ROCK};
-
-const Vector DIRECTIONS[] = {
-    Vector(0,-1),
-    Vector(1,-1),
-    Vector(1,0),
-    Vector(1,1),
-    Vector(0,1),
-    Vector(-1,1),
-    Vector(-1,0),
-    Vector(-1,-1)
-};
-
-/**
- * Terrain class. Represents game terrain and contains member
- * functions to manipulate terrain and get info about it.
- * 
- * Terrain resolution is a constant that is defined in
- * configuration. Terrain has a scale (i.e. the width and height in
- * "real" units. Scaling is needed because physics simulation uses
- * "real" units. The idea is that this class is used with "real" units
- * and it uses pixelcoordinates internally.
- */ 
-class Terrain {
-private:
-    std::vector<std::vector<TerrainType> > terrain;
-
-    // Terrain graphic
-    CL_PixelBuffer pixbuf;
-
-    /**
-     * Generates pixelbuffer from terrain. Should be used only on
-     * constructors because this is expected to be slow.
-     */
-    void generatePixelBuffer();
-
-    /**
-     * Get pixel location of a point that is in "real" units.
-     *
-     * @param point Point in "real" units
-     * @return Int vector
-     */
-    Vector getPixelLocation(Vector point) const;
-
-    /**
-     * Scale parameter to "pixels"
-     *
-     * @param x Scaled value
-     * @return Corresponding value in pixels
-     */
-    uint16_t scale(float x) const;
-
- public:
-
-    // TODO: This should be private.
-    /**
-     * Return the type of terrain at given position. Returns ROCK if
-     * given point is not inside terrain area.
-     *
-     * @param x X coordinate
-     * @param y Y coordinate
-     * @return Terrain type
-     */
-    TerrainType getType(int32_t x, int32_t y) const;
-    //point is just rounded and redirected to that above
-    TerrainType getType(Vector point) const;
-
-    /**
-     * Constructor.
-     *
-     * @param scale The "real" width and height of the terrain.
-     */
-    Terrain();
-    /**
-     * Constructor.
-     *
-     * @param scale The "real" width and height of the terrain.
-     * @param seed Random number generator seed used to create the
-     * terrain.
-     */
-    Terrain(const int &seed);
-    /**
-     * Copy constructor.
-     *
-     * @param t Terrain to be copied.
-     */
-    Terrain(const Terrain &t);
-    /**
-     * Destructor
-     */
-    ~Terrain() {}
-
-    /**
-     * Check if given point has some terrain.
-     *
-     * @param point Point that is in scaled units.
-     */
-    bool collides(const Vector &point) const;
-    /**
-     * Check if given line collides with terrain.
-     *
-     * @param begin Line begin point in scaled units.
-     * @param end Line end point in scaled units.
-     */
-    bool collides(const Vector &begin, const Vector &end) const;
-    
-    /**
-     * Remove a circular area from terrain.
-     *
-     * @param pos Circle center
-     * @param r Circle radius
-     */ 
-    void removeGround(const Vector &pos, const float &r);
-
-    /**
-     * Return normal for the given point.
-     *
-     * @param point Point for which the normal is calculated.
-     * @return Normal vector ((0,0) if there's no terrain)
-     */
-    Vector getNormal(Vector point, Vector prevPoint) const;
-
-    /**
-     * Generate random terrain.
-     *
-     * @param seed Seed for the randomnumber generator.
-     */
-    void generateTerrain(int seed);
-
-    /**
-     * Draw the terrain for given graphicscontext.
-     *
-     * @param gc CL_GraphicContext
-     */
-    virtual void draw(CL_GraphicContext *gc);
-    /**
-     * Draw part of the terrain for given graphiscontext.
-     *
-     * @param gc CL_GraphicContext
-     * @param center Center of the rectangle drawn.
-     * @param dimension Dimensions of the rectangle.
-     */
-    //void draw(CL_GraphicContext &gc, Vector center, Vector dimensions);
-
-    /**
-     * Set terrain.
-     *
-     * @param terrain Terrain.
-     */
-    void setTerrain(const std::vector<std::vector<TerrainType> > &terrain);
-    /**
-     * Get terrain.
-     *
-     * @return Terrain.
-     */
-    std::vector<std::vector<TerrainType> > getTerrain() const;
-};
-
-Vector direction(const Vector &v);
-
-#endif
--- a/src/proto2/Vector.hh	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-#ifndef VECTOR_HH
-#define VECTOR_HH
-
-#include <iostream>
-#include <cmath>
-
-/**
- * A 2D Vector class. Implements standard vector operations.
- */
-template <typename T>
-class _Vector {
-public:
-    T x;
-    T y;
-
-    /**
-     * Default constructor.
-     */
-    _Vector() : x(0), y(0) {}
-    
-    /**
-     * Constuctor.
-     *
-     * @param x Initial x-coordinate
-     * @param y Initial y-coordinate
-     */
-    _Vector(T x, T y) : x(x), y(y) {}
-
-    /**
-     * Copy constructor.
-     *
-     * @param v Vector to be copied.
-     */
-    _Vector(const _Vector &v) : x(v.x), y(v.y) {}
-
-    // Operator declarations
-    void operator=(const _Vector &v) {
-        this->x = v.x;
-        this->y = v.y;
-    }
-    _Vector operator+(const _Vector &v) const {
-        return _Vector(this->x+v.x, this->y+v.y);
-    }
-    _Vector operator-(const _Vector &v) const {
-        return _Vector(this->x-v.x, this->y-v.y);
-    }
-    _Vector operator*(const T &scalar) const {
-        return _Vector(this->x*scalar, this->y*scalar);
-    }
-    T operator*(const _Vector &v) const {
-        return (this->x*v.x + this->y*v.y);
-    }
-    _Vector operator/(const T &d) const {
-        return _Vector(this->x/d, this->y/d);
-    }
-    void operator+=(const _Vector &v) {
-        *this = *this + v;
-    }
-    void operator-=(const _Vector &v) {
-        *this = *this - v;
-    }
-    void operator*=(const T &scalar) {
-        *this = *this * scalar;
-    }
-    void operator/=(const T &scalar) {
-        *this = *this / scalar;
-    }
-
-    // Other operations
-    T length() const {
-        return sqrt(sqrLength());
-    }
-    T sqrLength() const {
-        return (this->x * this->x) + (this->y * this->y);
-    }
-    _Vector roundToInt() const {
-        return _Vector((int)(x), (int)(y));
-    }
-};
-
-// Unary operators
-template<typename T>
-_Vector<T> operator*(const T &scalar, const _Vector<T> v) {
-    return (v * scalar);
-} 
-
-// Comparison operators
-template<typename T>
-bool operator==(const _Vector<T> &v1, const _Vector<T> &v2) {
-    return ((v1.x == v2.x) && (v1.y == v2.y));
-}
-template<typename T>
-bool operator!=(const _Vector<T> &v1, const _Vector<T> &v2) {
-    return !(v1 == v2);
-}
-
-// Output operator
-template<typename T>
-std::ostream& operator<<(std::ostream &s, const _Vector<T> &v) {
-    return s<<"("<<v.x<<", "<<v.y<<")";
-}
-
-// Standard vector
-typedef _Vector<float> Vector;
-
-#endif
--- a/src/proto2/config.h.in	Wed Dec 03 18:59:10 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#ifndef @PROJECT_SHORT_NAME@_CONFIG_H
-#define @PROJECT_SHORT_NAME@_CONFIG_H
-
-/* Note: CMake autogenerates build/src/config.h from src/config.h.in */
-/* #include "config.h" to use the generated file */
-
-#define PROJECT_DATA_DIR "@PROJECT_DATA_DIR@"
-#define PROJECT_SHORT_NAME "@PROJECT_SHORT_NAME@"
-#define PROJECT_LONG_NAME "@PROJECT_LONG_NAME@"
-#define PROJECT_VERSION "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@"
-
-#endif
-