diff options
author | Paweł Redman <pawel.redman@gmail.com> | 2018-04-21 18:20:49 +0200 |
---|---|---|
committer | Paweł Redman <pawel.redman@gmail.com> | 2018-04-21 18:20:49 +0200 |
commit | 4cfe1361fff6223d11a25cefd74af7a51b7d57bd (patch) | |
tree | d1ca7dca22567ec15be3f97d34b44766ad5dc7f4 | |
parent | 076f69f12ba4000a9c307e803e05827d037d1ff6 (diff) |
Hide game and interface behind a pimpl.
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | src/common.hpp | 155 | ||||
-rw-r--r-- | src/game/game.cpp | 2 | ||||
-rw-r--r-- | src/game/game.hpp | 130 | ||||
-rw-r--r-- | src/game/interface.cpp | 6 | ||||
-rw-r--r-- | src/game/pseudostate.cpp | 64 | ||||
-rw-r--r-- | src/game/units.cpp | 6 | ||||
-rw-r--r-- | src/main.cpp | 13 | ||||
-rw-r--r-- | src/render.cpp | 14 |
9 files changed, 232 insertions, 159 deletions
@@ -14,6 +14,7 @@ SRC := src/game/assets.cpp \ src/game/effects.cpp \ src/game/game.cpp \ src/game/interface.cpp \ + src/game/pseudostate.cpp \ src/game/rocket.cpp \ src/game/text.cpp \ src/game/units.cpp \ diff --git a/src/common.hpp b/src/common.hpp index 0064c2e..9535305 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -270,137 +270,6 @@ namespace world { }; } -namespace interface { - class state_t; - - typedef struct { - std::string label; - int action; - - float r0, r1; - float t0, t1; - } pie_item_t; -} - -namespace game { - bool load_assets(void); - - class entity_t; - class unit_t; - class effect_t; - - enum { - SELECT_NEW, - SELECT_OR, - SELECT_XOR - }; - - class state_t { - void group_say(std::string text); - bool select_unit(unit_t *unit, int type); - - public: - world::world_t world; - interface::state_t *interface; - procgen::prng_t prng; - std::unordered_set<entity_t*> awake_entities; - std::unordered_set<unit_t*> selected_units; - // Some deletes have to be deferred to the next frame. - std::unordered_set<entity_t*> deletion_list; - - ntime_t time = 1; // game time - double now, dt; // FIXME: refactor the code, use ntime_t everywhere - - // frame timing data (game runs at a different frequency than the renderer) - bool paused; - ntime_t t0; - size_t frames = 0, frames_since_t0, frames_behind = 0; - - void start(void); - void stop(void); - void tick(ntime_t time); - void compute_ambience(render::state_t *render); - void pause(void); - void resume(void); - - void wake_area(v2f_t x); - void explosion(v2f_t x); - void hivemind_alert(v2f_t x, float r, bool do_move, v2f_t move_to); - - // These are called by the interface. - void select(rectf_t rect, int type); - bool populate_pie_menu(std::vector<interface::pie_item_t> &items); - void command(v2f_t x, int number); - }; -} - -namespace interface { - class pie_menu_t { - v2f_t x, x_world; - float radius; - pie_item_t *selected = nullptr; - - protected: - friend state_t; - std::vector<pie_item_t> items; - - public: - bool is_open = false; - - void open(v2f_t wmouse, v2f_t mouse); - void close(game::state_t *game); - void update(v2f_t mouse); - void render_to(render::state_t *render); - }; - - class state_t { - sf::RenderWindow *window; - game::state_t *game; - - float em; - - struct { - v2f_t zero_point_s = v2f_t(0, 0); - v2f_t center = v2f_t(0, 0); - - int zoom = 3; - float zoom_s = 3.0f; - - bool panning = false; - sf::Vector2f pan_ref; - - bool following = true; - } camera; - - struct { - bool selecting = false; - int type; - rectf_t rect; - } select; - - pie_menu_t pie_menu; - - typedef struct { - double time; - std::string text; - } log_entry_t; - - std::list<log_entry_t> log; - - void start_following(void); - void stop_following(void); - - public: - v3f_t camera_3d; // for audio - - state_t(sf::RenderWindow *window_, game::state_t *game); - void tick(double dt); - void render_to(render::state_t *render); - - void print(std::string str); - }; -} - namespace render { class animated_texture_t { friend state_t; @@ -452,7 +321,7 @@ namespace render { sf::RenderWindow *window; void render_tile(world::world_t *world, v2f_t tx, world::tile_t *tile); - void render_layer(game::state_t *game, rect_t<world::coord_t, 2> §ors, std::list<world::entity_t*> &ents, layer_t layer); + void render_layer(world::world_t *world, rect_t<world::coord_t, 2> §ors, std::list<world::entity_t*> &ents, layer_t layer); void drender_text(rectf_t rect, std::string str); void drender_entity(world::entity_t *ent); public: @@ -467,7 +336,7 @@ namespace render { void begin_frame(ntime_t time_, double dt); void end_frame(void); - void render(game::state_t *game); + void render(world::world_t *world); void render(double phase, animated_texture_t *anim, rectf_t bounds, sf::Color color = sf::Color::White, bool mirror = false); void render(double phase, oriented_sprite_t *sprite, rectf_t bounds, float angle); @@ -510,6 +379,26 @@ namespace audio { }; } +namespace game { + class state_t; + + class pseudostate_t { + state_t *pimpl; + + public: + pseudostate_t(sf::RenderWindow *window_); + ~pseudostate_t(void); + + void start(void); + void stop(void); + void tick(ntime_t time, double dt); + world::world_t *get_world(void); + void render_interface_to(render::state_t *render); + }; + + bool load_assets(void); +} + extern render::state_t *debug_render; // Divide and round to minus infinity. diff --git a/src/game/game.cpp b/src/game/game.cpp index 084ac38..5f89a60 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -400,7 +400,7 @@ void state_t::tick(ntime_t time_) frames_since_t0 = 0; frames_behind++; - interface->print("(Lag: " + std::to_string(left) + ")"); + interface.print("(Lag: " + std::to_string(left) + ")"); break; } diff --git a/src/game/game.hpp b/src/game/game.hpp index e35f156..e4fdba2 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -18,6 +18,136 @@ along with Minitrem. If not, see <http://www.gnu.org/licenses/>. #include "../common.hpp" namespace game { + class state_t; + class entity_t; + class unit_t; + class effect_t; +} + +namespace interface { + class state_t; + + typedef struct { + std::string label; + int action; + + float r0, r1; + float t0, t1; + } pie_item_t; + + class pie_menu_t { + v2f_t x, x_world; + float radius; + pie_item_t *selected = nullptr; + + protected: + friend state_t; + std::vector<pie_item_t> items; + + public: + bool is_open = false; + + void open(v2f_t wmouse, v2f_t mouse); + void close(game::state_t *game); + void update(v2f_t mouse); + void render_to(render::state_t *render); + }; + + class state_t { + protected: + friend game::pseudostate_t; + + sf::RenderWindow *window; + game::state_t *game; + + float em; + + struct { + v2f_t zero_point_s = v2f_t(0, 0); + v2f_t center = v2f_t(0, 0); + + int zoom = 3; + float zoom_s = 3.0f; + + bool panning = false; + sf::Vector2f pan_ref; + + bool following = true; + } camera; + + struct { + bool selecting = false; + int type; + rectf_t rect; + } select; + + pie_menu_t pie_menu; + + typedef struct { + double time; + std::string text; + } log_entry_t; + + std::list<log_entry_t> log; + + void start_following(void); + void stop_following(void); + + public: + v3f_t camera_3d; // for audio + + void tick(double dt); + void render_to(render::state_t *render); + + void print(std::string str); + }; +} + +namespace game { + enum { + SELECT_NEW, + SELECT_OR, + SELECT_XOR + }; + + class state_t { + void group_say(std::string text); + bool select_unit(unit_t *unit, int type); + + public: + world::world_t world; + interface::state_t interface; + procgen::prng_t prng; + std::unordered_set<entity_t*> awake_entities; + std::unordered_set<unit_t*> selected_units; + // Some deletes have to be deferred to the next frame. + std::unordered_set<entity_t*> deletion_list; + + ntime_t time = 1; // game time + double now, dt; // FIXME: refactor the code, use ntime_t everywhere + + // frame timing data (game runs at a different frequency than the renderer) + bool paused; + ntime_t t0; + size_t frames = 0, frames_since_t0, frames_behind = 0; + + void start(void); + void stop(void); + void tick(ntime_t time); + void compute_ambience(render::state_t *render); + void pause(void); + void resume(void); + + void wake_area(v2f_t x); + void explosion(v2f_t x); + void hivemind_alert(v2f_t x, float r, bool do_move, v2f_t move_to); + + // These are called by the interface. + void select(rectf_t rect, int type); + bool populate_pie_menu(std::vector<interface::pie_item_t> &items); + void command(v2f_t x, int number); + }; + enum { ET_NONE, ET_UNIT, diff --git a/src/game/interface.cpp b/src/game/interface.cpp index 8cc2a85..c40023d 100644 --- a/src/game/interface.cpp +++ b/src/game/interface.cpp @@ -22,12 +22,6 @@ 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); diff --git a/src/game/pseudostate.cpp b/src/game/pseudostate.cpp new file mode 100644 index 0000000..0f2d0c5 --- /dev/null +++ b/src/game/pseudostate.cpp @@ -0,0 +1,64 @@ +/* +This file is part of Minitrem. + +Minitrem 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 2 of the License, or +(at your option) any later version. + +Minitrem 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 Minitrem. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "game.hpp" + +namespace game { + +pseudostate_t::pseudostate_t(sf::RenderWindow *window_) +{ + pimpl = new state_t(); + + pimpl->interface.window = window_; + pimpl->interface.game = pimpl; +} + +pseudostate_t::~pseudostate_t(void) +{ + delete pimpl; +} + +void pseudostate_t::start(void) +{ + pimpl->start(); +} + +void pseudostate_t::stop(void) +{ + pimpl->stop(); +} + +void pseudostate_t::tick(ntime_t time, double dt) +{ + pimpl->tick(time); + pimpl->interface.tick(dt); +} + +world::world_t *pseudostate_t::get_world(void) +{ + return &pimpl->world; +} + +void pseudostate_t::render_interface_to(render::state_t *render) +{ + pimpl->interface.render_to(render); + + pimpl->compute_ambience(render); + audio::update(pimpl->interface.camera_3d, pimpl->paused); +} + +} diff --git a/src/game/units.cpp b/src/game/units.cpp index 2b3b081..828ca6b 100644 --- a/src/game/units.cpp +++ b/src/game/units.cpp @@ -102,7 +102,7 @@ void unit_t::say(std::string str, bool on_interface) say_time = game->now; if (on_interface) - game->interface->print(name + ": " + str); + game->interface.print(name + ": " + str); } bool unit_t::keep_moving(double speed) @@ -220,11 +220,11 @@ void unit_t::die(unit_t *killer) case UNIT_SOLDIER: case UNIT_SCIENTIST: case UNIT_SPIDER: - game->interface->print(name + " " + text::get(text::UNIT_DEATH) + "."); + game->interface.print(name + " " + text::get(text::UNIT_DEATH) + "."); break; default: - game->interface->print(name + " " + text::get(text::UNIT_DESTRUCTION) + "."); + game->interface.print(name + " " + text::get(text::UNIT_DESTRUCTION) + "."); break; } diff --git a/src/main.cpp b/src/main.cpp index 0a5977f..c7a6f77 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -98,10 +98,8 @@ int main() sf::RenderWindow window(sf::VideoMode(800, 600), "Minitrem"); render::state_t render(&window); - game::state_t game; - interface::state_t interface(&window, &game); + game::pseudostate_t game(&window); - game.interface = &interface; debug_render = &render; window.setVerticalSyncEnabled(true); @@ -119,8 +117,7 @@ int main() dt = 0.1; before = now; - game.tick(now); - interface.tick(dt); + game.tick(now, dt); if (!window.isOpen()) break; @@ -128,10 +125,8 @@ int main() window.clear(); render.begin_frame(now, dt); - render.render(&game); - game.compute_ambience(&render); - interface.render_to(&render); - audio::update(interface.camera_3d, game.paused); + render.render(game.get_world()); + game.render_interface_to(&render); render.end_frame(); } diff --git a/src/render.cpp b/src/render.cpp index 0840c9a..04700fd 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -224,7 +224,7 @@ bool visibility_order(const world::entity_t *x, const world::entity_t *y) return x->render_bounds[1][1] > y->render_bounds[1][1]; } -void state_t::render_layer(game::state_t *game, rect_t<world::coord_t, 2> §ors, +void state_t::render_layer(world::world_t *world, rect_t<world::coord_t, 2> §ors, std::list<world::entity_t*> &ents, layer_t layer) { std::list<world::entity_t*>::iterator ent; @@ -236,7 +236,7 @@ void state_t::render_layer(game::state_t *game, rect_t<world::coord_t, 2> §o world::sector_index_t sector_index(sx, sy); world::sector_t *sector; - sector = game->world.get_sector(sector_index, world::SECTOR_FULL); + sector = world->get_sector(sector_index, world::SECTOR_FULL); while (ent != ents.end() && (*ent)->render_bounds[1][1] < sy * SECTOR_SIZE + ty) { @@ -259,7 +259,7 @@ void state_t::render_layer(game::state_t *game, rect_t<world::coord_t, 2> §o if (tiledata[tile->type].layer != layer) continue; - render_tile(&game->world, index, tile); + render_tile(world, index, tile); } if (layer == LAYER_COUNT - 1) @@ -267,7 +267,7 @@ void state_t::render_layer(game::state_t *game, rect_t<world::coord_t, 2> §o } } -void state_t::render(game::state_t *game) +void state_t::render(world::world_t *world) { rectf_t bounds; std::list<world::entity_t*> ents; @@ -277,14 +277,14 @@ void state_t::render(game::state_t *game) sectors[0] = world::sector_index_at(bounds[0]); sectors[1] = world::sector_index_at(bounds[1]); - ents = game->world.get_render_entities(bounds); + ents = world->get_render_entities(bounds); ents.sort(rendering_order); for (layer_t layer = LAYER_FLAT; layer < LAYER_COUNT; layer++) - render_layer(game, sectors, ents, layer); + render_layer(world, sectors, ents, layer); if (debug_draw_tile_coords) { - for (world::sector_t *sector : game->world.get_sectors(bounds, world::SECTOR_FULL)) + for (world::sector_t *sector : world->get_sectors(bounds, world::SECTOR_FULL)) for (world::coord_t ty = 0; ty < SECTOR_SIZE; ty++) for (world::coord_t tx = 0; tx < SECTOR_SIZE; tx++) { std::stringstream ss; |