1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "common/config-manager.h"
24 #include "image/bmp.h"
25
26 #include "ultima/ultima8/gumps/cru_credits_gump.h"
27
28 #include "ultima/ultima8/ultima8.h"
29 #include "ultima/ultima8/kernel/mouse.h"
30 #include "ultima/ultima8/graphics/render_surface.h"
31 #include "ultima/ultima8/graphics/palette_manager.h"
32 #include "ultima/ultima8/graphics/fonts/rendered_text.h"
33 #include "ultima/ultima8/graphics/fonts/font.h"
34 #include "ultima/ultima8/graphics/fonts/font_manager.h"
35 #include "ultima/ultima8/graphics/fonts/shape_font.h"
36 #include "ultima/ultima8/audio/music_process.h"
37
38 namespace Ultima {
39 namespace Ultima8 {
40
DEFINE_RUNTIME_CLASSTYPE_CODE(CruCreditsGump)41 DEFINE_RUNTIME_CLASSTYPE_CODE(CruCreditsGump)
42
43 CruCreditsGump::CruCreditsGump()
44 : ModalGump(), _timer(0), _background(nullptr), _nextScreenStart(0),
45 _screenNo(-1) {
46 }
47
CruCreditsGump(Common::SeekableReadStream * txtrs,Common::SeekableReadStream * bmprs,uint32 flags,int32 layer)48 CruCreditsGump::CruCreditsGump(Common::SeekableReadStream *txtrs,
49 Common::SeekableReadStream *bmprs,
50 uint32 flags, int32 layer)
51 : ModalGump(0, 0, 640, 480, 0, flags, layer),
52 _timer(0), _background(nullptr), _nextScreenStart(0), _screenNo(-1)
53 {
54 Image::BitmapDecoder decoder;
55 _background = RenderSurface::CreateSecondaryRenderSurface(640, 480);
56 _background->Fill32(0xFF000000, 0, 0, 640, 480); // black background
57
58 if (decoder.loadStream(*bmprs)) {
59 // This does an extra copy via the ManagedSurface, but it's a once-off.
60 const Graphics::Surface *bmpsurf = decoder.getSurface();
61 Graphics::ManagedSurface *ms = new Graphics::ManagedSurface(bmpsurf);
62 ms->setPalette(decoder.getPalette(), decoder.getPaletteStartIndex(), decoder.getPaletteColorCount());
63 _background->Blit(ms, 0, 0, 640, 480, 0, 0);
64 } else {
65 warning("couldn't load bitmap background for credits.");
66 }
67
68 // Lots of extra copies here, but it's only 4kb of text so it's fine.
69 CredScreen screen;
70 CredLine credline;
71
72 // not sure what these 4 bytes are?
73 txtrs->readUint32LE();
74 while (!txtrs->eos()) {
75 Common::String line = txtrs->readString();
76 if (!line.size())
77 break;
78 credline._text = line.substr(1);
79 switch (line[0]) {
80 case '@':
81 credline._lineType = kCredTitle;
82 screen._lines.push_back(credline);
83 break;
84 case '$':
85 credline._lineType = kCredName;
86 screen._lines.push_back(credline);
87 break;
88 case '*': {
89 unsigned int i = 1;
90 while (i < line.size() && line[i] == '*')
91 i++;
92 screen._delay = 60 * i;
93 _screens.push_back(screen);
94 screen._lines.clear();
95 break;
96 }
97 default:
98 if (line.size())
99 debug(6, "unhandled line in credits: %s", line.c_str());
100 break;
101 }
102 }
103 }
104
~CruCreditsGump()105 CruCreditsGump::~CruCreditsGump() {
106 delete _background;
107
108 for (Common::Array<RenderedText *>::iterator iter = _currentLines.begin(); iter != _currentLines.end(); iter++) {
109 delete *iter;
110 }
111 }
112
InitGump(Gump * newparent,bool take_focus)113 void CruCreditsGump::InitGump(Gump *newparent, bool take_focus) {
114 ModalGump::InitGump(newparent, take_focus);
115
116 Mouse::get_instance()->pushMouseCursor();
117 Mouse::get_instance()->setMouseCursor(Mouse::MOUSE_NONE);
118
119 MusicProcess *musicproc = MusicProcess::get_instance();
120 if (musicproc) {
121 if (GAME_IS_REMORSE)
122 musicproc->playMusic(19);
123 else
124 musicproc->playMusic(17);
125 }
126 }
127
Close(bool no_del)128 void CruCreditsGump::Close(bool no_del) {
129 Mouse::get_instance()->popMouseCursor();
130
131 ModalGump::Close(no_del);
132
133 // Just let it play out?
134 //MusicProcess *musicproc = MusicProcess::get_instance();
135 //if (musicproc) musicproc->restoreMusic();
136 }
137
run()138 void CruCreditsGump::run() {
139 ModalGump::run();
140
141 _timer++;
142
143 if (_timer < _nextScreenStart)
144 return;
145
146 _screenNo++;
147 if (_screenNo >= static_cast<int>(_screens.size())) {
148 Close();
149 return;
150 }
151
152 _nextScreenStart += _screens[_screenNo]._delay;
153 for (Common::Array<RenderedText *>::iterator iter = _currentLines.begin();
154 iter != _currentLines.end(); iter++) {
155 delete *iter;
156 }
157 _currentLines.clear();
158
159 const Common::Array<CredLine> &lines = _screens[_screenNo]._lines;
160
161 Font *titlefont = FontManager::get_instance()->getGameFont(16, true);
162 Font *namefont = FontManager::get_instance()->getGameFont(17, true);
163 Palette *pal = PaletteManager::get_instance()->getPalette(PaletteManager::Pal_Cred);
164
165 ShapeFont *titleshapefont = dynamic_cast<ShapeFont *>(titlefont);
166 if (pal && titleshapefont)
167 titleshapefont->setPalette(pal);
168 ShapeFont *nameshapefont = dynamic_cast<ShapeFont *>(namefont);
169 if (pal && nameshapefont)
170 nameshapefont->setPalette(pal);
171
172 for (Common::Array<CredLine>::const_iterator iter = lines.begin();
173 iter != lines.end(); iter++) {
174 Font *linefont = (iter->_lineType == kCredTitle) ? titlefont : namefont;
175
176 unsigned int remaining;
177 RenderedText *rendered = linefont->renderText(iter->_text, remaining, 640, 0, Font::TEXT_CENTER);
178 _currentLines.push_back(rendered);
179 }
180 }
181
PaintThis(RenderSurface * surf,int32 lerp_factor,bool scaled)182 void CruCreditsGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
183 surf->Blit(_background->getRawSurface(), 0, 0, 640, 480, 0, 0);
184
185 unsigned int nlines = _currentLines.size();
186 if (!nlines)
187 return;
188
189 int width, height;
190 _currentLines[0]->getSize(width, height);
191 int vlead = _currentLines[0]->getVlead();
192
193 int total = nlines * (height + vlead);
194 int yoffset = 240 - total / 2;
195
196 for (Common::Array<RenderedText *>::iterator iter = _currentLines.begin();
197 iter != _currentLines.end(); iter++) {
198 (*iter)->draw(surf, 0, yoffset);
199 yoffset += (height + vlead);
200 }
201 }
202
OnKeyDown(int key,int mod)203 bool CruCreditsGump::OnKeyDown(int key, int mod) {
204 if (key == Common::KEYCODE_ESCAPE)
205 Close();
206
207 return true;
208 }
209
210 } // End of namespace Ultima8
211 } // End of namespace Ultima
212