summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2018-04-21 18:20:49 +0200
committerPaweł Redman <pawel.redman@gmail.com>2018-04-21 18:20:49 +0200
commit4cfe1361fff6223d11a25cefd74af7a51b7d57bd (patch)
treed1ca7dca22567ec15be3f97d34b44766ad5dc7f4 /src
parent076f69f12ba4000a9c307e803e05827d037d1ff6 (diff)
Hide game and interface behind a pimpl.
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp155
-rw-r--r--src/game/game.cpp2
-rw-r--r--src/game/game.hpp130
-rw-r--r--src/game/interface.cpp6
-rw-r--r--src/game/pseudostate.cpp64
-rw-r--r--src/game/units.cpp6
-rw-r--r--src/main.cpp13
-rw-r--r--src/render.cpp14
8 files changed, 231 insertions, 159 deletions
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> &sectors, std::list<world::entity_t*> &ents, layer_t layer);
+ void render_layer(world::world_t *world, rect_t<world::coord_t, 2> &sectors, 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> &sectors,
+void state_t::render_layer(world::world_t *world, rect_t<world::coord_t, 2> &sectors,
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> &secto
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> &secto
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> &secto
}
}
-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;