diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine/client/inp.c | 88 | ||||
| -rw-r--r-- | src/engine/interface.h | 4 | ||||
| -rw-r--r-- | src/game/client/game_client.cpp | 50 | ||||
| -rw-r--r-- | src/game/game_protocol.h | 7 | ||||
| -rw-r--r-- | src/game/server/game_server.cpp | 61 |
5 files changed, 169 insertions, 41 deletions
diff --git a/src/engine/client/inp.c b/src/engine/client/inp.c index 6b0ba829..fb29dc6c 100644 --- a/src/engine/client/inp.c +++ b/src/engine/client/inp.c @@ -1,3 +1,4 @@ +#include <string.h> #include <engine/external/glfw/include/GL/glfw.h> #include <engine/system.h> @@ -7,6 +8,19 @@ static int keyboard_state[2][1024]; /* TODO: fix this!! */ static int keyboard_current = 0; static int keyboard_first = 1; + +static struct +{ + unsigned char presses; + unsigned char releases; +} input_count[2][1024] = {{{0}}, {{0}}}; + +static unsigned char input_state[2][1024] = {{0}, {0}}; + +/*static unsigned char input_state[2][1024] = {{0},{0}};*/ +/*static unsigned char input_state[1024] = {{0},{0}};*/ +static int input_current = 0; + void inp_mouse_relative(int *x, int *y) { static int last_x = 0, last_y = 0; @@ -29,15 +43,55 @@ static void char_callback(int character, int action) static void key_callback(int key, int action) { - if(action == GLFW_PRESS) - last_k = key; + if(action == GLFW_PRESS) + last_k = key; + + if(action == GLFW_PRESS) + input_count[input_current^1][key].presses++; + if(action == GLFW_RELEASE) + input_count[input_current^1][key].releases++; + input_state[input_current^1][key] = action; +} + +static void mousebutton_callback(int button, int action) +{ + if(action == GLFW_PRESS) + input_count[input_current^1][KEY_MOUSE_FIRST+button].presses++; + if(action == GLFW_RELEASE) + input_count[input_current^1][KEY_MOUSE_FIRST+button].releases++; + input_state[input_current^1][KEY_MOUSE_FIRST+button] = action; +} + + +static void mousewheel_callback(int pos) +{ + if(pos > 0) + { + while(pos-- != 0) + { + input_count[input_current^1][KEY_MOUSE_WHEEL_UP].presses++; + input_count[input_current^1][KEY_MOUSE_WHEEL_UP].releases++; + } + } + else if(pos < 0) + { + while(pos++ != 0) + { + input_count[input_current^1][KEY_MOUSE_WHEEL_DOWN].presses++; + input_count[input_current^1][KEY_MOUSE_WHEEL_DOWN].releases++; + } + } + glfwSetMouseWheel(0); } + void inp_init() { glfwEnable(GLFW_KEY_REPEAT); glfwSetCharCallback(char_callback); glfwSetKeyCallback(key_callback); + glfwSetMouseButtonCallback(mousebutton_callback); + glfwSetMouseWheelCallback(mousewheel_callback); } char inp_last_char() @@ -66,6 +120,21 @@ void inp_mouse_mode_relative() glfwDisable(GLFW_MOUSE_CURSOR); } +int inp_key_presses(int key) +{ + return input_count[input_current][key].presses; +} + +int inp_key_releases(int key) +{ + return input_count[input_current][key].releases; +} + +int inp_key_state(int key) +{ + return input_state[input_current][key]; +} + 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); } @@ -74,6 +143,11 @@ int inp_button_pressed(int button) { return keyboard_state[keyboard_current][but void inp_update() { int i, v; + + /* clear and begin count on the other one */ + mem_zero(&input_count[input_current], sizeof(input_count[input_current])); + memcpy(input_state[input_current], input_state[input_current^1], sizeof(input_state[input_current])); + input_current^=1; if(keyboard_first) { @@ -93,13 +167,13 @@ void inp_update() } /* handle mouse wheel */ - i = glfwGetMouseWheel(); + /* + i = glfwGetMouseWheel(); keyboard_state[keyboard_current][KEY_MOUSE_WHEEL_UP] = 0; keyboard_state[keyboard_current][KEY_MOUSE_WHEEL_DOWN] = 0; - if(i > 0) + if(w > 0) keyboard_state[keyboard_current][KEY_MOUSE_WHEEL_UP] = 1; - if(i < 0) + if(w < 0) keyboard_state[keyboard_current][KEY_MOUSE_WHEEL_DOWN] = 1; - glfwSetMouseWheel(0); - + glfwSetMouseWheel(0);*/ } diff --git a/src/engine/interface.h b/src/engine/interface.h index 1ca692d6..94201ea0 100644 --- a/src/engine/interface.h +++ b/src/engine/interface.h @@ -766,6 +766,10 @@ void inp_init(); void inp_mouse_mode_absolute(); void inp_mouse_mode_relative(); +int inp_key_presses(int key); +int inp_key_releases(int key); +int inp_key_state(int key); + const char *inp_key_name(int k); int inp_key_code(const char *key_name); diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp index 332a84d9..dc135509 100644 --- a/src/game/client/game_client.cpp +++ b/src/game/client/game_client.cpp @@ -1786,6 +1786,14 @@ void render_world(float center_x, float center_y, float zoom) damageind.render(); } +static void do_input(int *v, int key) +{ + *v += inp_key_presses(key) + inp_key_releases(key); + if((*v&1) != inp_key_state(key)) + (*v)++; + *v &= INPUT_STATE_MASK; +} + void render_game() { float width = 400*3.0f; @@ -1934,12 +1942,10 @@ void render_game() // snap input { - player_input input; - mem_zero(&input, sizeof(input)); + static player_input input = {0}; input.target_x = (int)mouse_pos.x; input.target_y = (int)mouse_pos.y; - input.activeweapon = 0; if(chat_mode != CHATMODE_NONE) input.state = STATE_CHATTING; @@ -1948,27 +1954,36 @@ void render_game() else { input.state = STATE_PLAYING; - input.left = inp_key_pressed(config.key_move_left); - input.right = inp_key_pressed(config.key_move_right); - input.jump = inp_key_pressed(config.key_jump); - // TODO: this is not very well done. it should check this some other way - input.fire = emoticon_selector_active ? 0 : inp_key_pressed(config.key_fire); - input.hook = inp_key_pressed(config.key_hook); + input.left = inp_key_state(config.key_move_left); + input.right = inp_key_state(config.key_move_right); + input.hook = inp_key_state(config.key_hook); + input.jump = inp_key_state(config.key_jump); + + if(!emoticon_selector_active) + do_input(&input.fire, config.key_fire); + + // weapon selection + do_input(&input.next_weapon, config.key_next_weapon); + do_input(&input.prev_weapon, config.key_prev_weapon); - // Weapon switching - if(inp_key_pressed(config.key_next_weapon)) input.activeweapon = -1; - if(inp_key_pressed(config.key_prev_weapon)) input.activeweapon = -2; - if(inp_key_pressed(config.key_weapon1)) input.activeweapon = 1; - if(inp_key_pressed(config.key_weapon2)) input.activeweapon = 2; - if(inp_key_pressed(config.key_weapon3)) input.activeweapon = 3; - if(inp_key_pressed(config.key_weapon4)) input.activeweapon = 4; + if(inp_key_presses(config.key_next_weapon) || inp_key_presses(config.key_prev_weapon)) + input.wanted_weapon = 0; + else + { + if(inp_key_presses(config.key_weapon1)) input.wanted_weapon = 1; + if(inp_key_presses(config.key_weapon2)) input.wanted_weapon = 2; + if(inp_key_presses(config.key_weapon3)) input.wanted_weapon = 3; + if(inp_key_presses(config.key_weapon4)) input.wanted_weapon = 4; + } } // stress testing if(config.stress) { - float t = client_localtime(); + //float t = client_localtime(); mem_zero(&input, sizeof(input)); + + /* input.left = 1; input.jump = ((int)t)&1; input.fire = ((int)(t*10))&1; @@ -1976,6 +1991,7 @@ void render_game() input.activeweapon = ((int)t)%NUM_WEAPONS; input.target_x = (int)(sinf(t*3)*100.0f); input.target_y = (int)(cosf(t*3)*100.0f); + */ //input.target_x = (int)((rand()/(float)RAND_MAX)*64-32); //input.target_y = (int)((rand()/(float)RAND_MAX)*64-32); diff --git a/src/game/game_protocol.h b/src/game/game_protocol.h index 56156e24..0300c88a 100644 --- a/src/game/game_protocol.h +++ b/src/game/game_protocol.h @@ -60,6 +60,11 @@ enum enum { + INPUT_STATE_MASK=0x1f, +}; + +enum +{ STATE_UNKNOWN=0, STATE_PLAYING, STATE_IN_MENU, @@ -82,9 +87,9 @@ struct player_input int fire; int hook; int blink; - int activeweapon; int state; + int wanted_weapon; int next_weapon; int prev_weapon; }; diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp index ff5dbd84..9821c87f 100644 --- a/src/game/server/game_server.cpp +++ b/src/game/server/game_server.cpp @@ -602,6 +602,30 @@ int player::handle_ninja() return 0; } +struct input_count +{ + int presses; + int releases; +}; + +static input_count count_input(int prev, int cur) +{ + input_count c = {0,0}; + prev &= INPUT_STATE_MASK; + cur &= INPUT_STATE_MASK; + int i = prev; + while(i != cur) + { + i = (i+1)&INPUT_STATE_MASK; + if(i&1) + c.presses++; + else + c.releases++; + } + + return c; +} + int player::handle_weapons() { vec2 direction = normalize(vec2(input.target_x, input.target_y)); @@ -630,26 +654,30 @@ int player::handle_weapons() return handle_ninja(); } - // switch weapon if wanted - if(input.activeweapon && data->weapons[active_weapon].duration <= 0) + // switch weapon if wanted + if(data->weapons[active_weapon].duration <= 0) { int new_weapon = active_weapon; - if(input.activeweapon > 0) // straight selection - new_weapon = input.activeweapon-1; - else if(input.activeweapon == -1 && !previnput.activeweapon) // next weapon + int next = count_input(previnput.next_weapon, input.next_weapon).presses; + int prev = count_input(previnput.prev_weapon, input.prev_weapon).presses; + while(next) // next weapon selection { - do - new_weapon = (new_weapon+1)%NUM_WEAPONS; - while(!weapons[new_weapon].got); + new_weapon = (new_weapon+1)%NUM_WEAPONS; + if(weapons[new_weapon].got) + next--; } - else if(input.activeweapon == -2 && !previnput.activeweapon) + + while(prev) // prev weapon selection { - do - new_weapon = (new_weapon-1)<0?NUM_WEAPONS-1:new_weapon-1; - while(!weapons[new_weapon].got); + new_weapon = (new_weapon-1)<0?NUM_WEAPONS-1:new_weapon-1; + if(weapons[new_weapon].got) + prev--; } - - if(new_weapon >= 0 && new_weapon < NUM_WEAPONS && weapons[new_weapon].got) + + if(input.wanted_weapon) // direct weapon selection + new_weapon = input.wanted_weapon-1; + + if(new_weapon != active_weapon && new_weapon >= 0 && new_weapon < NUM_WEAPONS && weapons[new_weapon].got) { if(active_weapon != new_weapon) create_sound(pos, SOUND_WEAPON_SWITCH); @@ -659,7 +687,7 @@ int player::handle_weapons() } } - if(!previnput.fire && input.fire) + if(count_input(previnput.fire, input.fire).presses) //previnput.fire != input.fire && (input.fire&1)) { if(reload_timer == 0) { @@ -727,6 +755,7 @@ int player::handle_weapons() } } } + // Update weapons if (active_weapon == WEAPON_HAMMER && reload_timer > 0) { @@ -841,7 +870,7 @@ void player::tick() { if(server_tick()-die_tick >= server_tickspeed()*5) // auto respawn after 3 sec respawn(); - if(input.fire && server_tick()-die_tick >= server_tickspeed()/2) // auto respawn after 0.5 sec + if((input.fire&1) && server_tick()-die_tick >= server_tickspeed()/2) // auto respawn after 0.5 sec respawn(); return; } |