1 | // SuperTux |
2 | // Copyright (C) 2006 Matthias Braun <matze@braunis.de> |
3 | // Copyright (C) 2016 M. Teufel <mteufel@supertux.org> |
4 | // |
5 | // This program is free software: you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by |
7 | // the Free Software Foundation, either version 3 of the License, or |
8 | // (at your option) any later version. |
9 | // |
10 | // This program is distributed in the hope that it will be useful, |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | // GNU General Public License for more details. |
14 | // |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | |
18 | #include "supertux/textscroller_screen.hpp" |
19 | |
20 | #include <sstream> |
21 | |
22 | #include "audio/sound_manager.hpp" |
23 | #include "control/input_manager.hpp" |
24 | #include "object/textscroller.hpp" |
25 | #include "supertux/fadetoblack.hpp" |
26 | #include "supertux/globals.hpp" |
27 | #include "supertux/info_box_line.hpp" |
28 | #include "supertux/screen_manager.hpp" |
29 | #include "util/log.hpp" |
30 | #include "util/reader.hpp" |
31 | #include "util/reader_document.hpp" |
32 | #include "util/reader_mapping.hpp" |
33 | #include "video/compositor.hpp" |
34 | #include "video/drawing_context.hpp" |
35 | #include "video/surface.hpp" |
36 | #include "video/video_system.hpp" |
37 | #include "video/viewport.hpp" |
38 | |
39 | namespace { |
40 | |
41 | const float DEFAULT_SPEED = 20; |
42 | const float SCROLL = 60; |
43 | |
44 | } // namespace |
45 | |
46 | TextScrollerScreen::TextScrollerScreen(const std::string& filename) : |
47 | m_defaultspeed(DEFAULT_SPEED), |
48 | m_music(), |
49 | m_background(), |
50 | m_text_scroller(), |
51 | m_fading(false) |
52 | { |
53 | std::string background_file; |
54 | |
55 | try { |
56 | auto doc = ReaderDocument::from_file(filename); |
57 | auto root = doc.get_root(); |
58 | |
59 | m_text_scroller = std::make_unique<TextScroller>(root); |
60 | |
61 | if (root.get_name() != "supertux-text" ) { |
62 | throw std::runtime_error("File isn't a supertux-text file" ); |
63 | } else { |
64 | auto text_mapping = root.get_mapping(); |
65 | |
66 | if (!text_mapping.get("background" , background_file)) { |
67 | throw std::runtime_error("File doesn't contain a background file" ); |
68 | } |
69 | |
70 | text_mapping.get("speed" , m_defaultspeed); |
71 | text_mapping.get("music" , m_music); |
72 | } |
73 | } catch (std::exception& e) { |
74 | std::ostringstream msg; |
75 | msg << "Couldn't load file '" << filename << "': " << e.what() << std::endl; |
76 | throw std::runtime_error(msg.str()); |
77 | } |
78 | |
79 | // load background image |
80 | m_background = Surface::from_file("images/background/" + background_file); |
81 | } |
82 | |
83 | TextScrollerScreen::~TextScrollerScreen() |
84 | { |
85 | } |
86 | |
87 | void |
88 | TextScrollerScreen::setup() |
89 | { |
90 | SoundManager::current()->play_music(m_music); |
91 | ScreenManager::current()->set_screen_fade(std::make_unique<FadeToBlack>(FadeToBlack::FADEIN, 0.5)); |
92 | } |
93 | |
94 | void |
95 | TextScrollerScreen::update(float dt_sec, const Controller& controller) |
96 | { |
97 | if (controller.hold(Control::UP)) { |
98 | m_text_scroller->set_speed(-m_defaultspeed * 5); |
99 | } else if (controller.hold(Control::DOWN)) { |
100 | m_text_scroller->set_speed(m_defaultspeed * 5); |
101 | } else { |
102 | m_text_scroller->set_speed(m_defaultspeed); |
103 | } |
104 | |
105 | if ((controller.pressed(Control::JUMP) || |
106 | controller.pressed(Control::ACTION) || |
107 | controller.pressed(Control::MENU_SELECT)) && |
108 | !(controller.pressed(Control::UP))) { // prevent skipping if jump with up is enabled |
109 | m_text_scroller->scroll(SCROLL); |
110 | } |
111 | |
112 | if (controller.pressed(Control::START) || |
113 | controller.pressed(Control::ESCAPE)) { |
114 | ScreenManager::current()->pop_screen(std::make_unique<FadeToBlack>(FadeToBlack::FADEOUT, 0.5)); |
115 | } |
116 | |
117 | { // close when done |
118 | if (m_text_scroller->is_finished() && !m_fading) |
119 | { |
120 | m_fading = true; |
121 | ScreenManager::current()->pop_screen(std::make_unique<FadeToBlack>(FadeToBlack::FADEOUT, 0.5)); |
122 | } |
123 | } |
124 | |
125 | m_text_scroller->update(dt_sec); |
126 | } |
127 | |
128 | void |
129 | TextScrollerScreen::draw(Compositor& compositor) |
130 | { |
131 | auto& context = compositor.make_context(); |
132 | |
133 | const float ctx_w = static_cast<float>(context.get_width()); |
134 | const float ctx_h = static_cast<float>(context.get_height()); |
135 | |
136 | { // draw background |
137 | const float bg_w = static_cast<float>(m_background->get_width()); |
138 | const float bg_h = static_cast<float>(m_background->get_height()); |
139 | |
140 | const float bg_ratio = bg_w / bg_h; |
141 | const float ctx_ratio = ctx_w / ctx_h; |
142 | |
143 | if (bg_ratio > ctx_ratio) |
144 | { |
145 | const float new_bg_w = ctx_h * bg_ratio; |
146 | context.color().draw_surface_scaled(m_background, |
147 | Rectf::from_center(Vector(ctx_w / 2.0f, ctx_h / 2.0f), |
148 | Sizef(new_bg_w, ctx_h)), |
149 | 0); |
150 | } |
151 | else |
152 | { |
153 | const float new_bg_h = ctx_w / bg_ratio; |
154 | context.color().draw_surface_scaled(m_background, |
155 | Rectf::from_center(Vector(ctx_w / 2.0f, ctx_h / 2.0f), |
156 | Sizef(ctx_w, new_bg_h)), |
157 | 0); |
158 | } |
159 | } |
160 | |
161 | m_text_scroller->draw(context); |
162 | } |
163 | |
164 | /* EOF */ |
165 | |