#include "game.hpp" #include namespace interface { using namespace game; // FIXME state_t::state_t(sf::RenderWindow *window_, game::state_t *game_) { window = window_; game = game_; } static sf::Vector2f compute_pan(sf::RenderWindow *window, sf::Vector2f pan_ref) { sf::Vector2i mouse = sf::Mouse::getPosition(*window); sf::Vector2f vmouse = window->mapPixelToCoords(mouse); return -(vmouse - pan_ref); } void state_t::tick(double dt) { sf::Vector2u size; sf::Event event; sf::Vector2f view_size; v2f_t wmouse; // Mouse position in world space; v2f_t follow_center(0, 0), view_center, pan_delta; float view_scale; size = window->getSize(); camera.zoom = expfade(camera.zoom, camera.target_zoom, 15, dt); view_scale = 4.5 * exp(camera.zoom * 0.12); if (size.x < size.y) { view_size.y = view_scale; view_size.x = view_scale * size.x / size.y; } else { view_size.x = view_scale; view_size.y = view_scale * size.y / size.x; } if (game->selected_units.size() && camera.following) { for (entity_t *ent : game->selected_units) follow_center += ent->render_bounds.center(); follow_center /= game->selected_units.size(); camera.follow_center[0] = expfade(camera.follow_center[0], follow_center[0], dt, 25); camera.follow_center[1] = expfade(camera.follow_center[1], follow_center[1], dt, 25); } view_center = camera.center; if (camera.following) view_center += camera.follow_center; window->setView(sf::View(view_center, view_size)); if (camera.panning) { pan_delta = compute_pan(window, camera.pan_ref); view_center += compute_pan(window, camera.pan_ref); } window->setView(sf::View(view_center, view_size)); wmouse = window->mapPixelToCoords(sf::Mouse::getPosition(*window)); while (window->pollEvent(event)) { // FIXME: refactor this nested switch clusterfuck switch (event.type) { case sf::Event::Closed: window->close(); return; case sf::Event::MouseButtonPressed: switch (event.mouseButton.button) { case sf::Mouse::Button::Left: select.selecting = true; select.rect[0] = wmouse; select.rect[1] = wmouse; break; case sf::Mouse::Button::Right: game->command(wmouse); break; case sf::Mouse::Button::Middle: camera.panning = true; camera.pan_ref = wmouse; break; default:; } break; case sf::Event::MouseButtonReleased: switch (event.mouseButton.button) { case sf::Mouse::Button::Left: if (select.selecting) game->select(select.rect); select.selecting = false; break; case sf::Mouse::Button::Middle: if (camera.panning) camera.center += pan_delta; camera.panning = false; break; default:; } break; case sf::Event::MouseWheelScrolled: camera.target_zoom -= event.mouseWheelScroll.delta; if (camera.target_zoom < 0) camera.target_zoom = 0; if (camera.target_zoom > 17) camera.target_zoom = 17; break; case sf::Event::KeyPressed: switch (event.key.code) { case sf::Keyboard::Key::Space: game->paused ^= 1; if (game->paused) print(text::get(text::PAUSED)); else print(text::get(text::UNPAUSED)); break; case sf::Keyboard::Key::F: camera.following ^= 1; if (!camera.following) { camera.center = view_center; print(text::get(text::FOLLOWING_OFF)); } else { camera.center = v2f_t(0, 0); print(text::get(text::FOLLOWING_ON)); } break; case sf::Keyboard::Key::H: game->spawn_soldier(wmouse); break; case sf::Keyboard::Key::F1: debug_draw_cmodels ^= 1; print("debug_draw_cmodels = " + std::to_string(debug_draw_cmodels)); break; case sf::Keyboard::Key::F2: debug_draw_paths ^= 1; print("debug_draw_paths = " + std::to_string(debug_draw_paths)); break; case sf::Keyboard::Key::F3: debug_draw_tile_coords ^= 1; print("debug_draw_tile_coords = " + std::to_string(debug_draw_tile_coords)); break; case sf::Keyboard::Key::F4: debug_AI ^= 1; print("debug_AI = " + std::to_string(debug_AI)); break; default:; } default:; } } if (select.selecting) select.rect[1] = wmouse; } void state_t::print(std::string str) { log.push_back((log_entry_t){game->now, str}); std::cout << str << std::endl; } void state_t::render_to(render::state_t *render) { size_t w = window->getSize().x, h = window->getSize().y; v2f_t x; std::stringstream ss; double fps; if (select.selecting) render->render_hlrect(select.rect, sf::Color(60, 60, 150)); window->setView(sf::View(sf::FloatRect(0, 0, w, h))); em = std::max(w, h) * 0.017; for (auto i = log.begin(); i != log.end(); ) { if (i->time + 3 < game->now) i = log.erase(i); else i++; } x = v2f_t(0.0f, 0.0f); for (log_entry_t &entry : log) { render->render_text(x, em, entry.text, render::ALIGN_LEFT_TOP, sf::Color::White); x[1] += em; } x = v2f_t(0.0f, h - em * 4.5); ss << "World S/T:"; ss << game->world.stats.sectors << "/"; ss << game->world.stats.tiles; render->render_text(x, em, ss.str(), render::ALIGN_LEFT_TOP, sf::Color::White); x[1] += em; ss.str(std::string()); ss << "Awake: " << game->awake_entities.size() << "/" << game->world.stats.entities; render->render_text(x, em, ss.str(), render::ALIGN_LEFT_TOP, sf::Color::White); x[1] += em; ss.str(std::string()); ss << "View S/T/E: "; ss << render->stats.sectors << "/"; ss << render->stats.tiles << "/"; ss << render->stats.entities; render->render_text(x, em, ss.str(), render::ALIGN_LEFT_TOP, sf::Color::White); perf_hist_index = (perf_hist_index + 1) % count(perf_hist); perf_hist[perf_hist_index] = 1.0 / render->dt; fps = 0.0; for (size_t i = 0; i < count(perf_hist); i++) fps += perf_hist[i]; fps /= count(perf_hist); x[1] += em; ss.str(std::string()); ss << std::fixed << std::setprecision(1); ss << "FPS: " << fps; render->render_text(x, em, ss.str(), render::ALIGN_LEFT_TOP, sf::Color::White); } } // namespace interface