2022-05-19 01:51:26 -07:00
|
|
|
#include "credits.h"
|
|
|
|
|
2022-09-15 02:38:23 -07:00
|
|
|
#include <string.h>
|
|
|
|
|
2023-01-03 12:00:38 -08:00
|
|
|
#include <algorithm>
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "art.h"
|
|
|
|
#include "color.h"
|
|
|
|
#include "cycle.h"
|
2022-06-18 06:05:07 -07:00
|
|
|
#include "db.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "debug.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "game_mouse.h"
|
2022-10-04 23:23:27 -07:00
|
|
|
#include "input.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "memory.h"
|
|
|
|
#include "message.h"
|
2022-10-03 02:41:33 -07:00
|
|
|
#include "mouse.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "palette.h"
|
2022-05-28 02:34:49 -07:00
|
|
|
#include "platform_compat.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "sound.h"
|
2022-10-05 00:35:05 -07:00
|
|
|
#include "svga.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "text_font.h"
|
|
|
|
#include "window_manager.h"
|
|
|
|
|
2022-09-23 05:43:44 -07:00
|
|
|
namespace fallout {
|
|
|
|
|
2022-06-18 06:05:07 -07:00
|
|
|
#define CREDITS_WINDOW_SCROLLING_DELAY (38)
|
|
|
|
|
|
|
|
static bool creditsFileParseNextLine(char* dest, int* font, int* color);
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x56D740
|
2022-06-18 06:05:07 -07:00
|
|
|
static File* gCreditsFile;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x56D744
|
2022-06-18 06:05:07 -07:00
|
|
|
static int gCreditsWindowNameColor;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x56D748
|
2022-06-18 06:05:07 -07:00
|
|
|
static int gCreditsWindowTitleFont;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x56D74C
|
2022-06-18 06:05:07 -07:00
|
|
|
static int gCreditsWindowNameFont;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x56D750
|
2022-06-18 06:05:07 -07:00
|
|
|
static int gCreditsWindowTitleColor;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x42C860
|
|
|
|
void creditsOpen(const char* filePath, int backgroundFid, bool useReversedStyle)
|
|
|
|
{
|
|
|
|
int oldFont = fontGetCurrent();
|
|
|
|
|
|
|
|
colorPaletteLoad("color.pal");
|
|
|
|
|
|
|
|
if (useReversedStyle) {
|
|
|
|
gCreditsWindowTitleColor = _colorTable[18917];
|
|
|
|
gCreditsWindowNameFont = 103;
|
|
|
|
gCreditsWindowTitleFont = 104;
|
|
|
|
gCreditsWindowNameColor = _colorTable[13673];
|
|
|
|
} else {
|
|
|
|
gCreditsWindowTitleColor = _colorTable[13673];
|
|
|
|
gCreditsWindowNameFont = 104;
|
|
|
|
gCreditsWindowTitleFont = 103;
|
|
|
|
gCreditsWindowNameColor = _colorTable[18917];
|
|
|
|
}
|
|
|
|
|
|
|
|
soundContinueAll();
|
|
|
|
|
2022-05-28 02:34:49 -07:00
|
|
|
char localizedPath[COMPAT_MAX_PATH];
|
2022-12-08 12:05:50 -08:00
|
|
|
if (_message_make_path(localizedPath, sizeof(localizedPath), filePath)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
gCreditsFile = fileOpen(localizedPath, "rt");
|
|
|
|
if (gCreditsFile != NULL) {
|
|
|
|
soundContinueAll();
|
|
|
|
|
|
|
|
colorCycleDisable();
|
|
|
|
gameMouseSetCursor(MOUSE_CURSOR_NONE);
|
|
|
|
|
|
|
|
bool cursorWasHidden = cursorIsHidden();
|
|
|
|
if (cursorWasHidden) {
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
int windowWidth = screenGetWidth();
|
|
|
|
int windowHeight = screenGetHeight();
|
|
|
|
int window = windowCreate(0, 0, windowWidth, windowHeight, _colorTable[0], 20);
|
2022-05-19 01:51:26 -07:00
|
|
|
soundContinueAll();
|
|
|
|
if (window != -1) {
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(window);
|
|
|
|
if (windowBuffer != NULL) {
|
2023-01-02 02:09:03 -08:00
|
|
|
unsigned char* backgroundBuffer = (unsigned char*)internal_malloc(windowWidth * windowHeight);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (backgroundBuffer) {
|
|
|
|
soundContinueAll();
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
memset(backgroundBuffer, _colorTable[0], windowWidth * windowHeight);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (backgroundFid != -1) {
|
2023-01-02 02:09:03 -08:00
|
|
|
FrmImage backgroundFrmImage;
|
|
|
|
if (backgroundFrmImage.lock(backgroundFid)) {
|
|
|
|
blitBufferToBuffer(backgroundFrmImage.getData(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundFrmImage.getHeight(),
|
|
|
|
backgroundFrmImage.getWidth(),
|
|
|
|
backgroundBuffer + windowWidth * ((windowHeight - backgroundFrmImage.getHeight()) / 2) + (windowWidth - backgroundFrmImage.getWidth()) / 2,
|
|
|
|
windowWidth);
|
|
|
|
backgroundFrmImage.unlock();
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
unsigned char* intermediateBuffer = (unsigned char*)internal_malloc(windowWidth * windowHeight);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (intermediateBuffer != NULL) {
|
2023-01-02 02:09:03 -08:00
|
|
|
memset(intermediateBuffer, 0, windowWidth * windowHeight);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
fontSetCurrent(gCreditsWindowTitleFont);
|
|
|
|
int titleFontLineHeight = fontGetLineHeight();
|
|
|
|
|
|
|
|
fontSetCurrent(gCreditsWindowNameFont);
|
|
|
|
int nameFontLineHeight = fontGetLineHeight();
|
|
|
|
|
2023-01-03 12:00:38 -08:00
|
|
|
int lineHeight = std::max(titleFontLineHeight, nameFontLineHeight);
|
2023-01-02 02:09:03 -08:00
|
|
|
int stringBufferSize = windowWidth * lineHeight;
|
2022-05-21 08:22:03 -07:00
|
|
|
unsigned char* stringBuffer = (unsigned char*)internal_malloc(stringBufferSize);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (stringBuffer != NULL) {
|
|
|
|
blitBufferToBuffer(backgroundBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth,
|
|
|
|
windowHeight,
|
|
|
|
windowWidth,
|
2022-05-19 01:51:26 -07:00
|
|
|
windowBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
windowRefresh(window);
|
|
|
|
|
|
|
|
paletteFadeTo(_cmap);
|
|
|
|
|
|
|
|
char str[260];
|
|
|
|
int font;
|
|
|
|
int color;
|
|
|
|
unsigned int tick = 0;
|
|
|
|
bool stop = false;
|
|
|
|
while (creditsFileParseNextLine(str, &font, &color)) {
|
|
|
|
fontSetCurrent(font);
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
int stringWidth = fontGetStringWidth(str);
|
|
|
|
if (stringWidth >= windowWidth) {
|
2022-05-19 01:51:26 -07:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(stringBuffer, 0, stringBufferSize);
|
2023-01-02 02:09:03 -08:00
|
|
|
fontDrawText(stringBuffer, str, windowWidth, windowWidth, color);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
unsigned char* dest = intermediateBuffer + windowWidth * windowHeight - windowWidth + (windowWidth - stringWidth) / 2;
|
2022-05-19 01:51:26 -07:00
|
|
|
unsigned char* src = stringBuffer;
|
|
|
|
for (int index = 0; index < lineHeight; index++) {
|
2022-10-07 14:54:27 -07:00
|
|
|
sharedFpsLimiter.mark();
|
|
|
|
|
2022-10-05 00:11:47 -07:00
|
|
|
if (inputGetInput() != -1) {
|
2022-05-19 01:51:26 -07:00
|
|
|
stop = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
memmove(intermediateBuffer, intermediateBuffer + windowWidth, windowWidth * windowHeight - windowWidth);
|
|
|
|
memcpy(dest, src, stringWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
blitBufferToBuffer(backgroundBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth,
|
|
|
|
windowHeight,
|
|
|
|
windowWidth,
|
2022-05-19 01:51:26 -07:00
|
|
|
windowBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
blitBufferToBufferTrans(intermediateBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth,
|
|
|
|
windowHeight,
|
|
|
|
windowWidth,
|
2022-05-19 01:51:26 -07:00
|
|
|
windowBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
while (getTicksSince(tick) < CREDITS_WINDOW_SCROLLING_DELAY) {
|
|
|
|
}
|
|
|
|
|
2022-10-05 00:11:47 -07:00
|
|
|
tick = getTicks();
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
windowRefresh(window);
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
src += windowWidth;
|
2022-10-07 14:54:27 -07:00
|
|
|
|
|
|
|
sharedFpsLimiter.throttle();
|
|
|
|
renderPresent();
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (stop) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!stop) {
|
2023-01-02 02:09:03 -08:00
|
|
|
for (int index = 0; index < windowHeight; index++) {
|
2022-10-07 14:54:27 -07:00
|
|
|
sharedFpsLimiter.mark();
|
|
|
|
|
2022-10-05 00:11:47 -07:00
|
|
|
if (inputGetInput() != -1) {
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-01-02 02:09:03 -08:00
|
|
|
memmove(intermediateBuffer, intermediateBuffer + windowWidth, windowWidth * windowHeight - windowWidth);
|
|
|
|
memset(intermediateBuffer + windowWidth * windowHeight - windowWidth, 0, windowWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
blitBufferToBuffer(backgroundBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth,
|
|
|
|
windowHeight,
|
|
|
|
windowWidth,
|
2022-05-19 01:51:26 -07:00
|
|
|
windowBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
blitBufferToBufferTrans(intermediateBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth,
|
|
|
|
windowHeight,
|
|
|
|
windowWidth,
|
2022-05-19 01:51:26 -07:00
|
|
|
windowBuffer,
|
2023-01-02 02:09:03 -08:00
|
|
|
windowWidth);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
while (getTicksSince(tick) < CREDITS_WINDOW_SCROLLING_DELAY) {
|
|
|
|
}
|
|
|
|
|
2022-10-05 00:11:47 -07:00
|
|
|
tick = getTicks();
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
windowRefresh(window);
|
2022-10-07 14:54:27 -07:00
|
|
|
|
|
|
|
sharedFpsLimiter.throttle();
|
|
|
|
renderPresent();
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal_free(stringBuffer);
|
|
|
|
}
|
|
|
|
internal_free(intermediateBuffer);
|
|
|
|
}
|
|
|
|
internal_free(backgroundBuffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
soundContinueAll();
|
|
|
|
paletteFadeTo(gPaletteBlack);
|
|
|
|
soundContinueAll();
|
|
|
|
windowDestroy(window);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cursorWasHidden) {
|
|
|
|
mouseHideCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
|
|
|
|
colorCycleEnable();
|
|
|
|
fileClose(gCreditsFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fontSetCurrent(oldFont);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x42CE6C
|
2022-06-18 06:05:07 -07:00
|
|
|
static bool creditsFileParseNextLine(char* dest, int* font, int* color)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
char string[256];
|
|
|
|
while (fileReadString(string, 256, gCreditsFile)) {
|
|
|
|
char* pch;
|
|
|
|
if (string[0] == ';') {
|
|
|
|
continue;
|
|
|
|
} else if (string[0] == '@') {
|
|
|
|
*font = gCreditsWindowTitleFont;
|
|
|
|
*color = gCreditsWindowTitleColor;
|
|
|
|
pch = string + 1;
|
|
|
|
} else if (string[0] == '#') {
|
|
|
|
*font = gCreditsWindowNameFont;
|
|
|
|
*color = _colorTable[17969];
|
|
|
|
pch = string + 1;
|
|
|
|
} else {
|
|
|
|
*font = gCreditsWindowNameFont;
|
|
|
|
*color = gCreditsWindowNameColor;
|
|
|
|
pch = string;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(dest, pch);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2022-09-23 05:43:44 -07:00
|
|
|
|
|
|
|
} // namespace fallout
|