4 // Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 #include "../app/globals.h"
25 #include "../video/screen.h"
26 #include "../video/font.h"
27 #include "../video/drawing_context.h"
28 #include "../utils/lispreader.h"
30 using namespace SuperTux;
32 Font::Font(const std::string& file, FontType ntype, int nw, int nh,
34 : chars(0), shadow_chars(0), type(ntype), w(nw), h(nh),
35 shadowsize(nshadowsize)
37 chars = new Surface(file, true);
47 last_char = first_char + (chars->h / h) * 16;
48 if(last_char > 127) // we have left out some control chars at 128-159
53 SDL_Surface* conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
54 int pixels = conv->w * conv->h;
55 SDL_LockSurface(conv);
56 for(int i = 0; i < pixels; ++i) {
57 Uint32 *p = (Uint32 *)conv->pixels + i;
58 *p = *p & conv->format->Amask;
60 SDL_UnlockSurface(conv);
61 SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
62 shadow_chars = new Surface(conv, true);
63 SDL_FreeSurface(conv);
74 Font::get_text_width(const std::string& text) const
76 /** Let's calculate the size of the biggest paragraph */
81 l = text.find("\n", l+1);
82 if(l == (int)std::string::npos)
94 Font::get_text_height(const std::string& text) const
96 /** Let's calculate height of the text */
101 l = text.find("\n", l+1);
102 if(l == (int)std::string::npos)
111 Font::get_height() const
117 Font::draw(const std::string& text, const Vector& pos, Uint32 drawing_effect)
120 draw_chars(shadow_chars, text, pos + Vector(shadowsize, shadowsize),
123 draw_chars(chars, text, pos, drawing_effect);
127 Font::draw_center(const std::string& text, const Vector& pos, Uint32 drawing_effect)
129 /* Cut lines changes into seperate strings, needed to support centering text
131 Feel free to replace this hack with a more elegant solution
134 unsigned int i, l, y;
138 l = text.find("\n", i);
139 if(l == std::string::npos)
141 temp[text.copy(temp, text.size() - i, i)] = '\0';
142 draw(temp, Vector(screen->w/2 - get_text_width(temp)/2 + pos.x, pos.y + y),
146 temp[text.copy(temp, l - i, i)] = '\0';
147 draw(temp, Vector(screen->w/2 - get_text_width(temp)/2 + pos.x, pos.y + y),
156 Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
157 Uint32 drawing_effect)
159 SurfaceImpl* impl = pchars->impl;
162 for(size_t i = 0; i < text.size(); ++i)
164 int c = (unsigned char) text[i];
165 if(c > 127) // correct for the 32 controlchars at 128-159
167 // a non-printable character?
173 if(c == ' ' || c < first_char || c > last_char) {
178 int index = c - first_char;
179 int source_x = (index % 16) * w;
180 int source_y = (index / 16) * h;
182 impl->draw_part(source_x, source_y, p.x, p.y, w, h, 255, drawing_effect);
187 /* --- SCROLL TEXT FUNCTION --- */
190 #define SPEED_INC 0.01
192 #define ITEMS_SPACE 4
194 void SuperTux::display_text_file(const std::string& file, float scroll_speed, Font* heading_font, Font* normal_font, Font* small_font, Font* reference_font )
197 std::vector<std::string> names;
199 LispReader* reader = LispReader::load(datadir + "/" + file, "supertux-text");
203 std::cerr << "Error: Could not open text. Ignoring...\n";
207 reader->read_string("text", text, true);
208 std::string background_file;
209 reader->read_string("background", background_file, true);
212 // Split text string lines into a vector
218 l = text.find("\n", i);
220 if(l == std::string::npos)
223 temp[text.copy(temp, text.size() - i, i)] = '\0';
224 names.push_back(temp);
229 temp[text.copy(temp, l-i, i)] = '\0';
230 names.push_back(temp);
235 // load background image
236 Surface* background = new Surface(datadir + "/images/background/" + background_file, false);
240 float speed = scroll_speed / 50;
242 DrawingContext context;
243 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
245 Uint32 lastticks = SDL_GetTicks();
248 /* in case of input, exit */
250 while(SDL_PollEvent(&event))
254 switch(event.key.keysym.sym)
283 else if(speed < -MAX_VEL)
286 /* draw the credits */
287 context.draw_surface(background, Vector(0,0), 0);
290 for(size_t i = 0; i < names.size(); i++) {
291 if(names[i].size() == 0) {
292 y += normal_font->get_height() + ITEMS_SPACE;
299 case ' ': font = small_font; break;
300 case '\t': font = normal_font; break;
301 case '-': font = heading_font; break;
302 case '*': font = reference_font; break;
303 default: font = reference_font; break;
306 context.draw_text_center(font,
307 names[i].substr(1, names[i].size()-1),
308 Vector(0, screen->h + y - scroll), LAYER_FOREGROUND1);
309 y += font->get_height() + ITEMS_SPACE;
312 context.do_drawing();
314 if(screen->h+y-scroll < 0 && 20+screen->h+y-scroll < 0)
317 Uint32 ticks = SDL_GetTicks();
318 scroll += speed * (ticks - lastticks);
326 SDL_EnableKeyRepeat(0, 0); // disables key repeating