diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-01-12 17:09:00 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-01-12 17:09:00 +0000 |
| commit | 906ece7894927983b8ac69e37dd3cb82cfe7aad1 (patch) | |
| tree | c3e83b60f04c5f26975106d807ad5185d20827be /src/game/client/gc_hooks.cpp | |
| parent | 99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5 (diff) | |
| download | zcatch-906ece7894927983b8ac69e37dd3cb82cfe7aad1.tar.gz zcatch-906ece7894927983b8ac69e37dd3cb82cfe7aad1.zip | |
continued the cleanup
Diffstat (limited to 'src/game/client/gc_hooks.cpp')
| -rw-r--r-- | src/game/client/gc_hooks.cpp | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp new file mode 100644 index 00000000..febb6478 --- /dev/null +++ b/src/game/client/gc_hooks.cpp @@ -0,0 +1,500 @@ +#include <string.h> + +#include <engine/e_interface.h> + +extern "C" { + #include <engine/e_config.h> + #include <engine/client/ec_font.h> +}; + +#include <game/generated/gc_data.h> +#include <game/g_game.h> +#include <game/g_version.h> + +#include "gc_client.h" +#include "gc_skin.h" +#include "gc_render.h" +#include "gc_mapres_image.h" +#include "gc_mapres_tilemap.h" + +extern unsigned char internal_data[]; + +extern void menu_init(); +extern bool menu_active; +extern bool menu_game_active; + + +extern "C" void modc_init() +{ + static FONT_SET default_font; + + int before = gfx_memory_usage(); + font_set_load(&default_font, "fonts/default_font%d.tfnt", "fonts/default_font%d.png", "fonts/default_font%d_b.png", 14, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 36); + dbg_msg("font", "gfx memory usage: %d", gfx_memory_usage()-before); + + gfx_text_set_default_font(&default_font); + + menu_init(); + + // setup sound channels + snd_set_channel(CHN_GUI, 1.0f, 0.0f); + snd_set_channel(CHN_MUSIC, 1.0f, 0.0f); + snd_set_channel(CHN_WORLD, 0.9f, 1.0f); + snd_set_channel(CHN_GLOBAL, 1.0f, 0.0f); + + // load the data container + data = load_data_from_memory(internal_data); + + // TODO: should be removed + snd_set_listener_pos(0.0f, 0.0f); + + float total = data->num_sounds+data->num_images; + float current = 0; + + // load textures + for(int i = 0; i < data->num_images; i++) + { + render_loading(current/total); + data->images[i].id = gfx_load_texture(data->images[i].filename, IMG_AUTO); + current++; + } + + // load sounds + for(int s = 0; s < data->num_sounds; s++) + { + render_loading(current/total); + for(int i = 0; i < data->sounds[s].num_sounds; i++) + { + int id; + //if (strcmp(data->sounds[s].sounds[i].filename + strlen(data->sounds[s].sounds[i].filename) - 3, ".wv") == 0) + id = snd_load_wv(data->sounds[s].sounds[i].filename); + //else + // id = snd_load_wav(data->sounds[s].sounds[i].filename); + + data->sounds[s].sounds[i].id = id; + } + + current++; + } + + skin_init(); +} + +extern "C" void modc_entergame() +{ +} + +extern "C" void modc_shutdown() +{ + // shutdown the menu +} + + +player_core predicted_prev_player; +player_core predicted_player; +static int predicted_tick = 0; +static int last_new_predicted_tick = -1; + +extern "C" void modc_predict() +{ + player_core before_prev_player = predicted_prev_player; + player_core before_player = predicted_player; + + // repredict player + world_core world; + int local_cid = -1; + + // search for players + for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++) + { + SNAP_ITEM item; + const void *data = snap_get_item(SNAP_CURRENT, i, &item); + int client_id = item.id; + + if(item.type == OBJTYPE_PLAYER_CHARACTER) + { + const obj_player_character *character = (const obj_player_character *)data; + client_datas[client_id].predicted.world = &world; + world.players[client_id] = &client_datas[client_id].predicted; + + client_datas[client_id].predicted.read(character); + } + else if(item.type == OBJTYPE_PLAYER_INFO) + { + const obj_player_info *info = (const obj_player_info *)data; + if(info->local) + local_cid = client_id; + } + } + + // predict + for(int tick = client_tick()+1; tick <= client_predtick(); tick++) + { + // fetch the local + if(tick == client_predtick() && world.players[local_cid]) + predicted_prev_player = *world.players[local_cid]; + + // first calculate where everyone should move + for(int c = 0; c < MAX_CLIENTS; c++) + { + if(!world.players[c]) + continue; + + mem_zero(&world.players[c]->input, sizeof(world.players[c]->input)); + if(local_cid == c) + { + // apply player input + int *input = client_get_input(tick); + if(input) + world.players[c]->input = *((player_input*)input); + } + + world.players[c]->tick(); + } + + // move all players and quantize their data + for(int c = 0; c < MAX_CLIENTS; c++) + { + if(!world.players[c]) + continue; + + + // TODO: this should be moved into the g_game + // but not done to preserve the nethash + if(length(world.players[c]->vel) > 150.0f) + world.players[c]->vel = normalize(world.players[c]->vel) * 150.0f; + + world.players[c]->move(); + world.players[c]->quantize(); + } + + if(tick > last_new_predicted_tick) + { + last_new_predicted_tick = tick; + + if(local_cid != -1 && world.players[local_cid]) + { + vec2 pos = world.players[local_cid]->pos; + int events = world.players[local_cid]->triggered_events; + if(events&COREEVENT_GROUND_JUMP) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); + if(events&COREEVENT_AIR_JUMP) + { + effect_air_jump(pos); + snd_play_random(CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, pos); + } + //if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos); + if(events&COREEVENT_HOOK_ATTACH_PLAYER) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH_PLAYER, 1.0f, pos); + if(events&COREEVENT_HOOK_ATTACH_GROUND) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH_GROUND, 1.0f, pos); + //if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); + } + + + /* + dbg_msg("predict", "%d %d %d", tick, + (int)world.players[c]->pos.x, (int)world.players[c]->pos.y, + (int)world.players[c]->vel.x, (int)world.players[c]->vel.y);*/ + } + + if(tick == client_predtick() && world.players[local_cid]) + predicted_player = *world.players[local_cid]; + } + + if(config.debug && predicted_tick == client_predtick()) + { + if(predicted_player.pos.x != before_player.pos.x || + predicted_player.pos.y != before_player.pos.y) + { + dbg_msg("client", "prediction error, (%d %d) (%d %d)", + (int)before_player.pos.x, (int)before_player.pos.y, + (int)predicted_player.pos.x, (int)predicted_player.pos.y); + } + + if(predicted_prev_player.pos.x != before_prev_player.pos.x || + predicted_prev_player.pos.y != before_prev_player.pos.y) + { + dbg_msg("client", "prediction error, prev (%d %d) (%d %d)", + (int)before_prev_player.pos.x, (int)before_prev_player.pos.y, + (int)predicted_prev_player.pos.x, (int)predicted_prev_player.pos.y); + } + } + + predicted_tick = client_predtick(); +} + + +extern "C" void modc_newsnapshot() +{ + static int snapshot_count = 0; + snapshot_count++; + + process_events(SNAP_CURRENT); + + if(config.dbg_stress) + { + if((client_tick()%250) == 0) + { + msg_pack_start(MSG_SAY, MSGFLAG_VITAL); + msg_pack_int(-1); + msg_pack_string("galenskap!!!!", 512); + msg_pack_end(); + client_send_msg(); + } + } + + clear_object_pointers(); + + // setup world view + { + // 1. fetch local player + // 2. set him to the center + int num = snap_num_items(SNAP_CURRENT); + for(int i = 0; i < num; i++) + { + SNAP_ITEM item; + const void *data = snap_get_item(SNAP_CURRENT, i, &item); + + if(item.type == OBJTYPE_PLAYER_INFO) + { + const obj_player_info *info = (const obj_player_info *)data; + + client_datas[info->clientid].team = info->team; + + if(info->local) + { + local_info = info; + const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id); + if(data) + { + local_character = (const obj_player_character *)data; + local_character_pos = vec2(local_character->x, local_character->y); + + const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id); + if(p) + local_prev_character = (obj_player_character *)p; + } + } + } + else if(item.type == OBJTYPE_GAME) + gameobj = (obj_game *)data; + else if(item.type == OBJTYPE_FLAG) + { + flags[item.id%2] = (const obj_flag *)data; + } + } + } + + for(int i = 0; i < MAX_CLIENTS; i++) + client_datas[i].update_render_info(); +} + + + +extern "C" void modc_render() +{ + // this should be moved around abit + if(client_state() == CLIENTSTATE_ONLINE) + { + render_game(); + + // handle team switching + // TODO: FUGLY!!! + if(config.cl_team != -10) + { + msg_pack_start(MSG_SETTEAM, MSGFLAG_VITAL); + msg_pack_int(config.cl_team); + msg_pack_end(); + client_send_msg(); + } + } + else // if (client_state() != CLIENTSTATE_CONNECTING && client_state() != CLIENTSTATE_LOADING) + { + menu_render(); + } + + // + config.cl_team = -10; +} + + +extern "C" int modc_snap_input(int *data) +{ + picked_up_weapon = -1; + + if(!input_target_lock) + { + input_data.target_x = (int)mouse_pos.x; + input_data.target_y = (int)mouse_pos.y; + + if(!input_data.target_x && !input_data.target_y) + input_data.target_y = 1; + } + input_target_lock = 0; + + if(chat_mode != CHATMODE_NONE) + input_data.state = STATE_CHATTING; + else if(menu_active) + input_data.state = STATE_IN_MENU; + else + { + input_data.state = STATE_PLAYING; + input_data.left = inp_key_state(config.key_move_left); + input_data.right = inp_key_state(config.key_move_right); + input_data.hook = inp_key_state(config.key_hook); + input_data.jump = inp_key_state(config.key_jump); + } + + // stress testing + if(config.dbg_stress) + { + float t = client_localtime(); + mem_zero(&input_data, sizeof(input_data)); + + input_data.left = ((int)t/2)&1; + input_data.right = ((int)t/2+1)&1; + input_data.jump = ((int)t); + input_data.fire = ((int)(t*10)); + input_data.hook = ((int)(t*2))&1; + input_data.wanted_weapon = ((int)t)%NUM_WEAPONS; + input_data.target_x = (int)(sinf(t*3)*100.0f); + input_data.target_y = (int)(cosf(t*3)*100.0f); + } + + // copy and return size + mem_copy(data, &input_data, sizeof(input_data)); + return sizeof(input_data); +} + +void menu_do_disconnected(); +void menu_do_connecting(); +void menu_do_connected(); + +extern "C" void modc_statechange(int state, int old) +{ + clear_object_pointers(); + + if(state == CLIENTSTATE_OFFLINE) + { + menu_do_disconnected(); + menu_game_active = false; + } + else if(state == CLIENTSTATE_LOADING) + menu_do_connecting(); + else if(state == CLIENTSTATE_CONNECTING) + menu_do_connecting(); + else if (state == CLIENTSTATE_ONLINE) + { + menu_active = false; + menu_game_active = true; + //snapshot_count = 0; + + menu_do_connected(); + } +} + +extern "C" void modc_message(int msg) +{ + if(msg == MSG_CHAT) + { + int cid = msg_unpack_int(); + int team = msg_unpack_int(); + const char *message = msg_unpack_string(); + dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message); + chat_add_line(cid, team, message); + + if(cid >= 0) + snd_play(CHN_GUI, data->sounds[SOUND_CHAT_CLIENT].sounds[0].id, 0); + else + snd_play(CHN_GUI, data->sounds[SOUND_CHAT_SERVER].sounds[0].id, 0); + } + else if(msg == MSG_SETINFO) + { + int cid = msg_unpack_int(); + const char *name = msg_unpack_string(); + const char *skinname = msg_unpack_string(); + + strncpy(client_datas[cid].name, name, 64); + strncpy(client_datas[cid].skin_name, skinname, 64); + + int use_custom_color = msg_unpack_int(); + client_datas[cid].skin_info.color_body = skin_get_color(msg_unpack_int()); + client_datas[cid].skin_info.color_feet = skin_get_color(msg_unpack_int()); + client_datas[cid].skin_info.size = 64; + + // find new skin + client_datas[cid].skin_id = skin_find(client_datas[cid].skin_name); + if(client_datas[cid].skin_id < 0) + client_datas[cid].skin_id = 0; + + if(use_custom_color) + client_datas[cid].skin_info.texture = skin_get(client_datas[cid].skin_id)->color_texture; + else + { + client_datas[cid].skin_info.texture = skin_get(client_datas[cid].skin_id)->org_texture; + client_datas[cid].skin_info.color_body = vec4(1,1,1,1); + client_datas[cid].skin_info.color_feet = vec4(1,1,1,1); + } + + client_datas[cid].update_render_info(); + } + else if(msg == MSG_WEAPON_PICKUP) + { + int weapon = msg_unpack_int(); + + picked_up_weapon = weapon+1; + } + else if(msg == MSG_READY_TO_ENTER) + { + client_entergame(); + } + else if(msg == MSG_KILLMSG) + { + killmsg_current = (killmsg_current+1)%killmsg_max; + killmsgs[killmsg_current].killer = msg_unpack_int(); + killmsgs[killmsg_current].victim = msg_unpack_int(); + killmsgs[killmsg_current].weapon = msg_unpack_int(); + killmsgs[killmsg_current].mode_special = msg_unpack_int(); + killmsgs[killmsg_current].tick = client_tick(); + } + else if (msg == MSG_EMOTICON) + { + int cid = msg_unpack_int(); + int emoticon = msg_unpack_int(); + client_datas[cid].emoticon = emoticon; + client_datas[cid].emoticon_start = client_tick(); + } + else if(msg == MSG_SOUND_GLOBAL) + { + int soundid = msg_unpack_int(); + snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0)); + } +} + +extern "C" void modc_connected() +{ + // init some stuff + col_init(32); + + img_init(); + tilemap_init(); + chat_reset(); + + reset_projectile_particles(); + + clear_object_pointers(); + last_new_predicted_tick = -1; + + for(int i = 0; i < MAX_CLIENTS; i++) + { + client_datas[i].name[0] = 0; + client_datas[i].team = 0; + client_datas[i].emoticon = 0; + client_datas[i].emoticon_start = -1; + } + + for(int i = 0; i < killmsg_max; i++) + killmsgs[i].tick = -100000; + + send_info(true); +} + +extern "C" const char *modc_net_version() { return TEEWARS_NETVERSION; } |