diff options
| -rw-r--r-- | sword2/build_display.cpp | 421 | ||||
| -rw-r--r-- | sword2/build_display.h | 3 | ||||
| -rw-r--r-- | sword2/driver/animation.h | 2 | ||||
| -rw-r--r-- | sword2/driver/d_sound.cpp | 6 | ||||
| -rw-r--r-- | sword2/driver/render.cpp | 10 | ||||
| -rw-r--r-- | sword2/driver/sprite.cpp | 2 | ||||
| -rw-r--r-- | sword2/function.cpp | 365 | ||||
| -rw-r--r-- | sword2/maketext.cpp | 4 | ||||
| -rw-r--r-- | sword2/maketext.h | 2 | ||||
| -rw-r--r-- | sword2/router.cpp | 16 | ||||
| -rw-r--r-- | sword2/router.h | 24 | ||||
| -rw-r--r-- | sword2/save_rest.cpp | 8 | ||||
| -rw-r--r-- | sword2/sword2.cpp | 2 | ||||
| -rw-r--r-- | sword2/sync.cpp | 2 | 
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; | 
