1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "object/particlesystem.hpp"
18
19#include <math.h>
20
21#include "supertux/globals.hpp"
22#include "util/reader.hpp"
23#include "util/reader_mapping.hpp"
24#include "util/writer.hpp"
25#include "video/drawing_context.hpp"
26#include "video/surface_batch.hpp"
27#include "video/video_system.hpp"
28#include "video/viewport.hpp"
29
30ParticleSystem::ParticleSystem(const ReaderMapping& reader, float max_particle_size_) :
31 GameObject(reader),
32 ExposedObject<ParticleSystem, scripting::ParticleSystem>(this),
33 max_particle_size(max_particle_size_),
34 z_pos(LAYER_BACKGROUND1),
35 particles(),
36 virtual_width(static_cast<float>(SCREEN_WIDTH) + max_particle_size * 2.0f),
37 virtual_height(static_cast<float>(SCREEN_HEIGHT) + max_particle_size * 2.0f),
38 enabled(true)
39{
40 reader.get("enabled", enabled, true);
41 z_pos = reader_get_layer(reader, LAYER_BACKGROUND1);
42}
43
44ParticleSystem::ParticleSystem(float max_particle_size_) :
45 GameObject(),
46 ExposedObject<ParticleSystem, scripting::ParticleSystem>(this),
47 max_particle_size(max_particle_size_),
48 z_pos(LAYER_BACKGROUND1),
49 particles(),
50 virtual_width(static_cast<float>(SCREEN_WIDTH) + max_particle_size * 2.0f),
51 virtual_height(static_cast<float>(SCREEN_HEIGHT) + max_particle_size * 2.0f),
52 enabled(true)
53{
54}
55
56ObjectSettings
57ParticleSystem::get_settings()
58{
59 ObjectSettings result = GameObject::get_settings();
60
61 result.add_bool(_("Enabled"), &enabled, "enabled", true);
62 result.add_int(_("Z-pos"), &z_pos, "z-pos", LAYER_BACKGROUND1);
63
64 result.reorder({"enabled", "name"});
65
66 result.add_remove();
67
68 return result;
69}
70
71ParticleSystem::~ParticleSystem()
72{
73}
74
75void
76ParticleSystem::draw(DrawingContext& context)
77{
78 if (!enabled)
79 return;
80
81 float scrollx = context.get_translation().x;
82 float scrolly = context.get_translation().y;
83
84 context.push_transform();
85 context.set_translation(Vector(max_particle_size,max_particle_size));
86
87 std::unordered_map<SurfacePtr, SurfaceBatch> batches;
88 for (const auto& particle : particles)
89 {
90 // remap x,y coordinates onto screencoordinates
91 Vector pos;
92
93 pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
94 if (pos.x < 0) pos.x += virtual_width;
95
96 pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
97 if (pos.y < 0) pos.y += virtual_height;
98
99 //if(pos.x > virtual_width) pos.x -= virtual_width;
100 //if(pos.y > virtual_height) pos.y -= virtual_height;
101
102 auto it = batches.find(particle->texture);
103 if (it == batches.end()) {
104 const auto& batch_it = batches.emplace(particle->texture, SurfaceBatch(particle->texture));
105 batch_it.first->second.draw(pos, particle->angle);
106 } else {
107 it->second.draw(pos, particle->angle);
108 }
109 }
110
111 for(auto& it : batches) {
112 auto& surface = it.first;
113 auto& batch = it.second;
114 context.color().draw_surface_batch(surface,
115 batch.move_srcrects(),
116 batch.move_dstrects(),
117 batch.move_angles(),
118 Color::WHITE, z_pos);
119 }
120
121 context.pop_transform();
122}
123
124void
125ParticleSystem::set_enabled(bool enabled_)
126{
127 enabled = enabled_;
128}
129
130bool
131ParticleSystem::get_enabled() const
132{
133 return enabled;
134}
135
136/* EOF */
137