aboutsummaryrefslogtreecommitdiff
path: root/sword2/build_display.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sword2/build_display.cpp')
-rw-r--r--sword2/build_display.cpp1070
1 files changed, 0 insertions, 1070 deletions
diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp
deleted file mode 100644
index bc5a31a1f9..0000000000
--- a/sword2/build_display.cpp
+++ /dev/null
@@ -1,1070 +0,0 @@
-/* Copyright (C) 1994-1998 Revolution Software Ltd.
- * Copyright (C) 2003-2006 The ScummVM project
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-// ---------------------------------------------------------------------------
-// BUILD_DISPLAY.CPP like the old spr_engi but slightly more aptly named
-// ---------------------------------------------------------------------------
-
-#include "common/stdafx.h"
-#include "common/system.h"
-
-#include "sword2/sword2.h"
-#include "sword2/console.h"
-#include "sword2/defs.h"
-#include "sword2/logic.h"
-#include "sword2/maketext.h"
-#include "sword2/mouse.h"
-#include "sword2/resman.h"
-#include "sword2/sound.h"
-
-namespace Sword2 {
-
-Screen::Screen(Sword2Engine *vm, int16 width, int16 height) {
- _vm = vm;
-
- _dirtyGrid = _buffer = NULL;
-
- _vm->_system->initSize(width, height);
-
- _screenWide = width;
- _screenDeep = height;
-
- _gridWide = width / CELLWIDE;
- _gridDeep = height / CELLDEEP;
-
- if ((width % CELLWIDE) || (height % CELLDEEP))
- error("Bad cell size");
-
- _dirtyGrid = (byte *)calloc(_gridWide, _gridDeep);
- if (!_dirtyGrid)
- error("Could not initialise dirty grid");
-
- _buffer = (byte *)malloc(width * height);
- if (!_buffer)
- error("Could not initialise display");
-
- for (int i = 0; i < ARRAYSIZE(_blockSurfaces); i++)
- _blockSurfaces[i] = NULL;
-
- _lightMask = NULL;
- _needFullRedraw = false;
-
- memset(&_thisScreen, 0, sizeof(_thisScreen));
-
- _fps = 0;
- _frameCount = 0;
- _cycleTime = 0;
-
- _lastPaletteRes = 0;
-
- _scrollFraction = 16;
-
- _largestLayerArea = 0;
- _largestSpriteArea = 0;
-
- strcpy(_largestLayerInfo, "largest layer: none registered");
- strcpy(_largestSpriteInfo, "largest sprite: none registered");
-
- _fadeStatus = RDFADE_NONE;
- _renderAverageTime = 60;
-
- _layer = 0;
-}
-
-Screen::~Screen() {
- free(_buffer);
- free(_dirtyGrid);
- closeBackgroundLayer();
- free(_lightMask);
-}
-
-void Screen::buildDisplay() {
- if (_thisScreen.new_palette) {
- // start the layer palette fading up
- startNewPalette();
-
- // should be reset to zero at start of each screen change
- _largestLayerArea = 0;
- _largestSpriteArea = 0;
- }
-
- // Does this ever happen?
- if (!_thisScreen.background_layer_id)
- return;
-
- // there is a valid screen to run
-
- setScrollTarget(_thisScreen.scroll_offset_x, _thisScreen.scroll_offset_y);
- _vm->_mouse->animateMouse();
- startRenderCycle();
-
- byte *file = _vm->_resman->openResource(_thisScreen.background_layer_id);
-
- MultiScreenHeader screenLayerTable;
-
- screenLayerTable.read(file + ResHeader::size());
-
- // Render at least one frame, but if the screen is scrolling, and if
- // there is time left, we will render extra frames to smooth out the
- // scrolling.
-
- do {
- // first background parallax + related anims
- if (screenLayerTable.bg_parallax[0]) {
- renderParallax(_vm->fetchBackgroundParallaxLayer(file, 0), 0);
- drawBackPar0Frames();
- }
-
- // second background parallax + related anims
- if (screenLayerTable.bg_parallax[1]) {
- renderParallax(_vm->fetchBackgroundParallaxLayer(file, 1), 1);
- drawBackPar1Frames();
- }
-
- // normal backround layer (just the one!)
- renderParallax(_vm->fetchBackgroundLayer(file), 2);
-
- // sprites & layers
- drawBackFrames(); // background sprites
- drawSortFrames(file); // sorted sprites & layers
- drawForeFrames(); // foreground sprites
-
- // first foreground parallax + related anims
-
- if (screenLayerTable.fg_parallax[0]) {
- renderParallax(_vm->fetchForegroundParallaxLayer(file, 0), 3);
- drawForePar0Frames();
- }
-
- // second foreground parallax + related anims
-
- if (screenLayerTable.fg_parallax[1]) {
- renderParallax(_vm->fetchForegroundParallaxLayer(file, 1), 4);
- drawForePar1Frames();
- }
-
- _vm->_debugger->drawDebugGraphics();
- _vm->_fontRenderer->printTextBlocs();
- _vm->_mouse->processMenu();
-
- updateDisplay();
-
- _frameCount++;
- if (_vm->getMillis() > _cycleTime) {
- _fps = _frameCount;
- _frameCount = 0;
- _cycleTime = _vm->getMillis() + 1000;
- }
- } while (!endRenderCycle());
-
- _vm->_resman->closeResource(_thisScreen.background_layer_id);
-}
-
-/**
- * Fades down and displays a message on the screen.
- * @param text The message
- * @param time The number of seconds to display the message, or 0 to display it
- * until the user clicks the mouse or presses a key.
- */
-
-void Screen::displayMsg(byte *text, int time) {
- byte pal[256 * 4];
- byte oldPal[256 * 4];
-
- debug(2, "DisplayMsg: %s", text);
-
- if (getFadeStatus() != RDFADE_BLACK) {
- fadeDown();
- waitForFade();
- }
-
- _vm->_mouse->setMouse(0);
- _vm->_mouse->setLuggage(0);
- _vm->_mouse->closeMenuImmediately();
-
- clearScene();
-
- byte *text_spr = _vm->_fontRenderer->makeTextSprite(text, 640, 187, _vm->_speechFontId);
-
- FrameHeader frame;
-
- frame.read(text_spr);
-
- SpriteInfo spriteInfo;
-
- spriteInfo.x = _screenWide / 2 - frame.width / 2;
- if (!time)
- spriteInfo.y = _screenDeep / 2 - frame.height / 2 - MENUDEEP;
- else
- spriteInfo.y = 400 - frame.height;
- spriteInfo.w = frame.width;
- spriteInfo.h = frame.height;
- spriteInfo.scale = 0;
- spriteInfo.scaledWidth = 0;
- spriteInfo.scaledHeight = 0;
- spriteInfo.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION | RDSPR_TRANS;
- spriteInfo.blend = 0;
- spriteInfo.data = text_spr + FrameHeader::size();
- spriteInfo.colourTable = 0;
-
- uint32 rv = drawSprite(&spriteInfo);
- if (rv)
- error("Driver Error %.8x (in DisplayMsg)", rv);
-
- memcpy(oldPal, _palette, sizeof(oldPal));
- memset(pal, 0, sizeof(pal));
-
- pal[187 * 4 + 0] = 255;
- pal[187 * 4 + 1] = 255;
- pal[187 * 4 + 2] = 255;
-
- setPalette(0, 256, pal, RDPAL_FADE);
- fadeUp();
- free(text_spr);
- waitForFade();
-
- if (time > 0) {
- uint32 targetTime = _vm->getMillis() + (time * 1000);
- _vm->sleepUntil(targetTime);
- } else {
- while (!_vm->_quit) {
- MouseEvent *me = _vm->mouseEvent();
- if (me && (me->buttons & (RD_LEFTBUTTONDOWN | RD_RIGHTBUTTONDOWN)))
- break;
-
- if (_vm->keyboardEvent())
- break;
-
- updateDisplay();
- _vm->_system->delayMillis(50);
- }
- }
-
- fadeDown();
- waitForFade();
- clearScene();
- setPalette(0, 256, oldPal, RDPAL_FADE);
- fadeUp();
-}
-
-void Screen::drawBackPar0Frames() {
- // frame attached to 1st background parallax
- for (uint i = 0; i < _curBgp0; i++)
- processImage(&_bgp0List[i]);
-}
-
-void Screen::drawBackPar1Frames() {
- // frame attached to 2nd background parallax
- for (uint i = 0; i < _curBgp1; i++)
- processImage(&_bgp1List[i]);
-}
-
-void Screen::drawBackFrames() {
- // background sprite, fixed to main background
- for (uint i = 0; i < _curBack; i++)
- processImage(&_backList[i]);
-}
-
-void Screen::drawSortFrames(byte *file) {
- uint i, j;
-
- // Sort the sort list. Used to be a separate function, but it was only
- // called once, right before calling drawSortFrames().
-
- if (_curSort > 1) {
- for (i = 0; i < _curSort - 1; i++) {
- for (j = 0; j < _curSort - 1; j++) {
- if (_sortList[_sortOrder[j]].sort_y > _sortList[_sortOrder[j + 1]].sort_y) {
- SWAP(_sortOrder[j], _sortOrder[j + 1]);
- }
- }
- }
- }
-
- // Draw the sorted frames - layers, shrinkers & normal flat sprites
-
- for (i = 0; i < _curSort; i++) {
- if (_sortList[_sortOrder[i]].layer_number) {
- // it's a layer - minus 1 for true layer number
- // we need to know from the BuildUnit because the
- // layers will have been sorted in random order
- processLayer(file, _sortList[_sortOrder[i]].layer_number - 1);
- } else {
- // it's a sprite
- processImage(&_sortList[_sortOrder[i]]);
- }
- }
-}
-
-void Screen::drawForeFrames() {
- // foreground sprite, fixed to main background
- for (uint i = 0; i < _curFore; i++)
- processImage(&_foreList[i]);
-}
-
-void Screen::drawForePar0Frames() {
- // frame attached to 1st foreground parallax
- for (uint i = 0; i < _curFgp0; i++)
- processImage(&_fgp0List[i]);
-}
-
-void Screen::drawForePar1Frames() {
- // frame attached to 2nd foreground parallax
- for (uint i = 0; i < _curFgp1; i++)
- processImage(&_fgp1List[i]);
-}
-
-void Screen::processLayer(byte *file, uint32 layer_number) {
- LayerHeader layer_head;
-
- layer_head.read(_vm->fetchLayerHeader(file, layer_number));
-
- SpriteInfo spriteInfo;
-
- spriteInfo.x = layer_head.x;
- spriteInfo.y = layer_head.y;
- spriteInfo.w = layer_head.width;
- spriteInfo.scale = 0;
- spriteInfo.scaledWidth = 0;
- spriteInfo.scaledHeight = 0;
- spriteInfo.h = layer_head.height;
- spriteInfo.type = RDSPR_TRANS | RDSPR_RLE256FAST;
- spriteInfo.blend = 0;
- spriteInfo.data = file + ResHeader::size() + layer_head.offset;
- spriteInfo.colourTable = 0;
-
- // check for largest layer for debug info
-
- uint32 current_layer_area = layer_head.width * layer_head.height;
-
- if (current_layer_area > _largestLayerArea) {
- byte buf[NAME_LEN];
-
- _largestLayerArea = current_layer_area;
- sprintf(_largestLayerInfo,
- "largest layer: %s layer(%d) is %dx%d",
- _vm->_resman->fetchName(_thisScreen.background_layer_id, buf),
- layer_number, layer_head.width, layer_head.height);
- }
-
- uint32 rv = drawSprite(&spriteInfo);
- if (rv)
- error("Driver Error %.8x in processLayer(%d)", rv, layer_number);
-}
-
-void Screen::processImage(BuildUnit *build_unit) {
- byte *file = _vm->_resman->openResource(build_unit->anim_resource);
- byte *colTablePtr = NULL;
-
- byte *frame = _vm->fetchFrameHeader(file, build_unit->anim_pc);
-
- AnimHeader anim_head;
- CdtEntry cdt_entry;
- FrameHeader frame_head;
-
- anim_head.read(_vm->fetchAnimHeader(file));
- cdt_entry.read(_vm->fetchCdtEntry(file, build_unit->anim_pc));
- frame_head.read(frame);
-
- // so that 0-colour is transparent
- uint32 spriteType = RDSPR_TRANS;
-
- if (anim_head.blend)
- spriteType |= RDSPR_BLEND;
-
- // if the frame is to be flipped (only really applicable to frames
- // using offsets)
- if (cdt_entry.frameType & FRAME_FLIPPED)
- spriteType |= RDSPR_FLIP;
-
- if (cdt_entry.frameType & FRAME_256_FAST) {
- // scaling, shading & blending don't work with RLE256FAST
- // but the same compression can be decompressed using the
- // RLE256 routines!
-
- // NOTE: If this restriction refers to drawSprite(), I don't
- // think we have it any more. But I'm not sure.
-
- if (build_unit->scale || anim_head.blend || build_unit->shadingFlag)
- spriteType |= RDSPR_RLE256;
- else
- spriteType |= RDSPR_RLE256FAST;
- } else {
- switch (anim_head.runTimeComp) {
- case NONE:
- spriteType |= RDSPR_NOCOMPRESSION;
- break;
- case RLE256:
- spriteType |= RDSPR_RLE256;
- break;
- case RLE16:
- spriteType |= RDSPR_RLE16;
- // points to just after last cdt_entry, ie.
- // start of colour table
- colTablePtr = _vm->fetchAnimHeader(file) + AnimHeader::size() + anim_head.noAnimFrames * CdtEntry::size();
- break;
- }
- }
-
- // if we want this frame to be affected by the shading mask,
- // add the status bit
- if (build_unit->shadingFlag)
- spriteType |= RDSPR_SHADOW;
-
- SpriteInfo spriteInfo;
-
- spriteInfo.x = build_unit->x;
- spriteInfo.y = build_unit->y;
- spriteInfo.w = frame_head.width;
- spriteInfo.h = frame_head.height;
- spriteInfo.scale = build_unit->scale;
- spriteInfo.scaledWidth = build_unit->scaled_width;
- spriteInfo.scaledHeight = build_unit->scaled_height;
- spriteInfo.type = spriteType;
- spriteInfo.blend = anim_head.blend;
- // points to just after frame header, ie. start of sprite data
- spriteInfo.data = frame + FrameHeader::size();
- spriteInfo.colourTable = colTablePtr;
-
- // check for largest layer for debug info
- uint32 current_sprite_area = frame_head.width * frame_head.height;
-
- if (current_sprite_area > _largestSpriteArea) {
- byte buf[NAME_LEN];
-
- _largestSpriteArea = current_sprite_area;
- sprintf(_largestSpriteInfo,
- "largest sprite: %s frame(%d) is %dx%d",
- _vm->_resman->fetchName(build_unit->anim_resource, buf),
- build_unit->anim_pc,
- frame_head.width,
- frame_head.height);
- }
-
- if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) { // see anims.cpp
- // bring the anim into the visible screen
- // but leave extra pixel at edge for box
- if (spriteInfo.x + spriteInfo.scaledWidth >= 639)
- spriteInfo.x = 639 - spriteInfo.scaledWidth;
-
- if (spriteInfo.y + spriteInfo.scaledHeight >= 399)
- spriteInfo.y = 399 - spriteInfo.scaledHeight;
-
- if (spriteInfo.x < 1)
- spriteInfo.x = 1;
-
- if (spriteInfo.y < 1)
- spriteInfo.y = 1;
-
- // create box to surround sprite - just outside sprite box
- _vm->_debugger->_rectX1 = spriteInfo.x - 1;
- _vm->_debugger->_rectY1 = spriteInfo.y - 1;
- _vm->_debugger->_rectX2 = spriteInfo.x + spriteInfo.scaledWidth;
- _vm->_debugger->_rectY2 = spriteInfo.y + spriteInfo.scaledHeight;
- }
-
- uint32 rv = drawSprite(&spriteInfo);
- if (rv) {
- byte buf[NAME_LEN];
-
- error("Driver Error %.8x with sprite %s (%d) in processImage",
- rv,
- _vm->_resman->fetchName(build_unit->anim_resource, buf),
- build_unit->anim_resource);
- }
-
- // release the anim resource
- _vm->_resman->closeResource(build_unit->anim_resource);
-}
-
-void Screen::resetRenderLists() {
- // reset the sort lists - do this before a logic loop
- // takes into account the fact that the start of the list is pre-built
- // with the special sortable layers
-
- _curBgp0 = 0;
- _curBgp1 = 0;
- _curBack = 0;
- // beginning of sort list is setup with the special sort layers
- _curSort = _thisScreen.number_of_layers;
- _curFore = 0;
- _curFgp0 = 0;
- _curFgp1 = 0;
-
- if (_curSort) {
- // there are some layers - so rebuild the sort order list
- for (uint i = 0; i < _curSort; i++)
- _sortOrder[i] = i;
- }
-}
-
-void Screen::registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega, BuildUnit *build_unit) {
- ObjectGraphic obGraph(ob_graph);
- ObjectMega obMega(ob_mega);
-
- assert(obGraph.getAnimResource());
-
- byte *file = _vm->_resman->openResource(obGraph.getAnimResource());
-
- AnimHeader anim_head;
- CdtEntry cdt_entry;
- FrameHeader frame_head;
-
- anim_head.read(_vm->fetchAnimHeader(file));
- cdt_entry.read(_vm->fetchCdtEntry(file, obGraph.getAnimPc()));
- frame_head.read(_vm->fetchFrameHeader(file, obGraph.getAnimPc()));
-
- // update player graphic details for on-screen debug info
- if (_vm->_logic->readVar(ID) == CUR_PLAYER_ID) {
- _vm->_debugger->_graphType = obGraph.getType();
- _vm->_debugger->_graphAnimRes = obGraph.getAnimResource();
- // counting 1st frame as 'frame 1'
- _vm->_debugger->_graphAnimPc = obGraph.getAnimPc() + 1;
- _vm->_debugger->_graphNoFrames = anim_head.noAnimFrames;
- }
-
- // fill in the BuildUnit structure for this frame
-
- build_unit->anim_resource = obGraph.getAnimResource();
- build_unit->anim_pc = obGraph.getAnimPc();
- build_unit->layer_number = 0;
-
- // Affected by shading mask?
- if (obGraph.getType() & SHADED_SPRITE)
- build_unit->shadingFlag = true;
- else
- build_unit->shadingFlag = false;
-
- // Check if this frame has offsets ie. this is a scalable mega frame
-
- int scale = 0;
-
- if (cdt_entry.frameType & FRAME_OFFSET) {
- scale = obMega.calcScale();
-
- // calc final render coordinates (top-left of sprite), based
- // on feet coords & scaled offsets
-
- // add scaled offsets to feet coords
- build_unit->x = obMega.getFeetX() + (cdt_entry.x * scale) / 256;
- build_unit->y = obMega.getFeetY() + (cdt_entry.y * scale) / 256;
-
- // Work out new width and height. Always divide by 256 after
- // everything else, to maintain accurary
- build_unit->scaled_width = ((scale * frame_head.width) / 256);
- build_unit->scaled_height = ((scale * frame_head.height) / 256);
- } else {
- // It's a non-scaling anim. Get render coords for sprite, from cdt
- build_unit->x = cdt_entry.x;
- build_unit->y = cdt_entry.y;
-
- // Get width and height
- build_unit->scaled_width = frame_head.width;
- build_unit->scaled_height = frame_head.height;
- }
-
- // either 0 or required scale, depending on whether 'scale' computed
- build_unit->scale = scale;
-
- // calc the bottom y-coord for sorting purposes
- build_unit->sort_y = build_unit->y + build_unit->scaled_height - 1;
-
- if (ob_mouse) {
- // passed a mouse structure, so add to the _mouseList
- _vm->_mouse->registerMouse(ob_mouse, build_unit);
-
- }
-
- _vm->_resman->closeResource(obGraph.getAnimResource());
-}
-
-void Screen::registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega) {
- ObjectGraphic obGraph(ob_graph);
-
- // check low word for sprite type
- switch (obGraph.getType() & 0x0000ffff) {
- case BGP0_SPRITE:
- assert(_curBgp0 < MAX_bgp0_sprites);
- registerFrame(ob_mouse, ob_graph, ob_mega, &_bgp0List[_curBgp0]);
- _curBgp0++;
- break;
- case BGP1_SPRITE:
- assert(_curBgp1 < MAX_bgp1_sprites);
- registerFrame(ob_mouse, ob_graph, ob_mega, &_bgp1List[_curBgp1]);
- _curBgp1++;
- break;
- case BACK_SPRITE:
- assert(_curBack < MAX_back_sprites);
- registerFrame(ob_mouse, ob_graph, ob_mega, &_backList[_curBack]);
- _curBack++;
- break;
- case SORT_SPRITE:
- assert(_curSort < MAX_sort_sprites);
- _sortOrder[_curSort] = _curSort;
- registerFrame(ob_mouse, ob_graph, ob_mega, &_sortList[_curSort]);
- _curSort++;
- break;
- case FORE_SPRITE:
- assert(_curFore < MAX_fore_sprites);
- registerFrame(ob_mouse, ob_graph, ob_mega, &_foreList[_curFore]);
- _curFore++;
- break;
- case FGP0_SPRITE:
- assert(_curFgp0 < MAX_fgp0_sprites);
- registerFrame(ob_mouse, ob_graph, ob_mega, &_fgp0List[_curFgp0]);
- _curFgp0++;
- break;
- case FGP1_SPRITE:
- assert(_curFgp1 < MAX_fgp1_sprites);
- registerFrame(ob_mouse, ob_graph, ob_mega, &_fgp1List[_curFgp1]);
- _curFgp1++;
- break;
- default:
- // NO_SPRITE no registering!
- break;
- }
-}
-
-// FIXME:
-//
-// The original credits used a different font. I think it's stored in the
-// font.clu file, but I don't know how to interpret it.
-//
-// The original used the entire screen. This version cuts off the top and
-// bottom of the screen, because that's where the menus would usually be.
-//
-// The original had some sort of smoke effect at the bottom of the screen.
-
-enum {
- LINE_LEFT,
- LINE_CENTER,
- LINE_RIGHT
-};
-
-struct CreditsLine {
- char *str;
- byte type;
- int top;
- int height;
- byte *sprite;
-
- CreditsLine() {
- str = NULL;
- sprite = NULL;
- };
-
- ~CreditsLine() {
- free(str);
- free(sprite);
- str = NULL;
- sprite = NULL;
- }
-};
-
-#define CREDITS_FONT_HEIGHT 25
-#define CREDITS_LINE_SPACING 20
-
-void Screen::rollCredits() {
- uint32 loopingMusicId = _vm->_sound->getLoopingMusicId();
-
- // Prepare for the credits by fading down, stoping the music, etc.
-
- _vm->_mouse->setMouse(0);
-
- _vm->_sound->muteFx(true);
- _vm->_sound->muteSpeech(true);
-
- waitForFade();
- fadeDown();
- waitForFade();
-
- _vm->_mouse->closeMenuImmediately();
-
- // There are three files which I believe are involved in showing the
- // credits:
- //
- // credits.bmp - The "Smacker" logo, stored as follows:
- //
- // width 2 bytes, little endian
- // height 2 bytes, little endian
- // palette 3 * 256 bytes
- // data width * height bytes
- //
- // Note that the maximum colour component in the palette is 0x3F.
- // This is the same resolution as the _paletteMatch table. I doubt
- // that this is a coincidence, but let's use the image palette
- // directly anyway, just to be safe.
- //
- // credits.clu - The credits text
- //
- // This is simply a text file with CRLF line endings.
- // '^' is not shown, but used to mark the center of the line.
- // '@' is used as a placeholder for the "Smacker" logo. At least
- // when it appears alone.
- // Remaining lines are centered.
- // The German version also contains character code 9 for no
- // apparent reason. We ignore them.
- //
- // fonts.clu - The credits font?
- //
- // FIXME: At this time I don't know how to interpret fonts.clu. For
- // now, let's just the standard speech font instead.
-
- SpriteInfo spriteInfo;
- Common::File f;
- int i;
-
- // Read the "Smacker" logo
-
- uint16 logoWidth = 0;
- uint16 logoHeight = 0;
- byte *logoData = NULL;
- byte palette[256 * 4];
-
- if (f.open("credits.bmp")) {
- logoWidth = f.readUint16LE();
- logoHeight = f.readUint16LE();
-
- for (i = 0; i < 256; i++) {
- palette[i * 4 + 0] = f.readByte() << 2;
- palette[i * 4 + 1] = f.readByte() << 2;
- palette[i * 4 + 2] = f.readByte() << 2;
- palette[i * 4 + 3] = 0;
- }
-
- logoData = (byte *)malloc(logoWidth * logoHeight);
-
- f.read(logoData, logoWidth * logoHeight);
- f.close();
- } else {
- warning("Can't find credits.bmp");
- memset(palette, 0, sizeof(palette));
- palette[14 * 4 + 0] = 252;
- palette[14 * 4 + 1] = 252;
- palette[14 * 4 + 2] = 252;
- palette[14 * 4 + 3] = 0;
- }
-
- setPalette(0, 256, palette, RDPAL_INSTANT);
-
- // Read the credits text
-
- Common::Array<CreditsLine *> creditsLines;
-
- int lineCount = 0;
- int lineTop = 400;
- int paragraphStart = 0;
- bool hasCenterMark = false;
-
- if (!f.open("credits.clu")) {
- warning("Can't find credits.clu");
- return;
- }
-
- while (1) {
- char buffer[80];
- char *line = f.readLine(buffer, sizeof(buffer));
-
- if (!line || *line == 0) {
- if (!hasCenterMark) {
- for (i = paragraphStart; i < lineCount; i++)
- creditsLines[i]->type = LINE_CENTER;
- }
- paragraphStart = lineCount;
- hasCenterMark = false;
- if (paragraphStart == lineCount)
- lineTop += CREDITS_LINE_SPACING;
-
- if (!line)
- break;
-
- continue;
- }
-
- // The German credits contains character code 9. We don't want
- // the credits to show the 'dud' symbol, so we replace them
- // with spaces.
-
- for (char *ptr = line; *ptr; ptr++) {
- if (*ptr < 32)
- *ptr = 32;
- }
-
- char *center_mark = strchr(line, '^');
-
- if (center_mark) {
- // The current paragraph has at least one center mark.
- hasCenterMark = true;
-
- if (center_mark != line) {
- creditsLines.push_back(new CreditsLine);
-
- // The center mark is somewhere inside the
- // line. Split it into left and right side.
- *center_mark = 0;
-
- creditsLines[lineCount]->top = lineTop;
- creditsLines[lineCount]->height = CREDITS_FONT_HEIGHT;
- creditsLines[lineCount]->type = LINE_LEFT;
- creditsLines[lineCount]->str = strdup(line);
-
- lineCount++;
- *center_mark = '^';
- }
-
- line = center_mark;
- }
-
- creditsLines.push_back(new CreditsLine);
-
- creditsLines[lineCount]->top = lineTop;
-
- if (*line == '^') {
- creditsLines[lineCount]->type = LINE_RIGHT;
- line++;
- } else
- creditsLines[lineCount]->type = LINE_LEFT;
-
- if (strcmp(line, "@") == 0) {
- creditsLines[lineCount]->height = logoHeight;
- lineTop += logoHeight;
- } else {
- creditsLines[lineCount]->height = CREDITS_FONT_HEIGHT;
- lineTop += CREDITS_LINE_SPACING;
- }
-
- creditsLines[lineCount]->str = strdup(line);
- lineCount++;
- }
-
- f.close();
-
- // We could easily add some ScummVM stuff to the credits, if we wanted
- // to. On the other hand, anyone with the attention span to actually
- // read all the credits probably already knows. :-)
-
- // Start the music and roll the credits
-
- // The credits music (which can also be heard briefly in the "carib"
- // cutscene) is played once.
-
- _vm->_sound->streamCompMusic(309, false);
-
- clearScene();
- fadeUp(0);
-
- spriteInfo.scale = 0;
- spriteInfo.scaledWidth = 0;
- spriteInfo.scaledHeight = 0;
- spriteInfo.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION | RDSPR_TRANS;
- spriteInfo.blend = 0;
-
- int startLine = 0;
- int scrollPos = 0;
-
- bool abortCredits = false;
-
- int scrollSteps = lineTop + CREDITS_FONT_HEIGHT;
- uint32 musicStart = _vm->getMillis();
-
- // Ideally the music should last just a tiny bit longer than the
- // credits. Note that musicTimeRemaining() will return 0 if the music
- // is muted, so we need a sensible fallback for that case.
-
- uint32 musicLength = MAX((int32)(1000 * (_vm->_sound->musicTimeRemaining() - 3)), 25 * (int32)scrollSteps);
-
- while (scrollPos < scrollSteps && !_vm->_quit) {
- clearScene();
-
- for (i = startLine; i < lineCount; i++) {
- if (!creditsLines[i])
- continue;
-
- // Free any sprites that have scrolled off the screen
-
- if (creditsLines[i]->top + creditsLines[i]->height < scrollPos) {
- debug(2, "Freeing line %d: '%s'", i, creditsLines[i]->str);
-
- delete creditsLines[i];
- creditsLines[i] = NULL;
-
- startLine = i + 1;
- } else if (creditsLines[i]->top < scrollPos + 400) {
- if (!creditsLines[i]->sprite) {
- debug(2, "Creating line %d: '%s'", i, creditsLines[i]->str);
- creditsLines[i]->sprite = _vm->_fontRenderer->makeTextSprite((byte *)creditsLines[i]->str, 600, 14, _vm->_speechFontId, 0);
- }
-
- FrameHeader frame;
-
- frame.read(creditsLines[i]->sprite);
-
- spriteInfo.y = creditsLines[i]->top - scrollPos;
- spriteInfo.w = frame.width;
- spriteInfo.h = frame.height;
- spriteInfo.data = creditsLines[i]->sprite + FrameHeader::size();
-
- switch (creditsLines[i]->type) {
- case LINE_LEFT:
- spriteInfo.x = RENDERWIDE / 2 - 5 - frame.width;
- break;
- case LINE_RIGHT:
- spriteInfo.x = RENDERWIDE / 2 + 5;
- break;
- case LINE_CENTER:
- if (strcmp(creditsLines[i]->str, "@") == 0) {
- spriteInfo.data = logoData;
- spriteInfo.x = (RENDERWIDE - logoWidth) / 2;
- spriteInfo.w = logoWidth;
- spriteInfo.h = logoHeight;
- } else
- spriteInfo.x = (RENDERWIDE - frame.width) / 2;
- break;
- }
-
- if (spriteInfo.data)
- drawSprite(&spriteInfo);
- } else
- break;
- }
-
- updateDisplay();
-
- KeyboardEvent *ke = _vm->keyboardEvent();
-
- if (ke && ke->keycode == 27) {
- if (!abortCredits) {
- abortCredits = true;
- fadeDown();
- }
- }
-
- if (abortCredits && getFadeStatus() == RDFADE_BLACK)
- break;
-
- _vm->sleepUntil(musicStart + (musicLength * scrollPos) / scrollSteps);
- scrollPos++;
- }
-
- // We're done. Clean up and try to put everything back where it was
- // before the credits.
-
- for (i = 0; i < lineCount; i++) {
- delete creditsLines[i];
- }
-
- free(logoData);
-
- if (!abortCredits) {
- fadeDown();
-
- // The music should either have stopped or be about to stop, so
- // wait for it to really happen.
-
- while (_vm->_sound->musicTimeRemaining() && !_vm->_quit) {
- updateDisplay(false);
- _vm->_system->delayMillis(100);
- }
- }
-
- if (_vm->_quit)
- return;
-
- waitForFade();
-
- _vm->_sound->muteFx(false);
- _vm->_sound->muteSpeech(false);
-
- if (loopingMusicId)
- _vm->_sound->streamCompMusic(loopingMusicId, true);
- else
- _vm->_sound->stopMusic(false);
-
- if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing())
- _vm->_mouse->setMouse(NORMAL_MOUSE_ID);
-
- if (_vm->_logic->readVar(DEAD))
- _vm->_mouse->buildSystemMenu();
-}
-
-// This image used to be shown by CacheNewCluster() while copying a data file
-// from the CD to the hard disk. ScummVM doesn't do that, so the image is never
-// shown. It'd be nice if we could do something useful with it some day...
-
-void Screen::splashScreen() {
- byte *bgfile = _vm->_resman->openResource(2950);
-
- initialiseBackgroundLayer(NULL);
- initialiseBackgroundLayer(NULL);
- initialiseBackgroundLayer(_vm->fetchBackgroundLayer(bgfile));
- initialiseBackgroundLayer(NULL);
- initialiseBackgroundLayer(NULL);
-
- setPalette(0, 256, _vm->fetchPalette(bgfile), RDPAL_FADE);
- renderParallax(_vm->fetchBackgroundLayer(bgfile), 2);
-
- closeBackgroundLayer();
-
- byte *loadingBar = _vm->_resman->openResource(2951);
- byte *frame = _vm->fetchFrameHeader(loadingBar, 0);
-
- AnimHeader animHead;
- CdtEntry cdt;
- FrameHeader frame_head;
-
- animHead.read(_vm->fetchAnimHeader(loadingBar));
- cdt.read(_vm->fetchCdtEntry(loadingBar, 0));
- frame_head.read(_vm->fetchFrameHeader(loadingBar, 0));
-
- SpriteInfo barSprite;
-
- barSprite.x = cdt.x;
- barSprite.y = cdt.y;
- barSprite.w = frame_head.width;
- barSprite.h = frame_head.height;
- barSprite.scale = 0;
- barSprite.scaledWidth = 0;
- barSprite.scaledHeight = 0;
- barSprite.type = RDSPR_RLE256FAST | RDSPR_TRANS;
- barSprite.blend = 0;
- barSprite.colourTable = 0;
- barSprite.data = frame + FrameHeader::size();
-
- drawSprite(&barSprite);
-
- fadeUp();
- waitForFade();
-
- for (int i = 0; i < animHead.noAnimFrames; i++) {
- frame = _vm->fetchFrameHeader(loadingBar, i);
- barSprite.data = frame + FrameHeader::size();
- drawSprite(&barSprite);
- updateDisplay();
- _vm->_system->delayMillis(30);
- }
-
- _vm->_resman->closeResource(2951);
-
- fadeDown();
- waitForFade();
-}
-
-} // End of namespace Sword2