Browse Source

Make splash screen skipable and add tool equip hotkeys

master
C. J. Howard 1 year ago
parent
commit
6ad5c0764c
12 changed files with 348 additions and 5 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +5
    -0
      src/application.cpp
  3. +2
    -0
      src/application.hpp
  4. +31
    -0
      src/game/bootloader.cpp
  5. +4
    -0
      src/game/game-context.hpp
  6. +26
    -0
      src/game/states/splash-state.cpp
  7. +3
    -0
      src/game/systems/control-system.cpp
  8. +15
    -0
      src/game/systems/control-system.hpp
  9. +33
    -5
      src/game/systems/tool-system.cpp
  10. +10
    -0
      src/game/systems/tool-system.hpp
  11. +127
    -0
      src/input/input-listener.cpp
  12. +91
    -0
      src/input/input-listener.hpp

+ 1
- 0
CMakeLists.txt View File

@ -27,6 +27,7 @@ set(STATIC_LIBS
set(SHARED_LIBS
${OPENGL_gl_LIBRARY})
# Generate configuration header file
configure_file(${PROJECT_SOURCE_DIR}/src/configuration.hpp.in
${PROJECT_BINARY_DIR}/src/configuration.hpp)

+ 5
- 0
src/application.cpp View File

@ -426,6 +426,11 @@ void application::set_window_opacity(float opacity)
SDL_SetWindowOpacity(sdl_window, opacity);
}
void application::swap_buffers()
{
SDL_GL_SwapWindow(sdl_window);
}
void application::update(double t, double dt)
{
translate_sdl_events();

+ 2
- 0
src/application.hpp View File

@ -161,6 +161,8 @@ public:
void set_window_opacity(float opacity);
void swap_buffers();
/// Returns the dimensions of the current display.
const std::array<int, 2>& get_display_dimensions() const;

+ 31
- 0
src/game/bootloader.cpp View File

@ -80,6 +80,7 @@
#include "event/event-dispatcher.hpp"
#include "input/input-event-router.hpp"
#include "input/input-mapper.hpp"
#include "input/input-listener.hpp"
#include "input/game-controller.hpp"
#include "input/mouse.hpp"
#include "input/keyboard.hpp"
@ -868,6 +869,10 @@ void setup_controls(game_context* ctx)
ctx->input_mapper = new input_mapper();
ctx->input_mapper->set_event_dispatcher(event_dispatcher);
// Setup input listener
ctx->input_listener = new input_listener();
ctx->input_listener->set_event_dispatcher(event_dispatcher);
// Create toggle fullscreen control
ctx->toggle_fullscreen_control = new control();
ctx->toggle_fullscreen_control->set_activated_callback
@ -1011,6 +1016,32 @@ void setup_controls(game_context* ctx)
ctx->input_event_router->add_mapping(game_controller_axis_mapping(ctx->control_system->get_zoom_out_control(), nullptr, game_controller_axis::trigger_left, false));
ctx->input_event_router->add_mapping(game_controller_axis_mapping(ctx->control_system->get_zoom_in_control(), nullptr, game_controller_axis::trigger_right, false));
ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_forceps_control(), nullptr, scancode::one));
ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_brush_control(), nullptr, scancode::two));
ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_lens_control(), nullptr, scancode::three));
ctx->control_system->get_equip_forceps_control()->set_activated_callback
(
[ctx]()
{
ctx->tool_system->set_active_tool(ctx->forceps_entity);
}
);
ctx->control_system->get_equip_brush_control()->set_activated_callback
(
[ctx]()
{
ctx->tool_system->set_active_tool(ctx->brush_entity);
}
);
ctx->control_system->get_equip_lens_control()->set_activated_callback
(
[ctx]()
{
ctx->tool_system->set_active_tool(ctx->lens_entity);
}
);
event_dispatcher->subscribe<mouse_moved_event>(ctx->control_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->camera_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->tool_system);

+ 4
- 0
src/game/game-context.hpp View File

@ -51,6 +51,7 @@ class framebuffer;
class locomotion_system;
class logger;
class material;
class input_listener;
class material_pass;
class nest_system;
class orbit_cam;
@ -189,10 +190,13 @@ struct game_context
screen_transition* fade_transition;
screen_transition* radial_transition_inner;
screen_transition* radial_transition_outer;
animation<float>* equip_tool_animation;
animation<float>* unequip_tool_animation;
// Controls
input_event_router* input_event_router;
input_mapper* input_mapper;
input_listener* input_listener;
control_set* application_controls;
control_set* camera_controls;
control_set* menu_controls;

+ 26
- 0
src/game/states/splash-state.cpp View File

@ -23,6 +23,9 @@
#include "application.hpp"
#include "debug/logger.hpp"
#include "game/game-context.hpp"
#include "input/input-listener.hpp"
#include "event/input-events.hpp"
#include "rasterizer/rasterizer.hpp"
#include "game/states/game-states.hpp"
#include "renderer/passes/sky-pass.hpp"
#include "scene/billboard.hpp"
@ -72,6 +75,25 @@ void splash_state_enter(game_context* ctx)
};
timeline->add_sequence(splash_sequence);
// Set up splash skipper
ctx->input_listener->set_callback
(
[ctx](const event_base& event)
{
auto id = event.get_event_type_id();
if (id != mouse_moved_event::event_type_id && id != mouse_wheel_scrolled_event::event_type_id && id != game_controller_axis_moved_event::event_type_id)
{
ctx->timeline->clear();
ctx->fade_transition->get_animation()->stop();
ctx->rasterizer->set_clear_color(0.0f, 0.0f, 0.0f, 1.0f);
ctx->rasterizer->clear_framebuffer(true, false, false);
ctx->app->swap_buffers();
ctx->app->change_state({std::bind(play_state_enter, ctx), std::bind(play_state_exit, ctx)});
}
}
);
ctx->input_listener->set_enabled(true);
logger->pop_task(EXIT_SUCCESS);
}
@ -80,6 +102,10 @@ void splash_state_exit(game_context* ctx)
logger* logger = ctx->logger;
logger->push_task("Exiting splash state");
// Disable splash skipper
ctx->input_listener->set_enabled(false);
ctx->input_listener->set_callback(nullptr);
// Remove splash billboard from UI scene
ctx->ui_scene->remove_object(ctx->splash_billboard);

+ 3
- 0
src/game/systems/control-system.cpp View File

@ -51,6 +51,9 @@ control_system::control_system(entt::registry& registry):
control_set.add_control(&descend_control);
control_set.add_control(&toggle_view_control);
control_set.add_control(&tool_menu_control);
control_set.add_control(&equip_lens_control);
control_set.add_control(&equip_brush_control);
control_set.add_control(&equip_forceps_control);
// Set deadzone at 15% for all controls
const std::list<control*>* controls = control_set.get_controls();

+ 15
- 0
src/game/systems/control-system.hpp View File

@ -212,5 +212,20 @@ inline control* control_system::get_tool_menu_control()
return &tool_menu_control;
}
inline control* control_system::get_equip_lens_control()
{
return &equip_lens_control;
}
inline control* control_system::get_equip_brush_control()
{
return &equip_brush_control;
}
inline control* control_system::get_equip_forceps_control()
{
return &equip_forceps_control;
}
#endif // ANTKEEPER_CONTROL_SYSTEM_HPP

+ 33
- 5
src/game/systems/tool-system.cpp View File

@ -26,6 +26,7 @@
#include "geometry/mesh.hpp"
#include "geometry/intersection.hpp"
#include "math/math.hpp"
#include "game/entity-commands.hpp"
using namespace ecs;
@ -49,6 +50,8 @@ tool_system::tool_system(entt::registry& registry):
pick_spring.x1 = {0.0f, 0.0f, 0.0f};
pick_spring.x0 = pick_spring.x1;
pick_spring.v = {0.0f, 0.0f, 0.0f};
active_tool = entt::null;
}
void tool_system::update(double t, double dt)
@ -112,7 +115,7 @@ void tool_system::update(double t, double dt)
}
// Determine target hand angle
hand_angle_spring.x1 = math::pi<float> - std::min<float>(0.5f, std::max<float>(-0.5f, ((mouse_position[0] / viewport[2]) - 0.5f) * 3.0f)) * math::pi<float>;
hand_angle_spring.x1 = math::pi<float> - std::min<float>(0.5f, std::max<float>(-0.5f, ((mouse_position[0] / viewport[2]) - 0.5f) * 1.0f)) * (math::pi<float> + math::half_pi<float>);
// Solve springs
solve_numeric_spring<float, float>(hand_angle_spring, dt);
@ -130,23 +133,28 @@ void tool_system::update(double t, double dt)
if (!tool.active)
return;
active_tool = entity;
if (intersection)
{
transform.transform.translation = pick_spring.x0 + float3{0, tool.hover_distance, 0};
}
// Interpolate between left and right hand
math::quaternion<float> hand_rotation = math::angle_axis(orbit_cam->get_azimuth() + hand_angle_spring.x0, float3{0, 1, 0});
if (tool.heliotropic)
{
math::quaternion<float> solar_rotation = math::rotation(float3{0, -1, 0}, sun_direction);
transform.transform.translation = pick_spring.x0 + solar_rotation * float3{0, tool.hover_distance, 0};
// Interpolate between left and right hand
math::quaternion<float> hand_rotation = math::angle_axis(orbit_cam->get_azimuth() + hand_angle_spring.x0, float3{0, 1, 0});
transform.transform.rotation = solar_rotation * hand_rotation;
}
else
{
transform.transform.rotation = hand_rotation;
}
//math::quaternion<float> rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0});
//transform.transform.rotation = rotation;
@ -180,6 +188,26 @@ void tool_system::set_sun_direction(const float3& direction)
sun_direction = direction;
}
void tool_system::set_active_tool(entt::entity entity)
{
if (active_tool != entt::null)
{
auto& tool = registry.get<tool_component>(active_tool);
tool.active = false;
ec::assign_render_layers(registry, active_tool, 0);
}
active_tool = entity;
if (active_tool != entt::null)
{
auto& tool = registry.get<tool_component>(active_tool);
tool.active = true;
ec::assign_render_layers(registry, active_tool, 1);
}
}
void tool_system::handle_event(const mouse_moved_event& event)
{
if (pick_enabled && was_pick_enabled)

+ 10
- 0
src/game/systems/tool-system.hpp View File

@ -44,6 +44,10 @@ public:
void set_viewport(const float4& viewport);
void set_pick(bool enabled);
void set_sun_direction(const float3& direction);
void set_active_tool(entt::entity entity);
entt::entity get_active_tool() const;
private:
virtual void handle_event(const mouse_moved_event& event);
@ -56,9 +60,15 @@ private:
bool was_pick_enabled;
bool pick_enabled;
float3 sun_direction;
entt::entity active_tool;
numeric_spring<float, float> hand_angle_spring;
numeric_spring<float3, float> pick_spring;
};
inline entt::entity tool_system::get_active_tool() const
{
return active_tool;
}
#endif // ANTKEEPER_TOOL_SYSTEM_HPP

+ 127
- 0
src/input/input-listener.cpp View File

@ -0,0 +1,127 @@
/*
* Copyright (C) 2020 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "input-listener.hpp"
#include "event/event-dispatcher.hpp"
input_listener::input_listener():
event_dispatcher(nullptr),
callback(nullptr),
enabled(false)
{}
input_listener::~input_listener()
{
set_event_dispatcher(nullptr);
}
void input_listener::set_event_dispatcher(::event_dispatcher* event_dispatcher)
{
if (this->event_dispatcher)
{
this->event_dispatcher->unsubscribe<key_pressed_event>(this);
this->event_dispatcher->unsubscribe<mouse_moved_event>(this);
this->event_dispatcher->unsubscribe<mouse_wheel_scrolled_event>(this);
this->event_dispatcher->unsubscribe<mouse_button_pressed_event>(this);
this->event_dispatcher->unsubscribe<game_controller_axis_moved_event>(this);
this->event_dispatcher->unsubscribe<game_controller_button_pressed_event>(this);
}
this->event_dispatcher = event_dispatcher;
if (event_dispatcher)
{
event_dispatcher->subscribe<key_pressed_event>(this);
event_dispatcher->subscribe<mouse_moved_event>(this);
event_dispatcher->subscribe<mouse_wheel_scrolled_event>(this);
event_dispatcher->subscribe<mouse_button_pressed_event>(this);
event_dispatcher->subscribe<game_controller_axis_moved_event>(this);
event_dispatcher->subscribe<game_controller_button_pressed_event>(this);
}
}
void input_listener::set_callback(std::function<void(const event_base&)> callback)
{
this->callback = callback;
}
void input_listener::set_enabled(bool enabled)
{
this->enabled = enabled;
}
void input_listener::handle_event(const key_pressed_event& event)
{
if (!is_enabled() || !callback)
{
return;
}
callback(event);
}
void input_listener::handle_event(const mouse_moved_event& event)
{
if (!is_enabled() || !callback)
{
return;
}
callback(event);
}
void input_listener::handle_event(const mouse_button_pressed_event& event)
{
if (!is_enabled() || !callback)
{
return;
}
callback(event);
}
void input_listener::handle_event(const mouse_wheel_scrolled_event& event)
{
if (!is_enabled() || !callback)
{
return;
}
callback(event);
}
void input_listener::handle_event(const game_controller_button_pressed_event& event)
{
if (!is_enabled() || !callback)
{
return;
}
callback(event);
}
void input_listener::handle_event(const game_controller_axis_moved_event& event)
{
if (!is_enabled() || !callback)
{
return;
}
callback(event);
}

+ 91
- 0
src/input/input-listener.hpp View File

@ -0,0 +1,91 @@
/*
* Copyright (C) 2020 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_INPUT_LISTENER_HPP
#define ANTKEEPER_INPUT_LISTENER_HPP
#include "event/input-events.hpp"
#include "event/event-handler.hpp"
#include <functional>
class event_dispatcher;
class input_listener:
public event_handler<key_pressed_event>,
public event_handler<mouse_moved_event>,
public event_handler<mouse_wheel_scrolled_event>,
public event_handler<mouse_button_pressed_event>,
public event_handler<game_controller_axis_moved_event>,
public event_handler<game_controller_button_pressed_event>
{
public:
/**
* Creates an input listener.
*/
input_listener();
/**
* Destroys an input listener.
*/
virtual ~input_listener();
/**
* Sets the event dispatcher to which this input event router will subscribe itself.
*/
void set_event_dispatcher(event_dispatcher* event_dispatcher);
/**
* Sets the input event callback function.
*
* @param callback Callback function which operates on an input event.
*/
void set_callback(std::function<void(const event_base&)> event);
/**
* Enables or disables the input listening.
*
* @param enabled Whether to enable input listening or not.
*/
void set_enabled(bool enabled);
/**
* Returns true if input listening is enabled.
*/
bool is_enabled() const;
private:
void handle_event(const key_pressed_event& event);
void handle_event(const mouse_moved_event& event);
void handle_event(const mouse_wheel_scrolled_event& event);
void handle_event(const mouse_button_pressed_event& event);
void handle_event(const game_controller_axis_moved_event& event);
void handle_event(const game_controller_button_pressed_event& event);
event_dispatcher* event_dispatcher;
std::function<void(const event_base&)> callback;
bool enabled;
};
inline bool input_listener::is_enabled() const
{
return enabled;
}
#endif // ANTKEEPER_INPUT_LISTENER_HPP

Loading…
Cancel
Save