diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-05-24 20:54:08 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-05-24 20:54:08 +0000 |
| commit | 82023866ab4c7483652e9d4605290e39ced3bec3 (patch) | |
| tree | cbff99cb472b4434d18e8e1fe3c556ca194096a6 /src/client.cpp | |
| parent | 34e3df396630e9bb271ea8965869d23260900a7d (diff) | |
| download | zcatch-82023866ab4c7483652e9d4605290e39ced3bec3.tar.gz zcatch-82023866ab4c7483652e9d4605290e39ced3bec3.zip | |
large change. moved around all source. splitted server and client into separate files
Diffstat (limited to 'src/client.cpp')
| -rw-r--r-- | src/client.cpp | 713 |
1 files changed, 0 insertions, 713 deletions
diff --git a/src/client.cpp b/src/client.cpp deleted file mode 100644 index 2f231117..00000000 --- a/src/client.cpp +++ /dev/null @@ -1,713 +0,0 @@ -#include <baselib/system.h> -#include <baselib/keys.h> -#include <baselib/mouse.h> -#include <baselib/audio.h> -#include <baselib/stream/file.h> - -#include <string.h> -#include <stdarg.h> -#include <math.h> -#include "interface.h" - - -#include "packet.h" -#include "snapshot.h" -#include "ui.h" - -#include "lzw.h" - -#include "versions.h" - -using namespace baselib; - -// --- string handling (MOVE THESE!!) --- -void snap_encode_string(const char *src, int *dst, int length, int max_length) -{ - const unsigned char *p = (const unsigned char *)src; - - // handle whole int - for(int i = 0; i < length/4; i++) - { - *dst = (p[0]<<24|p[1]<<16|p[2]<<8|p[3]); - p += 4; - dst++; - } - - // take care of the left overs - int left = length%4; - if(left) - { - unsigned last = 0; - switch(left) - { - case 3: last |= p[2]<<8; - case 2: last |= p[1]<<16; - case 1: last |= p[0]<<24; - } - *dst = last; - } -} - -void snap_decode_string(const int *src, char *dst, int max_length) -{ - dbg_assert((max_length%4) == 0, "length must be power of 4"); - for(int i = 0; i < max_length; i++) - dst[0] = 0; - - for(int i = 0; i < max_length/4; i++) - { - dst[0] = (*src>>24)&0xff; - dst[1] = (*src>>16)&0xff; - dst[2] = (*src>>8)&0xff; - dst[3] = (*src)&0xff; - src++; - dst+=4; - } - dst[-1] = 0; // make sure to zero terminate -} - -// --- input wrappers --- -static int keyboard_state[2][keys::last]; -static int keyboard_current = 0; -static int keyboard_first = 1; - -void inp_mouse_relative(int *x, int *y) { mouse::position(x, y); } -int inp_key_pressed(int key) { return keyboard_state[keyboard_current][key]; } -int inp_key_was_pressed(int key) { return keyboard_state[keyboard_current^1][key]; } -int inp_key_down(int key) { return inp_key_pressed(key)&&!inp_key_was_pressed(key); } -int inp_mouse_button_pressed(int button) { return mouse::pressed(button); } - -void inp_update() -{ - if(keyboard_first) - { - // make sure to reset - keyboard_first = 0; - inp_update(); - } - - keyboard_current = keyboard_current^1; - for(int i = 0; i < keys::last; i++) - keyboard_state[keyboard_current][i] = keys::pressed(i); -} - -// --- input snapping --- -static int input_data[MAX_INPUT_SIZE]; -static int input_data_size; -static int input_is_changed = 1; -void snap_input(void *data, int size) -{ - if(input_data_size != size || memcmp(input_data, data, size)) - input_is_changed = 1; - mem_copy(input_data, data, size); - input_data_size = size; -} - -// -- snapshot handling --- -enum -{ - SNAP_INCOMMING=2, - NUM_SNAPSHOT_TYPES=3, -}; - -static snapshot *snapshots[NUM_SNAPSHOT_TYPES]; -static char snapshot_data[NUM_SNAPSHOT_TYPES][MAX_SNAPSHOT_SIZE]; -static int recived_snapshots; -static int64 snapshot_start_time; -static int64 local_start_time; - -float client_localtime() -{ - return (time_get()-local_start_time)/(float)(time_freq()); -} - -void *snap_get_item(int snapid, int index, snap_item *item) -{ - dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid"); - snapshot::item *i = snapshots[snapid]->get_item(index); - item->type = i->type(); - item->id = i->id(); - return (void *)i->data; -} - -int snap_num_items(int snapid) -{ - dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid"); - return snapshots[snapid]->num_items; -} - -static void snap_init() -{ - snapshots[SNAP_INCOMMING] = (snapshot*)snapshot_data[0]; - snapshots[SNAP_CURRENT] = (snapshot*)snapshot_data[1]; - snapshots[SNAP_PREV] = (snapshot*)snapshot_data[2]; - mem_zero(snapshot_data, NUM_SNAPSHOT_TYPES*MAX_SNAPSHOT_SIZE); - recived_snapshots = 0; -} - -float snap_intratick() -{ - return (time_get() - snapshot_start_time)/(float)(time_freq()/SERVER_TICK_SPEED); -} - -void *snap_find_item(int snapid, int type, int id) -{ - // TODO: linear search. should be fixed. - for(int i = 0; i < snapshots[snapid]->num_items; i++) - { - snapshot::item *itm = snapshots[snapid]->get_item(i); - if(itm->type() == type && itm->id() == id) - return (void *)itm->data; - } - return 0x0; -} - - -int menu_loop(); -float frametime = 0.0001f; - -float client_frametime() -{ - return frametime; -} - -void unpack(const char *src, const char *fmt, ...) -{ -} - -/*int modc_onmsg(int msg) -{ - msg_get("iis") -}*/ - -/* - i = int (int i) - s = string (const char *str) - r = raw data (int size, void *data) -*/ - -/* -class packet2 -{ -private: - // packet data - struct header - { - unsigned msg; - unsigned ack; - unsigned seq; - }; - - unsigned char packet_data[MAX_PACKET_SIZE]; - unsigned char *current; - - enum - { - MAX_PACKET_SIZE = 1024, - }; - -public: - packet2() - { - current = packet_data; - current += sizeof(header); - } - - int pack(char *dst, const char *fmt, ...) - { - va_list arg_list; - va_start(arg_list, fmt); - while(*fmt) - { - if(*fmt == 's') - { - // pack string - const char *s = va_arg(arg_list, const char*); - *dst++ = 2; - while(*s) - { - *dst = *s; - dst++; - s++; - } - *dst = 0; // null terminate - dst++; - fmt++; - } - else if(*fmt == 'i') - { - // pack int - int i = va_arg(arg_list, int); - *dst++ = 1; - *dst++ = (i>>24)&0xff; - *dst++ = (i>>16)&0xff; - *dst++ = (i>>8)&0xff; - *dst++ = i&0xff; - fmt++; - } - else - { - dbg_break(); // error - break; - } - } - va_end(arg_list); - } -}; -*/ -/* -int msg_get(const char *fmt) -{ - -} - -int client_msg_send(int msg, const char *fmt, ...) - -int server_msg_send(int msg, const char *fmt, ...) -{ - -}*/ - -// --- client --- -class client -{ -public: - socket_udp4 socket; - connection conn; - int64 reconnect_timer; - - int snapshot_part; - - int debug_font; // TODO: rfemove this line - - // data to hold three snapshots - // previous, - char name[MAX_NAME_LENGTH]; - - bool fullscreen; - - enum - { - STATE_OFFLINE, - STATE_CONNECTING, - STATE_LOADING, - STATE_ONLINE, - STATE_BROKEN, - STATE_QUIT, - }; - - int state; - int get_state() { return state; } - void set_state(int s) - { - dbg_msg("game", "state change. last=%d current=%d", state, s); - state = s; - } - - void set_name(const char *new_name) - { - mem_zero(name, MAX_NAME_LENGTH); - strncpy(name, new_name, MAX_NAME_LENGTH); - name[MAX_NAME_LENGTH-1] = 0; - } - - void set_fullscreen(bool flag) { fullscreen = flag; } - - void send_packet(packet *p) - { - conn.send(p); - } - - void send_connect() - { - recived_snapshots = 0; - - /* - pack(NETMSG_CLIENT_CONNECT, "sssss", - TEEWARS_NETVERSION, - name, - "no clan", - "password", - "myskin"); - */ - - packet p(NETMSG_CLIENT_CONNECT); - p.write_str(TEEWARS_NETVERSION); // payload - p.write_str(name); - p.write_str("no clan"); - p.write_str("password"); - p.write_str("myskin"); - send_packet(&p); - } - - void send_done() - { - packet p(NETMSG_CLIENT_DONE); - send_packet(&p); - } - - void send_error(const char *error) - { - /* - pack(NETMSG_CLIENT_ERROR, "s", error); - */ - packet p(NETMSG_CLIENT_ERROR); - p.write_str(error); - send_packet(&p); - //send_packet(&p); - //send_packet(&p); - } - - void send_input() - { - /* - pack(NETMSG_CLIENT_ERROR, "s", error); - */ - packet p(NETMSG_CLIENT_INPUT); - p.write_int(input_data_size); - for(int i = 0; i < input_data_size/4; i++) - p.write_int(input_data[i]); - send_packet(&p); - } - - void disconnect() - { - send_error("disconnected"); - set_state(STATE_OFFLINE); - map_unload(); - } - - void connect(netaddr4 *server_address) - { - conn.init(&socket, server_address); - - // start by sending connect - send_connect(); - set_state(STATE_CONNECTING); - reconnect_timer = time_get()+time_freq(); - } - - bool load_data() - { - debug_font = gfx_load_texture_tga("data/debug_font.tga"); - return true; - } - - void render() - { - gfx_clear(0.0f,0.0f,0.0f); - - // this should be moved around abit - if(get_state() == STATE_ONLINE) - { - modc_render(); - } - else if (get_state() != STATE_CONNECTING && get_state() != STATE_LOADING) - { - netaddr4 server_address; - int status = modmenu_render(&server_address, name, MAX_NAME_LENGTH); - - if (status == -1) - set_state(STATE_QUIT); - else if (status) - connect(&server_address); - } - else if (get_state() == STATE_CONNECTING) - { - static int64 start = time_get(); - static int tee_texture; - static int connecting_texture; - static bool inited = false; - - if (!inited) - { - tee_texture = gfx_load_texture_tga("data/gui_tee.tga"); - connecting_texture = gfx_load_texture_tga("data/gui/connecting.tga"); - - inited = true; - } - - gfx_mapscreen(0,0,400.0f,300.0f); - - float t = (time_get() - start) / (double)time_freq(); - - float speed = 2*sin(t); - - speed = 1.0f; - - float x = 208 + sin(t*speed) * 32; - float w = sin(t*speed + 3.149) * 64; - - ui_do_image(tee_texture, x, 95, w, 64); - ui_do_image(connecting_texture, 88, 150, 256, 64); - } - } - - void run(netaddr4 *server_address) - { - snapshot_part = 0; - - // init graphics and sound - if(!gfx_init(fullscreen)) - return; - - snd_init(); // sound is allowed to fail - - // load data - if(!load_data()) - return; - - // init snapshotting - snap_init(); - - // init the mod - modc_init(); - - // init menu - modmenu_init(); - - // open socket - if(!socket.open(0)) - { - dbg_msg("network/client", "failed to open socket"); - return; - } - - // connect to the server if wanted - if (server_address) - connect(server_address); - - int64 inputs_per_second = 50; - int64 time_per_input = time_freq()/inputs_per_second; - int64 game_starttime = time_get(); - int64 last_input = game_starttime; - - int64 reporttime = time_get(); - int64 reportinterval = time_freq()*1; - int frames = 0; - - mouse::set_mode(mouse::mode_relative); - - while (1) - { - frames++; - int64 frame_start_time = time_get(); - - // send input - if(get_state() == STATE_ONLINE) - { - if(input_is_changed || time_get() > last_input+time_freq()) - { - send_input(); - input_is_changed = 0; - last_input = time_get(); - } - } - - // update input - inp_update(); - - // - if(keys::pressed(keys::f1)) - mouse::set_mode(mouse::mode_absolute); - if(keys::pressed(keys::f2)) - mouse::set_mode(mouse::mode_relative); - - // pump the network - pump_network(); - - // render - render(); - - // swap the buffers - gfx_swap(); - - // check conditions - if(get_state() == STATE_BROKEN || get_state() == STATE_QUIT) - break; - - // be nice - //thread_sleep(1); - - if(reporttime < time_get()) - { - unsigned sent, recved; - conn.counter_get(&sent, &recved); - dbg_msg("client/report", "fps=%.02f", - frames/(float)(reportinterval/time_freq())); - frames = 0; - reporttime += reportinterval; - conn.counter_reset(); - } - - if (keys::pressed(keys::esc)) - if (get_state() == STATE_CONNECTING || get_state() == STATE_ONLINE) - disconnect(); - - // update frametime - frametime = (time_get()-frame_start_time)/(float)time_freq(); - } - - modc_shutdown(); - disconnect(); - - modmenu_shutdown(); - - gfx_shutdown(); - snd_shutdown(); - } - - void error(const char *msg) - { - dbg_msg("game", "error: %s", msg); - send_error(msg); - set_state(STATE_BROKEN); - } - - void process_packet(packet *p) - { - if(p->msg() == NETMSG_SERVER_ACCEPT) - { - const char *map; - map = p->read_str(); - - if(p->is_good()) - { - dbg_msg("client/network", "connection accepted, map=%s", map); - set_state(STATE_LOADING); - - if(map_load(map)) - { - modc_entergame(); - send_done(); - dbg_msg("client/network", "loading done"); - // now we will wait for two snapshots - // to finish the connection - } - else - { - error("failure to load map"); - } - } - } - else if(p->msg() == NETMSG_SERVER_SNAP) - { - //dbg_msg("client/network", "got snapshot"); - int num_parts = p->read_int(); - int part = p->read_int(); - int part_size = p->read_int(); - - if(p->is_good()) - { - if(snapshot_part == part) - { - const char *d = p->read_raw(part_size); - mem_copy((char*)snapshots[SNAP_INCOMMING] + part*MAX_SNAPSHOT_PACKSIZE, d, part_size); - snapshot_part++; - - if(snapshot_part == num_parts) - { - snapshot *tmp = snapshots[SNAP_PREV]; - snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT]; - snapshots[SNAP_CURRENT] = tmp; - - // decompress snapshot - lzw_decompress(snapshots[SNAP_INCOMMING], snapshots[SNAP_CURRENT]); - - // apply snapshot, cycle pointers - recived_snapshots++; - snapshot_start_time = time_get(); - - // we got two snapshots until we see us self as connected - if(recived_snapshots == 2) - { - local_start_time = time_get(); - set_state(STATE_ONLINE); - } - - if(recived_snapshots > 2) - modc_newsnapshot(); - - snapshot_part = 0; - } - - } - else - { - dbg_msg("client", "snapshot reset!"); - snapshot_part = 0; - } - } - } - else - { - dbg_msg("server/client", "unknown packet %x", p->msg()); - } - } - - void pump_network() - { - while(1) - { - packet p; - netaddr4 from; - int bytes = socket.recv(&from, p.data(), p.max_size()); - - if(bytes <= 0) - break; - - process_packet(&p); - } - - // - if(get_state() == STATE_CONNECTING && time_get() > reconnect_timer) - { - send_connect(); - reconnect_timer = time_get() + time_freq(); - } - } -}; - -int client_main(int argc, char **argv) -{ - dbg_msg("client", "starting..."); - netaddr4 server_address(127, 0, 0, 1, 8303); - const char *name = "nameless jerk"; - bool connect_at_once = false; - bool fullscreen = true; - - // init network, need to be done first so we can do lookups - net_init(); - - // parse arguments - for(int i = 1; i < argc; i++) - { - if(argv[i][0] == '-' && argv[i][1] == 'c' && argv[i][2] == 0 && argc - i > 1) - { - // -c SERVER - i++; - if(net_host_lookup(argv[i], 8303, &server_address) != 0) - dbg_msg("main", "could not find the address of %s, connecting to localhost", argv[i]); - else - connect_at_once = true; - } - else if(argv[i][0] == '-' && argv[i][1] == 'n' && argv[i][2] == 0 && argc - i > 1) - { - // -n NAME - i++; - name = argv[i]; - } - else if(argv[i][0] == '-' && argv[i][1] == 'w' && argv[i][2] == 0) - { - // -w - fullscreen = false; - } - } - - // start the server - client c; - c.set_name(name); - c.set_fullscreen(fullscreen); - c.run(connect_at_once ? &server_address : 0x0); - return 0; -} |