[Scummvm-git-logs] scummvm master -> 2392177a7c070e2ade826dadf70b09f34b7e524f
AndywinXp
noreply at scummvm.org
Mon Oct 16 11:00:06 UTC 2023
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e19ac44440 SWORD1: PSX: Fix text position margin to match original
5daae32032 SWORD1: PSX: Implement credits
2392177a7c SWORD1: PSX: Fix y coordinate for sprite drawing
Commit: e19ac44440f0b707a9d391c6f15f1d3127b3516b
https://github.com/scummvm/scummvm/commit/e19ac44440f0b707a9d391c6f15f1d3127b3516b
Author: AndywinXp (andywinxp at gmail.com)
Date: 2023-10-16T12:59:17+02:00
Commit Message:
SWORD1: PSX: Fix text position margin to match original
This still doesn't render correctly because the PSX version has
a blitting routing which moves coordinates around, but 34 is
the correct value to have here.
Changed paths:
engines/sword1/logic.cpp
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index 19dd6e7da31..e488adcc6ab 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -1219,7 +1219,7 @@ int Logic::fnISpeak(Object *cpt, int32 id, int32 cdt, int32 textNo, int32 spr, i
int textMargin = SwordEngine::_systemVars.isDemo ? 5 : 3; // distance kept from edges of screen
if (SwordEngine::isPsx())
- textMargin = 33;
+ textMargin = 34;
int aboveHead = (SwordEngine::_systemVars.isDemo || SwordEngine::isPsx()) ? 10 : 20; // distance kept above talking sprite
uint16 textX, textY;
Commit: 5daae320328fe65becb5fe92e779392f7e622529
https://github.com/scummvm/scummvm/commit/5daae320328fe65becb5fe92e779392f7e622529
Author: AndywinXp (andywinxp at gmail.com)
Date: 2023-10-16T12:59:17+02:00
Commit Message:
SWORD1: PSX: Implement credits
The PSX version doesn't have a credits Smacker video
but has a CREDITS.DAT file containing credits strings which
have to be displayed as a scrolling list of names and roles.
Changed paths:
engines/sword1/control.cpp
engines/sword1/control.h
engines/sword1/logic.cpp
engines/sword1/logic.h
engines/sword1/sword1.cpp
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 2eb11ebd106..7bbf08c1b2e 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -3312,4 +3312,374 @@ const uint8 Control::_mediaHouseLanguageStrings[20][43] = {
"DRIVE FULL!",
};
+/* ---------- PSX CREDITS CODE ---------- */
+
+int32 Control::getCreditsStringLength(uint8 *str, uint8 *font) {
+ int32 width = 0;
+ FrameHeader *f;
+
+ while (*str) {
+ f = (FrameHeader *)_resMan->fetchFrame(font, *str - 32);
+ width += f->width;
+ str++;
+
+ if (*str)
+ width += PSX_CREDITS_SPACING;
+ }
+
+ return width;
+}
+
+int32 Control::getCreditsFontHeight(uint8 *font) {
+ FrameHeader *f;
+
+ f = (FrameHeader *)_resMan->fetchFrame(font, 'A' - 32);
+ return (f->height / 2);
+}
+
+void Control::createCreditsTextSprite(uint8 *data, int32 pitch, uint8 *str, uint8 *font) {
+ uint16 x = 0;
+ FrameHeader *f;
+ uint8 *src, *dst;
+
+ while (*str) {
+ f = (FrameHeader *)_resMan->fetchFrame(font, *str - 32);
+
+ src = (uint8 *)f + sizeof(FrameHeader);
+ dst = data + x;
+
+ for (int i = 0; i < f->height / 2; i++) {
+ memcpy(dst, src, f->width);
+ src += f->width;
+ dst += pitch;
+ }
+
+ x += (f->width + PSX_CREDITS_SPACING);
+ str++;
+ }
+}
+
+void Control::renderCreditsTextSprite(uint8 *data, uint8 *screenBuf, int16 x, int16 y, int16 width, int16 height) {
+ // Coordinates corrections from disasm
+ // (remember that the PSX framebuffer is bigger than our target 640x480 screen)
+ x -= 129;
+ y -= 72;
+
+ // Boundary checks
+ if (x >= SCREEN_WIDTH || y >= SCREEN_FULL_DEPTH)
+ return;
+
+ if (x + width <= 0 || y + height <= 0)
+ return;
+
+ // Are there rows outside the screen?
+ // Calculate how many doubled rows of the sprite are outside the screen on the top
+ int16 skippedDoubledRows = (y < 0) ? -y : 0;
+ int16 skippedRowsInData = skippedDoubledRows / 2;
+
+ data += width * skippedRowsInData; // Adjust data pointer based on the number of skipped rows in the sprite
+ height -= skippedDoubledRows; // Adjust height based on the number of skipped doubled rows
+
+ if (y < 0) {
+ y = 0;
+ }
+
+ uint8 *dst = screenBuf + x + SCREEN_WIDTH * y;
+
+ for (int i = 0; i < height; i += 2) { // Increment by 2 for the doubled height
+ // Boundary check for y
+ if (y + i >= SCREEN_FULL_DEPTH)
+ break;
+
+ // First horizontal line
+ for (int j = 0; j < width; j++) {
+ // Boundary checks for x
+ if (x + j < 0)
+ continue;
+
+ if (x + j >= SCREEN_WIDTH)
+ break;
+
+ if (data[j])
+ dst[j] = data[j];
+ }
+
+ dst += SCREEN_WIDTH;
+
+ // Second horizontal line (duplicated)
+ for (int j = 0; j < width; j++) {
+ // Boundary checks for x
+ if (x + j < 0)
+ continue;
+
+ if (x + j >= SCREEN_WIDTH)
+ break;
+
+ if (data[j])
+ dst[j] = data[j];
+ }
+
+ dst += SCREEN_WIDTH; // Move to the next line
+ data += width; // Move to the next row of source sprite
+ }
+}
+
+void Control::psxEndCredits() {
+ int16 h;
+ int16 nextCredit = PSX_NUM_CREDITS + 1;
+ uint8 *creditLine = nullptr;
+ uint8 *titleLine = nullptr;
+ int32 *creditData = nullptr;
+ Common::File creditsFile;
+
+ int32 creditsFileSize = 0;
+ int32 totalCreditsNum = 0;
+
+ uint8 *creditSprite[PSX_NUM_CREDITS];
+ uint8 *titleSprite[PSX_NUM_CREDITS];
+ int16 creditWidth[PSX_NUM_CREDITS];
+ int16 titleWidth[PSX_NUM_CREDITS];
+ int16 creditsHeight[PSX_NUM_CREDITS] = {
+ 400, 440, 480, 520, 560, 600, 640,
+ 680, 720, 760, 800, 840, 880, 920
+ };
+
+ for (int i = 0; i < PSX_NUM_CREDITS; i++) {
+ creditSprite[i] = nullptr;
+ titleSprite[i] = nullptr;
+ creditWidth[i] = 0;
+ titleWidth[i] = 0;
+ }
+
+ // If we're here, the resource is already there, no need to open it
+ uint8 *font = (uint8 *)_resMan->fetchRes(GAME_FONT);
+
+ switch (SwordEngine::_systemVars.language) {
+ case BS1_ENGLISH:
+ totalCreditsNum = 101;
+ creditsFileSize = 2798;
+ break;
+ case BS1_GERMAN:
+ totalCreditsNum = 83;
+ creditsFileSize = 2382;
+ break;
+ case BS1_FRENCH:
+ totalCreditsNum = 83;
+ creditsFileSize = 2382;
+ break;
+ case BS1_SPANISH:
+ totalCreditsNum = 83;
+ creditsFileSize = 2412;
+ break;
+ case BS1_ITALIAN:
+ totalCreditsNum = 101;
+ creditsFileSize = 2823;
+ break;
+ default:
+ totalCreditsNum = 101;
+ creditsFileSize = 2798;
+ }
+
+ _sound->clearAllFx();
+ _screen->startFadePaletteUp(1);
+
+ for (int i = 0; i < PSX_NUM_CREDITS; i++)
+ creditsHeight[i] = 400 + i * 40;
+
+ h = getCreditsFontHeight(font);
+ _screen->fnSetFadeTargetPalette(193, 1, 0, TEXT_WHITE);
+
+ _sound->streamMusicFile(101, 1);
+ _sound->updateMusicStreaming();
+
+ uint8 *creditsScreenBuf = (uint8 *)malloc(SCREEN_WIDTH * SCREEN_FULL_DEPTH);
+ if (!creditsScreenBuf) {
+ warning("Control::psxEndCredits(): Couldn't allocate memory for credits screen buffer");
+ return;
+ }
+
+ memset(creditsScreenBuf, 0, SCREEN_WIDTH * SCREEN_FULL_DEPTH);
+
+ creditData = (int32 *)malloc(creditsFileSize);
+ if (!creditData) {
+ warning("Control::psxEndCredits(): Couldn't allocate memory for text data");
+ free(creditsScreenBuf);
+ return;
+ }
+
+ if (!creditsFile.exists("CREDITS.DAT")) {
+ debug(2, "Control::psxEndCredits(): Couldn't find CREDITS.DAT");
+ free(creditsScreenBuf);
+ free(creditData);
+ return;
+ }
+
+ creditsFile.open("CREDITS.DAT");
+ if (!creditsFile.isOpen()) {
+ debug(2, "Control::psxEndCredits(): Couldn't open CREDITS.DAT");
+ free(creditsScreenBuf);
+ free(creditData);
+ return;
+ }
+
+ creditsFile.read(creditData, creditsFileSize);
+ creditsFile.close();
+
+ bool allSet = true;
+
+ for (int i = 0; i < PSX_NUM_CREDITS; i++) {
+ _sound->updateMusicStreaming();
+ _sound->setCrossFadeIncrement();
+
+ creditLine = ((uint8 *)creditData + creditData[i + totalCreditsNum]);
+ titleLine = ((uint8 *)creditData + creditData[i]);
+
+ creditWidth[i] = (getCreditsStringLength(creditLine, font) + 1) & 0xFFFE;
+ titleWidth[i] = (getCreditsStringLength(titleLine, font) + 1) & 0xFFFE;
+
+ if (creditWidth[i]) {
+ creditSprite[i] = (uint8 *)malloc(h * creditWidth[i]);
+ if (!creditSprite[i]) {
+ warning("Control::psxEndCredits(): Couldn't allocate memory for text sprites");
+ allSet = false;
+ break; // Break so the clean-up code is executed
+ }
+
+ memset(creditSprite[i], 0, h * creditWidth[i]);
+ } else {
+ creditSprite[i] = nullptr;
+ }
+
+ if (titleWidth[i]) {
+ titleSprite[i] = (uint8 *)malloc(h * titleWidth[i]);
+ if (!titleSprite[i]) {
+ warning("Control::psxEndCredits(): Couldn't allocate memory for text sprites");
+ allSet = false;
+ break; // Break so the clean-up code is executed
+ }
+
+ memset(titleSprite[i], 0, h * titleWidth[i]);
+ } else {
+ titleSprite[i] = nullptr;
+ }
+
+ createCreditsTextSprite(creditSprite[i], creditWidth[i], creditLine, font);
+ createCreditsTextSprite(titleSprite[i], titleWidth[i], titleLine, font);
+ }
+
+ _keyPressed.reset();
+
+ while (allSet && creditsHeight[PSX_NUM_CREDITS - 1] > -120 &&
+ !Engine::shouldQuit() &&
+ _keyPressed.keycode != Common::KEYCODE_ESCAPE) {
+ memset(creditsScreenBuf, 0, SCREEN_WIDTH * SCREEN_FULL_DEPTH);
+
+ for (int i = 0; i < PSX_NUM_CREDITS; i++) {
+ // Name
+ renderCreditsTextSprite(
+ creditSprite[i],
+ creditsScreenBuf,
+ PSX_CREDITS_MIDDLE + Logic::_scriptVars[SCROLL_OFFSET_X],
+ PSX_CREDITS_OFFSET + creditsHeight[i],
+ creditWidth[i],
+ h * 2);
+
+ // Role
+ renderCreditsTextSprite(
+ titleSprite[i],
+ creditsScreenBuf,
+ PSX_CREDITS_MIDDLE + Logic::_scriptVars[SCROLL_OFFSET_X] - 30 - titleWidth[i],
+ PSX_CREDITS_OFFSET + creditsHeight[i],
+ titleWidth[i],
+ h * 2);
+
+ creditsHeight[i] -= 2;
+ }
+
+ _system->copyRectToScreen(creditsScreenBuf, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_FULL_DEPTH);
+
+ delay(33); // Run credits at about 30 FPS
+
+ // Always remember to update sound :-)
+ _sound->updateMusicStreaming();
+ _sound->setCrossFadeIncrement();
+
+ // Scroll the credits!
+ if (creditsHeight[0] < -120) {
+ if (nextCredit <= totalCreditsNum) {
+ for (int i = 0; i < PSX_NUM_CREDITS; i++) {
+ creditsHeight[i] += 40;
+ }
+
+ if (creditSprite[0] != nullptr)
+ free(creditSprite[0]);
+
+ if (titleSprite[0] != nullptr)
+ free(titleSprite[0]);
+
+ for (int i = 0; i < PSX_NUM_CREDITS - 1; i++) {
+ creditSprite[i] = creditSprite[i + 1];
+ titleSprite[i] = titleSprite[i + 1];
+ creditWidth[i] = creditWidth[i + 1];
+ titleWidth[i] = titleWidth[i + 1];
+ }
+
+ creditLine = ((uint8 *)creditData + creditData[nextCredit - 1 + totalCreditsNum]);
+ titleLine = ((uint8 *)creditData + creditData[nextCredit - 1]);
+
+ creditWidth[PSX_NUM_CREDITS - 1] = (getCreditsStringLength(creditLine, font) + 1) & 0xFFFE;
+ titleWidth[PSX_NUM_CREDITS - 1] = (getCreditsStringLength(titleLine, font) + 1) & 0xFFFE;
+
+ if (creditWidth[PSX_NUM_CREDITS - 1]) {
+ creditSprite[PSX_NUM_CREDITS - 1] = (uint8 *)malloc(h * creditWidth[PSX_NUM_CREDITS - 1]);
+ if (!creditSprite[PSX_NUM_CREDITS - 1]) {
+ warning("Control::psxEndCredits(): Couldn't allocate memory for text sprites");
+ break;
+ }
+
+ memset(creditSprite[PSX_NUM_CREDITS - 1], 0, h * creditWidth[PSX_NUM_CREDITS - 1]);
+ } else {
+ creditSprite[PSX_NUM_CREDITS - 1] = nullptr;
+ }
+
+ if (titleWidth[PSX_NUM_CREDITS - 1]) {
+ titleSprite[PSX_NUM_CREDITS - 1] = (uint8 *)malloc(h * titleWidth[PSX_NUM_CREDITS - 1]);
+ if (!titleSprite[PSX_NUM_CREDITS - 1]) {
+ warning("Control::psxEndCredits(): Couldn't allocate memory for text sprites");
+ break;
+ }
+
+ memset(titleSprite[PSX_NUM_CREDITS - 1], 0, h * titleWidth[PSX_NUM_CREDITS - 1]);
+ } else {
+ titleSprite[PSX_NUM_CREDITS - 1] = nullptr;
+ }
+
+ createCreditsTextSprite(creditSprite[PSX_NUM_CREDITS - 1], creditWidth[PSX_NUM_CREDITS - 1], creditLine, font);
+ createCreditsTextSprite(titleSprite[PSX_NUM_CREDITS - 1], titleWidth[PSX_NUM_CREDITS - 1], titleLine, font);
+
+ nextCredit += 1;
+ }
+ }
+ }
+
+ for (int i = 0; i < PSX_NUM_CREDITS; i++) {
+ if (creditSprite[i] != nullptr)
+ free(creditSprite[i]);
+
+ if (titleSprite[i] != nullptr)
+ free(titleSprite[i]);
+ }
+
+ free(creditData);
+
+ _screen->startFadePaletteDown(1);
+ _vm->waitForFade();
+
+ memset(creditsScreenBuf, 0, SCREEN_WIDTH * SCREEN_FULL_DEPTH);
+ _system->copyRectToScreen(creditsScreenBuf, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_FULL_DEPTH);
+ free(creditsScreenBuf);
+
+ _keyPressed.reset();
+}
+
} // End of namespace Sword1
diff --git a/engines/sword1/control.h b/engines/sword1/control.h
index 8784b9c47b6..870d0f91679 100644
--- a/engines/sword1/control.h
+++ b/engines/sword1/control.h
@@ -105,6 +105,11 @@ class Logic;
#define SP_OVERLAP 2
#define TEXTBUTTONID 7
+#define PSX_CREDITS_SPACING (-3)
+#define PSX_CREDITS_MIDDLE 450
+#define PSX_CREDITS_OFFSET 150
+#define PSX_NUM_CREDITS 14
+
struct Button {
int32 x1;
int32 y1;
@@ -126,6 +131,7 @@ public:
void checkForOldSaveGames();
bool isPanelShown();
const uint8 *getPauseString();
+ void psxEndCredits();
void setSaveDescription(int slot, const char *desc) {
Common::strcpy_s((char *)_fileDescriptions[slot], sizeof(_fileDescriptions[slot]), desc);
@@ -198,6 +204,12 @@ private:
int displayMessage(const char *altButton, MSVC_PRINTF const char *message, ...) GCC_PRINTF(3, 4);
+ // PSX Credits functions
+ int32 getCreditsFontHeight(uint8 *font);
+ int32 getCreditsStringLength(uint8 *str, uint8 *font);
+ void renderCreditsTextSprite(uint8 *data, uint8 *dst, int16 x, int16 y, int16 width, int16 height);
+ void createCreditsTextSprite(uint8 *data, int32 pitch, uint8 *str, uint8 *font);
+
Common::MemoryWriteStreamDynamic *_tempThumbnail;
static const uint8 _languageStrings[8 * 20][43];
static const uint8 _akellaLanguageStrings[20][43];
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index e488adcc6ab..d509cea2373 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -95,6 +95,10 @@ void Logic::initialize() {
SwordEngine::_systemVars.speechFinished = true;
}
+void Logic::setControlPanelObject(Control *control) {
+ _control = control;
+}
+
void Logic::newScreen(uint32 screen) {
Object *compact = (Object *)_objMan->fetchObject(PLAYER);
@@ -984,21 +988,26 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3
// meantime, we don't want any looping sound effects still playing.
_sound->clearAllFx();
- MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _sound, _system);
- if (player) {
- _screen->clearScreen();
- if (player->load(sequenceId))
- player->play();
- delete player;
-
- // In some instances, when you start a video when the palette is still fading
- // and the video is finished earlier, another palette fade(-out) is performed with the
- // wrong palette. This happens when traveling to Spain or Ireland. It couldn't happen
- // in the original, as it asked for the CD before loading the scene.
- // Let's fix this by forcing a black fade palette on the next fade out. If a fade-in
- // is then scheduled, we will clear the flag without doing anything different from the usual.
- _screen->setNextFadeOutToBlack();
+ if (SwordEngine::isPsx() && sequenceId == 19) {
+ _control->psxEndCredits();
+ } else {
+ MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _sound, _system);
+ if (player) {
+ _screen->clearScreen();
+ if (player->load(sequenceId))
+ player->play();
+ delete player;
+
+ // In some instances, when you start a video when the palette is still fading
+ // and the video is finished earlier, another palette fade(-out) is performed with the
+ // wrong palette. This happens when traveling to Spain or Ireland. It couldn't happen
+ // in the original, as it asked for the CD before loading the scene.
+ // Let's fix this by forcing a black fade palette on the next fade out. If a fade-in
+ // is then scheduled, we will clear the flag without doing anything different from the usual.
+ _screen->setNextFadeOutToBlack();
+ }
}
+
return SCRIPT_CONT;
}
diff --git a/engines/sword1/logic.h b/engines/sword1/logic.h
index 96089534263..20b298b6b0c 100644
--- a/engines/sword1/logic.h
+++ b/engines/sword1/logic.h
@@ -47,6 +47,7 @@ class Menu;
class Router;
class Screen;
class Mouse;
+class Control;
class Logic;
typedef int (Logic::*BSMcodeTable)(Object *, int32, int32, int32, int32, int32, int32, int32);
@@ -57,6 +58,7 @@ public:
Logic(SwordEngine *vm, ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Menu *pMenu, OSystem *system, Audio::Mixer *mixer);
~Logic();
void initialize();
+ void setControlPanelObject(Control *control);
void newScreen(uint32 screen);
void engine();
void updateScreenParams();
@@ -81,6 +83,7 @@ private:
Text *_textMan;
EventManager *_eventMan;
Menu *_menu;
+ Control *_control;
uint32 _newScript; // <= ugly, but I can't avoid it.
uint8 _speechClickDelay = 0;
Common::RandomSource _rnd;
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 53ecbb75524..4e890cb83d1 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -172,6 +172,7 @@ Common::Error SwordEngine::init() {
_objectMan->initialize();
_mouse->initialize();
_control = new Control(this, _saveFileMan, _resMan, _objectMan, _system, _mouse, _sound, _screen, _logic);
+ _logic->setControlPanelObject(_control);
return Common::kNoError;
}
Commit: 2392177a7c070e2ade826dadf70b09f34b7e524f
https://github.com/scummvm/scummvm/commit/2392177a7c070e2ade826dadf70b09f34b7e524f
Author: AndywinXp (andywinxp at gmail.com)
Date: 2023-10-16T12:59:17+02:00
Commit Message:
SWORD1: PSX: Fix y coordinate for sprite drawing
Now sprites don't randomly go up and down when being
animated :-) This was taken from disasm.
Changed paths:
engines/sword1/control.cpp
engines/sword1/screen.cpp
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 7bbf08c1b2e..74c10ab2370 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -3362,6 +3362,7 @@ void Control::createCreditsTextSprite(uint8 *data, int32 pitch, uint8 *str, uint
void Control::renderCreditsTextSprite(uint8 *data, uint8 *screenBuf, int16 x, int16 y, int16 width, int16 height) {
// Coordinates corrections from disasm
// (remember that the PSX framebuffer is bigger than our target 640x480 screen)
+ y = (y + 1) & 0xFFFE;
x -= 129;
y -= 72;
diff --git a/engines/sword1/screen.cpp b/engines/sword1/screen.cpp
index 02d06189554..7616acb743a 100644
--- a/engines/sword1/screen.cpp
+++ b/engines/sword1/screen.cpp
@@ -1396,6 +1396,9 @@ void Screen::spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *pSprWidth, u
gridBuf += _gridSizeX;
}
}
+
+ if (SwordEngine::isPsx())
+ *pSprY = (*pSprY + 1) & 0xFFFE;
}
void Screen::fnFlash(uint8 color) {
More information about the Scummvm-git-logs
mailing list