[Scummvm-git-logs] scummvm master -> 4f1676e38b5e5677ba7f647128a51002bbe40821
bluegr
bluegr at gmail.com
Sat Sep 4 09:14:28 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
4f1676e38b TINSEL: Initial work on the Saturn version of DW1
Commit: 4f1676e38b5e5677ba7f647128a51002bbe40821
https://github.com/scummvm/scummvm/commit/4f1676e38b5e5677ba7f647128a51002bbe40821
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-09-04T12:13:18+03:00
Commit Message:
TINSEL: Initial work on the Saturn version of DW1
This version is using the same graphics format as the PSX version, with
differences in resource endianess, but features digital music with a
different track structure and has a different sound sample format
Pending issues:
- Font rendering is wrong - this is evident in the text and menus in
the game title screen
- Cursor sprite and trails are wrong - can be seen in the menu of the
game title screen
- Digital music is not supported yet - seems that a different track
structure is used
- The sound sample format is different than the PC version - looks to
be raw, but isn't
- The game crashes at the first room after watching Rincewind's waking
up cutscene
Changed paths:
engines/tinsel/drives.cpp
engines/tinsel/drives.h
engines/tinsel/graphics.cpp
engines/tinsel/handle.cpp
engines/tinsel/music.cpp
engines/tinsel/scene.cpp
engines/tinsel/sound.cpp
engines/tinsel/strres.cpp
engines/tinsel/tinsel.h
diff --git a/engines/tinsel/drives.cpp b/engines/tinsel/drives.cpp
index a497fda200..6bfa086496 100644
--- a/engines/tinsel/drives.cpp
+++ b/engines/tinsel/drives.cpp
@@ -157,7 +157,11 @@ bool GotoCD() {
bool TinselFile::_warningShown = false;
-TinselFile::TinselFile() : ReadStreamEndian(TinselV1Mac) {
+TinselFile::TinselFile() : ReadStreamEndian(TinselV1Saturn) {
+ _stream = nullptr;
+}
+
+TinselFile::TinselFile(bool bigEndian) : ReadStreamEndian(bigEndian) {
_stream = nullptr;
}
diff --git a/engines/tinsel/drives.h b/engines/tinsel/drives.h
index afedd0d529..e2ded64b54 100644
--- a/engines/tinsel/drives.h
+++ b/engines/tinsel/drives.h
@@ -62,7 +62,9 @@ private:
Common::SeekableReadStream *_stream;
bool openInternal(const Common::String &filename);
public:
+ // This constructor is only used for _sampleStream inside sound.h
TinselFile();
+ TinselFile(bool bigEndian);
~TinselFile() override;
bool open(const Common::String &filename);
void close();
diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp
index 8d69003285..95b39a40c6 100644
--- a/engines/tinsel/graphics.cpp
+++ b/engines/tinsel/graphics.cpp
@@ -56,11 +56,11 @@ static inline uint16 t3getColor(uint8 r, uint8 g, uint8 b) {
}
/**
- * PSX Block list unwinder.
+ * PSX/Saturn Block list unwinder.
* Chunk type 0x0003 (CHUNK_CHARPTR) in PSX version of DW 1 & 2 is compressed (original code
* calls the compression PJCRLE), thus we need to decompress it before passing data to drawing functions
*/
-uint8* psxPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
+uint8* psxSaturnPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
uint32 remainingBlocks = 0;
uint16 compressionType = 0; // Kind of decompression to apply
@@ -84,7 +84,7 @@ uint8* psxPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
while (remainingBlocks) { // Repeat until all blocks are decompressed
if (!controlBits) {
- controlData = READ_16(srcIdx);
+ controlData = READ_LE_UINT16(srcIdx);
srcIdx += 2;
// If bit 15 of controlData is enabled, compression data is type 1.
@@ -103,7 +103,7 @@ uint8* psxPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
// If there is compression, we need to fetch an index
// to be treated as "base" for compression.
if (compressionType != 0) {
- controlData = READ_16(srcIdx);
+ controlData = READ_LE_UINT16(srcIdx);
srcIdx += 2;
baseIndex = controlData;
}
@@ -125,7 +125,7 @@ uint8* psxPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
switch (compressionType) {
case 0: // No compression, plain copy of indexes
while (decremTiles) {
- WRITE_LE_UINT16(dstIdx, READ_16(srcIdx));
+ WRITE_LE_UINT16(dstIdx, READ_LE_UINT16(srcIdx));
srcIdx += 2;
dstIdx += 2;
decremTiles--;
@@ -301,9 +301,9 @@ static void MacDrawTiles(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool apply
/**
- * Straight rendering with transparency support, PSX variant supporting also 4-BIT clut data
+ * Straight rendering with transparency support, PSX/Saturn variant supporting also 4-BIT clut data for PSX
*/
-static void PsxDrawTiles(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool applyClipping, bool fourBitClut, uint32 psxSkipBytes, byte *psxMapperTable, bool transparency) {
+static void psxSaturnDrawTiles(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool applyClipping, bool fourBitClut, uint32 psxSkipBytes, byte *psxMapperTable, bool transparency) {
// Set up the offset between destination blocks
int rightClip = applyClipping ? pObj->rightClip : 0;
Common::Rect boxBounds;
@@ -1066,7 +1066,7 @@ void DrawObject(DRAWOBJECT *pObj) {
byte psxMapperTable[16];
bool psxFourBitClut = false; // Used by Tinsel PSX, true if an image using a 4bit CLUT is rendered
- bool psxRLEindex = false; // Used by Tinsel PSX, true if an image is using PJCRLE compressed indexes
+ bool psxSaturnRLEindex = false; // Used by Tinsel PSX/Saturn, true if an image is using PJCRLE compressed indexes
uint32 psxSkipBytes = 0; // Used by Tinsel PSX, number of bytes to skip before counting indexes for image tiles
if ((pObj->width <= 0) || (pObj->height <= 0))
@@ -1083,29 +1083,30 @@ void DrawObject(DRAWOBJECT *pObj) {
byte *p = (byte *)_vm->_handle->LockMem(pObj->hBits & HANDLEMASK);
srcPtr = p + (pObj->hBits & OFFSETMASK);
- pObj->charBase = (char *)p + READ_LE_UINT32(p + 0x10);
- pObj->transOffset = READ_LE_UINT32(p + 0x14);
+ pObj->charBase = (char *)p + READ_32(p + 0x10);
+ pObj->transOffset = READ_32(p + 0x14);
- // Decompress block indexes for Discworld PSX
- if (TinselV1PSX) {
- uint8 paletteType = *(srcPtr); // if 0x88 we are using an 8bit palette type, if 0x44 we are using a 4 bit PSX CLUT
- uint8 indexType = *(srcPtr + 1); // if 0xCC indexes for this image are compressed with PCJRLE, if 0xDD indexes are not compressed
+ // Decompress block indexes for Discworld PSX/Saturn
+ if (TinselV1PSX || TinselV1Saturn) {
+ uint8 paletteType = TinselV1PSX ? *(srcPtr) : *(srcPtr + 1); // if 0x88 we are using an 8bit palette type, if 0x44 we are using a 4 bit PSX CLUT
+ uint8 indexType = TinselV1PSX ? *(srcPtr + 1) : *(srcPtr); // if 0xCC indexes for this image are compressed with PCJRLE, if 0xDD indexes are not compressed
switch (paletteType) {
- case 0x88: // Normal 8-bit palette
+ case 0x00: // Normal 8-bit palette (Saturn)
+ case 0x88: // Normal 8-bit palette (PSX)
psxFourBitClut = false;
psxSkipBytes = 0;
switch (indexType) {
case 0xDD: // Normal uncompressed indexes
- psxRLEindex = false;
+ psxSaturnRLEindex = false;
srcPtr += sizeof(uint16); // Get to the beginning of index data
break;
case 0xCC: // PJCRLE compressed indexes
- psxRLEindex = true;
- srcPtr = psxPJCRLEUnwinder(pObj->width, pObj->height, srcPtr + sizeof(uint16));
+ psxSaturnRLEindex = true;
+ srcPtr = psxSaturnPJCRLEUnwinder(pObj->width, pObj->height, srcPtr + sizeof(uint16));
break;
default:
- error("Unknown PSX index type 0x%.2X", indexType);
+ error("Unknown PSX/Saturn index type 0x%.2X", indexType);
break;
}
break;
@@ -1113,15 +1114,15 @@ void DrawObject(DRAWOBJECT *pObj) {
psxPaletteMapper(pObj->pPal, srcPtr + sizeof(uint16), psxMapperTable);
psxFourBitClut = true;
- psxSkipBytes = READ_LE_UINT32(p + sizeof(uint32) * 5) << 4; // Fetch number of bytes we have to skip
+ psxSkipBytes = READ_32(p + sizeof(uint32) * 5) << 4; // Fetch number of bytes we have to skip
switch (indexType) {
case 0xDD: // Normal uncompressed indexes
- psxRLEindex = false;
+ psxSaturnRLEindex = false;
srcPtr += sizeof(uint16) * 17; // Skip image type and clut, and get to beginning of index data
break;
case 0xCC: // PJCRLE compressed indexes
- psxRLEindex = true;
- srcPtr = psxPJCRLEUnwinder(pObj->width, pObj->height, srcPtr + sizeof(uint16) * 17);
+ psxSaturnRLEindex = true;
+ srcPtr = psxSaturnPJCRLEUnwinder(pObj->width, pObj->height, srcPtr + sizeof(uint16) * 17);
break;
default:
error("Unknown PSX index type 0x%.2X", indexType);
@@ -1129,7 +1130,7 @@ void DrawObject(DRAWOBJECT *pObj) {
}
break;
default:
- error("Unknown PSX palette type 0x%.2X", paletteType);
+ error("Unknown PSX/Saturn palette type 0x%.2X", paletteType);
break;
}
}
@@ -1169,8 +1170,8 @@ void DrawObject(DRAWOBJECT *pObj) {
t3WrtNonZero(pObj, srcPtr, destPtr);
else if (TinselV2)
t2WrtNonZero(pObj, srcPtr, destPtr, (typeId & DMA_CLIP) != 0, (typeId & DMA_FLIPH) != 0);
- else if (TinselV1PSX)
- PsxDrawTiles(pObj, srcPtr, destPtr, typeId == 0x41, psxFourBitClut, psxSkipBytes, psxMapperTable, true);
+ else if (TinselV1PSX || TinselV1Saturn)
+ psxSaturnDrawTiles(pObj, srcPtr, destPtr, typeId == 0x41, psxFourBitClut, psxSkipBytes, psxMapperTable, true);
else if (TinselV1Mac)
MacDrawTiles(pObj, srcPtr, destPtr, typeId == 0x41);
else if (TinselV1)
@@ -1184,8 +1185,8 @@ void DrawObject(DRAWOBJECT *pObj) {
t3WrtAll(pObj, srcPtr, destPtr);
else if (TinselV2 || TinselV1Mac || TinselV0)
WrtAll(pObj, srcPtr, destPtr, typeId == 0x48);
- else if (TinselV1PSX)
- PsxDrawTiles(pObj, srcPtr, destPtr, typeId == 0x48, psxFourBitClut, psxSkipBytes, psxMapperTable, false);
+ else if (TinselV1PSX || TinselV1Saturn)
+ psxSaturnDrawTiles(pObj, srcPtr, destPtr, typeId == 0x48, psxFourBitClut, psxSkipBytes, psxMapperTable, false);
else if (TinselV1)
WrtNonZero(pObj, srcPtr, destPtr, typeId == 0x48);
break;
@@ -1214,9 +1215,9 @@ void DrawObject(DRAWOBJECT *pObj) {
}
}
- // If we were using Discworld PSX, free the memory allocated
+ // If we were using Discworld PSX/Saturn, free the memory allocated
// for decompressed block indexes.
- if (TinselV1PSX && psxRLEindex)
+ if ((TinselV1PSX || TinselV1Saturn) && psxSaturnRLEindex)
free(srcPtr);
}
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 24e3875f3c..b5c3a1b6a0 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -83,7 +83,7 @@ void Handle::SetupHandleTable() {
int len;
uint i;
MEMHANDLE *pH;
- TinselFile f;
+ TinselFile f(TinselV1Mac || TinselV1Saturn);
const char *indexFileName = TinselV1PSX ? PSX_INDEX_FILENAME : INDEX_FILENAME;
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 498a5fb62f..bd0ed7fbf0 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -176,6 +176,8 @@ bool Music::PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
// The Macintosh version of DW1 uses raw PCM for music
dwSeqLen = midiStream.readUint32BE();
_vm->_sound->playDW1MacMusic(midiStream, dwSeqLen);
+ } else if (TinselV1Saturn) {
+ // TODO: Music format for the Saturn version
} else {
dwSeqLen = midiStream.readUint32LE();
@@ -298,6 +300,10 @@ void Music::OpenMidiFiles() {
}
midiStream.close();
+ } else if (TinselV1Saturn) {
+ // The Saturn version has digital music with a different track structure
+ // TODO
+ warning("Music support for Discworld 1 Saturn");
} else {
if (_midiBuffer.pDat)
// already allocated
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 293824f2b2..c6fa04205d 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -192,9 +192,8 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
// The following myEscape value setting is used for enabling title screen skipping in DW1
if (TinselV1 && (g_sceneCtr == 1)) g_initialMyEscape = GetEscEvents();
- // DW1 PSX has its own scene skipping script code for scenes 2 and 3 (bug #6094).
- // Same goes for DW1 Mac.
- _ctx->myEscape = (TinselV1 && (g_sceneCtr < ((TinselV1PSX || TinselV1Mac) ? 2 : 4))) ? g_initialMyEscape : 0;
+ // DW1 PSX, Saturn and Mac has its own scene skipping script code for scenes 2 and 3 (bug #6094).
+ _ctx->myEscape = (TinselV1 && (g_sceneCtr < ((TinselV1PSX || TinselV1Saturn || TinselV1Mac) ? 2 : 4))) ? g_initialMyEscape : 0;
// get the stuff copied to process when it was created
_ctx->pInit = (const TP_INIT *)param;
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp
index fc0df73887..3c46462789 100644
--- a/engines/tinsel/sound.cpp
+++ b/engines/tinsel/sound.cpp
@@ -100,7 +100,7 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound
error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
// read the length of the sample
- uint32 sampleLen = _sampleStream.readUint32LE();
+ uint32 sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
@@ -115,6 +115,8 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound
// Play the audio stream
_vm->_mixer->playStream(type, &curChan.handle, xaStream);
+ } else if (TinselV1Saturn) {
+ // TODO: Sound format for the Saturn version - looks to be raw, but isn't
} else {
// allocate a buffer
byte *sampleBuf = (byte *)malloc(sampleLen);
@@ -499,7 +501,7 @@ void SoundManager::openSampleFiles() {
if (TinselV0 || (TinselV1 && !_vm->isV1CD()))
return;
- TinselFile f;
+ TinselFile f(TinselV1Saturn);
if (_sampleIndex)
// already allocated
@@ -518,7 +520,7 @@ void SoundManager::openSampleFiles() {
// Load data
for (int i = 0; i < _sampleIndexLen; ++i) {
- _sampleIndex[i] = f.readUint32LE();
+ _sampleIndex[i] = f.readUint32();
if (f.err()) {
showSoundError(FILE_READ_ERROR, _vm->getSampleIndex(g_sampleLanguage));
}
diff --git a/engines/tinsel/strres.cpp b/engines/tinsel/strres.cpp
index 45b0b47e5c..ce7fae0622 100644
--- a/engines/tinsel/strres.cpp
+++ b/engines/tinsel/strres.cpp
@@ -88,7 +88,7 @@ void ResetVarsStrRes() {
* @param newLang The new language
*/
void ChangeLanguage(LANGUAGE newLang) {
- TinselFile f;
+ TinselFile f(TinselV1Mac || TinselV1Saturn);
uint32 textLen = 0; // length of buffer
g_textLanguage = newLang;
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 18c9f992d8..d0ef3421ce 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -107,12 +107,13 @@ typedef bool (*KEYFPTR)(const Common::KeyState &);
#define TinselV2Demo (TinselVersion == TINSEL_V2 && _vm->getIsADGFDemo())
#define TinselV1PSX (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformPSX)
#define TinselV1Mac (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformMacintosh)
+#define TinselV1Saturn (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformSaturn)
-#define READ_16(v) (TinselV1Mac ? READ_BE_UINT16(v) : READ_LE_UINT16(v))
-#define READ_32(v) (TinselV1Mac ? READ_BE_UINT32(v) : READ_LE_UINT32(v))
-#define FROM_16(v) (TinselV1Mac ? FROM_BE_16(v) : FROM_LE_16(v))
-#define FROM_32(v) (TinselV1Mac ? FROM_BE_32(v) : FROM_LE_32(v))
-#define TO_32(v) (TinselV1Mac ? TO_BE_32(v) : TO_LE_32(v))
+#define READ_16(v) (TinselV1Mac || TinselV1Saturn ? READ_BE_UINT16(v) : READ_LE_UINT16(v))
+#define READ_32(v) (TinselV1Mac || TinselV1Saturn ? READ_BE_UINT32(v) : READ_LE_UINT32(v))
+#define FROM_16(v) (TinselV1Mac || TinselV1Saturn ? FROM_BE_16(v) : FROM_LE_16(v))
+#define FROM_32(v) (TinselV1Mac || TinselV1Saturn ? FROM_BE_32(v) : FROM_LE_32(v))
+#define TO_32(v) (TinselV1Mac || TinselV1Saturn ? TO_BE_32(v) : TO_LE_32(v))
// Global reference to the TinselEngine object
extern TinselEngine *_vm;
More information about the Scummvm-git-logs
mailing list