aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sword2/build_display.cpp421
-rw-r--r--sword2/build_display.h3
-rw-r--r--sword2/driver/animation.h2
-rw-r--r--sword2/driver/d_sound.cpp6
-rw-r--r--sword2/driver/render.cpp10
-rw-r--r--sword2/driver/sprite.cpp2
-rw-r--r--sword2/function.cpp365
-rw-r--r--sword2/maketext.cpp4
-rw-r--r--sword2/maketext.h2
-rw-r--r--sword2/router.cpp16
-rw-r--r--sword2/router.h24
-rw-r--r--sword2/save_rest.cpp8
-rw-r--r--sword2/sword2.cpp2
-rw-r--r--sword2/sync.cpp2
14 files changed, 464 insertions, 403 deletions
diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp
index cb07a5e510..0bd185f7fa 100644
--- a/sword2/build_display.cpp
+++ b/sword2/build_display.cpp
@@ -32,6 +32,7 @@
#include "sword2/maketext.h"
#include "sword2/mouse.h"
#include "sword2/resman.h"
+#include "sword2/sound.h"
namespace Sword2 {
@@ -624,4 +625,424 @@ void Screen::registerFrame(ObjectMouse *ob_mouse, ObjectGraphic *ob_graph, Objec
}
}
+// 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;
+};
+
+#define CREDITS_FONT_HEIGHT 25
+#define CREDITS_LINE_SPACING 20
+
+void Screen::rollCredits() {
+ ScreenInfo *screenInfo = getScreenInfo();
+ 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.
+ //
+ // 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;
+ 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
+
+ // This should be plenty
+ CreditsLine creditsLines[350];
+
+ for (i = 0; i < ARRAYSIZE(creditsLines); i++) {
+ creditsLines[i].str = NULL;
+ creditsLines[i].sprite = NULL;
+ }
+
+ if (!f.open("credits.clu")) {
+ warning("Can't find credits.clu");
+ return;
+ }
+
+ int lineTop = 400;
+ int lineCount = 0;
+ int paragraphStart = 0;
+ bool hasCenterMark = false;
+
+ while (1) {
+ if (lineCount >= ARRAYSIZE(creditsLines)) {
+ warning("Too many credits lines");
+ break;
+ }
+
+ 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;
+ }
+
+ char *center_mark = strchr(line, '^');
+
+ if (center_mark) {
+ // The current paragraph has at least one center mark.
+ hasCenterMark = true;
+
+ if (center_mark != line) {
+ // 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++;
+
+ if (lineCount >= ARRAYSIZE(creditsLines)) {
+ warning("Too many credits lines");
+ break;
+ }
+
+ *center_mark = '^';
+ }
+
+ line = center_mark;
+ }
+
+ 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) {
+ bool foundStartLine = false;
+
+ clearScene();
+
+ for (i = startLine; i < lineCount; i++) {
+ // Free any sprites that have scrolled off the screen
+
+ if (creditsLines[i].top + creditsLines[i].height < scrollPos) {
+ if (creditsLines[i].sprite) {
+ free(creditsLines[i].sprite);
+ creditsLines[i].sprite = NULL;
+ debug(2, "Freeing sprite '%s'", creditsLines[i].str);
+ }
+ if (creditsLines[i].str) {
+ free(creditsLines[i].str);
+ creditsLines[i].str = NULL;
+ }
+ } else if (creditsLines[i].top < scrollPos + 400) {
+ if (!foundStartLine) {
+ startLine = i;
+ foundStartLine = true;
+ }
+
+ if (!creditsLines[i].sprite) {
+ debug(2, "Creating sprite '%s'", creditsLines[i].str);
+ creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((byte *) creditsLines[i].str, 600, 14, _vm->_speechFontId, 0);
+ }
+
+ FrameHeader *frame = (FrameHeader *) creditsLines[i].sprite;
+
+ spriteInfo.y = creditsLines[i].top - scrollPos;
+ spriteInfo.w = frame->width;
+ spriteInfo.h = frame->height;
+ spriteInfo.data = creditsLines[i].sprite + sizeof(FrameHeader);
+
+ 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++) {
+ if (creditsLines[i].str)
+ free(creditsLines[i].str);
+ if (creditsLines[i].sprite)
+ free(creditsLines[i].sprite);
+ }
+
+ if (logoData)
+ free(logoData);
+
+ if (!abortCredits) {
+ // 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;
+
+ _vm->_sound->muteFx(false);
+ _vm->_sound->muteSpeech(false);
+
+ if (loopingMusicId)
+ _vm->_sound->streamCompMusic(loopingMusicId, true);
+ else
+ _vm->_sound->stopMusic(false);
+
+ screenInfo->new_palette = 99;
+
+ if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing())
+ _vm->_mouse->setMouse(NORMAL_MOUSE_ID);
+
+ if (Logic::_scriptVars[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);
+ AnimHeader *animHead = _vm->fetchAnimHeader(loadingBar);
+ FrameHeader *frame = _vm->fetchFrameHeader(loadingBar, 0);
+ CdtEntry *cdt = _vm->fetchCdtEntry(loadingBar, 0);
+
+ SpriteInfo barSprite;
+
+ barSprite.x = cdt->x;
+ barSprite.y = cdt->y;
+ barSprite.w = frame->width;
+ barSprite.h = frame->height;
+ barSprite.scale = 0;
+ barSprite.scaledWidth = 0;
+ barSprite.scaledHeight = 0;
+ barSprite.type = RDSPR_RLE256FAST | RDSPR_TRANS;
+ barSprite.blend = 0;
+ barSprite.colourTable = 0;
+ barSprite.data = (byte *) (frame + 1);
+
+ drawSprite(&barSprite);
+
+ fadeUp();
+ waitForFade();
+
+ for (int i = 0; i < animHead->noAnimFrames; i++) {
+ frame = _vm->fetchFrameHeader(loadingBar, i);
+ barSprite.data = (byte *) (frame + 1);
+
+ barSprite.x = cdt->x;
+ barSprite.y = cdt->y;
+
+ drawSprite(&barSprite);
+ updateDisplay();
+ _vm->_system->delayMillis(30);
+ }
+
+ _vm->_resman->closeResource(2951);
+
+ fadeDown();
+ waitForFade();
+}
+
} // End of namespace Sword2
diff --git a/sword2/build_display.h b/sword2/build_display.h
index 76853bcf7e..72eddaa593 100644
--- a/sword2/build_display.h
+++ b/sword2/build_display.h
@@ -421,6 +421,9 @@ public:
#ifdef BACKEND_8BIT
void plotYUV(byte *lut, int width, int height, byte *const *dat);
#endif
+
+ void rollCredits();
+ void splashScreen();
};
} // End of namespace Sword2
diff --git a/sword2/driver/animation.h b/sword2/driver/animation.h
index 3d6c3fc385..ae9495dc57 100644
--- a/sword2/driver/animation.h
+++ b/sword2/driver/animation.h
@@ -54,7 +54,7 @@ public:
#endif
void clearScreen();
- void updateScreen(void);
+ void updateScreen();
private:
void drawYUV(int width, int height, byte *const *dat);
diff --git a/sword2/driver/d_sound.cpp b/sword2/driver/d_sound.cpp
index 774f33c5cf..94afd8ba35 100644
--- a/sword2/driver/d_sound.cpp
+++ b/sword2/driver/d_sound.cpp
@@ -618,7 +618,7 @@ int32 Sound::streamCompMusic(uint32 musicId, bool loop) {
* @return the time left for the current music, in seconds.
*/
-int32 Sound::musicTimeRemaining(void) {
+int32 Sound::musicTimeRemaining() {
Common::StackLock lock(_mutex);
for (int i = 0; i < MAXMUS; i++) {
@@ -653,7 +653,7 @@ void Sound::muteSpeech(bool mute) {
* Stops the speech dead in its tracks.
*/
-void Sound::pauseSpeech(void) {
+void Sound::pauseSpeech() {
_speechPaused = true;
_vm->_mixer->pauseHandle(_soundHandleSpeech, true);
}
@@ -662,7 +662,7 @@ void Sound::pauseSpeech(void) {
* Restarts the speech from where it was stopped.
*/
-void Sound::unpauseSpeech(void) {
+void Sound::unpauseSpeech() {
_speechPaused = false;
_vm->_mixer->pauseHandle(_soundHandleSpeech, false);
}
diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp
index f2030a295f..dfee05f6b3 100644
--- a/sword2/driver/render.cpp
+++ b/sword2/driver/render.cpp
@@ -294,7 +294,7 @@ void Screen::renderParallax(Parallax *p, int16 l) {
* Initialises the timers before the render loop is entered.
*/
-void Screen::initialiseRenderCycle(void) {
+void Screen::initialiseRenderCycle() {
_initialTime = _vm->_system->getMillis();
_totalTime = _initialTime + MILLISECSPERCYCLE;
}
@@ -304,7 +304,7 @@ void Screen::initialiseRenderCycle(void) {
* render cycle.
*/
-void Screen::startRenderCycle(void) {
+void Screen::startRenderCycle() {
_scrollXOld = _scrollX;
_scrollYOld = _scrollY;
@@ -332,7 +332,7 @@ void Screen::startRenderCycle(void) {
* or false if it should continue
*/
-bool Screen::endRenderCycle(void) {
+bool Screen::endRenderCycle() {
static int32 renderTimeLog[4] = { 60, 60, 60, 60 };
static int32 renderCountIndex = 0;
int32 time;
@@ -398,7 +398,7 @@ bool Screen::endRenderCycle(void) {
* Reset scrolling stuff. This function is called from initBackground()
*/
-void Screen::resetRenderEngine(void) {
+void Screen::resetRenderEngine() {
_parallaxScrollX = 0;
_parallaxScrollY = 0;
_scrollX = 0;
@@ -529,7 +529,7 @@ int32 Screen::initialiseBackgroundLayer(Parallax *p) {
* Should be called once after leaving the room to free up memory.
*/
-void Screen::closeBackgroundLayer(void) {
+void Screen::closeBackgroundLayer() {
debug(2, "CloseBackgroundLayer");
for (int i = 0; i < MAXLAYERS; i++) {
diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp
index 1cae26bdc6..2845bdefb0 100644
--- a/sword2/driver/sprite.cpp
+++ b/sword2/driver/sprite.cpp
@@ -635,7 +635,7 @@ int32 Screen::openLightMask(SpriteInfo *s) {
* Closes the light masking sprite for a room.
*/
-int32 Screen::closeLightMask(void) {
+int32 Screen::closeLightMask() {
if (!_lightMask)
return RDERR_NOTOPEN;
diff --git a/sword2/function.cpp b/sword2/function.cpp
index 37affd9923..6508cee08a 100644
--- a/sword2/function.cpp
+++ b/sword2/function.cpp
@@ -2770,37 +2770,7 @@ int32 Logic::fnCheckMusicPlaying(int32 *params) {
return IR_CONT;
}
-// 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;
-};
-
-#define CREDITS_FONT_HEIGHT 25
-#define CREDITS_LINE_SPACING 20
-
int32 Logic::fnPlayCredits(int32 *params) {
- ScreenInfo *screenInfo = _vm->_screen->getScreenInfo();
- uint32 loopingMusicId = _vm->_sound->getLoopingMusicId();
-
// This function just quits the game if this is the playable demo, ie.
// credits are NOT played in the demo any more!
@@ -2811,340 +2781,7 @@ int32 Logic::fnPlayCredits(int32 *params) {
return IR_STOP;
}
- // Prepare for the credits by fading down, stoping the music, etc.
-
- _vm->_mouse->setMouse(0);
-
- _vm->_sound->muteFx(true);
- _vm->_sound->muteSpeech(true);
-
- _vm->_screen->waitForFade();
- _vm->_screen->fadeDown();
- _vm->_screen->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.
- //
- // 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;
- 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;
- }
-
- _vm->_screen->setPalette(0, 256, palette, RDPAL_INSTANT);
-
- // Read the credits text
-
- // This should be plenty
- CreditsLine creditsLines[350];
-
- for (i = 0; i < ARRAYSIZE(creditsLines); i++) {
- creditsLines[i].str = NULL;
- creditsLines[i].sprite = NULL;
- }
-
- if (!f.open("credits.clu")) {
- warning("Can't find credits.clu");
- return IR_CONT;
- }
-
- int lineTop = 400;
- int lineCount = 0;
- int paragraphStart = 0;
- bool hasCenterMark = false;
-
- while (1) {
- if (lineCount >= ARRAYSIZE(creditsLines)) {
- warning("Too many credits lines");
- break;
- }
-
- 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;
- }
-
- char *center_mark = strchr(line, '^');
-
- if (center_mark) {
- // The current paragraph has at least one center mark.
- hasCenterMark = true;
-
- if (center_mark != line) {
- // 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++;
-
- if (lineCount >= ARRAYSIZE(creditsLines)) {
- warning("Too many credits lines");
- break;
- }
-
- *center_mark = '^';
- }
-
- line = center_mark;
- }
-
- 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.
-
- int32 pars[2];
-
- pars[0] = 309;
- pars[1] = FX_SPOT;
- fnPlayMusic(pars);
-
- _vm->_screen->clearScene();
- _vm->_screen->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) {
- bool foundStartLine = false;
-
- _vm->_screen->clearScene();
-
- for (i = startLine; i < lineCount; i++) {
- // Free any sprites that have scrolled off the screen
-
- if (creditsLines[i].top + creditsLines[i].height < scrollPos) {
- if (creditsLines[i].sprite) {
- free(creditsLines[i].sprite);
- creditsLines[i].sprite = NULL;
- debug(2, "Freeing sprite '%s'", creditsLines[i].str);
- }
- if (creditsLines[i].str) {
- free(creditsLines[i].str);
- creditsLines[i].str = NULL;
- }
- } else if (creditsLines[i].top < scrollPos + 400) {
- if (!foundStartLine) {
- startLine = i;
- foundStartLine = true;
- }
-
- if (!creditsLines[i].sprite) {
- debug(2, "Creating sprite '%s'", creditsLines[i].str);
- creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((byte *) creditsLines[i].str, 600, 14, _vm->_speechFontId, 0);
- }
-
- FrameHeader *frame = (FrameHeader *) creditsLines[i].sprite;
-
- spriteInfo.y = creditsLines[i].top - scrollPos;
- spriteInfo.w = frame->width;
- spriteInfo.h = frame->height;
- spriteInfo.data = creditsLines[i].sprite + sizeof(FrameHeader);
-
- 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)
- _vm->_screen->drawSprite(&spriteInfo);
- } else
- break;
- }
-
- _vm->_screen->updateDisplay();
-
- KeyboardEvent *ke = _vm->keyboardEvent();
-
- if (ke && ke->keycode == 27) {
- if (!abortCredits) {
- abortCredits = true;
- _vm->_screen->fadeDown();
- }
- }
-
- if (abortCredits && _vm->_screen->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++) {
- if (creditsLines[i].str)
- free(creditsLines[i].str);
- if (creditsLines[i].sprite)
- free(creditsLines[i].sprite);
- }
-
- if (logoData)
- free(logoData);
-
- if (!abortCredits) {
- // The music should either have stopped or be about to stop, so
- // wait for it to really happen.
-
- while (_vm->_sound->musicTimeRemaining() && !_vm->_quit) {
- _vm->_screen->updateDisplay(false);
- _vm->_system->delayMillis(100);
- }
- }
-
- if (_vm->_quit)
- return IR_CONT;
-
- _vm->_sound->muteFx(false);
- _vm->_sound->muteSpeech(false);
-
- if (loopingMusicId) {
- pars[0] = loopingMusicId;
- pars[1] = FX_LOOP;
- fnPlayMusic(pars);
- } else
- fnStopMusic(NULL);
-
- screenInfo->new_palette = 99;
-
- if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing())
- _vm->_mouse->setMouse(NORMAL_MOUSE_ID);
-
- if (_scriptVars[DEAD])
- _vm->_mouse->buildSystemMenu();
-
+ _vm->_screen->rollCredits();
return IR_CONT;
}
diff --git a/sword2/maketext.cpp b/sword2/maketext.cpp
index aefccb4d86..0ca8619687 100644
--- a/sword2/maketext.cpp
+++ b/sword2/maketext.cpp
@@ -457,7 +457,7 @@ uint32 FontRenderer::buildNewBloc(byte *ascii, int16 x, int16 y, uint16 width, u
* Called by buildDisplay()
*/
-void FontRenderer::printTextBlocs(void) {
+void FontRenderer::printTextBlocs() {
for (uint i = 0; i < MAX_text_blocs; i++) {
if (_blocList[i].text_mem) {
FrameHeader *frame = (FrameHeader *) _blocList[i].text_mem;
@@ -497,7 +497,7 @@ void FontRenderer::killTextBloc(uint32 bloc_number) {
#define SAVE_LINE_NO 1
-void Sword2Engine::initialiseFontResourceFlags(void) {
+void Sword2Engine::initialiseFontResourceFlags() {
byte *textFile = _resman->openResource(TEXT_RES);
// If language is Polish or Finnish it requires alternate fonts.
diff --git a/sword2/maketext.h b/sword2/maketext.h
index 3e82dff2d5..31477705e7 100644
--- a/sword2/maketext.h
+++ b/sword2/maketext.h
@@ -108,7 +108,7 @@ public:
byte *makeTextSprite(byte *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border = BORDER_PEN);
void killTextBloc(uint32 bloc_number);
- void printTextBlocs(void);
+ void printTextBlocs();
uint32 buildNewBloc(byte *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification);
};
diff --git a/sword2/router.cpp b/sword2/router.cpp
index ef0b81f5a6..de92f28855 100644
--- a/sword2/router.cpp
+++ b/sword2/router.cpp
@@ -92,7 +92,7 @@ uint8 Router::returnSlotNo(uint32 megaId) {
}
}
-void Router::allocateRouteMem(void) {
+void Router::allocateRouteMem() {
uint8 slotNo;
// Player character always always slot 0, while the other mega
@@ -124,20 +124,20 @@ void Router::allocateRouteMem(void) {
// megaObject->route_slot_id = slotNo + 1;
}
-WalkData *Router::getRouteMem(void) {
+WalkData *Router::getRouteMem() {
uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]);
return (WalkData *) _routeSlots[slotNo];
}
-void Router::freeRouteMem(void) {
+void Router::freeRouteMem() {
uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]);
free(_routeSlots[slotNo]);
_routeSlots[slotNo] = NULL;
}
-void Router::freeAllRouteMem(void) {
+void Router::freeAllRouteMem() {
for (int i = 0; i < TOTAL_ROUTE_SLOTS; i++) {
free(_routeSlots[i]);
_routeSlots[i] = NULL;
@@ -256,7 +256,7 @@ int32 Router::routeFinder(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int3
return routeFlag; // send back null route
}
-int32 Router::getRoute(void) {
+int32 Router::getRoute() {
/*********************************************************************
* GetRoute.C extract a path from walk grid
* 12 october 94
@@ -2357,7 +2357,7 @@ void Router::setUpWalkGrid(ObjectMega *ob_mega, int32 x, int32 y, int32 dir) {
_node[_nNodes].dist = 9999;
}
-void Router::plotWalkGrid(void) {
+void Router::plotWalkGrid() {
int32 i;
// get walk grid file + extra grid into 'bars' & 'node' arrays
@@ -2380,7 +2380,7 @@ void Router::plotCross(int16 x, int16 y, uint8 colour) {
_vm->_screen->drawLine(x + 1, y - 1, x - 1, y + 1, colour);
}
-void Router::loadWalkGrid(void) {
+void Router::loadWalkGrid() {
WalkGridHeader floorHeader;
byte *fPolygrid;
uint32 theseBars;
@@ -2439,7 +2439,7 @@ void Router::loadWalkGrid(void) {
}
}
-void Router::clearWalkGridList(void) {
+void Router::clearWalkGridList() {
memset(_walkGridList, 0, sizeof(_walkGridList));
}
diff --git a/sword2/router.h b/sword2/router.h
index ea6bf8824c..20cd14bfa0 100644
--- a/sword2/router.h
+++ b/sword2/router.h
@@ -176,9 +176,9 @@ private:
uint8 returnSlotNo(uint32 megaId);
- int32 getRoute(void);
- void extractRoute(void);
- void loadWalkGrid(void);
+ int32 getRoute();
+ void extractRoute();
+ void loadWalkGrid();
void setUpWalkGrid(ObjectMega *ob_mega, int32 x, int32 y, int32 dir);
void loadWalkData(ObjectWalkdata *ob_walkdata);
bool scan(int32 level);
@@ -190,8 +190,8 @@ private:
bool check(int32 x1, int32 y1, int32 x2, int32 y2);
int32 checkTarget(int32 x, int32 y);
- int32 smoothestPath(void);
- void slidyPath(void);
+ int32 smoothestPath();
+ void slidyPath();
int32 smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD);
@@ -200,7 +200,7 @@ private:
void slidyWalkAnimator(WalkData *walkAnim);
#ifndef FORCE_SLIDY
- int32 solidPath(void);
+ int32 solidPath();
int32 solidWalkAnimator(WalkData *walkAnim);
#endif
@@ -228,15 +228,15 @@ public:
void earlySlowOut(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata);
- void allocateRouteMem(void);
- WalkData *getRouteMem(void);
- void freeRouteMem(void);
- void freeAllRouteMem(void);
+ void allocateRouteMem();
+ WalkData *getRouteMem();
+ void freeRouteMem();
+ void freeAllRouteMem();
void addWalkGrid(int32 gridResource);
void removeWalkGrid(int32 gridResource);
- void clearWalkGridList(void);
+ void clearWalkGridList();
- void plotWalkGrid(void);
+ void plotWalkGrid();
};
} // End of namespace Sword2
diff --git a/sword2/save_rest.cpp b/sword2/save_rest.cpp
index 610b50435d..c8e27ee53c 100644
--- a/sword2/save_rest.cpp
+++ b/sword2/save_rest.cpp
@@ -123,7 +123,7 @@ uint32 Sword2Engine::saveGame(uint16 slotNo, byte *desc) {
* Calculate size of required savegame buffer
*/
-uint32 Sword2Engine::findBufferSize(void) {
+uint32 Sword2Engine::findBufferSize() {
// Size of savegame header + size of global variables
return sizeof(_saveGameHeader) + _resman->fetchLen(1);
}
@@ -420,7 +420,7 @@ uint32 Sword2Engine::getSaveDescription(uint16 slotNo, byte *description) {
return SR_OK;
}
-bool Sword2Engine::saveExists(void) {
+bool Sword2Engine::saveExists() {
for (int i = 0; i <= 99; i++)
if (saveExists(i))
return true;
@@ -446,7 +446,7 @@ bool Sword2Engine::saveExists(uint16 slotNo) {
* Request the player object structures which need saving.
*/
-void Sword2Engine::getPlayerStructures(void) {
+void Sword2Engine::getPlayerStructures() {
StandardHeader *head = (StandardHeader *) _resman->openResource(CUR_PLAYER_ID);
assert(head->fileType == GAME_OBJECT);
@@ -466,7 +466,7 @@ void Sword2Engine::getPlayerStructures(void) {
* Nico's anim tables.
*/
-void Sword2Engine::putPlayerStructures(void) {
+void Sword2Engine::putPlayerStructures() {
StandardHeader *head = (StandardHeader *) _resman->openResource(CUR_PLAYER_ID);
assert(head->fileType == GAME_OBJECT);
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 20b75998a8..a4d57e8821 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -42,7 +42,7 @@
#include "sword2/sound.h"
#ifdef _WIN32_WCE
-extern bool isSmartphone(void);
+extern bool isSmartphone();
#endif
struct Sword2GameSettings {
diff --git a/sword2/sync.cpp b/sword2/sync.cpp
index 5d51feb12e..54627426e8 100644
--- a/sword2/sync.cpp
+++ b/sword2/sync.cpp
@@ -45,7 +45,7 @@ void Logic::clearSyncs(uint32 id) {
* animation is to be finished. Returns an index into _syncList[], or -1.
*/
-int Logic::getSync(void) {
+int Logic::getSync() {
for (int i = 0; i < MAX_syncs; i++) {
if (_syncList[i].id == _scriptVars[ID])
return i;