/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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 this program. If not, see . * */ #include "common/config-manager.h" #include "image/bmp.h" #include "ultima/ultima8/gumps/cru_credits_gump.h" #include "ultima/ultima8/ultima8.h" #include "ultima/ultima8/kernel/mouse.h" #include "ultima/ultima8/gfx/render_surface.h" #include "ultima/ultima8/gfx/palette_manager.h" #include "ultima/ultima8/gfx/texture.h" #include "ultima/ultima8/gfx/fonts/rendered_text.h" #include "ultima/ultima8/gfx/fonts/font.h" #include "ultima/ultima8/gfx/fonts/font_manager.h" #include "ultima/ultima8/gfx/fonts/shape_font.h" #include "ultima/ultima8/audio/music_process.h" namespace Ultima { namespace Ultima8 { DEFINE_RUNTIME_CLASSTYPE_CODE(CruCreditsGump) CruCreditsGump::CruCreditsGump() : ModalGump(), _timer(0), _background(nullptr), _nextScreenStart(0), _screenNo(-1) { } CruCreditsGump::CruCreditsGump(Common::SeekableReadStream *txtrs, Common::SeekableReadStream *bmprs, uint32 flags, int32 layer) : ModalGump(0, 0, 640, 480, 0, flags, layer), _timer(0), _background(nullptr), _nextScreenStart(0), _screenNo(-1) { Image::BitmapDecoder decoder; Graphics::Screen *sc = Ultima8Engine::get_instance()->getScreen(); _background = new RenderSurface(640, 480, sc->format); uint32 color = TEX32_PACK_RGB(0, 0, 0); _background->fill32(color, 0, 0, 640, 480); // black background if (decoder.loadStream(*bmprs)) { // This does an extra copy via the ManagedSurface, but it's a once-off. const Graphics::Surface *bmpsurf = decoder.getSurface(); Graphics::ManagedSurface ms; ms.copyFrom(*bmpsurf); ms.setPalette(decoder.getPalette().data(), 0, decoder.getPalette().size()); Common::Rect srcRect(640, 480); _background->Blit(ms, srcRect, 0, 0); } else { warning("couldn't load bitmap background for credits."); } // Lots of extra copies here, but it's only 4kb of text so it's fine. CredScreen screen; CredLine credline; // not sure what these 4 bytes are? txtrs->readUint32LE(); while (!txtrs->eos()) { Common::String line = txtrs->readString(); if (!line.size()) break; credline._text = line.substr(1); switch (line[0]) { case '@': credline._lineType = kCredTitle; screen._lines.push_back(credline); break; case '$': credline._lineType = kCredName; screen._lines.push_back(credline); break; case '*': { unsigned int i = 1; while (i < line.size() && line[i] == '*') i++; screen._delay = 60 * i; _screens.push_back(screen); screen._lines.clear(); break; } default: if (line.size()) debug(6, "unhandled line in credits: %s", line.c_str()); break; } } } CruCreditsGump::~CruCreditsGump() { delete _background; for (auto *line : _currentLines) { delete line; } } void CruCreditsGump::InitGump(Gump *newparent, bool take_focus) { ModalGump::InitGump(newparent, take_focus); Mouse::get_instance()->pushMouseCursor(Mouse::MOUSE_NONE); MusicProcess *musicproc = MusicProcess::get_instance(); if (musicproc) { if (GAME_IS_REMORSE) musicproc->playMusic(19); else musicproc->playMusic(17); } } void CruCreditsGump::Close(bool no_del) { Mouse::get_instance()->popMouseCursor(); ModalGump::Close(no_del); // Just let it play out? //MusicProcess *musicproc = MusicProcess::get_instance(); //if (musicproc) musicproc->restoreMusic(); } void CruCreditsGump::run() { ModalGump::run(); _timer++; if (_timer < _nextScreenStart) return; _screenNo++; if (_screenNo >= static_cast(_screens.size())) { Close(); return; } _nextScreenStart += _screens[_screenNo]._delay; for (auto *line : _currentLines) { delete line; } _currentLines.clear(); const Common::Array &lines = _screens[_screenNo]._lines; Font *titlefont = FontManager::get_instance()->getGameFont(16, true); Font *namefont = FontManager::get_instance()->getGameFont(17, true); Palette *pal = PaletteManager::get_instance()->getPalette(PaletteManager::Pal_Cred); ShapeFont *titleshapefont = dynamic_cast(titlefont); if (pal && titleshapefont) titleshapefont->setPalette(pal); ShapeFont *nameshapefont = dynamic_cast(namefont); if (pal && nameshapefont) nameshapefont->setPalette(pal); for (const auto &line : lines) { Font *linefont = (line._lineType == kCredTitle) ? titlefont : namefont; if (!linefont) { // shouldn't happen.. just to be sure? warning("can't render credits line type %d, font is null", line._lineType); break; } unsigned int remaining; RenderedText *rendered = linefont->renderText(line._text, remaining, 640, 0, Font::TEXT_CENTER); _currentLines.push_back(rendered); } } void CruCreditsGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) { Common::Rect srcRect(640, 480); surf->Blit(*_background->getRawSurface(), srcRect, 0, 0); unsigned int nlines = _currentLines.size(); if (!nlines) return; int width, height; _currentLines[0]->getSize(width, height); int vlead = _currentLines[0]->getVlead(); int total = nlines * (height + vlead); int yoffset = 240 - total / 2; for (auto *line : _currentLines) { line->draw(surf, 0, yoffset); yoffset += (height + vlead); } } bool CruCreditsGump::OnKeyDown(int key, int mod) { if (key == Common::KEYCODE_ESCAPE) Close(); return true; } } // End of namespace Ultima8 } // End of namespace Ultima