Android port fixes

This commit is contained in:
Nikita Lisitsa 2024-08-22 18:37:05 +03:00
parent 2f86481f89
commit f5101e7ec9
3 changed files with 152 additions and 128 deletions

View file

@ -3,6 +3,7 @@ project(gmtk-2024)
set(CMAKE_CXX_STANDARD 20)
set(PSEMEK_EXAMPLES OFF)
set(PSEMEK_APPLICATION_NAME ColorFractory)
set(PSEMEK_PACKAGE_OUTPUT_PATH package)
set(PSEMEK_GRAPHICS_API OPENGL)

2
psemek

@ -1 +1 @@
Subproject commit 5042fbbf7e02ae3053df91bc6142b26364cbda4e
Subproject commit 4e9a551452952c95f98dc1ed96645d8208ec1649

View file

@ -32,6 +32,8 @@
#include <psemek/audio/effect/pitch.hpp>
#include <psemek/audio/track.hpp>
#include <psemek/app/resource.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
@ -1312,7 +1314,7 @@ namespace gmtk
});
}
void draw(map & map, gfx::painter & painter, float pixel_size, bool sandbox)
void draw(map & map, gfx::painter & painter, float ui_scale, bool sandbox)
{
map.world->apply<vertex const, crossing const>([&](vertex const & v, crossing const & c)
{
@ -1403,18 +1405,16 @@ namespace gmtk
{
auto pen = v.location.bbox(-0.4f).corner(0.5f, 1.f);
float vs = 2.f * pixel_size;
int opacity = std::round(255 * (1.f - std::abs(i + map.stage_animation)));
if (map.stage + i >= 1 && map.stage + i < std::size(stages))
draw_item(stages[map.stage + i].type, pen + geom::vector{(i + map.stage_animation) * 40.f * vs, 0.f}, 1.f, painter, false, opacity);
draw_item(stages[map.stage + i].type, pen + geom::vector{(i + map.stage_animation) * 40.f * ui_scale, 0.f}, 1.f, painter, false, opacity);
if (i == 0)
{
pen[1] -= 24.f * vs;
pen[1] -= 12.f * ui_scale;
painter.text(pen, std::format("{}/{}", map.resource_count, stages[map.stage].count), {.scale = {vs, -vs}, .c = {0, 0, 0, 255}});
painter.text(pen, util::to_string(map.resource_count, "/", stages[map.stage].count), {.scale = {ui_scale, -ui_scale}, .c = {0, 0, 0, 255}});
}
}
}
@ -1495,13 +1495,13 @@ namespace gmtk
auto sounds_root = util::executable_path().parent_path() / "sounds";
click_low_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "click_low.mp3"}));
click_high_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "click_high.mp3"}));
key_click_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "key_click.mp3"}));
gears_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "gears.mp3"}));
machine_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "machine.mp3"}));
pop_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "pop.mp3"}));
error_ = audio::load_mp3(io::read_full(io::file_istream{sounds_root / "error.mp3"}));
click_low_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/click_low.mp3"))));
click_high_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/click_high.mp3"))));
key_click_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/key_click.mp3"))));
gears_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/gears.mp3"))));
machine_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/machine.mp3"))));
pop_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/pop.mp3"))));
error_ = audio::load_mp3(io::read_full(std::move(*app::open_resource("sounds/error.mp3"))));
context_.windowed(is_windowed_);
set_start_menu();
@ -1512,6 +1512,24 @@ namespace gmtk
screen_size_ = event.size;
}
void on_event(app::touch_down_event const & event) override
{
on_event(app::mouse_move_event{event.position, {0, 0}});
on_event(app::mouse_button_event{app::mouse_button::left, true});
}
void on_event(app::touch_up_event const & event) override
{
on_event(app::mouse_move_event{event.position, {0, 0}});
on_event(app::mouse_button_event{app::mouse_button::left, false});
on_event(app::mouse_move_event{{-1000, -1000}, {0, 0}});
}
void on_event(app::touch_move_event const & event) override
{
on_event(app::mouse_move_event{event.position, {0, 0}});
}
void on_event(app::mouse_wheel_event const & event) override
{
if (!in_menu())
@ -1556,21 +1574,14 @@ namespace gmtk
void on_event(app::mouse_move_event const & event) override
{
mouse_ = event.position;
update_selected();
}
void on_event(app::mouse_button_event const & event) override
{
if (event.down && event.button == app::mouse_button::left)
{
if (selected_button_)
{
if (*selected_button_ < menu_buttons_.size() && menu_buttons_[*selected_button_].action)
{
button_click_sound();
menu_buttons_[*selected_button_].action();
}
}
else if (selected_ && active_card_)
if (selected_ && active_card_)
{
if (auto entity = map_.world->index<index>().find(*selected_))
{
@ -1640,11 +1651,6 @@ namespace gmtk
}
}
}
else if (selected_card_)
{
active_card_ = *selected_card_;
button_click_sound();
}
else if (selected_item_)
{
item_killing_spree_ = true;
@ -1662,7 +1668,23 @@ namespace gmtk
{
item_killing_spree_ = false;
if (selected_ && belt_start_ && selected_->level == belt_start_->level)
if (selected_button_)
{
if (*selected_button_ < menu_buttons_.size() && menu_buttons_[*selected_button_].action)
{
button_click_sound();
menu_buttons_[*selected_button_].action();
}
}
else if (selected_card_)
{
if (selected_card_ == active_card_)
active_card_ = std::nullopt;
else
active_card_ = *selected_card_;
button_click_sound();
}
else if (selected_ && belt_start_ && selected_->level == belt_start_->level)
{
auto d = selected_->coords - belt_start_->coords;
if (std::abs(d[0]) + std::abs(d[1]) == 1)
@ -1709,6 +1731,7 @@ namespace gmtk
tutorial_state_ = 1;
}
}
belt_start_ = std::nullopt;
}
@ -2089,82 +2112,7 @@ namespace gmtk
view_box_[0] = geom::expand(view_box_[0], (view_box_[1].length() * aspect_ratio - view_box_[0].length()) / 2.f);
mouse_world_ = view_box_.corner(
mouse_[0] * 1.f / screen_size_[0],
1.f - mouse_[1] * 1.f / screen_size_[1]
);
auto old_selected = selected_;
selected_ = std::nullopt;
selected_item_ = std::nullopt;
if (!in_menu() && !view_transition_)
{
if (geom::contains(geom::shrink(view_box_[0], (view_box_[0].length() - view_box_[1].length()) / 2.f), mouse_world_[0]))
map_.world->apply<item const>([&](ecs::handle entity, item const & i)
{
auto box = geom::expand(geom::box<float, 2>::singleton(position(*map_.world, i)), scale(*map_.world, i) / 9.f);
if (geom::contains(box, mouse_world_))
selected_item_ = entity;
});
if (selected_item_ && item_killing_spree_)
{
auto const & i = map_.world->get(*selected_item_).get<item const>();
if (i.target)
map_.world->detach<occupied>(i.target);
else
map_.world->detach<occupied>(map_.world->index<path_index>().get(i.start));
map_.world->destroy(*selected_item_);
selected_item_ = std::nullopt;
item_removed_sound();
}
{
float s = std::pow(3.f, 1 + view_stack_.back().level);
auto m = mouse_world_;
m[0] *= s;
m[1] *= s;
auto l = view_stack_.back();
location p{1 + l.level, {std::floor(m[0]), std::floor(m[1])}};
geom::interval xrange{3 * l.coords[0], 3 * l.coords[0] + 2};
geom::interval yrange{3 * l.coords[1], 3 * l.coords[1] + 2};
auto xwrange = geom::expand(xrange, 1);
auto ywrange = geom::expand(yrange, 1);
if (geom::contains(xrange, p.coords[0]) && geom::contains(yrange, p.coords[1]))
selected_ = p;
else if (view_stack_.size() > 1 && within_grid(p) && ((geom::contains(xwrange, p.coords[0]) && geom::contains(yrange, p.coords[1])) || (geom::contains(xrange, p.coords[0]) && geom::contains(ywrange, p.coords[1]))))
{
selected_ = p;
while (selected_->level > 0)
{
if (auto entity = map_.world->index<index>().find(p.up()))
if (map_.world->get(*entity).contains<zoomer>())
break;
selected_ = std::nullopt;
break;
// TODO:
selected_ = selected_->up();
}
}
else if (!within_grid(p))
if (auto entity = map_.world->index<index>().find(p))
selected_ = p;
if (belt_start_ && selected_ && old_selected != selected_)
{
button_mouseover_sound();
}
}
}
update_selected();
for (auto & p : card_animation_)
{
@ -2199,6 +2147,7 @@ namespace gmtk
float view_level = view_stack_.back().level;
float pixel_size = view_box_[1].length() / screen_size_[1];
float ui_scale = (screen_size_[0] > 2000 ? 4.f : 2.f) * pixel_size;
std::vector<std::string> helper_text;
std::optional<resource_type> helper_resource;
@ -2281,7 +2230,7 @@ namespace gmtk
draw_selection(belt_start_->bbox(), painter_, {64, 64, 64, 255});
}
draw(map_, painter_, pixel_size, is_sandbox_mode_);
draw(map_, painter_, ui_scale, is_sandbox_mode_);
if (!in_menu())
{
@ -2352,7 +2301,7 @@ namespace gmtk
float const scale = std::pow(3.f, -1.f - view_level);
float const step = 1.5f * scale / 9.f;
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{18.f, -120.f} * pixel_size + geom::vector{step, - 3.f * step} / 2.f;
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{9.f, -60.f} * ui_scale + geom::vector{step, - 3.f * step} / 2.f;
for (auto const & recipe : recipies.at(*shown_recipies))
{
int i = 0;
@ -2387,8 +2336,6 @@ namespace gmtk
{
float const step = 0.5f * std::pow(3.f, - 1.f - view_level);
float vs = 2.f * pixel_size;
geom::point<float, 2> pen = view_box_.corner(1, 1) - geom::vector{step, step} / 2.f;
if (map_.cards.size() > 1)
@ -2418,7 +2365,7 @@ namespace gmtk
draw_card(box, type, painter_, 1.f - animation);
if (map_.cards.at(type) < 1000)
painter_.text(box.center() - geom::vector{step, 0.f}, std::to_string(map_.cards.at(type)), {.scale = {vs, -vs}, .c = gfx::black});
painter_.text(box.center() - geom::vector{step, 0.f}, std::to_string(map_.cards.at(type)), {.scale = {ui_scale, -ui_scale}, .c = gfx::black});
pen[1] -= step;
}
@ -2494,10 +2441,9 @@ namespace gmtk
}
{
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{18.f, -24.f} * pixel_size;
float s = 2.f * pixel_size;
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{9.f, -12.f} * ui_scale;
gfx::painter::text_options opts{.scale = {s, -s}, .x = gfx::painter::x_align::left, .y = gfx::painter::y_align::top, .c = gfx::black};
gfx::painter::text_options opts{.scale = {ui_scale, -ui_scale}, .x = gfx::painter::x_align::left, .y = gfx::painter::y_align::top, .c = gfx::black};
std::string extra_line;
@ -2507,8 +2453,8 @@ namespace gmtk
if (i + 1 == helper_text.size() && helper_resource)
{
float text_width = painter_.text_size(helper_text[i])[0] * s;
draw_item(*helper_resource, {pen[0] + text_width + 18.f * pixel_size, pen[1] - 12.f * pixel_size}, 1.f, painter_);
float text_width = painter_.text_size(helper_text[i])[0] * ui_scale;
draw_item(*helper_resource, {pen[0] + text_width + 9.f * ui_scale, pen[1] - 6.f * ui_scale}, 1.f, painter_);
if (auto t = transformer_for(*helper_resource))
{
@ -2517,7 +2463,7 @@ namespace gmtk
}
}
pen[1] -= 32.f * pixel_size;
pen[1] -= 16.f * ui_scale;
}
if (!extra_line.empty())
@ -2528,17 +2474,16 @@ namespace gmtk
if (!in_start_menu_)
{
geom::point<float, 2> pen = view_box_.corner(0, 0) + geom::vector{18.f, 24.f} * pixel_size;
float s = 2.f * pixel_size;
geom::point<float, 2> pen = view_box_.corner(0, 0) + geom::vector{9.f, 12.f} * ui_scale;
gfx::color_rgba c{127, 127, 127, 255};
gfx::painter::text_options opts
{
.scale = {s, -s}, .x = gfx::painter::x_align::left, .y = gfx::painter::y_align::bottom, .c = c
.scale = {ui_scale, -ui_scale}, .x = gfx::painter::x_align::left, .y = gfx::painter::y_align::bottom, .c = c
};
painter_.text(pen + geom::vector{0.f, 32.f * pixel_size}, std::format("Level {}/{}", map_.stage, std::size(stages) - 1), opts);
painter_.text(pen + geom::vector{0.f, 16.f * ui_scale}, util::to_string("Level ", map_.stage, "/", std::size(stages) - 1), opts);
painter_.text(pen, is_sandbox_mode_ ? "Sandbox" : is_challenge_mode_ ? "Challenge" : "Campaign", opts);
}
@ -2549,9 +2494,9 @@ namespace gmtk
{
painter_.rect(view_box_, gfx::to_coloru8(gfx::color_4f{1.f, 1.f, 1.f, menu_transition_ * 0.75f}));
float button_width = pixel_size * 500.f;
float button_height = pixel_size * 64.f;
float button_spacing = pixel_size * 32.f;
float button_width = ui_scale * 250.f;
float button_height = ui_scale * 32.f;
float button_spacing = ui_scale * 16.f;
float total_height = button_height * menu_buttons_.size() + button_spacing * (menu_buttons_.size() - 1.f);
@ -2570,7 +2515,7 @@ namespace gmtk
if (active)
{
box = geom::expand(box, menu_buttons_[i].selected_state * 8.f * pixel_size);
box = geom::expand(box, menu_buttons_[i].selected_state * 4.f * ui_scale);
if (geom::contains(box, mouse_world_))
{
@ -2588,12 +2533,10 @@ namespace gmtk
text_color = {0, 0, 0, 255};
}
painter_.rect(geom::expand(box, pixel_size * 5.f), text_color);
painter_.rect(geom::expand(box, ui_scale * 2.5f), text_color);
painter_.rect(box, bg_color);
float s = pixel_size * 4.f;
painter_.text(box.center(), menu_buttons_[i].text, {.scale = {s, -s}, .c = text_color});
painter_.text(box.center(), menu_buttons_[i].text, {.scale = {ui_scale * 2.f, - ui_scale * 2.f}, .c = text_color});
pen[1] -= button_height;
pen[1] -= button_spacing;
@ -2787,6 +2730,86 @@ namespace gmtk
int tutorial_state_ = 0;
void update_selected()
{
mouse_world_ = view_box_.corner(
mouse_[0] * 1.f / screen_size_[0],
1.f - mouse_[1] * 1.f / screen_size_[1]
);
auto old_selected = selected_;
selected_ = std::nullopt;
selected_item_ = std::nullopt;
if (!in_menu() && !view_transition_)
{
if (geom::contains(geom::shrink(view_box_[0], (view_box_[0].length() - view_box_[1].length()) / 2.f), mouse_world_[0]))
map_.world->apply<item const>([&](ecs::handle entity, item const & i)
{
auto box = geom::expand(geom::box<float, 2>::singleton(position(*map_.world, i)), scale(*map_.world, i) / 9.f);
if (geom::contains(box, mouse_world_))
selected_item_ = entity;
});
if (selected_item_ && item_killing_spree_)
{
auto const & i = map_.world->get(*selected_item_).get<item const>();
if (i.target)
map_.world->detach<occupied>(i.target);
else
map_.world->detach<occupied>(map_.world->index<path_index>().get(i.start));
map_.world->destroy(*selected_item_);
selected_item_ = std::nullopt;
item_removed_sound();
}
{
float s = std::pow(3.f, 1 + view_stack_.back().level);
auto m = mouse_world_;
m[0] *= s;
m[1] *= s;
auto l = view_stack_.back();
location p{1 + l.level, {std::floor(m[0]), std::floor(m[1])}};
geom::interval xrange{3 * l.coords[0], 3 * l.coords[0] + 2};
geom::interval yrange{3 * l.coords[1], 3 * l.coords[1] + 2};
auto xwrange = geom::expand(xrange, 1);
auto ywrange = geom::expand(yrange, 1);
if (geom::contains(xrange, p.coords[0]) && geom::contains(yrange, p.coords[1]))
selected_ = p;
else if (view_stack_.size() > 1 && within_grid(p) && ((geom::contains(xwrange, p.coords[0]) && geom::contains(yrange, p.coords[1])) || (geom::contains(xrange, p.coords[0]) && geom::contains(ywrange, p.coords[1]))))
{
selected_ = p;
while (selected_->level > 0)
{
if (auto entity = map_.world->index<index>().find(p.up()))
if (map_.world->get(*entity).contains<zoomer>())
break;
selected_ = std::nullopt;
break;
// TODO:
selected_ = selected_->up();
}
}
else if (!within_grid(p))
if (auto entity = map_.world->index<index>().find(p))
selected_ = p;
if (belt_start_ && selected_ && old_selected != selected_)
{
button_mouseover_sound();
}
}
}
}
void button_mouseover_sound()
{
mixer_->add(audio::volume(pop_->stream(), 0.125f));