diff options
Diffstat (limited to 'engines/gob')
51 files changed, 2461 insertions, 2144 deletions
diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp index 25cd470f04..4ceca3ce24 100644 --- a/engines/gob/demos/demoplayer.cpp +++ b/engines/gob/demos/demoplayer.cpp @@ -123,7 +123,7 @@ void DemoPlayer::init() { void DemoPlayer::clearScreen() { debugC(1, kDebugDemo, "Clearing the screen"); - _vm->_video->clearSurf(*_vm->_draw->_backSurface); + _vm->_draw->_backSurface->clear(); _vm->_draw->forceBlit(); _vm->_video->retrace(); } @@ -244,10 +244,11 @@ void DemoPlayer::playVideoDoubled(int slot) { int16 wD = (rect->left * 2) + (w * 2); int16 hD = (rect->top * 2) + (h * 2); - _vm->_video->drawSpriteDouble(*_vm->_draw->_spritesArray[0], *_vm->_draw->_frontSurface, - rect->left, rect->top, rect->right - 1, rect->bottom - 1, rect->left, rect->top, 0); - _vm->_draw->dirtiedRect(_vm->_draw->_frontSurface, - rect->left * 2, rect->top * 2, wD, hD); + _vm->_draw->_frontSurface->blitScaled(*_vm->_draw->_spritesArray[0], + rect->left, rect->top, rect->right - 1, rect->bottom - 1, rect->left * 2, rect->top * 2, 2); + + _vm->_draw->dirtiedRect(_vm->_draw->_frontSurface, + rect->left * 2, rect->top * 2, wD, hD); } } @@ -297,10 +298,10 @@ void DemoPlayer::evaluateVideoMode(const char *mode) { _doubleMode = false; // Only applicable when we actually can double - if (_vm->is640()) { - if (!scumm_strnicmp(mode, "AUTO", 4)) + if (_vm->is640x480() || _vm->is800x600()) { + if (!scumm_strnicmp(mode, "AUTO", 4)) _autoDouble = true; - else if (!scumm_strnicmp(mode, "VGA", 3) && _vm->is640()) + else if (!scumm_strnicmp(mode, "VGA", 3)) _doubleMode = true; } } diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index 20edb9fbc3..93c1cc6d1c 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -420,6 +420,20 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesAdLib, 0, 0, 0 }, + { // Provided by pykman in the forums. + { + "gob1cd", + "Polish", + AD_ENTRY1s("intro.stk", "97d2443948b2e367cf567fe7e101f5f2", 4049267), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 + }, { // CD 1.000 version. { "gob1cd", @@ -1054,6 +1068,20 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesCD, 0, 0, 0 }, + { // Supplied by pykman in bug report #3067489 + { + "gob2cd", + "v2.01 Polish", + AD_ENTRY1s("intro.stk", "3025f05482b646c18c2c79c615a3a1df", 5011726), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, { { "gob2cd", @@ -1798,6 +1826,22 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, +// This version is not detected on purpose: it's a pirated version. +// Tagged ADGF_PIRATED! Do not re-add nor un-tag! + { + { + "lit", + "", + AD_ENTRY1s("intro.stk", "3712e7527ba8ce5637d2aadf62783005", 72318), + FR_FRA, + kPlatformPC, + ADGF_PIRATED, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 + }, { { "lit", @@ -2220,18 +2264,20 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesAdLib, "demo.stk", "demo.tot", 0 }, +// This version is not detected on purpose: it's a pirated version, using a corrupted crack. +// Tagged ADGF_PIRATED! Do not re-add nor un-tag! { { "fascination", - "CD Version (Censored)", - AD_ENTRY1s("disk0.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), - EN_ANY, + "", + AD_ENTRY1s("disk0.stk", "c14330d052fe4da5a441ac9d81bc5891", 1061955), + UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + ADGF_PIRATED, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, - kFeaturesCD, + kFeaturesAdLib, "disk0.stk", 0, 0 }, { @@ -2239,7 +2285,7 @@ static const GOBGameDescription gameDescriptions[] = { "fascination", "VGA 3 disks edition", AD_ENTRY1s("disk0.stk", "a50a8495e1b2d67699fb562cb98fc3e2", 1064387), - UNK_LANG, + FR_FRA, kPlatformPC, ADGF_NO_FLAGS, GUIO_NOSUBTITLES | GUIO_NOSPEECH @@ -2251,7 +2297,7 @@ static const GOBGameDescription gameDescriptions[] = { { { "fascination", - "VGA 3 disks edition", + "Hebrew edition (censored)", AD_ENTRY1s("intro.stk", "d6e45ce548598727e2b5587a99718eba", 1055909), HE_ISR, kPlatformPC, @@ -2262,20 +2308,6 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesAdLib, "intro.stk", 0, 0 }, - { // Supplied by sanguine - { - "fascination", - "VGA 3 disks edition", - AD_ENTRY1s("disk0.stk", "c14330d052fe4da5a441ac9d81bc5891", 1061955), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO_NOSUBTITLES | GUIO_NOSPEECH - }, - kGameTypeFascination, - kFeaturesAdLib, - "disk0.stk", 0, 0 - }, { // Supplied by windlepoons in bug report #2809247 { "fascination", @@ -2376,6 +2408,76 @@ static const GOBGameDescription gameDescriptions[] = { }, { { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 + }, + { + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 + }, + { + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 + }, + { + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 + }, + { + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 + }, + { + { "geisha", "", AD_ENTRY1s("disk1.stk", "6eebbb98ad90cd3c44549fc2ab30f632", 212153), @@ -2724,6 +2826,20 @@ static const GOBGameDescription gameDescriptions[] = { kFeaturesCD, 0, 0, 0 }, + { // Supplied by pykman in bug report #3067489 + { + "gob3cd", + "v1.02 Polish", + AD_ENTRY1s("intro.stk", "978afddcac81bb95a04757b61f78471c", 619825), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 + }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 { "gob3cd", @@ -3126,7 +3242,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3140,7 +3256,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3154,7 +3270,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3168,7 +3284,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3182,7 +3298,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3196,7 +3312,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3210,7 +3326,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3224,7 +3340,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3238,7 +3354,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3252,7 +3368,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3266,7 +3382,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by jvprat on #scummvm @@ -3280,7 +3396,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by jvprat on #scummvm @@ -3294,7 +3410,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by jvprat on #scummvm @@ -3308,7 +3424,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by jvprat on #scummvm @@ -3322,7 +3438,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by jvprat on #scummvm @@ -3336,7 +3452,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by Hkz on #scummvm @@ -3350,7 +3466,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by Hkz on #scummvm @@ -3364,7 +3480,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by Hkz on #scummvm @@ -3378,7 +3494,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by DjDiabolik in bug report #1971294 @@ -3392,7 +3508,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by DjDiabolik in bug report #1971294 @@ -3406,7 +3522,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by DjDiabolik in bug report #1971294 @@ -3420,7 +3536,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by DjDiabolik in bug report #1971294 @@ -3434,7 +3550,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by DjDiabolik in bug report #1971294 @@ -3448,7 +3564,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { // Supplied by goodoldgeorg in bug report #2098838 @@ -3462,7 +3578,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3480,7 +3596,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesSCNDemo, 0, 0, 1 }, { @@ -3494,7 +3610,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3508,7 +3624,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3522,7 +3638,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3536,7 +3652,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3550,7 +3666,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3564,7 +3680,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -3578,7 +3694,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, "lda1.stk", 0, 0 }, { @@ -3592,7 +3708,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeDynasty, - kFeatures640, + kFeatures640x480, "lda1.stk", 0, 0 }, { @@ -3606,7 +3722,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, - kFeatures640, + kFeatures640x480 | kFeaturesTrueColor, 0, 0, 0 }, { // Supplied by gamin in the forums @@ -3620,7 +3736,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, - kFeatures640, + kFeatures640x480 | kFeaturesTrueColor, 0, 0, 0 }, { // Supplied by jvprat on #scummvm @@ -3634,7 +3750,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, - kFeatures640, + kFeatures640x480 | kFeaturesTrueColor, 0, 0, 0 }, { // Supplied by goodoldgeorg in bug report #2770340 @@ -3648,7 +3764,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, - kFeatures640, + kFeatures640x480 | kFeaturesTrueColor, 0, 0, 0 }, { @@ -3667,7 +3783,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeUrban, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesTrueColor | kFeaturesSCNDemo, 0, 0, 2 }, { @@ -3685,7 +3801,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3703,7 +3819,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3721,7 +3837,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { // Supplied by scoriae in the forums @@ -3739,7 +3855,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3762,7 +3878,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesSCNDemo, 0, 0, 3 }, { @@ -3780,7 +3896,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesSCNDemo, 0, 0, 4 }, { @@ -3802,7 +3918,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesSCNDemo, 0, 0, 5 }, { @@ -3823,7 +3939,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesSCNDemo, 0, 0, 6 }, { @@ -3841,7 +3957,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3859,7 +3975,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3877,7 +3993,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { // Supplied by scoriae in the forums @@ -3895,7 +4011,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3913,7 +4029,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3931,7 +4047,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3949,7 +4065,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -3967,7 +4083,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { // Supplied by Hkz on #scummvm @@ -3985,7 +4101,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -4003,7 +4119,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { //Supplied by goodoldgeorg in bug report #2820006 @@ -4021,7 +4137,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -4039,7 +4155,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -4057,7 +4173,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBambou, - kFeatures640, + kFeatures640x480, "intro.stk", "intro.tot", 0 }, { @@ -4075,7 +4191,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -4093,7 +4209,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -4111,7 +4227,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, "intro2.stk", 0, 0 }, { @@ -4139,7 +4255,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { // Found in french ADI 2 Francais-Maths CE2. Exact version not specified. @@ -4153,7 +4269,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4181,7 +4297,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4195,7 +4311,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4209,7 +4325,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4223,7 +4339,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4237,7 +4353,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4251,7 +4367,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", "ediintro.tot", 0 }, { @@ -4271,7 +4387,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeAdi2, - kFeatures640 | kFeaturesSCNDemo, + kFeatures640x480 | kFeaturesSCNDemo, 0, 0, 1 }, { @@ -4285,7 +4401,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4299,7 +4415,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4313,7 +4429,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4327,7 +4443,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4341,7 +4457,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4355,7 +4471,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4411,7 +4527,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4439,7 +4555,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4453,7 +4569,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO_NONE }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { @@ -4751,7 +4867,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //9 @@ -4807,7 +4923,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, - kFeaturesCD, + kFeaturesCD | kFeaturesTrueColor, 0, 0, 0 }, { //13 @@ -4821,7 +4937,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //14 @@ -4835,7 +4951,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //15 @@ -4849,7 +4965,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //16 @@ -4863,7 +4979,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //17 @@ -4877,7 +4993,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //18 @@ -4891,7 +5007,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoons, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //19 @@ -4905,7 +5021,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBambou, - kFeatures640, + kFeatures640x480, 0, 0, 0 }, { //20 @@ -4947,7 +5063,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeAdi2, - kFeatures640, + kFeatures640x480, "adi2.stk", 0, 0 }, { //23 @@ -4961,7 +5077,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeAdi4, - kFeatures640, + kFeatures640x480, "adif41.stk", 0, 0 }, { //24 @@ -4975,7 +5091,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO_NONE }, kGameTypeUrban, - kFeaturesAdLib | kFeatures640 | kFeaturesSCNDemo, + kFeaturesAdLib | kFeatures640x480 | kFeaturesSCNDemo, "", "", 8 } }; diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index b572ccb566..960f4e9e34 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -263,10 +263,10 @@ void Draw::blitInvalidated() { _vm->_video->_doRangeClamp = false; for (int i = 0; i < _invalidatedCount; i++) { - _vm->_video->drawSprite(*_backSurface, *_frontSurface, + _frontSurface->blit(*_backSurface, _invalidatedLefts[i], _invalidatedTops[i], _invalidatedRights[i], _invalidatedBottoms[i], - _invalidatedLefts[i], _invalidatedTops[i], 0); + _invalidatedLefts[i], _invalidatedTops[i]); _vm->_video->dirtyRectsAdd(_invalidatedLefts[i], _invalidatedTops[i], _invalidatedRights[i], _invalidatedBottoms[i]); } @@ -300,7 +300,7 @@ void Draw::dirtiedRect(int16 surface, dirtiedRect(_spritesArray[surface], left, top, right, bottom); } -void Draw::dirtiedRect(SurfaceDescPtr surface, +void Draw::dirtiedRect(SurfacePtr surface, int16 left, int16 top, int16 right, int16 bottom) { if (surface == _backSurface) @@ -316,7 +316,7 @@ void Draw::initSpriteSurf(int16 index, int16 width, int16 height, _spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); - _vm->_video->clearSurf(*_spritesArray[index]); + _spritesArray[index]->clear(); } void Draw::adjustCoords(char adjust, int16 *coord1, int16 *coord2) { @@ -381,14 +381,14 @@ int Draw::stringLength(const char *str, int16 fontIndex) { } void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, SurfaceDesc &dest, const Font &font) { + int16 transp, Surface &dest, const Font &font) { while (*str != '\0') { const int16 charRight = x + font.getCharWidth(*str); const int16 charBottom = y + font.getCharHeight(); if ((charRight <= dest.getWidth()) && (charBottom <= dest.getHeight())) - _vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest); + font.drawLetter(dest, *str, x, y, color1, color2, transp); x += font.getCharWidth(*str); str++; @@ -530,777 +530,6 @@ void Draw::oPlaytoons_sub_F_1B(uint16 id, int16 left, int16 top, int16 right, in return; } -void Draw::activeWin(int16 id) { - bool found = false; - int16 t[10], t2[10]; - int nextId = -1; - int oldId = -1; - SurfaceDescPtr tempSrf; - SurfaceDescPtr oldSrf[10]; - - if (_fascinWin[id].id == -1) - return; - - blitInvalidated(); - - for (int i = 0; i < 10; i++) { - t[i] = -1; - t2[i] = -1; - oldSrf[i].reset(); - } - - for (int i = 0; i < 10; i++) - if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id) && (winOverlap(i, id))) { - t[_fascinWin[i].id] = i; - found = true; - } - - if (found) { - for (int i = 9; i >= 0; i--) { - if (t[i] != -1) { - if (nextId != -1) - _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, - _fascinWin[t[i]].left, _fascinWin[t[i]].top, - _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, - _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1, - _fascinWin[t[i]].left & 7, 0, 0); - t2[i] = nextId; - restoreWin(t[i]); - nextId = t[i]; - } - } - - oldId = nextId; - _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, - _fascinWin[id].left, _fascinWin[id].top, - _fascinWin[id].left + _fascinWin[id].width - 1, - _fascinWin[id].top + _fascinWin[id].height - 1, - _fascinWin[id].left & 7, 0, 0); - restoreWin(id); - nextId = id; - - for (int i = 0; i < 10; i++) { - if (t[i] != -1) { - _vm->_video->drawSprite(*_backSurface, *_fascinWin[nextId].savedSurface, - _fascinWin[t[i]].left, _fascinWin[t[i]].top, - _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, - _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1, - _fascinWin[t[i]].left & 7, 0, 0); - oldSrf[t[i]] = _fascinWin[nextId].savedSurface; - if (t2[i] != -1) - _vm->_video->drawSprite(*_fascinWin[t2[i]].savedSurface, *_backSurface, - _fascinWin[t[i]].left & 7, 0, - (_fascinWin[t[i]].left & 7) + _fascinWin[t[i]].width - 1, - _fascinWin[t[i]].height - 1, _fascinWin[t[i]].left, - _fascinWin[t[i]].top, 0); - else { - // Shift skipped as always set to zero (?) - _vm->_video->drawSprite(*_frontSurface, *_backSurface, - _fascinWin[t[i]].left, _fascinWin[t[i]].top, - _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, - _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1, - _fascinWin[t[i]].left, _fascinWin[t[i]].top, 0); - } - invalidateRect(_fascinWin[t[i]].left, _fascinWin[t[i]].top, - _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, - _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1); - nextId = t2[i]; - } - } - - tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0); - _vm->_video->drawSprite(*_backSurface, *tempSrf, - _fascinWin[id].left, _fascinWin[id].top, - _fascinWin[id].left + _fascinWin[id].width - 1, - _fascinWin[id].top + _fascinWin[id].height - 1, - _fascinWin[id].left & 7, 0, 0); - _vm->_video->drawSprite(*_fascinWin[oldId].savedSurface, *_backSurface, - _fascinWin[id].left & 7, 0, - (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, - _fascinWin[id].height - 1, - _fascinWin[id].left, _fascinWin[id].top, 0); - - _fascinWin[oldId].savedSurface.reset(); - _fascinWin[oldId].savedSurface = tempSrf; - oldSrf[id] = _fascinWin[oldId].savedSurface; - - invalidateRect(_fascinWin[id].left, _fascinWin[id].top, - _fascinWin[id].left + _fascinWin[id].width - 1, - _fascinWin[id].top + _fascinWin[id].height - 1); - nextId = id; - - for (int j = 0; j < 10; j++) { - if (oldSrf[j]!=0) - _fascinWin[j].savedSurface = oldSrf[j]; - } - } - - for (int i = 0; i < 10; i++) { - if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id)) - _fascinWin[i].id--; - } - - _fascinWin[id].id = _winCount - 1; -} - -bool Draw::winOverlap(int16 idWin1, int16 idWin2) { - if ((_fascinWin[idWin1].left + _fascinWin[idWin1].width <= _fascinWin[idWin2].left) || - (_fascinWin[idWin2].left + _fascinWin[idWin2].width <= _fascinWin[idWin1].left) || - (_fascinWin[idWin1].top + _fascinWin[idWin1].height <= _fascinWin[idWin2].top ) || - (_fascinWin[idWin2].top + _fascinWin[idWin2].height <= _fascinWin[idWin1].top )) - return false; - - return true; -} - -void Draw::closeWin(int16 i) { - if (_fascinWin[i].id == -1) - return; - - WRITE_VAR((_winVarArrayStatus / 4) + i, VAR((_winVarArrayStatus / 4) + i) | 1); - restoreWin(i); - _fascinWin[i].id = -1; - _fascinWin[i].savedSurface.reset(); - _winCount--; -} - -void Draw::closeAllWin() { - for (int i = 0; i < 10; i++){ - activeWin(i); - closeWin(i); - } -} - -int16 Draw::openWin(int16 id) { - if (_fascinWin[id].id != -1) - return 0; - - _fascinWin[id].id = _winCount++; - _fascinWin[id].left = VAR((_winVarArrayLeft / 4) + id); - _fascinWin[id].top = VAR((_winVarArrayTop / 4) + id); - _fascinWin[id].width = VAR((_winVarArrayWidth / 4) + id); - _fascinWin[id].height = VAR((_winVarArrayHeight / 4) + id); - - _fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0); - - saveWin(id); - WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) & 0xFFFFFFFE); - - return 1; -} - -void Draw::restoreWin(int16 i) { - _vm->_video->drawSprite(*_fascinWin[i].savedSurface, *_backSurface, - _fascinWin[i].left & 7, 0, - (_fascinWin[i].left & 7) + _fascinWin[i].width - 1, _fascinWin[i].height - 1, - _fascinWin[i].left, _fascinWin[i].top, 0); - invalidateRect(_fascinWin[i].left, _fascinWin[i].top, - _fascinWin[i].left + _fascinWin[i].width - 1, - _fascinWin[i].top + _fascinWin[i].height - 1); -} - -void Draw::saveWin(int16 id) { - _vm->_video->drawSprite(*_backSurface, *_fascinWin[id].savedSurface, - _fascinWin[id].left, _fascinWin[id].top, - _fascinWin[id].left + _fascinWin[id].width - 1, - _fascinWin[id].top + _fascinWin[id].height - 1, - _fascinWin[id].left & 7, 0, 0); -} - -void Draw::winMove(int16 id) { - int oldLeft = _fascinWin[id].left; - int oldTop = _fascinWin[id].top; - - restoreWin(id); - - _fascinWin[id].left = _vm->_global->_inter_mouseX; - _fascinWin[id].top = _vm->_global->_inter_mouseY; - - WRITE_VAR((_winVarArrayLeft / 4) + id, _fascinWin[id].left); - WRITE_VAR((_winVarArrayTop / 4) + id, _fascinWin[id].top); - - saveWin(id); - - // Shift skipped as always set to zero (?) - _vm->_video->drawSprite(*_frontSurface, *_backSurface, - oldLeft, oldTop, - oldLeft + _fascinWin[id].width - 1, - oldTop + _fascinWin[id].height - 1, - _fascinWin[id].left, _fascinWin[id].top, 0); - invalidateRect(_fascinWin[id].left, _fascinWin[id].top, - _fascinWin[id].left + _fascinWin[id].width - 1, - _fascinWin[id].top + _fascinWin[id].height - 1); -} - -void Draw::winTrace(int16 left, int16 top, int16 width, int16 height) { - // TODO: Implement proper behavior for the trace of the Window. In short, - // - drawline currently use the wrong surface, to be fixed - // - dirtiedRect should be put after the 4 drawlines when the surface is fixed <- Not in 256 col version - // - drawline should be replaced by a drawline with palette inversion - // - Shift skipped as always set to zero (?) - - int16 right, bottom; - - right = left + width - 1; - bottom = top + height - 1; - -// To be fixed : either wrong surface, or anything else, but crappy look. -// _vm->_video->drawLine(*_frontSurface, left, top, right, top, 0); -// _vm->_video->drawLine(*_frontSurface, left, top, left, bottom, 0); -// _vm->_video->drawLine(*_frontSurface, left, bottom, right, bottom, 0); -// _vm->_video->drawLine(*_frontSurface, right, top, right, bottom, 0); - -// Not in 256 col version - _vm->_video->dirtyRectsAll(); - -} - -void Draw::handleWinBorder(int16 id) { - int16 minX = 0; - int16 maxX = 320; - int16 minY = 0; - int16 maxY = 200; - - if (VAR((_winVarArrayStatus / 4) + id) & 8) - minX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) >> 16L); - if (VAR((_winVarArrayStatus / 4) + id) & 16) - maxX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) & 0xFFFFL); - if (VAR((_winVarArrayStatus / 4) + id) & 32) - minY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) >> 16L); - if (VAR((_winVarArrayStatus / 4) + id) & 64) - maxY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) & 0xFFFFL); - - _vm->_global->_inter_mouseX = _fascinWin[id].left; - _vm->_global->_inter_mouseY = _fascinWin[id].top; - - if (_vm->_global->_mousePresent) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - - winTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height); - _cursorX = _vm->_global->_inter_mouseX; - _cursorY = _vm->_global->_inter_mouseY; - - do { - _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 1); - - if (_vm->_global->_inter_mouseX != _cursorX || _vm->_global->_inter_mouseY != _cursorY) { - if (_vm->_global->_inter_mouseX < minX) { - _vm->_global->_inter_mouseX = minX; - if (_vm->_global->_mousePresent) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - } - - if (_vm->_global->_inter_mouseY < minY) { - _vm->_global->_inter_mouseY = minY; - if (_vm->_global->_mousePresent) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - } - - if (_vm->_global->_inter_mouseX + _fascinWin[id].width > maxX) { - _vm->_global->_inter_mouseX = maxX - _fascinWin[id].width; - if (_vm->_global->_mousePresent) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - } - - if (_vm->_global->_inter_mouseY + _fascinWin[id].height > maxY) { - _vm->_global->_inter_mouseY = maxY - _fascinWin[id].height; - if (_vm->_global->_mousePresent) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - } - - winTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); - winTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height); - _cursorX = _vm->_global->_inter_mouseX; - _cursorY = _vm->_global->_inter_mouseY; - } - } while (_vm->_game->_mouseButtons); - winTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); - _cursorX = _vm->_global->_inter_mouseX; - _cursorY = _vm->_global->_inter_mouseY; -} - -int16 Draw::handleCurWin() { - int8 matchNum = 0; - int16 bestMatch = -1; - - if ((_vm->_game->_mouseButtons != 1) || ((_renderFlags & 128) == 0)) - return 0; - - for (int i = 0; i < 10; i++) - if (_fascinWin[i].id != -1) { - if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) && - (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) && - (_vm->_global->_inter_mouseY >= _fascinWin[i].top) && - (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) { - - if (_fascinWin[i].id == _winCount - 1) { - if ((_vm->_global->_inter_mouseX < _fascinWin[i].left + 12) && - (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) && - (VAR(_winVarArrayStatus / 4 + i) & 2)) { - - blitCursor(); - activeWin(i); - closeWin(i); - _vm->_util->waitMouseRelease(1); - return i; - } - - if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left + _fascinWin[i].width - 12) && - (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) && - (VAR(_winVarArrayStatus / 4 + i) & 4) && - (_vm->_global->_mousePresent) && - (_vm->_global->_videoMode != 0x07)) { - - blitCursor(); - handleWinBorder(i); - winMove(i); - _vm->_global->_inter_mouseX = _fascinWin[i].left + _fascinWin[i].width - 11; - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - return -i; - } - - return 0; - - } else - if (_fascinWin[i].id > bestMatch) { - bestMatch = _fascinWin[i].id; - matchNum = i; - } - } - } - if (bestMatch != -1) { - warning("handleCurWin - activeWin %d", matchNum); - blitCursor(); - activeWin(matchNum); - } - - return 0; -} - -void Draw::winDecomp(int16 x, int16 y, SurfaceDescPtr destPtr) { - Resource *resource; - resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, - &_spriteRight, &_spriteBottom); - - if (!resource) - return; - - _vm->_video->drawPackedSprite(resource->getData(), - _spriteRight, _spriteBottom, x, y, _transparency, *destPtr); - - delete resource; - return; -} - -void Draw::winDraw(int16 fct) { - int16 left; - int16 top; - int16 width; - int16 height; - - bool found = false; - int len; - Resource *resource; - int table[10]; - SurfaceDescPtr tempSrf; - - if (_destSurface == kBackSurface) { - - if (_vm->_global->_curWinId) { - if (_fascinWin[_vm->_global->_curWinId].id == -1) - return; - - else { - _destSpriteX += _fascinWin[_vm->_global->_curWinId].left; - _destSpriteY += _fascinWin[_vm->_global->_curWinId].top; - if (fct == 3 || (fct >= 7 && fct <= 9)) { - _spriteRight += _fascinWin[_vm->_global->_curWinId].left; - _spriteBottom += _fascinWin[_vm->_global->_curWinId].top; - } - } - } - - left = _destSpriteX; - top = _destSpriteY; - - } else { - if (_vm->_global->_curWinId) { - if (_fascinWin[_vm->_global->_curWinId].id == -1) - return; - else { - _spriteLeft += _fascinWin[_vm->_global->_curWinId].left; - _spriteTop += _fascinWin[_vm->_global->_curWinId].top; - } - } - - left = _spriteLeft; - top = _spriteTop; - } - - for (int i = 0; i < 10; i++) - table[i] = 0; - - switch (fct) { - case DRAW_BLITSURF: // 0 - move - case DRAW_FILLRECT: // 2 - fill rectangle - width = left + _spriteRight - 1; - height = top + _spriteBottom - 1; - break; - - case DRAW_PUTPIXEL: // 1 - put a pixel - width = _destSpriteX; - height = _destSpriteY; - break; - - case DRAW_DRAWLINE: // 3 - draw line - case DRAW_DRAWBAR: // 7 - draw border - case DRAW_CLEARRECT: // 8 - clear rectangle - case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates - width = _spriteRight; - height = _spriteBottom; - break; - - case DRAW_INVALIDATE: // 4 - Draw a circle - left = _destSpriteX - _spriteRight; - top = _destSpriteY - _spriteRight; - width = _destSpriteX + _spriteRight; - height = _destSpriteY + _spriteBottom; - break; - - case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite - // TODO: check the implementation, currently dirty cut and paste of DRAW_SPRITE code - resource = _vm->_game->_resources->getResource((_spriteLeft & 0x3FFF), - &_spriteRight, &_spriteBottom); - - if (!resource) { - width = 0; - height = 0; - break; - } - - _vm->_video->drawPackedSprite(resource->getData(), - _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, - _transparency, *_spritesArray[_destSurface]); - - dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); - - delete resource; - - width = _destSpriteX + _spriteRight - 1; - height = _destSpriteY + _spriteBottom - 1; - break; - - case DRAW_PRINTTEXT: // 6 - Display string - width = _destSpriteX - 1 + strlen(_textToPrint) * _fonts[_fontIndex]->getCharWidth(); - height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight(); - break; - - case DRAW_DRAWLETTER: // 10 - Display a character - if (_fontToSprite[_fontIndex].sprite == -1) { - width = _destSpriteX - 1 + _fonts[_fontIndex]->getCharWidth(); - height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight(); - } else { - width = _destSpriteX + _fontToSprite[_fontIndex].width - 1; - height = _destSpriteY + _fontToSprite[_fontIndex].height - 1; - } - break; - - default: - width = 0; - height = 0; - warning("Unexpected fct value %d", fct); - break; - } - - for (int i = 0; i < 10; i++) - if ((i != _vm->_global->_curWinId) && (_fascinWin[i].id != -1)) - if (!_vm->_global->_curWinId || _fascinWin[i].id>_fascinWin[_vm->_global->_curWinId].id) - if ((_fascinWin[i].left + _fascinWin[i].width > left) && (width >= _fascinWin[i].left) && - (_fascinWin[i].top + _fascinWin[i].height > top ) && (height >= _fascinWin[i].top)) { - found = true; - table[_fascinWin[i].id] = i; - } - - if ((_sourceSurface == kBackSurface) && (fct == 0)) { - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface], - _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); - if (!found) - return; - - int j = 0; - if (_vm->_global->_curWinId != 0) - j = _fascinWin[_vm->_global->_curWinId].id + 1; - - for (int i = 9; i >= j; i--) { - if (table[i]) - _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *_spritesArray[_destSurface], - _fascinWin[table[i]].left & 7, 0, - (_fascinWin[table[i]].left & 7) + _fascinWin[table[i]].width - 1, - _fascinWin[table[i]].height - 1, _fascinWin[table[i]].left - _spriteLeft + _destSpriteX, - _fascinWin[table[i]].top - _spriteTop + _destSpriteY, 0); - } - return; - } - - if (found) { - tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0); - _vm->_video->drawSprite(*_backSurface, *tempSrf, left, top, width, height, 0, 0, 0); - - int max = 0; - if (_vm->_global->_curWinId != 0) - max = _fascinWin[_vm->_global->_curWinId].id + 1; - - for (int i = 9; i >= max; i--) { - if (table[i]) - _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *tempSrf, - _fascinWin[table[i]].left & 7, 0, - (_fascinWin[table[i]].left & 7) + _fascinWin[table[i]].width - 1, - _fascinWin[table[i]].height - 1, - _fascinWin[table[i]].left - left, - _fascinWin[table[i]].top - top , 0); - } - - invalidateRect(left, top, width, height); - - switch (fct) { - case DRAW_BLITSURF: // 0 - move - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *tempSrf, - _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, 0, 0, _transparency); - break; - - case DRAW_PUTPIXEL: // 1 - put a pixel - _vm->_video->putPixel(0, 0, _frontColor, *tempSrf); - break; - - case DRAW_FILLRECT: // 2 - fill rectangle - _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor); - break; - - case DRAW_DRAWLINE: // 3 - draw line - _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); - break; - - case DRAW_INVALIDATE: // 4 - Draw a circle - _vm->_video->drawCircle(*tempSrf, _spriteRight, _spriteRight, _spriteRight, _frontColor); - break; - - case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite - winDecomp(0, 0, tempSrf); - break; - - case DRAW_PRINTTEXT: // 6 - Display string - len = strlen(_textToPrint); - for (int j = 0; j < len; j++) - _vm->_video->drawLetter(_textToPrint[j], j * _fonts[_fontIndex]->getCharWidth(), 0, - *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); - _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); - break; - - case DRAW_DRAWBAR: // 7 - draw border - _vm->_video->drawLine(*tempSrf, 0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); - _vm->_video->drawLine(*tempSrf, 0, 0, 0, _spriteBottom - _destSpriteY, _frontColor); - _vm->_video->drawLine(*tempSrf, _spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); - _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, 0, _frontColor); - break; - - case DRAW_CLEARRECT: // 8 - clear rectangle - if (_backColor < 16) - _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); - break; - - case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates - _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); - break; - - case DRAW_DRAWLETTER: // 10 - Display a character - if (_fontToSprite[_fontIndex].sprite == -1) { - - if (_letterToPrint) - _vm->_video->drawLetter(_letterToPrint, 0, 0, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); - } else { - int xx, yy, nn; - nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width; - yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height; - xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *tempSrf, - xx, yy, xx + _fontToSprite[_fontIndex].width - 1, - yy + _fontToSprite[_fontIndex].height - 1, 0, 0, _transparency); - } - break; - - default: - warning("Unexpected fct value"); - break; - } - - int i = 0; - if (_vm->_global->_curWinId != 0) - i = _fascinWin[_vm->_global->_curWinId].id + 1; - - for (; i < 10; i++) { - if (table[i]) { - int k = table[i]; - _vm->_video->drawSprite(*tempSrf, *_fascinWin[k].savedSurface, - 0, 0, width - left, height - top, - left - _fascinWin[k].left + (_fascinWin[k].left & 7), - top - _fascinWin[k].top, 0); - // Shift skipped as always set to zero (?) - _vm->_video->drawSprite(*_frontSurface, *tempSrf, - MAX(left , _fascinWin[k].left), - MAX(top , _fascinWin[k].top), - MIN(width , (int16) (_fascinWin[k].left + _fascinWin[k].width - 1)), - MIN(height, (int16) (_fascinWin[k].top + _fascinWin[k].height - 1)), - MAX(left , _fascinWin[k].left) - left, - MAX(top , _fascinWin[k].top) - top, 0); - if (_cursorIndex != -1) - _vm->_video->drawSprite(*_cursorSpritesBack, *tempSrf, - 0, 0, _cursorWidth - 1, _cursorHeight - 1, - _cursorX - left, _cursorY - top, 0); - for (int j = 9; j > i; j--) { - if (table[j] && winOverlap(k, table[j])) { - int l = table[j]; - _vm->_video->drawSprite(*_fascinWin[l].savedSurface, *tempSrf, - MAX(_fascinWin[l].left, _fascinWin[k].left) - - _fascinWin[l].left + (_fascinWin[l].left & 7), - MAX(_fascinWin[l].top , _fascinWin[k].top ) - _fascinWin[l].top, - MIN(_fascinWin[l].left + _fascinWin[l].width - 1, _fascinWin[k].left + _fascinWin[k].width - 1) - - _fascinWin[l].left + (_fascinWin[l].left & 7), - MIN(_fascinWin[l].top + _fascinWin[l].height - 1, _fascinWin[k].top + _fascinWin[k].height - 1) - - _fascinWin[l].top, - MAX(_fascinWin[l].left, _fascinWin[k].left) - left, - MAX(_fascinWin[l].top , _fascinWin[k].top ) - top, 0); - } - } - } - } - _vm->_video->drawSprite(*tempSrf, *_backSurface, 0, 0, width - left, height - top, left, top, 0); - tempSrf.reset(); - } else { - invalidateRect(left, top, width, height); - switch (fct) { - case DRAW_BLITSURF: // 0 - move - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_backSurface, - _spriteLeft, _spriteTop, - _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); - break; - case DRAW_PUTPIXEL: // 1 - put a pixel - _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, *_backSurface); - break; - - case DRAW_FILLRECT: // 2 - fill rectangle - _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); - break; - - case DRAW_DRAWLINE: // 3 - draw line - _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - break; - - case DRAW_INVALIDATE: // 4 - Draw a circle - _vm->_video->drawCircle(*_backSurface, _spriteRight, _spriteRight, _spriteRight, _frontColor); - break; - - case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite - winDecomp(_destSpriteX, _destSpriteY, _backSurface); - break; - - case DRAW_PRINTTEXT: // 6 - Display string - len = strlen(_textToPrint); - for (int j = 0; j < len; j++) - _vm->_video->drawLetter(_textToPrint[j], _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(), - _destSpriteY, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *_backSurface); - _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); - break; - - case DRAW_DRAWBAR: // 7 - draw border - _vm->_video->drawLine(*_backSurface, _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_backSurface, _spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); - break; - - case DRAW_CLEARRECT: // 8 - clear rectangle - if (_backColor < 16) - _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); - break; - - case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates - _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); - break; - - case DRAW_DRAWLETTER: // 10 - Display a character - if (_fontToSprite[_fontIndex].sprite == -1) { - if (_letterToPrint) - _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, *_fonts[_fontIndex], _transparency, - _frontColor, _backColor, *_spritesArray[_destSurface]); - } else { - int xx, yy, nn; - nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width; - yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height; - xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *_spritesArray[_destSurface], - xx, yy, - xx + _fontToSprite[_fontIndex].width - 1, - yy + _fontToSprite[_fontIndex].height - 1, - _destSpriteX, _destSpriteY, _transparency); - } - break; - - default: - warning("Unexpected fct value"); - break; - } - } - - if (_renderFlags & 16) { - if (_sourceSurface == kBackSurface) { - _spriteLeft -= _backDeltaX; - _spriteTop -= _backDeltaY; - } - if (_destSurface == kBackSurface) { - _destSpriteX -= _backDeltaX; - _destSpriteY -= _backDeltaY; - } - } - - if (_vm->_global->_curWinId) { - _destSpriteX -= _fascinWin[_vm->_global->_curWinId].left; - _destSpriteY -= _fascinWin[_vm->_global->_curWinId].top; - } -} - -int16 Draw::isOverWin(int16 &dx, int16 &dy) { - int16 bestMatch = -1; - - if ((_renderFlags & 128) == 0) - return -1; - - for (int i = 0; i < 10; i++) - if (_fascinWin[i].id != -1) { - if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) && - (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) && - (_vm->_global->_inter_mouseY >= _fascinWin[i].top) && - (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) { - - if (_fascinWin[i].id == _winCount - 1) { - dx = _fascinWin[i].left; - dy = _fascinWin[i].top; - return(i); - } else - if (_fascinWin[i].id > bestMatch) - bestMatch = _fascinWin[i].id; - } - } - - if (bestMatch != -1) - return(0); - else - return(-1); -} int32 Draw::getSpriteRectSize(int16 index) { if (!_spritesArray[index]) return 0; @@ -1319,14 +548,10 @@ void Draw::forceBlit(bool backwards) { return; if (!backwards) { - _vm->_video->drawSprite(*_backSurface, *_frontSurface, 0, 0, - _backSurface->getWidth() - 1, _backSurface->getHeight() - 1, - 0, 0, 0); + _frontSurface->blit(*_backSurface); _vm->_video->dirtyRectsAll(); } else - _vm->_video->drawSprite(*_frontSurface, *_backSurface, 0, 0, - _frontSurface->getWidth() - 1, _frontSurface->getHeight() - 1, - 0, 0, 0); + _backSurface->blit(*_frontSurface); } @@ -1373,7 +598,7 @@ const int16 Draw::_wobbleTable[360] = { -0x0A03, -0x08E8, -0x07CC, -0x06B0, -0x0593, -0x0476, -0x0359, -0x023B, -0x011D }; -void Draw::wobble(SurfaceDesc &surfDesc) { +void Draw::wobble(Surface &surfDesc) { int16 amplitude = 32; uint16 curFrame = 0; uint16 frameWobble = 0; @@ -1397,16 +622,14 @@ void Draw::wobble(SurfaceDesc &surfDesc) { amplitude--; for (uint16 y = 0; y < _vm->_height; y++) - _vm->_video->drawSprite(surfDesc, *_frontSurface, - 0, y, _vm->_width - 1, y, offsets[y], y, 0); + _frontSurface->blit(surfDesc, 0, y, _vm->_width - 1, y, offsets[y], y); _vm->_palAnim->fadeStep(0); _vm->_video->dirtyRectsAll(); _vm->_video->waitRetrace(); } - _vm->_video->drawSprite(surfDesc, *_frontSurface, - 0, 0, _vm->_width - 1, _vm->_height - 1, 0, 0, 0); + _frontSurface->blit(surfDesc); _applyPal = false; _invalidatedCount = 0; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index fa3cbb84cc..fe37382666 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -66,7 +66,7 @@ public: int16 top; int16 width; int16 height; - SurfaceDescPtr savedSurface; + SurfacePtr savedSurface; }; int16 _renderFlags; @@ -98,7 +98,7 @@ public: FontToSprite _fontToSprite[4]; Font *_fonts[kFontCount]; - Common::Array<SurfaceDescPtr> _spritesArray; + Common::Array<SurfacePtr> _spritesArray; int16 _invalidatedCount; int16 _invalidatedLefts[30]; @@ -112,8 +112,8 @@ public: bool _paletteCleared; bool _applyPal; - SurfaceDescPtr _backSurface; - SurfaceDescPtr _frontSurface; + SurfacePtr _backSurface; + SurfacePtr _frontSurface; int16 _unusedPalette1[18]; int16 _unusedPalette2[16]; @@ -137,9 +137,9 @@ public: int32 _cursorHotspotXVar; int32 _cursorHotspotYVar; - SurfaceDescPtr _cursorSprites; - SurfaceDescPtr _cursorSpritesBack; - SurfaceDescPtr _scummvmCursor; + SurfacePtr _cursorSprites; + SurfacePtr _cursorSpritesBack; + SurfacePtr _scummvmCursor; int16 _cursorAnim; int8 _cursorAnimLow[40]; @@ -174,7 +174,7 @@ public: void clearPalette(); void dirtiedRect(int16 surface, int16 left, int16 top, int16 right, int16 bottom); - void dirtiedRect(SurfaceDescPtr surface, int16 left, int16 top, int16 right, int16 bottom); + void dirtiedRect(SurfacePtr surface, int16 left, int16 top, int16 right, int16 bottom); void initSpriteSurf(int16 index, int16 width, int16 height, int16 flags); void freeSprite(int16 index) { @@ -187,31 +187,16 @@ public: } int stringLength(const char *str, int16 fontIndex); void drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, SurfaceDesc &dest, const Font &font); + int16 transp, Surface &dest, const Font &font); void printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, const char *str, int16 fontIndex, int16 color); void oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 var3, int16 var4, int16 shortId); - int16 openWin(int16 id); - int16 handleCurWin(); - bool winOverlap(int16 idWin1, int16 idWin2); - void winDecomp(int16 x, int16 y, SurfaceDescPtr destPtr); - void activeWin(int16 id); - void closeWin(int16 id); - void closeAllWin(); - void restoreWin(int16 i); - void saveWin(int16 id); - void winMove(int16 id); - void handleWinBorder(int16 id); - void winDraw(int16 fct); - void winTrace(int16 left, int16 top, int16 width, int16 height); - int16 isOverWin(int16 &dx, int16 &dy); - int32 getSpriteRectSize(int16 index); void forceBlit(bool backwards = false); static const int16 _wobbleTable[360]; - void wobble(SurfaceDesc &surfDesc); + void wobble(Surface &surfDesc); Font *loadFont(const char *path) const; bool loadFont(int fontIndex, const char *path); @@ -223,6 +208,15 @@ public: virtual void printTotText(int16 id) = 0; virtual void spriteOperation(int16 operation) = 0; + virtual int16 openWin(int16 id) { return 0; } + virtual void closeWin(int16 id) {} + virtual int16 handleCurWin() { return 0; } + virtual int16 getWinFromCoord(int16 &dx, int16 &dy) { return -1; } + virtual void moveWin(int16 id) {} + virtual bool overlapWin(int16 idWin1, int16 idWin2) { return false; } + virtual void closeAllWin() {} + virtual void activeWin(int16 id) {} + Draw(GobEngine *vm); virtual ~Draw(); @@ -272,6 +266,23 @@ public: Draw_Fascination(GobEngine *vm); virtual ~Draw_Fascination() {} virtual void spriteOperation(int16 operation); + + void decompWin(int16 x, int16 y, SurfacePtr destPtr); + void drawWin(int16 fct); + void saveWin(int16 id); + void restoreWin(int16 id); + void handleWinBorder(int16 id); + void drawWinTrace(int16 left, int16 top, int16 width, int16 height); + + virtual int16 openWin(int16 id); + virtual void closeWin(int16 id); + virtual int16 getWinFromCoord(int16 &dx, int16 &dy); + virtual int16 handleCurWin(); + virtual void activeWin(int16 id); + virtual void moveWin(int16 id); + virtual bool overlapWin(int16 idWin1, int16 idWin2); + virtual void closeAllWin(); + }; class Draw_Playtoons: public Draw_v2 { diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 1e01db7dfb..86e5cb8314 100644 --- a/engines/gob/draw_fascin.cpp +++ b/engines/gob/draw_fascin.cpp @@ -28,6 +28,8 @@ #include "gob/draw.h" #include "gob/game.h" +#include "gob/global.h" +#include "gob/inter.h" #include "gob/resources.h" namespace Gob { @@ -38,7 +40,7 @@ Draw_Fascination::Draw_Fascination(GobEngine *vm) : Draw_v2(vm) { void Draw_Fascination::spriteOperation(int16 operation) { int16 len; int16 x, y; - SurfaceDescPtr sourceSurf, destSurf; + SurfacePtr sourceSurf, destSurf; bool deltaVeto; int16 left; int16 ratio; @@ -71,7 +73,7 @@ void Draw_Fascination::spriteOperation(int16 operation) { if (_renderFlags & 0x20) { if (_destSurface == kBackSurface || (operation == 0 && _sourceSurface == kBackSurface)) { - winDraw(operation); + drawWin(operation); return; } } @@ -147,26 +149,24 @@ void Draw_Fascination::spriteOperation(int16 operation) { if (!sourceSurf || !destSurf) break; - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], - *_spritesArray[_destSurface], + _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface], _spriteLeft, spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: - _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, - *_spritesArray[_destSurface]); + _spritesArray[_destSurface]->putPixel(_destSpriteX, _destSpriteY, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: - _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX, + _spritesArray[_destSurface]->fillRect(destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); @@ -175,15 +175,14 @@ void Draw_Fascination::spriteOperation(int16 operation) { break; case DRAW_DRAWLINE: - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_INVALIDATE: - _vm->_video->drawCircle(*_spritesArray[_destSurface], _destSpriteX, + _spritesArray[_destSurface]->drawCircle(_destSpriteX, _destSpriteY, _spriteRight, _frontColor); dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, @@ -225,9 +224,8 @@ void Draw_Fascination::spriteOperation(int16 operation) { byte *dataBuf = _vm->_game->_resources->getTexts() + _textToPrint[1] + 1; len = *dataBuf++; for (int i = 0; i < len; i++, dataBuf += 2) { - _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, - _destSpriteY, *font, _transparency, _frontColor, - _backColor, *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], READ_LE_UINT16(dataBuf), + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); } } else { drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, @@ -236,9 +234,8 @@ void Draw_Fascination::spriteOperation(int16 operation) { } } else { for (int i = 0; i < len; i++) { - _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, - _destSpriteY, *font, _transparency, - _frontColor, _backColor, *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], _textToPrint[i], + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); _destSpriteX += font->getCharWidth(_textToPrint[i]); } } @@ -253,11 +250,10 @@ void Draw_Fascination::spriteOperation(int16 operation) { * _fontToSprite[_fontIndex].height; x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio) * _fontToSprite[_fontIndex].width; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], - *_spritesArray[_destSurface], x, y, + _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], x, y, x + _fontToSprite[_fontIndex].width - 1, y + _fontToSprite[_fontIndex].height - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); _destSpriteX += _fontToSprite[_fontIndex].width; } } @@ -268,36 +264,28 @@ void Draw_Fascination::spriteOperation(int16 operation) { case DRAW_DRAWBAR: if (_needAdjust != 2) { - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom - 1, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _spriteBottom - 1, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect( _destSpriteX, _destSpriteY, _destSpriteX + 1, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _spriteRight - 1, _destSpriteY, + _spritesArray[_destSurface]->fillRect( _spriteRight - 1, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect( _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY + 1, _frontColor); } else { - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _spriteRight, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); } @@ -306,19 +294,14 @@ void Draw_Fascination::spriteOperation(int16 operation) { case DRAW_CLEARRECT: if ((_backColor != 16) && (_backColor != 144)) { - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom, - _backColor); + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); } dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_FILLRECTABS: - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom, _backColor); + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; @@ -352,4 +335,783 @@ void Draw_Fascination::spriteOperation(int16 operation) { } } +void Draw_Fascination::drawWin(int16 fct) { + int16 left; + int16 top; + int16 width; + int16 height; + + bool found = false; + int len; + Resource *resource; + int table[10]; + SurfacePtr tempSrf; + + if (_destSurface == kBackSurface) { + + if (_vm->_global->_curWinId) { + if (_fascinWin[_vm->_global->_curWinId].id == -1) + return; + + else { + _destSpriteX += _fascinWin[_vm->_global->_curWinId].left; + _destSpriteY += _fascinWin[_vm->_global->_curWinId].top; + if (fct == 3 || (fct >= 7 && fct <= 9)) { + _spriteRight += _fascinWin[_vm->_global->_curWinId].left; + _spriteBottom += _fascinWin[_vm->_global->_curWinId].top; + } + } + } + + left = _destSpriteX; + top = _destSpriteY; + + } else { + if (_vm->_global->_curWinId) { + if (_fascinWin[_vm->_global->_curWinId].id == -1) + return; + else { + _spriteLeft += _fascinWin[_vm->_global->_curWinId].left; + _spriteTop += _fascinWin[_vm->_global->_curWinId].top; + } + } + + left = _spriteLeft; + top = _spriteTop; + } + + for (int i = 0; i < 10; i++) + table[i] = 0; + + switch (fct) { + case DRAW_BLITSURF: // 0 - move + case DRAW_FILLRECT: // 2 - fill rectangle + width = left + _spriteRight - 1; + height = top + _spriteBottom - 1; + break; + + case DRAW_PUTPIXEL: // 1 - put a pixel + width = _destSpriteX; + height = _destSpriteY; + break; + + case DRAW_DRAWLINE: // 3 - draw line + case DRAW_DRAWBAR: // 7 - draw border + case DRAW_CLEARRECT: // 8 - clear rectangle + case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates + width = _spriteRight; + height = _spriteBottom; + break; + + case DRAW_INVALIDATE: // 4 - Draw a circle + left = _destSpriteX - _spriteRight; + top = _destSpriteY - _spriteRight; + width = _destSpriteX + _spriteRight; + height = _destSpriteY + _spriteBottom; + break; + + case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite + // TODO: check the implementation, currently dirty cut and paste of DRAW_SPRITE code + resource = _vm->_game->_resources->getResource((_spriteLeft & 0x3FFF), + &_spriteRight, &_spriteBottom); + + if (!resource) { + width = 0; + height = 0; + break; + } + + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, *_spritesArray[_destSurface]); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + + delete resource; + + width = _destSpriteX + _spriteRight - 1; + height = _destSpriteY + _spriteBottom - 1; + break; + + case DRAW_PRINTTEXT: // 6 - Display string + width = _destSpriteX - 1 + strlen(_textToPrint) * _fonts[_fontIndex]->getCharWidth(); + height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight(); + break; + + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) { + width = _destSpriteX - 1 + _fonts[_fontIndex]->getCharWidth(); + height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight(); + } else { + width = _destSpriteX + _fontToSprite[_fontIndex].width - 1; + height = _destSpriteY + _fontToSprite[_fontIndex].height - 1; + } + break; + + default: + error("winDraw - Unexpected fct value %d", fct); + break; + } + + for (int i = 0; i < 10; i++) { + if ((i != _vm->_global->_curWinId) && (_fascinWin[i].id != -1)) { + if (!_vm->_global->_curWinId || _fascinWin[i].id>_fascinWin[_vm->_global->_curWinId].id) { + if ((_fascinWin[i].left + _fascinWin[i].width > left) && (width >= _fascinWin[i].left) && + (_fascinWin[i].top + _fascinWin[i].height > top ) && (height >= _fascinWin[i].top)) { + found = true; + table[_fascinWin[i].id] = i; + } + } + } + } + + if ((_sourceSurface == kBackSurface) && (fct == 0)) { + _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface], + _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); + if (!found) + return; + + int j = 0; + if (_vm->_global->_curWinId != 0) + j = _fascinWin[_vm->_global->_curWinId].id + 1; + + for (int i = 9; i >= j; i--) { + if (table[i]) + _spritesArray[_destSurface]->blit(*_fascinWin[table[i]].savedSurface, + _fascinWin[table[i]].left & 7, 0, + (_fascinWin[table[i]].left & 7) + _fascinWin[table[i]].width - 1, + _fascinWin[table[i]].height - 1, _fascinWin[table[i]].left - _spriteLeft + _destSpriteX, + _fascinWin[table[i]].top - _spriteTop + _destSpriteY); + } + return; + } + + if (found) { + tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0); + tempSrf->blit(*_backSurface, left, top, width, height, 0, 0); + + int max = 0; + if (_vm->_global->_curWinId != 0) + max = _fascinWin[_vm->_global->_curWinId].id + 1; + + for (int i = 9; i >= max; i--) { + if (table[i]) + tempSrf->blit(*_fascinWin[table[i]].savedSurface, + _fascinWin[table[i]].left & 7, 0, + (_fascinWin[table[i]].left & 7) + _fascinWin[table[i]].width - 1, + _fascinWin[table[i]].height - 1, + _fascinWin[table[i]].left - left, + _fascinWin[table[i]].top - top); + } + + invalidateRect(left, top, width, height); + + switch (fct) { + case DRAW_BLITSURF: // 0 - move + tempSrf->blit(*_spritesArray[_sourceSurface], + _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, 0, 0, (_transparency == 0) ? -1 : 0); + break; + + case DRAW_PUTPIXEL: // 1 - put a pixel + tempSrf->putPixel(0, 0, _frontColor); + break; + + case DRAW_FILLRECT: // 2 - fill rectangle + tempSrf->fillRect(0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor); + break; + + case DRAW_DRAWLINE: // 3 - draw line + tempSrf->drawLine(0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + break; + + case DRAW_INVALIDATE: // 4 - Draw a circle + tempSrf->drawCircle(_spriteRight, _spriteRight, _spriteRight, _frontColor); + break; + + case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite + decompWin(0, 0, tempSrf); + break; + + case DRAW_PRINTTEXT: // 6 - Display string + len = strlen(_textToPrint); + for (int j = 0; j < len; j++) + _fonts[_fontIndex]->drawLetter(*tempSrf, _textToPrint[j], + j * _fonts[_fontIndex]->getCharWidth(), 0, _frontColor, _backColor, _transparency); + _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); + break; + + case DRAW_DRAWBAR: // 7 - draw border + tempSrf->drawLine(0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + tempSrf->drawLine(0, 0, 0, _spriteBottom - _destSpriteY, _frontColor); + tempSrf->drawLine(_spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + tempSrf->drawLine(0, 0, _spriteRight - _destSpriteX, 0, _frontColor); + break; + + case DRAW_CLEARRECT: // 8 - clear rectangle + if (_backColor < 16) + tempSrf->fillRect(0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); + break; + + case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates + tempSrf->fillRect(0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); + break; + + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) { + + if (_letterToPrint) + _fonts[_fontIndex]->drawLetter(*tempSrf, _letterToPrint, 0, 0, _frontColor, _backColor, _transparency); + } else { + int xx, yy, nn; + nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width; + yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height; + xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width; + tempSrf->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], + xx, yy, xx + _fontToSprite[_fontIndex].width - 1, + yy + _fontToSprite[_fontIndex].height - 1, 0, 0, (_transparency == 0) ? -1 : 0); + } + break; + + default: + error("winDraw - Unexpected fct value %d", fct); + break; + } + + int i = 0; + if (_vm->_global->_curWinId != 0) + i = _fascinWin[_vm->_global->_curWinId].id + 1; + + for (; i < 10; i++) { + if (table[i]) { + int k = table[i]; + _fascinWin[k].savedSurface->blit(*tempSrf, + 0, 0, width - left, height - top, + left - _fascinWin[k].left + (_fascinWin[k].left & 7), + top - _fascinWin[k].top); + // Shift skipped as always set to zero (?) + tempSrf->blit(*_frontSurface, + MAX(left , _fascinWin[k].left), + MAX(top , _fascinWin[k].top), + MIN(width , (int16) (_fascinWin[k].left + _fascinWin[k].width - 1)), + MIN(height, (int16) (_fascinWin[k].top + _fascinWin[k].height - 1)), + MAX(left , _fascinWin[k].left) - left, + MAX(top , _fascinWin[k].top) - top); + if (_cursorIndex != -1) + tempSrf->blit(*_cursorSpritesBack, + 0, 0, _cursorWidth - 1, _cursorHeight - 1, + _cursorX - left, _cursorY - top); + for (int j = 9; j > i; j--) { + if (table[j] && overlapWin(k, table[j])) { + int l = table[j]; + tempSrf->blit(*_fascinWin[l].savedSurface, + MAX(_fascinWin[l].left, _fascinWin[k].left) + - _fascinWin[l].left + (_fascinWin[l].left & 7), + MAX(_fascinWin[l].top , _fascinWin[k].top ) - _fascinWin[l].top, + MIN(_fascinWin[l].left + _fascinWin[l].width - 1, _fascinWin[k].left + _fascinWin[k].width - 1) + - _fascinWin[l].left + (_fascinWin[l].left & 7), + MIN(_fascinWin[l].top + _fascinWin[l].height - 1, _fascinWin[k].top + _fascinWin[k].height - 1) + - _fascinWin[l].top, + MAX(_fascinWin[l].left, _fascinWin[k].left) - left, + MAX(_fascinWin[l].top , _fascinWin[k].top ) - top); + } + } + } + } + _backSurface->blit(*tempSrf, 0, 0, width - left, height - top, left, top); + tempSrf.reset(); + } else { + invalidateRect(left, top, width, height); + switch (fct) { + case DRAW_BLITSURF: // 0 - move + _backSurface->blit(*_spritesArray[_sourceSurface], + _spriteLeft, _spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); + break; + case DRAW_PUTPIXEL: // 1 - put a pixel + _backSurface->putPixel(_destSpriteX, _destSpriteY, _frontColor); + break; + + case DRAW_FILLRECT: // 2 - fill rectangle + _backSurface->fillRect(_destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); + break; + + case DRAW_DRAWLINE: // 3 - draw line + _backSurface->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); + break; + + case DRAW_INVALIDATE: // 4 - Draw a circle + _backSurface->drawCircle(_spriteRight, _spriteRight, _spriteRight, _frontColor); + break; + + case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite + decompWin(_destSpriteX, _destSpriteY, _backSurface); + break; + + case DRAW_PRINTTEXT: // 6 - Display string + len = strlen(_textToPrint); + for (int j = 0; j < len; j++) + _fonts[_fontIndex]->drawLetter(*_backSurface, _textToPrint[j], + _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(), _destSpriteY, + _frontColor, _backColor, _transparency); + _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); + break; + + case DRAW_DRAWBAR: // 7 - draw border + _backSurface->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); + _backSurface->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); + _backSurface->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); + _backSurface->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); + break; + + case DRAW_CLEARRECT: // 8 - clear rectangle + if (_backColor < 16) + _backSurface->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); + break; + + case DRAW_FILLRECTABS: // 9 - fill rectangle, with other coordinates + _backSurface->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); + break; + + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) { + if (_letterToPrint) + _fonts[_fontIndex]->drawLetter(*_spritesArray[_destSurface], _letterToPrint, + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); + } else { + int xx, yy, nn; + nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width; + yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height; + xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width; + _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], + xx, yy, + xx + _fontToSprite[_fontIndex].width - 1, + yy + _fontToSprite[_fontIndex].height - 1, + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); + } + break; + + default: + error("winDraw - Unexpected fct value"); + break; + } + } + + if (_renderFlags & 16) { + if (_sourceSurface == kBackSurface) { + _spriteLeft -= _backDeltaX; + _spriteTop -= _backDeltaY; + } + if (_destSurface == kBackSurface) { + _destSpriteX -= _backDeltaX; + _destSpriteY -= _backDeltaY; + } + } + + if (_vm->_global->_curWinId) { + _destSpriteX -= _fascinWin[_vm->_global->_curWinId].left; + _destSpriteY -= _fascinWin[_vm->_global->_curWinId].top; + } +} + +void Draw_Fascination::decompWin(int16 x, int16 y, SurfacePtr destPtr) { + Resource *resource; + resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, + &_spriteRight, &_spriteBottom); + + if (!resource) + return; + + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, x, y, _transparency, *destPtr); + + delete resource; + return; +} + +int16 Draw_Fascination::openWin(int16 id) { + if (_fascinWin[id].id != -1) + return 0; + + _fascinWin[id].id = _winCount++; + _fascinWin[id].left = VAR((_winVarArrayLeft / 4) + id); + _fascinWin[id].top = VAR((_winVarArrayTop / 4) + id); + _fascinWin[id].width = VAR((_winVarArrayWidth / 4) + id); + _fascinWin[id].height = VAR((_winVarArrayHeight / 4) + id); + + _fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0); + + saveWin(id); + WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) & 0xFFFFFFFE); + + return 1; +} + +int16 Draw_Fascination::getWinFromCoord(int16 &dx, int16 &dy) { + int16 bestMatch = -1; + + if ((_renderFlags & 128) == 0) + return -1; + + for (int i = 0; i < 10; i++) { + if (_fascinWin[i].id != -1) { + if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) && + (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) && + (_vm->_global->_inter_mouseY >= _fascinWin[i].top) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) { + + if (_fascinWin[i].id == _winCount - 1) { + dx = _fascinWin[i].left; + dy = _fascinWin[i].top; + return(i); + } else { + if (_fascinWin[i].id > bestMatch) + bestMatch = _fascinWin[i].id; + } + } + } + } + + if (bestMatch != -1) + return(0); + else + return(-1); +} + +void Draw_Fascination::closeWin(int16 id) { + if (_fascinWin[id].id == -1) + return; + + WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) | 1); + restoreWin(id); + _fascinWin[id].id = -1; + _fascinWin[id].savedSurface.reset(); + _winCount--; +} + +int16 Draw_Fascination::handleCurWin() { + int8 matchNum = 0; + int16 bestMatch = -1; + + if ((_vm->_game->_mouseButtons != 1) || ((_renderFlags & 128) == 0)) + return 0; + + for (int i = 0; i < 10; i++) { + if (_fascinWin[i].id != -1) { + if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) && + (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) && + (_vm->_global->_inter_mouseY >= _fascinWin[i].top) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) { + + if (_fascinWin[i].id == _winCount - 1) { + if ((_vm->_global->_inter_mouseX < _fascinWin[i].left + 12) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) && + (VAR(_winVarArrayStatus / 4 + i) & 2)) { + + blitCursor(); + activeWin(i); + closeWin(i); + _vm->_util->waitMouseRelease(1); + return i; + } + + if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left + _fascinWin[i].width - 12) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) && + (VAR(_winVarArrayStatus / 4 + i) & 4) && + (_vm->_global->_mousePresent) && + (_vm->_global->_videoMode != 0x07)) { + + blitCursor(); + handleWinBorder(i); + moveWin(i); + _vm->_global->_inter_mouseX = _fascinWin[i].left + _fascinWin[i].width - 11; + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + return -i; + } + return 0; + } else { + if (_fascinWin[i].id > bestMatch) { + bestMatch = _fascinWin[i].id; + matchNum = i; + } + } + } + } + } + + if (bestMatch != -1) { + blitCursor(); + activeWin(matchNum); + } + + return 0; +} + +void Draw_Fascination::moveWin(int16 id) { + int oldLeft = _fascinWin[id].left; + int oldTop = _fascinWin[id].top; + + restoreWin(id); + + _fascinWin[id].left = _vm->_global->_inter_mouseX; + _fascinWin[id].top = _vm->_global->_inter_mouseY; + + WRITE_VAR((_winVarArrayLeft / 4) + id, _fascinWin[id].left); + WRITE_VAR((_winVarArrayTop / 4) + id, _fascinWin[id].top); + + saveWin(id); + + // Shift skipped as always set to zero (?) + _backSurface->blit(*_frontSurface, + oldLeft, oldTop, + oldLeft + _fascinWin[id].width - 1, + oldTop + _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top); + invalidateRect(_fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1); +} + +bool Draw_Fascination::overlapWin(int16 idWin1, int16 idWin2) { + if ((_fascinWin[idWin1].left + _fascinWin[idWin1].width <= _fascinWin[idWin2].left) || + (_fascinWin[idWin2].left + _fascinWin[idWin2].width <= _fascinWin[idWin1].left) || + (_fascinWin[idWin1].top + _fascinWin[idWin1].height <= _fascinWin[idWin2].top ) || + (_fascinWin[idWin2].top + _fascinWin[idWin2].height <= _fascinWin[idWin1].top )) + return false; + + return true; +} + +void Draw_Fascination::activeWin(int16 id) { + bool found = false; + int16 t[10], t2[10]; + int nextId = -1; + int oldId = -1; + SurfacePtr tempSrf; + SurfacePtr oldSrf[10]; + + if (_fascinWin[id].id == -1) + return; + + blitInvalidated(); + + for (int i = 0; i < 10; i++) { + t[i] = -1; + t2[i] = -1; + oldSrf[i].reset(); + } + + for (int i = 0; i < 10; i++) { + if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id) && (overlapWin(i, id))) { + t[_fascinWin[i].id] = i; + found = true; + } + } + + if (found) { + for (int i = 9; i >= 0; i--) { + if (t[i] != -1) { + if (nextId != -1) + _fascinWin[nextId].savedSurface->blit(*_backSurface, + _fascinWin[t[i]].left, _fascinWin[t[i]].top, + _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, + _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1, + _fascinWin[t[i]].left & 7, 0); + t2[i] = nextId; + restoreWin(t[i]); + nextId = t[i]; + } + } + + oldId = nextId; + _fascinWin[nextId].savedSurface->blit(*_backSurface, + _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1, + _fascinWin[id].left & 7, 0); + restoreWin(id); + nextId = id; + + for (int i = 0; i < 10; i++) { + if (t[i] != -1) { + _fascinWin[nextId].savedSurface->blit(*_backSurface, + _fascinWin[t[i]].left, _fascinWin[t[i]].top, + _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, + _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1, + _fascinWin[t[i]].left & 7, 0); + oldSrf[t[i]] = _fascinWin[nextId].savedSurface; + if (t2[i] != -1) + _backSurface->blit(*_fascinWin[t2[i]].savedSurface, + _fascinWin[t[i]].left & 7, 0, + (_fascinWin[t[i]].left & 7) + _fascinWin[t[i]].width - 1, + _fascinWin[t[i]].height - 1, _fascinWin[t[i]].left, + _fascinWin[t[i]].top); + else { + // Shift skipped as always set to zero (?) + _backSurface->blit(*_frontSurface, + _fascinWin[t[i]].left, _fascinWin[t[i]].top, + _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, + _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1, + _fascinWin[t[i]].left, _fascinWin[t[i]].top); + } + invalidateRect(_fascinWin[t[i]].left, _fascinWin[t[i]].top, + _fascinWin[t[i]].left + _fascinWin[t[i]].width - 1, + _fascinWin[t[i]].top + _fascinWin[t[i]].height - 1); + nextId = t2[i]; + } + } + + tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0); + tempSrf->blit(*_backSurface, + _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1, + _fascinWin[id].left & 7, 0); + _backSurface->blit(*_fascinWin[oldId].savedSurface, + _fascinWin[id].left & 7, 0, + (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, + _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top); + + _fascinWin[oldId].savedSurface.reset(); + _fascinWin[oldId].savedSurface = tempSrf; + oldSrf[id] = _fascinWin[oldId].savedSurface; + + invalidateRect(_fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1); + nextId = id; + + for (int j = 0; j < 10; j++) { + if (oldSrf[j] != 0) + _fascinWin[j].savedSurface = oldSrf[j]; + } + } + + for (int i = 0; i < 10; i++) { + if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id)) + _fascinWin[i].id--; + } + + _fascinWin[id].id = _winCount - 1; +} + +void Draw_Fascination::closeAllWin() { + for (int i = 0; i < 10; i++) { + activeWin(i); + closeWin(i); + } +} + +void Draw_Fascination::saveWin(int16 id) { + _fascinWin[id].savedSurface->blit(*_backSurface, + _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1, + _fascinWin[id].left & 7, 0); +} + +void Draw_Fascination::restoreWin(int16 id) { + _backSurface->blit(*_fascinWin[id].savedSurface, + _fascinWin[id].left & 7, 0, + (_fascinWin[id].left & 7) + _fascinWin[id].width - 1, _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top); + invalidateRect(_fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1); +} + +void Draw_Fascination::drawWinTrace(int16 left, int16 top, int16 width, int16 height) { + int16 right, bottom; + + right = left + width - 1; + bottom = top + height - 1; + + Pixel pixelTop = _frontSurface->get(left, top); + Pixel pixelBottom = _frontSurface->get(left, bottom); + for (int16 i = 0; i < width; i++, pixelTop++, pixelBottom++) { + pixelTop.set((pixelTop.get() + 128) & 0xFF); + pixelBottom.set((pixelBottom.get() + 128) & 0xFF); + } + + Pixel pixelLeft = _frontSurface->get(left, top); + Pixel pixelRight = _frontSurface->get(right, top); + + for (int16 i = 0; i < height; i++, pixelLeft += _frontSurface->getWidth(), pixelRight += _frontSurface->getWidth()) { + pixelLeft.set((pixelLeft.get() + 128) & 0xFF); + pixelRight.set((pixelRight.get() + 128) & 0xFF); + } + + _vm->_video->dirtyRectsAll(); + _vm->_video->retrace(true); +} + +void Draw_Fascination::handleWinBorder(int16 id) { + int16 minX = 0; + int16 maxX = 320; + int16 minY = 0; + int16 maxY = 200; + + if (VAR((_winVarArrayStatus / 4) + id) & 8) + minX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) >> 16L); + if (VAR((_winVarArrayStatus / 4) + id) & 16) + maxX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) & 0xFFFFL); + if (VAR((_winVarArrayStatus / 4) + id) & 32) + minY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) >> 16L); + if (VAR((_winVarArrayStatus / 4) + id) & 64) + maxY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) & 0xFFFFL); + + _vm->_global->_inter_mouseX = _fascinWin[id].left; + _vm->_global->_inter_mouseY = _fascinWin[id].top; + + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + + drawWinTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height); + _cursorX = _vm->_global->_inter_mouseX; + _cursorY = _vm->_global->_inter_mouseY; + + do { + _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 1); + + if (_vm->_global->_inter_mouseX != _cursorX || _vm->_global->_inter_mouseY != _cursorY) { + if (_vm->_global->_inter_mouseX < minX) { + _vm->_global->_inter_mouseX = minX; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + + if (_vm->_global->_inter_mouseY < minY) { + _vm->_global->_inter_mouseY = minY; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + + if (_vm->_global->_inter_mouseX + _fascinWin[id].width > maxX) { + _vm->_global->_inter_mouseX = maxX - _fascinWin[id].width; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + + if (_vm->_global->_inter_mouseY + _fascinWin[id].height > maxY) { + _vm->_global->_inter_mouseY = maxY - _fascinWin[id].height; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + + drawWinTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); + drawWinTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height); + _cursorX = _vm->_global->_inter_mouseX; + _cursorY = _vm->_global->_inter_mouseY; + } + } while (_vm->_game->_mouseButtons); + drawWinTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); + _cursorX = _vm->_global->_inter_mouseX; + _cursorY = _vm->_global->_inter_mouseY; +} + } // End of namespace Gob diff --git a/engines/gob/draw_playtoons.cpp b/engines/gob/draw_playtoons.cpp index 583d13986e..8d8f040924 100644 --- a/engines/gob/draw_playtoons.cpp +++ b/engines/gob/draw_playtoons.cpp @@ -38,7 +38,7 @@ Draw_Playtoons::Draw_Playtoons(GobEngine *vm) : Draw_v2(vm) { void Draw_Playtoons::spriteOperation(int16 operation) { int16 len; int16 x, y; - SurfaceDescPtr sourceSurf, destSurf; + SurfacePtr sourceSurf, destSurf; bool deltaVeto; int16 left; int16 ratio; @@ -139,12 +139,11 @@ void Draw_Playtoons::spriteOperation(int16 operation) { if (!sourceSurf || !destSurf) break; - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], - *_spritesArray[_destSurface], + _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface], _spriteLeft, spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); @@ -156,22 +155,22 @@ void Draw_Playtoons::spriteOperation(int16 operation) { warning("oPlaytoons_spriteOperation: operation DRAW_PUTPIXEL, pattern -1"); break; case 1: - _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX, + _spritesArray[_destSurface]->fillRect(destSpriteX, _destSpriteY, _destSpriteX + 1, _destSpriteY + 1, _frontColor); break; case 2: - _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX - 1, + _spritesArray[_destSurface]->fillRect(destSpriteX - 1, _destSpriteY - 1, _destSpriteX + 1, _destSpriteY + 1, _frontColor); break; case 3: - _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX - 1, + _spritesArray[_destSurface]->fillRect(destSpriteX - 1, _destSpriteY - 1, _destSpriteX + 2, _destSpriteY + 2, _frontColor); break; default: - _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, *_spritesArray[_destSurface]); + _spritesArray[_destSurface]->putPixel(_destSpriteX, _destSpriteY, _frontColor); break; } dirtiedRect(_destSurface, _destSpriteX - (_pattern / 2), @@ -188,7 +187,7 @@ void Draw_Playtoons::spriteOperation(int16 operation) { warning("oPlaytoons_spriteOperation: operation DRAW_FILLRECT, pattern %d", _pattern & 0xFF); break; case 0: - _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX, + _spritesArray[_destSurface]->fillRect(destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); @@ -204,23 +203,18 @@ void Draw_Playtoons::spriteOperation(int16 operation) { case DRAW_DRAWLINE: if ((_needAdjust != 2) && (_needAdjust < 10)) { warning ("oPlaytoons_spriteOperation: operation DRAW_DRAWLINE, draw multiple lines"); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX + 1, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX + 1, _destSpriteY, _spriteRight + 1, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY + 1, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY + 1, _spriteRight, _spriteBottom + 1, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX + 1, _destSpriteY + 1, + _spritesArray[_destSurface]->drawLine(_destSpriteX + 1, _destSpriteY + 1, _spriteRight + 1, _spriteBottom + 1, _frontColor); } else { switch (_pattern & 0xFF) { case 0: - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); break; @@ -228,7 +222,7 @@ void Draw_Playtoons::spriteOperation(int16 operation) { warning("oPlaytoons_spriteOperation: operation DRAW_DRAWLINE, draw %d lines", (_pattern & 0xFF) * (_pattern & 0xFF)); for (int16 i = 0; i <= _pattern ; i++) for (int16 j = 0; j <= _pattern ; j++) - _vm->_video->drawLine(*_spritesArray[_destSurface], + _spritesArray[_destSurface]->drawLine( _destSpriteX - (_pattern / 2) + i, _destSpriteY - (_pattern / 2) + j, _spriteRight - (_pattern / 2) + i, @@ -247,7 +241,7 @@ void Draw_Playtoons::spriteOperation(int16 operation) { if ((_pattern & 0xFF) != 0) warning("oPlaytoons_spriteOperation: operation DRAW_INVALIDATE, pattern %d", _pattern & 0xFF); - _vm->_video->drawCircle(*_spritesArray[_destSurface], _destSpriteX, + _spritesArray[_destSurface]->drawCircle(_destSpriteX, _destSpriteY, _spriteRight, _frontColor); dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, @@ -289,9 +283,8 @@ void Draw_Playtoons::spriteOperation(int16 operation) { byte *dataBuf = _vm->_game->_resources->getTexts() + _textToPrint[1] + 1; len = *dataBuf++; for (int i = 0; i < len; i++, dataBuf += 2) { - _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, - _destSpriteY, *font, _transparency, _frontColor, - _backColor, *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], READ_LE_UINT16(dataBuf), + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); } } else { drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, @@ -300,9 +293,8 @@ void Draw_Playtoons::spriteOperation(int16 operation) { } } else { for (int i = 0; i < len; i++) { - _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, - _destSpriteY, *font, _transparency, - _frontColor, _backColor, *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], _textToPrint[i], + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); _destSpriteX += font->getCharWidth(_textToPrint[i]); } } @@ -317,11 +309,10 @@ void Draw_Playtoons::spriteOperation(int16 operation) { * _fontToSprite[_fontIndex].height; x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio) * _fontToSprite[_fontIndex].width; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], - *_spritesArray[_destSurface], x, y, + _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], x, y, x + _fontToSprite[_fontIndex].width - 1, y + _fontToSprite[_fontIndex].height - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); _destSpriteX += _fontToSprite[_fontIndex].width; } } @@ -332,36 +323,28 @@ void Draw_Playtoons::spriteOperation(int16 operation) { case DRAW_DRAWBAR: if ((_needAdjust != 2) && (_needAdjust < 10)){ - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom - 1, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _spriteBottom - 1, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _destSpriteX + 1, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _spriteRight - 1, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_spriteRight - 1, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY + 1, _frontColor); } else { - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _spriteRight, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); } @@ -371,8 +354,7 @@ void Draw_Playtoons::spriteOperation(int16 operation) { case DRAW_CLEARRECT: warning ("oPlaytoons_spriteOperation: DRAW_CLEARRECT uses _backColor %d", _backColor); if (_backColor != -1) { - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); } @@ -381,8 +363,7 @@ void Draw_Playtoons::spriteOperation(int16 operation) { break; case DRAW_FILLRECTABS: - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 1cec15ce04..6496229282 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -119,13 +119,13 @@ void Draw_v1::animateCursor(int16 cursor) { newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); } - _vm->_video->clearSurf(*_scummvmCursor); - _vm->_video->drawSprite(*_cursorSprites, *_scummvmCursor, + _scummvmCursor->clear(); + _scummvmCursor->blit(*_cursorSprites, cursorIndex * _cursorWidth, 0, (cursorIndex + 1) * _cursorWidth - 1, - _cursorHeight - 1, 0, 0, 0); - CursorMan.replaceCursor(_scummvmCursor->getVidMem(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0); + _cursorHeight - 1, 0, 0); + CursorMan.replaceCursor(_scummvmCursor->getData(), + _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat()); if (_frontSurface != _backSurface) { _showCursor = 3; @@ -346,27 +346,24 @@ void Draw_v1::spriteOperation(int16 operation) { Font *font = 0; switch (operation) { case DRAW_BLITSURF: - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], - *_spritesArray[_destSurface], + _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface], _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: - _vm->_video->putPixel(_destSpriteX, _destSpriteY, - _frontColor, *_spritesArray[_destSurface]); + _spritesArray[_destSurface]->putPixel(_destSpriteX, _destSpriteY, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); @@ -375,8 +372,7 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_DRAWLINE: - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); @@ -417,31 +413,24 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteY + font->getCharHeight() - 1); for (int i = 0; i < len; i++) { - _vm->_video->drawLetter(_textToPrint[i], - _destSpriteX, _destSpriteY, - *font, _transparency, - _frontColor, _backColor, - *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], _textToPrint[i], + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); _destSpriteX += font->getCharWidth(); } break; case DRAW_DRAWBAR: - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _spriteRight, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); @@ -449,8 +438,7 @@ void Draw_v1::spriteOperation(int16 operation) { case DRAW_CLEARRECT: if (_backColor < 16) { - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); } @@ -458,8 +446,7 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_FILLRECTABS: - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); @@ -476,11 +463,8 @@ void Draw_v1::spriteOperation(int16 operation) { dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + font->getCharWidth() - 1, _destSpriteY + font->getCharHeight() - 1); - _vm->_video->drawLetter(_letterToPrint, - _destSpriteX, _destSpriteY, - *font, _transparency, - _frontColor, _backColor, - *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], _letterToPrint, + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); break; } @@ -498,11 +482,10 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX + _fontToSprite[_fontIndex].width, _destSpriteY + _fontToSprite[_fontIndex].height); - _vm->_video->drawSprite(*_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], - *_spritesArray[_destSurface], x, y, + _spritesArray[_destSurface]->blit(*_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], x, y, x + _fontToSprite[_fontIndex].width, y + _fontToSprite[_fontIndex].height, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); break; } diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 5d001f4b59..bb2a57b790 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -53,7 +53,7 @@ void Draw_v2::initScreen() { initSpriteSurf(kBackSurface, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); _backSurface = _spritesArray[kBackSurface]; - _vm->_video->clearSurf(*_backSurface); + _backSurface->clear(); if (!_spritesArray[kCursorSurface]) { initSpriteSurf(kCursorSurface, 32, 16, 2); @@ -144,13 +144,13 @@ void Draw_v2::animateCursor(int16 cursor) { newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); } - _vm->_video->clearSurf(*_scummvmCursor); - _vm->_video->drawSprite(*_cursorSprites, *_scummvmCursor, + _scummvmCursor->clear(); + _scummvmCursor->blit(*_cursorSprites, cursorIndex * _cursorWidth, 0, (cursorIndex + 1) * _cursorWidth - 1, - _cursorHeight - 1, 0, 0, 0); - CursorMan.replaceCursor(_scummvmCursor->getVidMem(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0); + _cursorHeight - 1, 0, 0); + CursorMan.replaceCursor(_scummvmCursor->getData(), + _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat()); if (_frontSurface != _backSurface) { if (!_noInvalidated) { @@ -230,7 +230,10 @@ void Draw_v2::printTotText(int16 id) { destX = (READ_LE_UINT16(ptr) & 0x7FFF) * 2; spriteRight = READ_LE_UINT16(ptr + 4) * 2 + 1; } else { - destX = READ_LE_UINT16(ptr) & 0x7FFF; +// No mask used for Fascination + destX = READ_LE_UINT16(ptr); + if (_vm->getGameType() != kGameTypeFascination) + destX &= 0x7FFF; spriteRight = READ_LE_UINT16(ptr + 4); } @@ -614,7 +617,7 @@ void Draw_v2::printTotText(int16 id) { void Draw_v2::spriteOperation(int16 operation) { int16 len; int16 x, y; - SurfaceDescPtr sourceSurf, destSurf; + SurfacePtr sourceSurf, destSurf; bool deltaVeto; int16 left; int16 ratio; @@ -715,26 +718,24 @@ void Draw_v2::spriteOperation(int16 operation) { if (!sourceSurf || !destSurf) break; - _vm->_video->drawSprite(*_spritesArray[_sourceSurface], - *_spritesArray[_destSurface], + _spritesArray[_destSurface]->blit(*_spritesArray[_sourceSurface], _spriteLeft, spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: - _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, - *_spritesArray[_destSurface]); + _spritesArray[_destSurface]->putPixel(_destSpriteX, _destSpriteY, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: - _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX, + _spritesArray[_destSurface]->fillRect(destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); @@ -743,15 +744,14 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_DRAWLINE: - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_INVALIDATE: - _vm->_video->drawCircle(*_spritesArray[_destSurface], _destSpriteX, + _spritesArray[_destSurface]->drawCircle(_destSpriteX, _destSpriteY, _spriteRight, _frontColor); dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, @@ -793,9 +793,8 @@ void Draw_v2::spriteOperation(int16 operation) { byte *dataBuf = _vm->_game->_resources->getTexts() + _textToPrint[1] + 1; len = *dataBuf++; for (int i = 0; i < len; i++, dataBuf += 2) { - _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, - _destSpriteY, *font, _transparency, _frontColor, - _backColor, *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], READ_LE_UINT16(dataBuf), + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); } } else { drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, @@ -804,9 +803,8 @@ void Draw_v2::spriteOperation(int16 operation) { } } else { for (int i = 0; i < len; i++) { - _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, - _destSpriteY, *font, _transparency, - _frontColor, _backColor, *_spritesArray[_destSurface]); + font->drawLetter(*_spritesArray[_destSurface], _textToPrint[i], + _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); _destSpriteX += font->getCharWidth(_textToPrint[i]); } } @@ -821,11 +819,10 @@ void Draw_v2::spriteOperation(int16 operation) { * _fontToSprite[_fontIndex].height; x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio) * _fontToSprite[_fontIndex].width; - _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], - *_spritesArray[_destSurface], x, y, + _spritesArray[_destSurface]->blit(*_spritesArray[_fontToSprite[_fontIndex].sprite], x, y, x + _fontToSprite[_fontIndex].width - 1, y + _fontToSprite[_fontIndex].height - 1, - _destSpriteX, _destSpriteY, _transparency); + _destSpriteX, _destSpriteY, (_transparency == 0) ? -1 : 0); _destSpriteX += _fontToSprite[_fontIndex].width; } } @@ -836,36 +833,28 @@ void Draw_v2::spriteOperation(int16 operation) { case DRAW_DRAWBAR: if (_needAdjust != 2) { - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom - 1, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _spriteBottom - 1, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _destSpriteX + 1, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _spriteRight - 1, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_spriteRight - 1, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY + 1, _frontColor); } else { - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _spriteBottom, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _spriteRight, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->drawLine(_destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); } @@ -874,8 +863,7 @@ void Draw_v2::spriteOperation(int16 operation) { case DRAW_CLEARRECT: if ((_backColor != 16) && (_backColor != 144)) { - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); } @@ -884,8 +872,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_FILLRECTABS: - _vm->_video->fillRect(*_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, + _spritesArray[_destSurface]->fillRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp deleted file mode 100644 index c93962c206..0000000000 --- a/engines/gob/driver_vga.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/endian.h" -#include "graphics/primitives.h" - -#include "gob/driver_vga.h" - -namespace Gob { - -static void plotPixel(int x, int y, int color, void *data) { - SurfaceDesc *dest = (SurfaceDesc *)data; - - if ((x >= 0) && (x < dest->getWidth()) && - (y >= 0) && (y < dest->getHeight())) - dest->getVidMem()[(y * dest->getWidth()) + x] = color; -} - -void VGAVideoDriver::putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest) { - if ((x >= 0) && (x < dest.getWidth()) && - (y >= 0) && (y < dest.getHeight())) - dest.getVidMem()[(y * dest.getWidth()) + x] = color; -} - -void VGAVideoDriver::drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, - int16 y1, byte color) { - - Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, &dest); -} - -void VGAVideoDriver::fillRect(SurfaceDesc &dest, int16 left, int16 top, - int16 right, int16 bottom, byte color) { - - if ((left >= dest.getWidth()) || (right >= dest.getWidth()) || - (top >= dest.getHeight()) || (bottom >= dest.getHeight())) - return; - - byte *pos = dest.getVidMem() + (top * dest.getWidth()) + left; - int16 width = (right - left) + 1; - int16 height = (bottom - top) + 1; - - while (height--) { - for (int16 i = 0; i < width; ++i) - pos[i] = color; - - pos += dest.getWidth(); - } -} - -void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, - const Font &font, byte color1, byte color2, - byte transp, SurfaceDesc &dest) { - uint16 data; - - const byte *src = font.getCharData(item); - byte *dst = dest.getVidMem() + x + dest.getWidth() * y; - - int nWidth = font.getCharWidth(); - - if (nWidth & 7) - nWidth = (nWidth & 0xF8) + 8; - - nWidth >>= 3; - - for (int i = 0; i < font.getCharHeight(); i++) { - int width = font.getCharWidth(); - - for (int k = 0; k < nWidth; k++) { - - data = *src++; - for (int j = 0; j < MIN(8, width); j++) { - if (data & 0x80) - *dst = color2; - else if (color1 == 0) - *dst = transp; - - dst++; - data <<= 1; - } - - width -= 8; - - } - - dst += dest.getWidth() - font.getCharWidth(); - } -} - -void VGAVideoDriver::drawSprite(SurfaceDesc &source, SurfaceDesc &dest, - int16 left, int16 top, int16 right, int16 bottom, - int16 x, int16 y, int16 transp) { - - if ((x >= dest.getWidth()) || (x < 0) || - (y >= dest.getHeight()) || (y < 0)) - return; - - int16 width = MIN((right - left) + 1, (int) dest.getWidth()); - int16 height = MIN((bottom - top) + 1, (int) dest.getHeight()); - - if ((width < 1) || (height < 1)) - return; - - const byte *srcPos = source.getVidMem() + (top * source.getWidth()) + left; - byte *destPos = dest.getVidMem() + (y * dest.getWidth()) + x; - - uint32 size = width * height; - - if (transp) { - - while (height--) { - for (int16 i = 0; i < width; ++i) { - if (srcPos[i]) - destPos[i] = srcPos[i]; - } - - srcPos += source.getWidth(); - destPos += dest.getWidth(); - } - - } else if (((srcPos >= destPos) && (srcPos <= (destPos + size))) || - ((destPos >= srcPos) && (destPos <= (srcPos + size)))) { - - while (height--) { - memmove(destPos, srcPos, width); - - srcPos += source.getWidth(); - destPos += dest.getWidth(); - } - - } else { - - while (height--) { - memcpy(destPos, srcPos, width); - - srcPos += source.getWidth(); - destPos += dest.getWidth(); - } - - } -} - -void VGAVideoDriver::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, - int16 left, int16 top, int16 right, int16 bottom, - int16 x, int16 y, int16 transp) { - - if ((x >= dest.getWidth()) || (x < 0) || - (y >= dest.getHeight()) || (y < 0)) - return; - - int16 width = MIN<int>((right - left) + 1, dest.getWidth() / 2); - int16 height = MIN<int>((bottom - top) + 1, dest.getHeight() / 2); - - if ((width < 1) || (height < 1)) - return; - - const byte *srcPos = source.getVidMem() + (top * source.getWidth()) + left; - byte *destPos = dest.getVidMem() + ((y * 2) * dest.getWidth()) + (x * 2); - - while (height--) { - const byte *srcBak = srcPos; - - for (int i = 0; i < 2; i++) { - srcPos = srcBak; - - for (int16 j = 0; j < width; j++) { - if (!transp || srcPos[i]) { - destPos[2 * j + 0] = srcPos[j]; - destPos[2 * j + 1] = srcPos[j]; - } - } - - destPos += dest.getWidth(); - } - - srcPos = srcBak + source.getWidth(); - } -} - -void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, byte transp, SurfaceDesc &dest) { - int destRight = x + width; - int destBottom = y + height; - - byte *dst = dest.getVidMem() + x + dest.getWidth() * y; - - int curx = x; - int cury = y; - - while (1) { - uint8 val = *sprBuf++; - unsigned int repeat = val & 7; - val &= 0xF8; - - if (!(val & 8)) { - repeat <<= 8; - repeat |= *sprBuf++; - } - repeat++; - val >>= 4; - - for (unsigned int i = 0; i < repeat; ++i) { - if (curx < dest.getWidth() && cury < dest.getHeight()) - if (!transp || val) - *dst = val; - - dst++; - curx++; - if (curx == destRight) { - dst += dest.getWidth() + x - curx; - curx = x; - cury++; - if (cury == destBottom) - return; - } - } - - } - -} - -} - diff --git a/engines/gob/driver_vga.h b/engines/gob/driver_vga.h deleted file mode 100644 index 3102016cb5..0000000000 --- a/engines/gob/driver_vga.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef GOB_DRIVER_VGA_H -#define GOB_DRIVER_VGA_H - -#include "gob/video.h" - -namespace Gob { - -class VGAVideoDriver : public VideoDriver { -public: - VGAVideoDriver() {} - virtual ~VGAVideoDriver() {} - - void putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest); - void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, - int16 x1, int16 y1, byte color); - void fillRect(SurfaceDesc &dest, int16 left, int16 top, - int16 right, int16 bottom, byte color); - void drawLetter(unsigned char item, int16 x, int16 y, - const Font &font, byte color1, byte color2, - byte transp, SurfaceDesc &dest); - void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, - int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, - int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, byte transp, SurfaceDesc &dest); -}; - -} - -#endif // GOB_DRIVER_VGA_H diff --git a/engines/gob/expression.cpp b/engines/gob/expression.cpp index 9652862b2f..d053345b4c 100644 --- a/engines/gob/expression.cpp +++ b/engines/gob/expression.cpp @@ -1002,7 +1002,6 @@ int16 Expression::parseExpr(byte stopToken, byte *type) { Stack stack; StackFrame stackFrame(stack); byte operation; - bool escape; int16 brackStart; uint32 varBase; @@ -1037,7 +1036,6 @@ int16 Expression::parseExpr(byte stopToken, byte *type) { if ((operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR)) { while (stackFrame.pos >= 2) { - escape = false; if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) && ((operation == OP_END_EXPR) || (operation == stopToken))) { stackFrame.opers[-2] = stackFrame.opers[-1]; diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 1a8823b156..f77b3e946a 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -214,8 +214,8 @@ void Game::prepareStart() { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); _vm->_draw->initScreen(); - _vm->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0, - _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); + _vm->_draw->_frontSurface->fillRect(0, 0, + _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); _vm->_util->setMousePos(152, 92); _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152; @@ -352,8 +352,8 @@ void Game::playTot(int16 skipPlay) { } } - if (_vm->getGameType() == kGameTypeFascination) - _vm->_draw->closeAllWin(); + _vm->_draw->closeAllWin(); + if (_totToLoad[0] == 0) break; diff --git a/engines/gob/global.h b/engines/gob/global.h index 4fce5952eb..713b501f35 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -127,7 +127,7 @@ public: bool _setAllPalette; bool _dontSetPalette; - SurfaceDescPtr _primarySurfDesc; + SurfacePtr _primarySurfDesc; int16 _debugFlag; int16 _inVM; diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 03c0b1d991..65c960bd73 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -209,10 +209,6 @@ bool GobEngine::isEGA() const { return (_features & kFeaturesEGA) != 0; } -bool GobEngine::is640() const { - return (_features & kFeatures640) != 0; -} - bool GobEngine::hasAdLib() const { return (_features & kFeaturesAdLib) != 0; } @@ -225,22 +221,36 @@ bool GobEngine::isBATDemo() const { return (_features & kFeaturesBATDemo) != 0; } +bool GobEngine::is640x480() const { + return (_features & kFeatures640x480) != 0; +} + bool GobEngine::is800x600() const { return (_features & kFeatures800x600) != 0; } +bool GobEngine::isTrueColor() const { + return (_features & kFeaturesTrueColor) != 0; +} + bool GobEngine::isDemo() const { return (isSCNDemo() || isBATDemo()); } +const Graphics::PixelFormat &GobEngine::getPixelFormat() const { + return _pixelFormat; +} + Common::Error GobEngine::run() { if (!initGameParts()) { GUIErrorMessage("GobEngine::init(): Unknown version of game engine"); return Common::kUnknownError; } - _video->setSize(is640()); - _video->init(); + if (!initGraphics()) { + GUIErrorMessage("GobEngine::init(): Failed to set up graphics"); + return Common::kUnknownError; + } // On some systems it's not safe to run CD audio games from the CD. if (isCD()) @@ -376,7 +386,7 @@ bool GobEngine::initGameParts() { break; case kGameTypeFascination: - _init = new Init_v2(this); + _init = new Init_Fascination(this); _video = new Video_v2(this); _inter = new Inter_Fascination(this); _mult = new Mult_v2(this); @@ -518,22 +528,6 @@ bool GobEngine::initGameParts() { _inter->setupOpcodes(); - if (is640()) { - _video->_surfWidth = _width = 640; - _video->_surfHeight = _video->_splitHeight1 = _height = 480; - _global->_mouseMaxX = 640; - _global->_mouseMaxY = 480; - _mode = 0x18; - _global->_primarySurfDesc = SurfaceDescPtr(new SurfaceDesc(0x18, 640, 480)); - } else { - _video->_surfWidth = _width = 320; - _video->_surfHeight = _video->_splitHeight1 = _height = 200; - _global->_mouseMaxX = 320; - _global->_mouseMaxY = 200; - _mode = 0x14; - _global->_primarySurfDesc = SurfaceDescPtr(new SurfaceDesc(0x14, 320, 200)); - } - return true; } @@ -556,4 +550,34 @@ void GobEngine::deinitGameParts() { delete _dataIO; _dataIO = 0; } +bool GobEngine::initGraphics() { + if (is800x600()) { + warning("GobEngine::initGraphics(): 800x600 games currently unsupported"); + return false; + } else if (is640x480()) { + _width = 640; + _height = 480; + _mode = 0x18; + } else { + _width = 320; + _height = 200; + _mode = 0x14; + } + + _video->setSize(is640x480()); + + _pixelFormat = g_system->getScreenFormat(); + + _video->_surfWidth = _width; + _video->_surfHeight = _height; + _video->_splitHeight1 = _height; + + _global->_mouseMaxX = _width; + _global->_mouseMaxY = _height; + + _global->_primarySurfDesc = SurfacePtr(new Surface(_width, _height, _pixelFormat.bytesPerPixel)); + + return true; +} + } // End of namespace Gob diff --git a/engines/gob/gob.h b/engines/gob/gob.h index dcca236ee3..f6c03fa617 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -119,14 +119,15 @@ enum GameType { }; enum Features { - kFeaturesNone = 0, - kFeaturesCD = 1 << 0, - kFeaturesEGA = 1 << 1, - kFeaturesAdLib = 1 << 2, - kFeatures640 = 1 << 3, - kFeaturesSCNDemo = 1 << 4, - kFeaturesBATDemo = 1 << 5, - kFeatures800x600 = 1 << 6 + kFeaturesNone = 0, + kFeaturesCD = 1 << 0, + kFeaturesEGA = 1 << 1, + kFeaturesAdLib = 1 << 2, + kFeaturesSCNDemo = 1 << 3, + kFeaturesBATDemo = 1 << 4, + kFeatures640x480 = 1 << 5, + kFeatures800x600 = 1 << 6, + kFeaturesTrueColor = 1 << 7 }; enum { @@ -163,6 +164,8 @@ private: bool initGameParts(); void deinitGameParts(); + bool initGraphics(); + public: static const Common::Language _gobToScummVMLang[]; @@ -173,6 +176,8 @@ public: uint16 _height; uint8 _mode; + Graphics::PixelFormat _pixelFormat; + Common::String _startStk; Common::String _startTot; uint32 _demoIndex; @@ -208,13 +213,16 @@ public: GameType getGameType() const; bool isCD() const; bool isEGA() const; - bool is640() const; bool hasAdLib() const; bool isSCNDemo() const; bool isBATDemo() const; + bool is640x480() const; bool is800x600() const; + bool isTrueColor() const; bool isDemo() const; + const Graphics::PixelFormat &getPixelFormat() const; + GobEngine(OSystem *syst); virtual ~GobEngine(); diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp index 11043df782..ee2b4f52c9 100644 --- a/engines/gob/goblin.cpp +++ b/engines/gob/goblin.cpp @@ -233,9 +233,9 @@ void Goblin::drawObjects() { if (objDesc->toRedraw == 0) continue; - _vm->_video->drawSprite(*_vm->_mult->_animSurf, *_vm->_draw->_backSurface, + _vm->_draw->_backSurface->blit(*_vm->_mult->_animSurf, objDesc->left, objDesc->top, objDesc->right, - objDesc->bottom, objDesc->left, objDesc->top, 0); + objDesc->bottom, objDesc->left, objDesc->top); _vm->_draw->invalidateRect(objDesc->left, objDesc->top, objDesc->right, objDesc->bottom); diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index 1edb7fc0cb..dad141a254 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -431,9 +431,10 @@ void Hotspots::pop() { // Find the end of the filled hotspot space int i; Hotspot *destPtr = _hotspots; - for (i = 0; i < kHotspotCount; i++, destPtr++) + for (i = 0; i < kHotspotCount; i++, destPtr++) { if (destPtr->isEnd()) break; + } if (((uint32) (kHotspotCount - i)) < backup.size) error("Hotspots::pop(): Not enough free space in the current Hotspot " @@ -525,12 +526,12 @@ void Hotspots::leave(uint16 index) { int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { if ((_vm->_draw->_renderFlags & 0x80)==0) return(0); - for (int i = 0; i < 10; i++) - if (_vm->_draw->_fascinWin[i].id != -1) + for (int i = 0; i < 10; i++) { + if (_vm->_draw->_fascinWin[i].id != -1) { if (_vm->_global->_inter_mouseX >= _vm->_draw->_fascinWin[i].left && _vm->_global->_inter_mouseX < _vm->_draw->_fascinWin[i].left + _vm->_draw->_fascinWin[i].width && _vm->_global->_inter_mouseY >= _vm->_draw->_fascinWin[i].top && - _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + _vm->_draw->_fascinWin[i].height) + _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + _vm->_draw->_fascinWin[i].height) { if (_vm->_draw->_fascinWin[i].id == _vm->_draw->_winCount-1) { dx = _vm->_draw->_fascinWin[i].left; dy = _vm->_draw->_fascinWin[i].top; @@ -546,6 +547,9 @@ int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { return(6); return(-i); } + } + } + } return(0); } @@ -555,10 +559,7 @@ uint16 Hotspots::checkMouse(Type type, uint16 &id, uint16 &index) const { int16 dx = 0; int16 dy = 0; - int16 winId = -1; - - if (_vm->getGameType() == kGameTypeFascination) - winId = _vm->_draw->isOverWin(dx, dy); + int16 winId = _vm->_draw->getWinFromCoord(dx, dy); if (winId < 0) { winId = 0; @@ -753,11 +754,8 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index if (_vm->_game->_mouseButtons != kMouseButtonsNone) { // Mouse button pressed - int i; - if (_vm->getGameType() == kGameTypeFascination) - i = _vm->_draw->handleCurWin(); - else - i = 0; + int i = _vm->_draw->handleCurWin(); + if (!i) { _vm->_draw->animateCursor(2); if (delay > 0) { @@ -778,9 +776,11 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone))) _vm->_draw->blitCursor(); + + if ((key != _currentKey) && (_vm->getGameType() != kGameTypeFascination)) // If the hotspot changed, leave the old one - if (key != _currentKey) - leave(_currentIndex); + // Code not present in Fascination executables + leave(_currentIndex); _currentKey = 0; break; @@ -800,11 +800,9 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index enter(_currentIndex); } else { WRITE_VAR(16, (int32)i); - if (id) - id = 0; - if (index) - index = 0; - return(0); + id = 0; + index = 0; + return 0; } } else // No mouse button pressed, check whether the position changed at least @@ -1232,28 +1230,28 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, height = _vm->_game->_script->readUint16(); } if (_vm->_draw->_renderFlags & 64) { - warning("_renderFlags check added for Fascination"); _vm->_draw->_invalidatedTops[0] = 0; _vm->_draw->_invalidatedLefts[0] = 0; _vm->_draw->_invalidatedRights[0] = 319; _vm->_draw->_invalidatedBottoms[0] = 199; _vm->_draw->_invalidatedCount = 1; if (windowNum == 0) { - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0); - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); - } else + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left + width - 1, top, left + width - 1, top + height - 1, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left, top + height - 1, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left + width - 1, top, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top + height - 1, left + width - 1, top + height - 1, 0); + } else { if ((_vm->_draw->_fascinWin[windowNum].id != -1) && (_vm->_draw->_fascinWin[windowNum].id == _vm->_draw->_winCount - 1)) { left += _vm->_draw->_fascinWin[windowNum].left; top += _vm->_draw->_fascinWin[windowNum].top; - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0); - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); - _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left + width - 1, top, left + width - 1, top + height - 1, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left, top + height - 1, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left + width - 1, top, 0); + _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top + height - 1, left + width - 1, top + height - 1, 0); left -= _vm->_draw->_fascinWin[windowNum].left; top -= _vm->_draw->_fascinWin[windowNum].top; } + } } type &= 0x7F; @@ -1297,7 +1295,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, uint32 funcEnter = 0, funcLeave = 0; if ((windowNum != 0) && (type != 0) && (type != 2)) - warning("evaluateNew - type %d, win %d\n",type, windowNum); + warning("evaluateNew - type %d, win %d",type, windowNum); // Evaluate parameters for the new hotspot switch (type) { @@ -1393,9 +1391,9 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, ids[i] = _vm->_game->_script->readInt16(); flags = _vm->_game->_script->readInt16(); - if (flags > 3) - warning("evaluateNew: Warning, use of type 2 or 20. flags = %d, should be %d\n", flags, flags&3); - + if (flags > 3) + warning("evaluateNew: Warning, use of type 2 or 20. flags = %d, should be %d", flags, flags&3); + funcEnter = 0; funcLeave = _vm->_game->_script->pos(); @@ -1424,7 +1422,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, } bool Hotspots::evaluateFind(uint16 key, int16 timeVal, const uint16 *ids, - uint16 leaveWindowIndex, uint16 hotspotIndex1, uint16 hotspotIndex2, + uint16 leaveWindowIndex, uint16 hotspotIndex1, uint16 hotspotIndex2, uint16 endIndex, int16 &duration, uint16 &id, uint16 &index, bool &finished) { bool fascinCheck = false; @@ -1518,7 +1516,7 @@ void Hotspots::evaluate() { int16 duration = _vm->_game->_script->peekByte(1); byte leaveWindowIndex = 0; - if ( _vm->getGameType() == kGameTypeFascination ) + if (_vm->getGameType() == kGameTypeFascination) leaveWindowIndex = _vm->_game->_script->peekByte(2); byte hotspotIndex1 = _vm->_game->_script->peekByte(3); @@ -1644,7 +1642,7 @@ int16 Hotspots::findCursor(uint16 x, uint16 y) const { int16 deltax = 0; int16 deltay = 0; - if ( _vm->getGameType() == kGameTypeFascination ) + if (_vm->getGameType() == kGameTypeFascination) cursor = curWindow(deltax, deltay); if (cursor == 0) { @@ -1678,7 +1676,7 @@ int16 Hotspots::findCursor(uint16 x, uint16 y) const { cursor = 0; for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) { const Hotspot &spot = _hotspots[i]; - // this check is /really/ Fascination specific. + // this check is /really/ Fascination specific. // It's illogical, so if it's to be reused in Adi games... Be careful! if ((spot.flags & 0xFF00) == curType) if (spot.isIn(x - deltax, y - deltay)) { @@ -1722,9 +1720,9 @@ void Hotspots::oPlaytoons_F_1B() { // var_4 += unk_var; for (int i = 0; i < kHotspotCount; i++) { - if (_hotspots[i].isEnd()) { + if (_hotspots[i].isEnd()) return; - } + if ((_hotspots[i].id == 0xD000 + shortId) || (_hotspots[i].id == 0xB000 + shortId) || (_hotspots[i].id == 0x4000 + shortId)) { longId = _hotspots[i].id; @@ -1745,7 +1743,6 @@ void Hotspots::oPlaytoons_F_1B() { right -= 2; bottom -= 2; } -// oPlaytoons_sub_F_1B(0x8000 + var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), var3, var4, shortId); _vm->_draw->oPlaytoons_sub_F_1B(0x8000+ var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), fontIndex, var4, shortId); return; } @@ -2053,7 +2050,6 @@ void Hotspots::matchInputStrings(const InputDesc *inputs) const { cleanFloatString(spot); if ((spot.getType() >= kTypeInput2NoLeave) && (spot.getType() <= kTypeInput3Leave)) { - // Look if we find a match between the wanted and the typed string checkStringMatch(spot, inputs[inputIndex], inputPos); strInputCount++; @@ -2110,7 +2106,7 @@ void Hotspots::fillRect(uint16 x, uint16 y, uint16 width, uint16 height, uint16 _vm->_draw->_spriteBottom = height; _vm->_draw->_backColor = color; - _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 ); + _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10); } void Hotspots::printText(uint16 x, uint16 y, const char *str, uint16 fontIndex, uint16 color) const { diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h index cba400d5b6..7346c66bb5 100644 --- a/engines/gob/hotspots.h +++ b/engines/gob/hotspots.h @@ -224,7 +224,7 @@ private: uint16 &inputId, bool &hasInput, uint16 &inputCount); /** Find the hotspot requested by script commands. */ bool evaluateFind(uint16 key, int16 timeVal, const uint16 *ids, - uint16 leaveWindowIndex, uint16 hotspotIndex1, uint16 hotspotIndex2, + uint16 leaveWindowIndex, uint16 hotspotIndex1, uint16 hotspotIndex2, uint16 endIndex, int16 &duration, uint16 &id, uint16 &index, bool &finished); // Finding specific hotspots diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 3da71a2ba6..5c59a5692f 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -53,7 +53,6 @@ Init::~Init() { } void Init::cleanup() { - _vm->_video->freeDriver(); _vm->_global->_primarySurfDesc.reset(); _vm->_sound->speakerOff(); @@ -65,8 +64,6 @@ void Init::doDemo() { if (_vm->isSCNDemo()) { // This is a non-interactive demo with a SCN script and VMD videos - _vm->_video->setPrePalette(); - SCNPlayer scnPlayer(_vm); if (_vm->_demoIndex > 0) diff --git a/engines/gob/init.h b/engines/gob/init.h index d4481d8e16..8fc301d7a6 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -96,6 +96,7 @@ public: Init_Fascination(GobEngine *vm); ~Init_Fascination(); + void updateConfig(); void initGame(); }; } // End of namespace Gob diff --git a/engines/gob/init_fascin.cpp b/engines/gob/init_fascin.cpp new file mode 100644 index 0000000000..9842b7e752 --- /dev/null +++ b/engines/gob/init_fascin.cpp @@ -0,0 +1,58 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/init.h" +#include "gob/game.h" +#include "gob/global.h" + +namespace Gob { + +Init_Fascination::Init_Fascination(GobEngine *vm) : Init_v2(vm) { +} + +Init_Fascination::~Init_Fascination() { +} + +void Init_Fascination::updateConfig() { +// In Fascination, some empty texts are present and used to clean up the text area. +// Using _doSubtitles does the trick. +// The first obvious example is in the hotel hall: 'Use ...' is displayed at +// the same place than the character dialogs. + _vm->_global->_doSubtitles = true; +} + +void Init_Fascination::initGame() { +// HACK - Suppress ADLIB_FLAG as the MDY/TBR player is not working. suppress +// the PC Speaker too, as the script checks in the intro for it's presence +// to play or not some noices. + _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG; + + Init::initGame(); +} + +} // End of namespace Gob diff --git a/engines/gob/init_v3.cpp b/engines/gob/init_v3.cpp index 4a2379bad0..b3816c10e9 100644 --- a/engines/gob/init_v3.cpp +++ b/engines/gob/init_v3.cpp @@ -39,10 +39,11 @@ Init_v3::~Init_v3() { } void Init_v3::updateConfig() { -// In the CD version of Goblins3, some texts are flagged 'subtitles' -// incorrectly and therefore should be displayed in all cases. +// In the CD and Windows version of Goblins3, some texts are flagged +// 'subtitles' incorrectly and therefore should be displayed in all cases. // The first obvious example is just after Death level. - if ((_vm->getGameType() == kGameTypeGob3) && _vm->isCD()) + if ((_vm->getGameType() == kGameTypeGob3) && + (_vm->isCD() || (_vm->getPlatform() == Common::kPlatformWindows))) _vm->_global->_doSubtitles = true; } diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 0d48ad719c..f6e6d41100 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -288,7 +288,21 @@ void Inter::funcBlock(int16 retFlag) { _vm->_util->longDelay(5000); } + } // End of workaround + // WORKAROUND: + // Apart the CD version which is playing a speech in this room, all the versions + // of Fascination have a too short delay between the storage room and the lab. + // We manually add it here. + if ((_vm->getGameType() == kGameTypeFascination) && + !strncmp(_vm->_game->_curTotFile, "PLANQUE.tot", 9)) { + int addr = _vm->_game->_script->pos(); + if ((startaddr == 0x0202 && addr == 0x0330) || // Before Lab, Amiga & Atari, English + (startaddr == 0x023D && addr == 0x032D) || // Before Lab, PC floppy, German + (startaddr == 0x02C2 && addr == 0x03C2)) { // Before Lab, PC floppy, Hebrew + warning("Fascination - Adding delay"); + _vm->_util->longDelay(3000); + } } // End of workaround cmd = _vm->_game->_script->readByte(); diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 8dabe12637..4554a0783b 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -432,6 +432,8 @@ protected: void oFascin_playProtracker(OpGobParams ¶ms); + bool oFascin_repeatUntil(OpFuncParams ¶ms); + bool oFascin_assign(OpFuncParams ¶ms); bool oFascin_copySprite(OpFuncParams ¶ms); bool oFascin_keyFunc(OpFuncParams ¶ms); @@ -452,6 +454,7 @@ protected: void oFascin_closeWin(); void oFascin_activeWin(); void oFascin_openWin(); + void oFascin_initCursorAnim(); void oFascin_setRenderFlags(); void oFascin_setWinFlags(); }; @@ -539,7 +542,6 @@ protected: bool o6_loadCursor(OpFuncParams ¶ms); bool o6_assign(OpFuncParams ¶ms); - bool o6_palLoad(OpFuncParams ¶ms); bool o6_removeHotspot(OpFuncParams ¶ms); bool o6_fillRect(OpFuncParams ¶ms); diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index 5c56196641..3afb70d6c0 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -120,16 +120,16 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { int16 mouseX; int16 mouseY; MouseButtons buttons; - SurfaceDescPtr surface; + SurfacePtr surface; SoundDesc samples[4]; int16 comp[5] = { 0, 1, 2, 3, -1 }; static const char *sndFiles[] = {"1INTROII.snd", "2INTROII.snd", "1INTRO3.snd", "2INTRO3.snd"}; surface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); _vm->_video->drawPackedSprite("2ille.ims", *surface); - _vm->_video->drawSprite(*surface, *_vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0); + _vm->_draw->_frontSurface->blit(*surface, 0, 0, 319, 199, 0, 0); _vm->_video->drawPackedSprite("2ille4.ims", *surface); - _vm->_video->drawSprite(*surface, *_vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); + _vm->_draw->_frontSurface->blit(*surface, 0, 0, 319, 199, 320, 0); _vm->_util->setScrollOffset(320, 0); _vm->_video->dirtyRectsAll(); _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); @@ -140,7 +140,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == kKeyEscape) || _vm->shouldQuit()) { _vm->_palAnim->fade(0, -2, 0); - _vm->_video->clearSurf(*_vm->_draw->_frontSurface); + _vm->_draw->_frontSurface->clear(); memset((char *)_vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); WRITE_VAR(0, kKeyEscape); @@ -161,7 +161,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { _vm->_sound->blasterPlayComposition(comp, 0, samples, 4); _vm->_sound->blasterWaitEndPlay(true, false); _vm->_palAnim->fade(0, 0, 0); - _vm->_video->clearSurf(*_vm->_draw->_frontSurface); + _vm->_draw->_frontSurface->clear(); } void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { @@ -192,7 +192,7 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { _vm->shouldQuit()) { _vm->_sound->blasterStop(10); _vm->_palAnim->fade(0, -2, 0); - _vm->_video->clearSurf(*_vm->_draw->_frontSurface); + _vm->_draw->_frontSurface->clear(); memset(_vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); WRITE_VAR(0, kKeyEscape); diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp index 304f02f4fa..895eb85440 100644 --- a/engines/gob/inter_fascin.cpp +++ b/engines/gob/inter_fascin.cpp @@ -33,6 +33,7 @@ #include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/expression.h" #include "gob/script.h" #include "gob/palanim.h" #include "gob/video.h" @@ -57,6 +58,8 @@ void Inter_Fascination::setupOpcodesDraw() { OPCODEDRAW(0x05, oFascin_activeWin); OPCODEDRAW(0x06, oFascin_openWin); + OPCODEDRAW(0x08, oFascin_initCursorAnim); + OPCODEDRAW(0x0A, oFascin_setRenderFlags); OPCODEDRAW(0x0B, oFascin_setWinFlags); @@ -85,7 +88,8 @@ void Inter_Fascination::setupOpcodesDraw() { void Inter_Fascination::setupOpcodesFunc() { Inter_v2::setupOpcodesFunc(); - OPCODEFUNC(0x09, o1_assign); + OPCODEFUNC(0x06, oFascin_repeatUntil); + OPCODEFUNC(0x09, oFascin_assign); OPCODEFUNC(0x32, oFascin_copySprite); } @@ -110,6 +114,90 @@ void Inter_Fascination::setupOpcodesGob() { OPCODEGOB(1002, o2_stopProtracker); } +bool Inter_Fascination::oFascin_repeatUntil(OpFuncParams ¶ms) { + int16 size; + bool flag; + + _nestLevel[0]++; + + uint32 blockPos = _vm->_game->_script->pos(); + + do { + _vm->_game->_script->seek(blockPos); + size = _vm->_game->_script->peekUint16(2) + 2; + + funcBlock(1); + + _vm->_game->_script->seek(blockPos + size + 1); + + flag = _vm->_game->_script->evalBoolResult(); + + // WORKAROUND: The script of the PC version of Fascination, when the protection check + // fails, writes on purpose everywhere in the memory in order to hang the computer. + // This results in a crash in Scummvm. This workaround avoids that crash. + if (_vm->getPlatform() == Common::kPlatformPC) { + if ((!scumm_stricmp(_vm->_game->_curTotFile, "INTRO1.TOT") && (blockPos == 3533)) || + (!scumm_stricmp(_vm->_game->_curTotFile, "INTRO2.TOT") && (blockPos == 3519)) || + (!scumm_stricmp(_vm->_game->_curTotFile, "INTRO2.TOT") && (blockPos == 3265))) //PC Hebrew + _terminate = 1; + } + } while (!flag && !_break && !_terminate && !_vm->shouldQuit()); + + _nestLevel[0]--; + + if (*_breakFromLevel > -1) { + _break = false; + *_breakFromLevel = -1; + } + return false; +} + +bool Inter_Fascination::oFascin_assign(OpFuncParams ¶ms) { + byte destType = _vm->_game->_script->peekByte(); + int16 dest = _vm->_game->_script->readVarIndex(); + + byte loopCount; + if (_vm->_game->_script->peekByte() == 99) { + _vm->_game->_script->skip(1); + loopCount = _vm->_game->_script->readByte(); + } else + loopCount = 1; + + for (int i = 0; i < loopCount; i++) { + int16 result; + int16 srcType = _vm->_game->_script->evalExpr(&result); + + switch (destType) { + case TYPE_VAR_INT8: + if (srcType != TYPE_IMM_INT16) { + char* str = _vm->_game->_script->getResultStr(); + WRITE_VARO_STR(dest, str); + } else + WRITE_VARO_UINT8(dest + i, _vm->_game->_script->getResultInt()); + break; + + case TYPE_VAR_INT32_AS_INT16: + case TYPE_ARRAY_INT16: + WRITE_VARO_UINT16(dest + i * 2, _vm->_game->_script->getResultInt()); + break; + + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: + WRITE_VAR_OFFSET(dest + i * 4, _vm->_game->_script->getResultInt()); + break; + + case TYPE_VAR_STR: + case TYPE_ARRAY_STR: + if (srcType == TYPE_IMM_INT16) + WRITE_VARO_UINT8(dest, result); + else + WRITE_VARO_STR(dest, _vm->_game->_script->getResultStr()); + break; + } + } + + return false; +} bool Inter_Fascination::oFascin_copySprite(OpFuncParams ¶ms) { _vm->_draw->_sourceSurface = _vm->_game->_script->readInt16(); @@ -129,8 +217,6 @@ bool Inter_Fascination::oFascin_copySprite(OpFuncParams ¶ms) { } void Inter_Fascination::oFascin_playTirb(OpGobParams ¶ms) { - warning("funcPlayImd with parameter : 'tirb.imd'"); - VideoPlayer::Properties vidProps; vidProps.type = VideoPlayer::kVideoTypePreIMD; @@ -149,8 +235,6 @@ void Inter_Fascination::oFascin_playTirb(OpGobParams ¶ms) { } void Inter_Fascination::oFascin_playTira(OpGobParams ¶ms) { - warning("funcPlayImd with parameter : 'tira.imd'"); - VideoPlayer::Properties vidProps; vidProps.type = VideoPlayer::kVideoTypePreIMD; @@ -255,6 +339,13 @@ void Inter_Fascination::oFascin_openWin() { WRITE_VAR((retVal / 4), (int32) _vm->_draw->openWin(id)); } +void Inter_Fascination::oFascin_initCursorAnim() { + int16 ind = _vm->_game->_script->readValExpr(); + _vm->_draw->_cursorAnimLow[ind] = _vm->_game->_script->readInt16(); + _vm->_draw->_cursorAnimHigh[ind] = _vm->_game->_script->readInt16(); + _vm->_draw->_cursorAnimDelays[ind] = _vm->_game->_script->readInt16(); +} + void Inter_Fascination::oFascin_setRenderFlags() { int16 expr; _vm->_game->_script->evalExpr(&expr); @@ -270,4 +361,5 @@ void Inter_Fascination::oFascin_setWinFlags() { void Inter_Fascination::oFascin_playProtracker(OpGobParams ¶ms) { _vm->_sound->protrackerPlay("mod.extasy"); } + } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 11fe0c9c5e..3bf7fc8fd4 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -492,10 +492,10 @@ void Inter_v1::o1_initMult() { _vm->_mult->_animSurf = _vm->_draw->_spritesArray[Draw::kAnimSurface]; } - _vm->_video->drawSprite(*_vm->_draw->_backSurface, *_vm->_mult->_animSurf, + _vm->_mult->_animSurf->blit(*_vm->_draw->_backSurface, _vm->_mult->_animLeft, _vm->_mult->_animTop, _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1, - _vm->_mult->_animTop + _vm->_mult->_animHeight - 1, 0, 0, 0); + _vm->_mult->_animTop + _vm->_mult->_animHeight - 1, 0, 0); debugC(4, kDebugGraphics, "o1_initMult: x = %d, y = %d, w = %d, h = %d", _vm->_mult->_animLeft, _vm->_mult->_animTop, @@ -707,8 +707,7 @@ bool Inter_v1::o1_loadCursor(OpFuncParams ¶ms) { if (!resource) return false; - _vm->_video->fillRect(*_vm->_draw->_cursorSprites, - index * _vm->_draw->_cursorWidth, 0, + _vm->_draw->_cursorSprites->fillRect(index * _vm->_draw->_cursorWidth, 0, index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, _vm->_draw->_cursorHeight - 1, 0); @@ -1075,7 +1074,7 @@ bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { } } if (!allZero) { - _vm->_video->clearSurf(*_vm->_draw->_frontSurface); + _vm->_draw->_frontSurface->clear(); _vm->_draw->_noInvalidated57 = true; _vm->_game->_script->skip(48); return false; @@ -1190,6 +1189,9 @@ bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { int16 key; uint32 now; + _vm->_draw->forceBlit(); + _vm->_video->retrace(); + cmd = _vm->_game->_script->readInt16(); animPalette(); _vm->_draw->blitInvalidated(); diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp index d0824ffb58..26eff4f675 100644 --- a/engines/gob/inter_v4.cpp +++ b/engines/gob/inter_v4.cpp @@ -134,8 +134,8 @@ void Inter_v4::o4_initScreen() { _vm->_util->setScrollOffset(); if (offY > 0) { - _vm->_draw->_spritesArray[24] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); - _vm->_draw->_spritesArray[25] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); + _vm->_draw->_spritesArray[24] = SurfacePtr(new Surface(_vm->_width, offY, _vm->getPixelFormat().bytesPerPixel)); + _vm->_draw->_spritesArray[25] = SurfacePtr(new Surface(_vm->_width, offY, _vm->getPixelFormat().bytesPerPixel)); _vm->_video->_splitSurf = _vm->_draw->_spritesArray[25]; } } @@ -228,7 +228,7 @@ void Inter_v4::o4_playVmdOrMusic() { _vm->_vidPlayer->evaluateFlags(props); - int slot; + int slot = 0; if ((fileName[0] != 0) && ((slot = _vm->_vidPlayer->openVideo(true, fileName, props)) < 0)) { WRITE_VAR(11, (uint32) -1); return; diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp index b6cfe0ea3c..a684a94a7d 100644 --- a/engines/gob/inter_v5.cpp +++ b/engines/gob/inter_v5.cpp @@ -194,8 +194,8 @@ void Inter_v5::o5_initScreen() { _vm->_util->setScrollOffset(); if (offY > 0) { - _vm->_draw->_spritesArray[24] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); - _vm->_draw->_spritesArray[25] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); + _vm->_draw->_spritesArray[24] = SurfacePtr(new Surface(_vm->_width, offY, _vm->getPixelFormat().bytesPerPixel)); + _vm->_draw->_spritesArray[25] = SurfacePtr(new Surface(_vm->_width, offY, _vm->getPixelFormat().bytesPerPixel)); _vm->_video->_splitSurf = _vm->_draw->_spritesArray[25]; } } diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index 73ef46bf31..c6d0211c8f 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -65,7 +65,6 @@ void Inter_v6::setupOpcodesFunc() { OPCODEFUNC(0x03, o6_loadCursor); OPCODEFUNC(0x09, o6_assign); - OPCODEFUNC(0x13, o6_palLoad); OPCODEFUNC(0x19, o6_removeHotspot); OPCODEFUNC(0x33, o6_fillRect); } @@ -171,7 +170,7 @@ void Inter_v6::o6_playVmdOrMusic() { _vm->_vidPlayer->evaluateFlags(props); - int slot; + int slot = 0; if ((fileName[0] != 0) && ((slot = _vm->_vidPlayer->openVideo(true, fileName, props)) < 0)) { WRITE_VAR(11, (uint32) -1); return; @@ -239,7 +238,7 @@ bool Inter_v6::o6_loadCursor(OpFuncParams ¶ms) { props.lastFrame = i; _vm->_vidPlayer->play(vmdSlot, props); - _vm->_vidPlayer->copyFrame(vmdSlot, _vm->_draw->_cursorSprites->getVidMem(), + _vm->_vidPlayer->copyFrame(vmdSlot, _vm->_draw->_cursorSprites->getData(), 0, 0, _vm->_draw->_cursorWidth, _vm->_draw->_cursorWidth, (start + i) * _vm->_draw->_cursorWidth, 0, _vm->_draw->_cursorSprites->getWidth()); @@ -263,8 +262,7 @@ bool Inter_v6::o6_loadCursor(OpFuncParams ¶ms) { if (!resource) return false; - _vm->_video->fillRect(*_vm->_draw->_cursorSprites, - index * _vm->_draw->_cursorWidth, 0, + _vm->_draw->_cursorSprites->fillRect(index * _vm->_draw->_cursorWidth, 0, index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, _vm->_draw->_cursorHeight - 1, 0); @@ -357,17 +355,6 @@ bool Inter_v6::o6_assign(OpFuncParams ¶ms) { return false; } -bool Inter_v6::o6_palLoad(OpFuncParams ¶ms) { - o1_palLoad(params); - - if (_gotFirstPalette) - _vm->_video->_palLUT->setPalette((const byte *)_vm->_global->_pPaletteDesc->vgaPal, - Graphics::PaletteLUT::kPaletteRGB, 6, 0); - - _gotFirstPalette = true; - return false; -} - bool Inter_v6::o6_removeHotspot(OpFuncParams ¶ms) { int16 id; uint8 stateType1 = Hotspots::kStateFilledDisabled | Hotspots::kStateType1; diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 69e7dbcf52..05658e0ca8 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -9,7 +9,6 @@ MODULE_OBJS := \ draw_bargon.o \ draw_fascin.o \ draw_playtoons.o \ - driver_vga.o \ expression.o \ game.o \ global.o \ @@ -23,6 +22,7 @@ MODULE_OBJS := \ init.o \ init_v1.o \ init_v2.o \ + init_fascin.o \ init_v3.o \ init_v4.o \ init_v6.o \ @@ -48,6 +48,7 @@ MODULE_OBJS := \ scenery_v1.o \ scenery_v2.o \ script.o \ + surface.o \ totfile.o \ util.o \ variables.o \ diff --git a/engines/gob/mult.h b/engines/gob/mult.h index 7766508922..fc83e2dbe3 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -232,7 +232,7 @@ public: int8 *_orderArray; - SurfaceDescPtr _animSurf; + SurfacePtr _animSurf; int16 _animLeft; int16 _animTop; int16 _animWidth; diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index 84869066e1..4be0a49b45 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -320,8 +320,7 @@ void Mult_v1::playMultInit() { 320, 200, 0); _vm->_draw->_spritesArray[Draw::kAnimSurface] = _animSurf; - _vm->_video->drawSprite(*_vm->_draw->_backSurface, - *_animSurf, 0, 0, 319, 199, 0, 0, 0); + _animSurf->blit(*_vm->_draw->_backSurface, 0, 0, 319, 199, 0, 0); _animDataAllocated = true; } else @@ -350,8 +349,7 @@ void Mult_v1::drawStatics(bool &stop) { _vm->_scenery->_curStatic = _multData->staticIndices[_vm->_scenery->_curStatic]; _vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); - _vm->_video->drawSprite(*_vm->_draw->_backSurface, *_animSurf, - 0, 0, 319, 199, 0, 0, 0); + _animSurf->blit(*_vm->_draw->_backSurface, 0, 0, 319, 199, 0, 0); } } diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 66488054e7..6fc292950f 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -272,9 +272,9 @@ void Mult_v2::loadImds(Common::SeekableReadStream &data) { memcpy(_multData->imdFiles, _vm->_game->_script->getData() + _vm->_game->_script->pos(), size * 14); - // WORKAROUND: The Windows version of Lost in Time has VMD not IMD files, - // but they are still referenced as IMD. - if ((_vm->getGameType() == kGameTypeLostInTime) && + // WORKAROUND: The Windows versions of Lost in Time and Gob3 have VMD not + // IMD files, but they are still referenced as IMD. + if (((_vm->getGameType() == kGameTypeLostInTime) || (_vm->getGameType() == kGameTypeGob3)) && (_vm->getPlatform() == Common::kPlatformWindows)) { for (int i = 0; i < size; i++) { @@ -582,9 +582,8 @@ void Mult_v2::playMultInit() { _vm->_draw->initSpriteSurf(Draw::kAnimSurface, width, height, 0); _animSurf = _vm->_draw->_spritesArray[Draw::kAnimSurface]; - _vm->_video->drawSprite(*_vm->_draw->_spritesArray[Draw::kBackSurface], - *_vm->_draw->_spritesArray[Draw::kAnimSurface], 0, 0, - _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); + _vm->_draw->_spritesArray[Draw::kAnimSurface]->blit(*_vm->_draw->_spritesArray[Draw::kBackSurface], + 0, 0, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0); for (_counter = 0; _counter < _objCount; _counter++) _multData->palAnimIndices[_counter] = _counter; @@ -639,9 +638,8 @@ void Mult_v2::drawStatics(bool &stop) { _vm->_scenery->_curStatic = -1; } - _vm->_video->drawSprite(*_vm->_draw->_spritesArray[Draw::kBackSurface], - *_vm->_draw->_spritesArray[Draw::kAnimSurface], 0, 0, - _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); + _vm->_draw->_spritesArray[Draw::kAnimSurface]->blit(*_vm->_draw->_spritesArray[Draw::kBackSurface], + 0, 0, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0); } } @@ -946,7 +944,7 @@ void Mult_v2::animate() { _vm->_draw->_destSpriteX = maxleft; _vm->_draw->_destSpriteY = maxtop; _vm->_draw->_transparency = 0; - _vm->_draw->spriteOperation(DRAW_DRAWLETTER); + _vm->_draw->spriteOperation(DRAW_BLITSURF); } // Figure out the correct drawing order diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp index f3770b0425..755d28c6e9 100644 --- a/engines/gob/palanim.cpp +++ b/engines/gob/palanim.cpp @@ -88,7 +88,7 @@ bool PalAnim::fadeStep(int16 oper) { if (oper == 0) { if (_vm->_global->_setAllPalette) { if (_vm->_global->_inVM != 0) - error("PalAnim::fadeStep(): _vm->_global->_inVM != 0 not supported."); + error("PalAnim::fadeStep(): _vm->_global->_inVM != 0 not supported"); for (int i = 0; i < 256; i++) { newRed = fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]); diff --git a/engines/gob/save/savefile.cpp b/engines/gob/save/savefile.cpp index e1c4c62b12..79e931fe30 100644 --- a/engines/gob/save/savefile.cpp +++ b/engines/gob/save/savefile.cpp @@ -331,14 +331,18 @@ bool SavePartSprite::readPalette(const byte *palette) { return true; } -bool SavePartSprite::readSprite(const SurfaceDesc &sprite) { +bool SavePartSprite::readSprite(const Surface &sprite) { // The sprite's dimensions have to fit if (((uint32)sprite.getWidth()) != _width) return false; if (((uint32)sprite.getHeight()) != _height) return false; - memcpy(_dataSprite, sprite.getVidMem(), _width * _height); + // Only 8bit sprites supported for now + if (sprite.getBPP() != 1) + return false; + + memcpy(_dataSprite, sprite.getData(), _width * _height); return true; } @@ -357,14 +361,18 @@ bool SavePartSprite::writePalette(byte *palette) const { return true; } -bool SavePartSprite::writeSprite(SurfaceDesc &sprite) const { +bool SavePartSprite::writeSprite(Surface &sprite) const { // The sprite's dimensions have to fit if (((uint32)sprite.getWidth()) != _width) return false; if (((uint32)sprite.getHeight()) != _height) return false; - memcpy(sprite.getVidMem(), _dataSprite, _width * _height); + // Only 8bit sprites supported for now + if (sprite.getBPP() != 1) + return false; + + memcpy(sprite.getData(), _dataSprite, _width * _height); return true; } diff --git a/engines/gob/save/savefile.h b/engines/gob/save/savefile.h index 615be8e0f2..da3696dee8 100644 --- a/engines/gob/save/savefile.h +++ b/engines/gob/save/savefile.h @@ -33,7 +33,7 @@ namespace Gob { class GobEngine; -class SurfaceDesc; +class Surface; /** A class wrapping a save part header. * @@ -162,7 +162,7 @@ public: /** Read a palette into the part. */ bool readPalette(const byte *palette); /** Read a sprite into the part. */ - bool readSprite(const SurfaceDesc &sprite); + bool readSprite(const Surface &sprite); /** Read size bytes of raw data into the sprite. */ bool readSpriteRaw(const byte *data, uint32 size); @@ -170,7 +170,7 @@ public: /** Write a palette out of the part. */ bool writePalette(byte *palette) const; /** Write a sprite out of the part. */ - bool writeSprite(SurfaceDesc &sprite) const; + bool writeSprite(Surface &sprite) const; private: uint32 _width; diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 14cd82480d..8b7a661278 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -245,7 +245,7 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { if ((index < 0) || (index >= SPRITES_COUNT)) return false; - SurfaceDescPtr sprite = _vm->_draw->_spritesArray[index]; + SurfacePtr sprite = _vm->_draw->_spritesArray[index]; // Target sprite exists? if (!sprite) @@ -275,7 +275,7 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { } bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { - SurfaceDescPtr sprite; + SurfacePtr sprite; if (isDummy(size)) return true; @@ -297,7 +297,7 @@ bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { } bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, - int32 offset, SurfaceDescPtr *sprite) { + int32 offset, SurfacePtr *sprite) { delete _sprite; _sprite = 0; @@ -311,7 +311,7 @@ bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, if ((index < 0) || (index >= SPRITES_COUNT)) return false; - SurfaceDescPtr sprt = _vm->_draw->_spritesArray[index]; + SurfacePtr sprt = _vm->_draw->_spritesArray[index]; // Sprite exists? if (!sprt) diff --git a/engines/gob/save/savehandler.h b/engines/gob/save/savehandler.h index 6a7e563a8f..723215cf08 100644 --- a/engines/gob/save/savehandler.h +++ b/engines/gob/save/savehandler.h @@ -27,7 +27,7 @@ #define GOB_SAVE_SAVEHANDLER_H #include "common/savefile.h" -#include "engines/gob/video.h" // for SurfaceDescPtr +#include "engines/gob/video.h" // for SurfacePtr namespace Gob { @@ -139,7 +139,7 @@ public: /** Create a fitting sprite. */ bool createSprite(int16 dataVar, int32 size, - int32 offset, SurfaceDescPtr *sprite = 0); + int32 offset, SurfacePtr *sprite = 0); protected: SavePartSprite *_sprite; diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index f9587dc0b3..ec33137739 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -65,7 +65,7 @@ Scenery::Scenery(GobEngine *vm) : _vm(vm) { _pCaptureCounter = 0; - for (int i = 0; i < 70; i++ ) { + for (int i = 0; i < 70; i++) { _staticPictToSprite[i] = 0; _animPictToSprite[i] = 0; } @@ -80,6 +80,10 @@ Scenery::~Scenery() { void Scenery::init() { for (int i = 0; i < 10; i++) { + if (_vm->getGameType() == kGameTypeFascination) { + freeAnim(i); + freeStatic(i); + } _animPictCount[i] = 0; _staticPictCount[i] = -1; } @@ -192,7 +196,7 @@ int16 Scenery::loadStatic(char search) { _spriteResId[sprIndex] = sprResId; _vm->_draw->initSpriteSurf(sprIndex, width, height, 2); - _vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]); + _vm->_draw->_spritesArray[sprIndex]->clear(); _vm->_draw->_destSurface = sprIndex; _vm->_draw->_spriteLeft = sprResId; _vm->_draw->_transparency = 0; @@ -522,7 +526,7 @@ int16 Scenery::loadAnim(char search) { _spriteResId[sprIndex] = sprResId; _vm->_draw->initSpriteSurf(sprIndex, width, height, 2); - _vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]); + _vm->_draw->_spritesArray[sprIndex]->clear(); _vm->_draw->_destSurface = sprIndex; _vm->_draw->_spriteLeft = sprResId; _vm->_draw->_transparency = 0; @@ -619,6 +623,16 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (frame >= (int32)_vm->_vidPlayer->getFrameCount(obj.videoSlot - 1)) frame = _vm->_vidPlayer->getFrameCount(obj.videoSlot - 1) - 1; + if (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) >= 255) { + // Allow for object videos with more than 255 frames, although the + // object frame counter is just a byte. + + uint32 curFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) + 1; + uint16 frameWrap = curFrame / 256; + + frame = ((frame + 1) % 256) + frameWrap * 256; + } + if (frame != (int32)_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1)) { // Seek to frame @@ -719,7 +733,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, _vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - (destX + _vm->_draw->_spriteRight); - _vm->_vidPlayer->copyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(), + _vm->_vidPlayer->copyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getData(), _vm->_draw->_spriteLeft, _vm->_draw->_spriteTop, _vm->_draw->_spriteRight, _vm->_draw->_spriteBottom, _vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, @@ -919,13 +933,24 @@ void Scenery::writeAnimLayerInfo(uint16 index, uint16 layer, int16 varDX, int16 varDY, int16 varUnk0, int16 varFrames) { assert(index < 10); - assert(layer < _animations[index].layersCount); - AnimLayer &animLayer = _animations[index].layers[layer]; - WRITE_VAR_OFFSET(varDX, animLayer.animDeltaX); - WRITE_VAR_OFFSET(varDY, animLayer.animDeltaY); - WRITE_VAR_OFFSET(varUnk0, animLayer.unknown0); - WRITE_VAR_OFFSET(varFrames, animLayer.framesCount); +// WORKAROUND - Fascination Hebrew is using scripts from the CD versions, but of course +// no CD track, so the anim syncing failed, and the anims were suppressed. But they +// didn't updated the scripts. Skipping the wrong anims is a solution. + if ((_vm->getGameType() == kGameTypeFascination) && (layer >= _animations[index].layersCount)) { + WRITE_VAR_OFFSET(varDX, 0); + WRITE_VAR_OFFSET(varDY, 0); + WRITE_VAR_OFFSET(varUnk0, 0); + WRITE_VAR_OFFSET(varFrames, 0); + } else { + assert(layer < _animations[index].layersCount); + + AnimLayer &animLayer = _animations[index].layers[layer]; + WRITE_VAR_OFFSET(varDX, animLayer.animDeltaX); + WRITE_VAR_OFFSET(varDY, animLayer.animDeltaY); + WRITE_VAR_OFFSET(varUnk0, animLayer.unknown0); + WRITE_VAR_OFFSET(varFrames, animLayer.framesCount); + } } int16 Scenery::getStaticLayersCount(uint16 index) { diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index f2b9004a41..bc4495fafd 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -610,9 +610,14 @@ void Sound::cdPlayMultMusic() { void Sound::cdPlay(const char *trackName) { if (!_cdrom) return; - debugC(1, kDebugSound, "CDROM: Playing track \"%s\"", trackName); - _cdrom->startTrack(trackName); + +// WORKAROUND - In Fascination CD, in the storage room, a track has the wrong +// name in the scripts, and therefore doesn't play. This fixes the problem. + if ((_vm->getGameType() == kGameTypeFascination) && !scumm_stricmp(trackName, "boscle")) + _cdrom->startTrack("bosscle"); + else + _cdrom->startTrack(trackName); } void Sound::cdStop() { diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp new file mode 100644 index 0000000000..554edfc753 --- /dev/null +++ b/engines/gob/surface.cpp @@ -0,0 +1,584 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "gob/surface.h" + +#include "common/system.h" +#include "common/util.h" +#include "common/frac.h" + +#include "graphics/primitives.h" + +namespace Gob { + +static void plotPixel(int x, int y, int color, void *data) { + Surface *dest = (Surface *)data; + + dest->putPixel(x, y, color); +} + + +Pixel::Pixel(byte *vidMem, uint8 bpp) : _vidMem(vidMem), _bpp(bpp) { + assert((_bpp == 1) || (_bpp == 2)); +} + +Pixel &Pixel::operator++() { + _vidMem += _bpp; + return *this; +} + +Pixel Pixel::operator++(int x) { + Pixel p = *this; + ++(*this); + return p; +} + +Pixel &Pixel::operator--() { + _vidMem -= _bpp; + return *this; +} + +Pixel Pixel::operator--(int x) { + Pixel p = *this; + --(*this); + return p; +} + +Pixel &Pixel::operator+=(int x) { + _vidMem += x * _bpp; + return *this; +} + +Pixel &Pixel::operator-=(int x) { + _vidMem -= x * _bpp; + return *this; +} + +uint32 Pixel::get() const { + if (_bpp == 1) + return *((byte *) _vidMem); + if (_bpp == 2) + return *((uint16 *) _vidMem); + + return 0; +} + +void Pixel::set(uint32 p) { + if (_bpp == 1) + *((byte *) _vidMem) = (byte) p; + if (_bpp == 2) + *((uint16 *) _vidMem) = (uint16) p; +} + + +ConstPixel::ConstPixel(const byte *vidMem, uint8 bpp) : _vidMem(vidMem), _bpp(bpp) { + assert((_bpp == 1) || (_bpp == 2)); +} + +ConstPixel &ConstPixel::operator++() { + _vidMem += _bpp; + return *this; +} + +ConstPixel ConstPixel::operator++(int x) { + ConstPixel p = *this; + ++(*this); + return p; +} + +ConstPixel &ConstPixel::operator--() { + _vidMem -= _bpp; + return *this; +} + +ConstPixel ConstPixel::operator--(int x) { + ConstPixel p = *this; + --(*this); + return p; +} + +ConstPixel &ConstPixel::operator+=(int x) { + _vidMem += x * _bpp; + return *this; +} + +ConstPixel &ConstPixel::operator-=(int x) { + _vidMem -= x * _bpp; + return *this; +} + +uint32 ConstPixel::get() const { + if (_bpp == 1) + return *((const byte *) _vidMem); + if (_bpp == 2) + return *((const uint16 *) _vidMem); + + return 0; +} + + +Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) : + _width(width), _height(height), _bpp(bpp), _vidMem(vidMem) { + + assert((_width > 0) && (_height > 0)); + assert((_bpp == 1) || (_bpp == 2)); + + if (!_vidMem) { + _vidMem = new byte[_bpp * _width * _height]; + _ownVidMem = true; + + memset(_vidMem, 0, _bpp * _width * _height); + } else + _ownVidMem = false; +} + +Surface::~Surface() { + if (_ownVidMem) + delete[] _vidMem; +} + +uint16 Surface::getWidth() const { + return _width; +} + +uint16 Surface::getHeight() const { + return _height; +} + +uint16 Surface::getBPP() const { + return _bpp; +} + +void Surface::resize(uint16 width, uint16 height) { + assert((width > 0) && (height > 0)); + + if (_ownVidMem) + delete[] _vidMem; + + _width = width; + _height = height; + + _vidMem = new byte[_bpp * _width * _height]; + _ownVidMem = true; + + memset(_vidMem, 0, _bpp * _width * _height); +} + +byte *Surface::getData(uint16 x, uint16 y) { + return _vidMem + (y * _width * _bpp) + (x * _bpp); +} + +const byte *Surface::getData(uint16 x, uint16 y) const { + return _vidMem + (y * _width * _bpp) + (x * _bpp); +} + +Pixel Surface::get(uint16 x, uint16 y) { + byte *vidMem = getData(x, y); + + return Pixel(vidMem, _bpp); +} + +ConstPixel Surface::get(uint16 x, uint16 y) const { + const byte *vidMem = getData(x, y); + + return ConstPixel(vidMem, _bpp); +} + +bool Surface::clipBlitRect(int16 &left, int16 &top, int16 &right, int16 &bottom, int16 &x, int16 &y, + uint16 dWidth, uint16 dHeight, uint16 sWidth, uint16 sHeight) { + + if ((x >= dWidth) || (y >= dHeight)) + // Nothing to do + return false; + + // Just in case those are swapped + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); + + if ((left >= sWidth) || (top >= sHeight) || (right < 0) || (bottom < 0)) + // Nothing to do + return false; + + // Adjust from coordinates + if (left < 0) { + x -= left; + left = 0; + } + if (top < 0) { + y -= top; + top = 0; + } + + // Adjust to coordinates + if (x < 0) { + left -= x; + x = 0; + } + if (y < 0) { + top -= y; + y = 0; + } + + // Limit by source and destination dimensions + right = MIN<int32>(right , MIN<int32>(sWidth , dWidth - x + left) - 1); + bottom = MIN<int32>(bottom, MIN<int32>(sHeight, dHeight - y + top ) - 1); + + if ((right < left) || (bottom < top)) + // Nothing to do + return false; + + // Clip to sane values + right = MAX<int16>(right , 0); + bottom = MAX<int16>(bottom, 0); + + return true; +} + +void Surface::blit(const Surface &from, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y, int32 transp) { + + // Color depths have to fit + assert(_bpp == from._bpp); + + // Clip + if (!clipBlitRect(left, top, right, bottom, x, y, _width, _height, from._width, from._height)) + return; + + // Area to actually copy + uint16 width = right - left + 1; + uint16 height = bottom - top + 1; + + if ((width == 0) || (height == 0)) + // Nothing to do + return; + + if ((left == 0) && (_width == from._width) && (_width == width) && (transp == -1)) { + // If these conditions are met, we can directly use memcpy + + // Pointers to the blit destination and source start points + byte *dst = getData(x , y); + const byte *src = from.getData(left, top); + + memcpy(dst, src, width * height * _bpp); + return; + } + + if (transp == -1) { + // We don't have to look for transparency => we can use memcpy line-wise + + // Pointers to the blit destination and source start points + byte *dst = getData(x , y); + const byte *src = from.getData(left, top); + + while (height-- > 0) { + memcpy(dst, src, width * _bpp); + + dst += _width * _bpp; + src += from._width * from._bpp; + } + + return; + } + + // Otherwise, we have to copy by pixel + + // Pointers to the blit destination and source start points + Pixel dst = get(x , y); + ConstPixel src = from.get(left, top); + + while (height-- > 0) { + Pixel dstRow = dst; + ConstPixel srcRow = src; + + for (uint16 i = 0; i < width; i++, dstRow++, srcRow++) + if (srcRow.get() != ((uint32) transp)) + dstRow.set(srcRow.get()); + + dst += _width; + src += from._width; + } +} + +void Surface::blit(const Surface &from, int16 x, int16 y, int32 transp) { + blit(from, 0, 0, from._width - 1, from._height - 1, x, y, transp); +} + +void Surface::blit(const Surface &from, int32 transp) { + blit(from, 0, 0, from._width - 1, from._height - 1, 0, 0, transp); +} + +void Surface::blitScaled(const Surface &from, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y, Common::Rational scale, int32 transp) { + + if (scale == 1) { + // Yeah, "scaled" + + blit(from, left, top, right, bottom, x, y, transp); + return; + } + + // Color depths have to fit + assert(_bpp == from._bpp); + + uint16 dWidth = (uint16) floor((_width / scale).toDouble()); + uint16 dHeight = (uint16) floor((_height / scale).toDouble()); + + // Clip + if (!clipBlitRect(left, top, right, bottom, x, y, dWidth, dHeight, from._width, from._height)) + return; + + // Area to actually copy + uint16 width = right - left + 1; + uint16 height = bottom - top + 1; + + if ((width == 0) || (height == 0)) + // Nothing to do + return; + + width = MIN<int32>((int32) floor((width * scale).toDouble()), _width); + height = MIN<int32>((int32) floor((height * scale).toDouble()), _height); + + // Pointers to the blit destination and source start points + byte *dst = getData(x , y); + const byte *src = from.getData(left, top); + + frac_t step = scale.getInverse().toFrac(); + + frac_t posW = 0, posH = 0; + while (height-- > 0) { + byte *dstRow = dst; + const byte *srcRow = src; + + posW = 0; + + for (uint16 i = 0; i < width; i++, dstRow += _bpp) { + memcpy(dstRow, srcRow, _bpp); + + posW += step; + while (posW >= ((frac_t) FRAC_ONE)) { + srcRow += from._bpp; + posW -= FRAC_ONE; + } + } + + posH += step; + while (posH >= ((frac_t) FRAC_ONE)) { + src += from._width * from._bpp; + posH -= FRAC_ONE; + } + + dst += _width * _bpp; + } + +} + +void Surface::blitScaled(const Surface &from, int16 x, int16 y, Common::Rational scale, int32 transp) { + blitScaled(from, 0, 0, from._width - 1, from._height - 1, x, y, scale, transp); +} + +void Surface::blitScaled(const Surface &from, Common::Rational scale, int32 transp) { + blitScaled(from, 0, 0, from._width - 1, from._height - 1, 0, 0, scale, transp); +} + +void Surface::fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color) { + // Just in case those are swapped + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); + + if ((left >= _width) || (top >= _height)) + // Nothing to do + return; + + // Area to actually fill + uint16 width = CLIP<int32>(right - left + 1, 0, _width - left); + uint16 height = CLIP<int32>(bottom - top + 1, 0, _height - top); + + if ((width == 0) || (height == 0)) + // Nothing to do + return; + + if ((left == 0) && (width == _width) && (_bpp == 1)) { + // We can directly use memset + + byte *dst = getData(left, top); + + memset(dst, (byte) color, width * height); + return; + } + + if (_bpp == 1) { + // We can use memset line-wise + + byte *dst = getData(left, top); + + while (height-- > 0) { + memset(dst, (byte) color, width); + dst += _width; + } + + return; + } + + assert(_bpp == 2); + + // Otherwise, we have to fill by pixel + + Pixel p = get(left, top); + while (height-- > 0) { + for (uint16 i = 0; i < width; i++, ++p) + p.set(color); + + p += _width - width; + } +} + +void Surface::fill(uint32 color) { + if (_bpp == 1) { + // We can directly use memset + + memset(_vidMem, (byte) color, _width * _height); + return; + } + + fillRect(0, 0, _width - 1, _height - 1, color); +} + +void Surface::clear() { + fill(0); +} + +void Surface::putPixel(uint16 x, uint16 y, uint32 color) { + if ((x >= _width) || (y >= _height)) + return; + + get(x, y).set(color); +} + +void Surface::drawLine(uint16 x0, uint16 y0, uint16 x1, uint16 y1, uint32 color) { + Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, this); +} + +/* + * The original's version of the Bresenham Algorithm was a bit "unclean" + * and produced strange edges at 45, 135, 225 and 315 degrees, so using the + * version found in the Wikipedia article about the + * "Bresenham's line algorithm" instead + */ +void Surface::drawCircle(uint16 x0, uint16 y0, uint16 radius, uint32 color, int16 pattern) { + int16 f = 1 - radius; + int16 ddFx = 0; + int16 ddFy = -2 * radius; + int16 x = 0; + int16 y = radius; + + if (pattern == 0) { + putPixel(x0, y0 + radius, color); + putPixel(x0, y0 - radius, color); + putPixel(x0 + radius, y0, color); + putPixel(x0 - radius, y0, color); + } else + warning("Surface::drawCircle - pattern %d", pattern); + + while (x < y) { + if (f >= 0) { + y--; + ddFy += 2; + f += ddFy; + } + x++; + ddFx += 2; + f += ddFx + 1; + + switch (pattern) { + case -1: + fillRect(x0 - y, y0 + x, x0 + y, y0 + x, color); + fillRect(x0 - x, y0 + y, x0 + x, y0 + y, color); + fillRect(x0 - y, y0 - x, x0 + y, y0 - x, color); + fillRect(x0 - x, y0 - y, x0 + x, y0 - y, color); + break; + case 0: + putPixel(x0 + x, y0 + y, color); + putPixel(x0 - x, y0 + y, color); + putPixel(x0 + x, y0 - y, color); + putPixel(x0 - x, y0 - y, color); + putPixel(x0 + y, y0 + x, color); + putPixel(x0 - y, y0 + x, color); + putPixel(x0 + y, y0 - x, color); + putPixel(x0 - y, y0 - x, color); + break; + default: + fillRect(x0 + y - pattern, y0 + x - pattern, x0 + y, y0 + x, color); + fillRect(x0 + x - pattern, y0 + y - pattern, x0 + x, y0 + y, color); + fillRect(x0 - y, y0 + x - pattern, x0 - y + pattern, y0 + x, color); + fillRect(x0 - x, y0 + y - pattern, x0 - x + pattern, y0 + y, color); + fillRect(x0 + y - pattern, y0 - x, x0 + y, y0 - x + pattern, color); + fillRect(x0 + x - pattern, y0 - y, x0 + x, y0 - y + pattern, color); + fillRect(x0 - y, y0 - x, x0 - y + pattern, y0 - x + pattern, color); + fillRect(x0 - x, y0 - y, x0 - x + pattern, y0 - y + pattern, color); + break; + } + } +} + +void Surface::blitToScreen(uint16 left, uint16 top, uint16 right, uint16 bottom, uint16 x, uint16 y) const { + // Color depths have to fit + assert(g_system->getScreenFormat().bytesPerPixel == _bpp); + + uint16 sWidth = g_system->getWidth(); + uint16 sHeight = g_system->getHeight(); + + if ((x >= sWidth) || (y >= sHeight)) + // Nothing to do + return; + + // Just in case those are swapped + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); + + if ((left >= _width) || (top >= _height)) + // Nothing to do + return; + + // Area to actually copy + uint16 width = MAX<int32>(MIN<int32>(MIN<int32>(right - left + 1, _width - left), sWidth - x), 0); + uint16 height = MAX<int32>(MIN<int32>(MIN<int32>(bottom - top + 1, _height - top ), sHeight - y), 0); + + if ((width == 0) || (height == 0)) + // Nothing to do + return; + + // Pointers to the blit destination and source start points + const byte *src = getData(left, top); + + g_system->copyRectToScreen(src, _width * _bpp, x, y, width, height); +} + +} // End of namespace Gob diff --git a/engines/gob/surface.h b/engines/gob/surface.h new file mode 100644 index 0000000000..9a26dbc79b --- /dev/null +++ b/engines/gob/surface.h @@ -0,0 +1,131 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_SURFACE_H +#define GOB_SURFACE_H + +#include "common/scummsys.h" +#include "common/ptr.h" +#include "common/rational.h" + +namespace Gob { + +/** An iterator over a surface's image data, automatically handles different color depths. */ +class Pixel { +public: + Pixel(byte *vidMem, uint8 bpp); + + Pixel &operator++(); + Pixel operator++(int x); + + Pixel &operator--(); + Pixel operator--(int x); + + Pixel &operator+=(int x); + Pixel &operator-=(int x); + + uint32 get() const; + void set(uint32 p); + +private: + byte *_vidMem; + uint8 _bpp; +}; + +/** A const iterator over a surface's image data, automatically handles different color depths. */ +class ConstPixel { +public: + ConstPixel(const byte *vidMem, uint8 bpp); + + ConstPixel &operator++(); + ConstPixel operator++(int x); + + ConstPixel &operator--(); + ConstPixel operator--(int x); + + ConstPixel &operator+=(int x); + ConstPixel &operator-=(int x); + + uint32 get() const; + +private: + const byte *_vidMem; + uint8 _bpp; +}; + +class Surface { +public: + Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem = 0); + ~Surface(); + + uint16 getWidth () const; + uint16 getHeight() const; + uint16 getBPP () const; + + byte *getData(uint16 x = 0, uint16 y = 0); + const byte *getData(uint16 x = 0, uint16 y = 0) const; + + void resize(uint16 width, uint16 height); + + Pixel get(uint16 x = 0, uint16 y = 0); + ConstPixel get(uint16 x = 0, uint16 y = 0) const; + + void blit(const Surface &from, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y, int32 transp = -1); + void blit(const Surface &from, int16 x, int16 y, int32 transp = -1); + void blit(const Surface &from, int32 transp = -1); + + void blitScaled(const Surface &from, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y, Common::Rational scale, int32 transp = -1); + void blitScaled(const Surface &from, int16 x, int16 y, Common::Rational scale, int32 transp = -1); + void blitScaled(const Surface &from, Common::Rational scale, int32 transp = -1); + + void fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color); + void fill(uint32 color); + void clear(); + + void putPixel(uint16 x, uint16 y, uint32 color); + void drawLine(uint16 x0, uint16 y0, uint16 x1, uint16 y1, uint32 color); + void drawCircle(uint16 x0, uint16 y0, uint16 radius, uint32 color, int16 pattern = 0); + + void blitToScreen(uint16 left, uint16 top, uint16 right, uint16 bottom, uint16 x, uint16 y) const; + +private: + uint16 _width; + uint16 _height; + uint8 _bpp; + + bool _ownVidMem; + byte *_vidMem; + + static bool clipBlitRect(int16 &left, int16 &top, int16 &right, int16 &bottom, int16 &x, int16 &y, + uint16 dWidth, uint16 dHeight, uint16 sWidth, uint16 sHeight); +}; + +typedef Common::SharedPtr<Surface> SurfacePtr; + +} // End of namespace Gob + +#endif // GOB_SURFACE_H diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 26899232e2..00d8c2c9ac 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -316,8 +316,11 @@ void Util::clearPalette() { _vm->validateVideoMode(_vm->_global->_videoMode); if (_vm->_global->_setAllPalette) { - memset(colors, 0, 1024); - g_system->setPalette(colors, 0, 256); + if (_vm->getPixelFormat().bytesPerPixel == 1) { + memset(colors, 0, 1024); + g_system->setPalette(colors, 0, 256); + } + return; } @@ -435,7 +438,7 @@ void Util::cleanupStr(char *str) { cutFromStr(str, 0, 1); // Trim spaces right - while ((strlen(str) > 0) && (str[strlen(str) - 1] == ' ')) + while ((*str != '\0') && (str[strlen(str) - 1] == ' ')) cutFromStr(str, strlen(str) - 1, 1); // Merge double spaces diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index e2c25c3a22..ee73f14dfa 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -30,7 +30,6 @@ #include "graphics/cursorman.h" #include "graphics/fontman.h" #include "graphics/surface.h" -#include "graphics/dither.h" #include "gob/gob.h" #include "gob/video.h" @@ -39,8 +38,6 @@ #include "gob/dataio.h" #include "gob/draw.h" -#include "gob/driver_vga.h" - namespace Gob { Font::Font(const byte *data) : _dataPtr(data) { @@ -90,84 +87,68 @@ uint16 Font::getCharCount() const { return _endItem - _startItem + 1; } -uint8 Font::getFirstChar() const { - return _startItem; -} - -uint8 Font::getLastChar() const { - return _endItem; -} - -uint8 Font::getCharSize() const { - return _itemSize; -} - bool Font::isMonospaced() const { return _charWidths == 0; } -const byte *Font::getCharData(uint8 c) const { - if (_endItem == 0) { - warning("Font::getCharData(): _endItem == 0"); - return 0; +void Font::drawLetter(Surface &surf, uint8 c, uint16 x, uint16 y, + uint32 color1, uint32 color2, bool transp) const { + + uint16 data; + + const byte *src = getCharData(c); + if (!src) { + warning("Font::drawLetter(): getCharData() == 0"); + return; } - if ((c < _startItem) || (c > _endItem)) - return 0; + Pixel dst = surf.get(x, y); - return _data + (c - _startItem) * _itemSize; -} + int nWidth = _itemWidth; + if (nWidth & 7) + nWidth = (nWidth & 0xF8) + 8; + nWidth >>= 3; -SurfaceDesc::SurfaceDesc(int16 vidMode, int16 width, int16 height, - byte *vidMem) : _width(width), _height(height) { + for (int i = 0; i < _itemHeight; i++) { + int width = _itemWidth; - if (vidMem) { - _vidMode = vidMode; - _ownVidMem = false; - _vidMem = vidMem; - } else { - _vidMode = vidMode; - _ownVidMem = true; - _vidMem = new byte[width * height]; - assert(_vidMem); - memset(_vidMem, 0, width * height); - } -} + for (int k = 0; k < nWidth; k++) { -void SurfaceDesc::setVidMem(byte *vidMem) { - assert(vidMem); + data = *src++; + for (int j = 0; j < MIN(8, width); j++) { + if (data & 0x80) + dst.set(color1); + else if (!transp) + dst.set(color2); - if (hasOwnVidMem()) - delete[] _vidMem; + dst++; + data <<= 1; + } - _ownVidMem = false; - _vidMem = vidMem; -} + width -= 8; -void SurfaceDesc::resize(int16 width, int16 height) { - if (hasOwnVidMem()) - delete[] _vidMem; + } - _width = width; - _height = height; - _ownVidMem = true; - _vidMem = new byte[width * height]; - assert(_vidMem); - memset(_vidMem, 0, width * height); + dst += surf.getWidth() - _itemWidth; + } } -void SurfaceDesc::swap(SurfaceDesc &surf) { - SWAP(_width, surf._width); - SWAP(_height, surf._height); - SWAP(_vidMode, surf._vidMode); - SWAP(_ownVidMem, surf._ownVidMem); - SWAP(_vidMem, surf._vidMem); +const byte *Font::getCharData(uint8 c) const { + if (_endItem == 0) { + warning("Font::getCharData(): _endItem == 0"); + return 0; + } + + if ((c < _startItem) || (c > _endItem)) + return 0; + + return _data + (c - _startItem) * _itemSize; } + Video::Video(GobEngine *vm) : _vm(vm) { _doRangeClamp = false; - _videoDriver = 0; _surfWidth = 320; _surfHeight = 200; @@ -186,24 +167,9 @@ Video::Video(GobEngine *vm) : _vm(vm) { _lastSparse = 0xFFFFFFFF; _dirtyAll = false; - - _palLUT = new Graphics::PaletteLUT(5, Graphics::PaletteLUT::kPaletteYUV); -} - -char Video::initDriver(int16 vidMode) { - if (_videoDriver) - return 1; - - _videoDriver = new VGAVideoDriver(); - return 1; } Video::~Video() { - delete _palLUT; -} - -void Video::freeDriver() { - delete _videoDriver; } void Video::initPrimary(int16 mode) { @@ -215,9 +181,6 @@ void Video::initPrimary(int16 mode) { mode = 3; _vm->_global->_oldMode = mode; - if (mode != 3) - Video::initDriver(mode); - if (mode != 3) { initSurfDesc(mode, _surfWidth, _surfHeight, PRIMARY_SURFACE); @@ -226,8 +189,8 @@ void Video::initPrimary(int16 mode) { } } -SurfaceDescPtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { - SurfaceDescPtr descPtr; +SurfacePtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { + SurfacePtr descPtr; if (flags & PRIMARY_SURFACE) assert((width == _surfWidth) && (height == _surfHeight)); @@ -240,14 +203,13 @@ SurfaceDescPtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int descPtr = _vm->_global->_primarySurfDesc; descPtr->resize(width, height); - descPtr->_vidMode = vidMode; } else { assert(!(flags & DISABLE_SPR_ALLOC)); if (!(flags & SCUMMVM_CURSOR)) width = (width + 7) & 0xFFF8; - descPtr = SurfaceDescPtr(new SurfaceDesc(vidMode, width, height)); + descPtr = SurfacePtr(new Surface(width, height, _vm->getPixelFormat().bytesPerPixel)); } return descPtr; } @@ -257,14 +219,16 @@ void Video::clearScreen() { } void Video::setSize(bool defaultTo1XScaler) { - initGraphics(_vm->_width, _vm->_height, defaultTo1XScaler); + if (_vm->isTrueColor()) + initGraphics(_vm->_width, _vm->_height, defaultTo1XScaler, 0); + else + initGraphics(_vm->_width, _vm->_height, defaultTo1XScaler); } void Video::retrace(bool mouse) { if (mouse) CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); if (_vm->_global->_primarySurfDesc) { - int screenOffset = _scrollOffsetY * _surfWidth + _scrollOffsetX; int screenX = _screenDeltaX; int screenY = _screenDeltaY; int screenWidth = MIN<int>(_surfWidth - _scrollOffsetX, _vm->_width); @@ -275,18 +239,15 @@ void Video::retrace(bool mouse) { if (_splitSurf) { - screenOffset = 0; screenX = 0; screenY = _vm->_height - _splitSurf->getHeight(); screenWidth = MIN<int>(_vm->_width, _splitSurf->getWidth()); screenHeight = _splitSurf->getHeight(); - g_system->copyRectToScreen(_splitSurf->getVidMem() + screenOffset, - _splitSurf->getWidth(), screenX, screenY, screenWidth, screenHeight); + _splitSurf->blitToScreen(0, 0, screenWidth - 1, screenHeight - 1, screenX, screenY); } else if (_splitHeight2 > 0) { - screenOffset = _splitStart * _surfWidth; screenX = 0; screenY = _vm->_height - _splitHeight2; screenWidth = MIN<int>(_surfWidth, _vm->_width); @@ -318,191 +279,58 @@ void Video::sparseRetrace(int max) { _lastSparse = timeKey; } -void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc &dest) { - if ((x >= dest.getWidth()) || (x < 0) || - (y >= dest.getHeight()) || (y < 0)) - return; +void Video::drawPacked(byte *sprBuf, int16 width, int16 height, + int16 x, int16 y, byte transp, Surface &dest) { - _videoDriver->putPixel(x, y, color, dest); -} - -void Video::fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, - int16 bottom, int16 color) { - - if (_doRangeClamp) { - if (left > right) - SWAP(left, right); - if (top > bottom) - SWAP(top, bottom); + int destRight = x + width; + int destBottom = y + height; - if ((left >= dest.getWidth()) || (right < 0) || - (top >= dest.getHeight()) || (bottom < 0)) - return; + Pixel dst = dest.get(x, y); - left = CLIP(left, (int16)0, (int16)(dest.getWidth() - 1)); - top = CLIP(top, (int16)0, (int16)(dest.getHeight() - 1)); - right = CLIP(right, (int16)0, (int16)(dest.getWidth() - 1)); - bottom = CLIP(bottom, (int16)0, (int16)(dest.getHeight() - 1)); - } - - _videoDriver->fillRect(dest, left, top, right, bottom, color); -} + int curx = x; + int cury = y; -void Video::drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, - int16 y1, int16 color) { - - if ((x0 == x1) || (y0 == y1)) - Video::fillRect(dest, x0, y0, x1, y1, color); - else - _videoDriver->drawLine(dest, x0, y0, x1, y1, color); -} - -/* - * The original's version of the Bresenham Algorithm was a bit "unclean" - * and produced strange edges at 45, 135, 225 and 315 degrees, so using the - * version found in the Wikipedia article about the - * "Bresenham's line algorithm" instead - */ -void Video::drawCircle(SurfaceDesc &dest, int16 x0, int16 y0, - int16 radius, int16 color) { - int16 f = 1 - radius; - int16 ddFx = 0; - int16 ddFy = -2 * radius; - int16 x = 0; - int16 y = radius; - int16 tmpPattern = (_vm->_draw->_pattern & 0xFF); - - if (tmpPattern == 0) { - putPixel(x0, y0 + radius, color, dest); - putPixel(x0, y0 - radius, color, dest); - putPixel(x0 + radius, y0, color, dest); - putPixel(x0 - radius, y0, color, dest); - } else - warning ("Video::drawCircle - pattern %d", _vm->_draw->_pattern); + while (1) { + uint8 val = *sprBuf++; + unsigned int repeat = val & 7; + val &= 0xF8; - while (x < y) { - if (f >= 0) { - y--; - ddFy += 2; - f += ddFy; + if (!(val & 8)) { + repeat <<= 8; + repeat |= *sprBuf++; } - x++; - ddFx += 2; - f += ddFx + 1; - - switch (tmpPattern) { - case -1: - fillRect(dest, x0 - y, y0 + x, x0 + y, y0 + x, color); - fillRect(dest, x0 - x, y0 + y, x0 + x, y0 + y, color); - fillRect(dest, x0 - y, y0 - x, x0 + y, y0 - x, color); - fillRect(dest, x0 - x, y0 - y, x0 + x, y0 - y, color); - break; - case 0: - putPixel(x0 + x, y0 + y, color, dest); - putPixel(x0 - x, y0 + y, color, dest); - putPixel(x0 + x, y0 - y, color, dest); - putPixel(x0 - x, y0 - y, color, dest); - putPixel(x0 + y, y0 + x, color, dest); - putPixel(x0 - y, y0 + x, color, dest); - putPixel(x0 + y, y0 - x, color, dest); - putPixel(x0 - y, y0 - x, color, dest); - break; - default: - fillRect(dest, x0 + y - tmpPattern, y0 + x - tmpPattern, x0 + y, y0 + x, color); - fillRect(dest, x0 + x - tmpPattern, y0 + y - tmpPattern, x0 + x, y0 + y, color); - fillRect(dest, x0 - y, y0 + x - tmpPattern, x0 - y + tmpPattern, y0 + x, color); - fillRect(dest, x0 - x, y0 + y - tmpPattern, x0 - x + tmpPattern, y0 + y, color); - fillRect(dest, x0 + y - tmpPattern, y0 - x, x0 + y, y0 - x + tmpPattern, color); - fillRect(dest, x0 + x - tmpPattern, y0 - y, x0 + x, y0 - y + tmpPattern, color); - fillRect(dest, x0 - y, y0 - x, x0 - y + tmpPattern, y0 - x + tmpPattern, color); - fillRect(dest, x0 - x, y0 - y, x0 - x + tmpPattern, y0 - y + tmpPattern, color); - break; + repeat++; + val >>= 4; + + for (unsigned int i = 0; i < repeat; ++i) { + if (curx < dest.getWidth() && cury < dest.getHeight()) + if (!transp || val) + dst.set(val); + + dst++; + curx++; + if (curx == destRight) { + dst += dest.getWidth() + x - curx; + curx = x; + cury++; + if (cury == destBottom) + return; + } } - } -} - -void Video::clearSurf(SurfaceDesc &dest) { - Video::fillRect(dest, 0, 0, dest.getWidth() - 1, dest.getHeight() - 1, 0); -} - -void Video::drawSprite(SurfaceDesc &source, SurfaceDesc &dest, - int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { - int16 destRight; - int16 destBottom; - if (_doRangeClamp) { - if (left > right) - SWAP(left, right); - if (top > bottom) - SWAP(top, bottom); - - if ((left >= source.getWidth()) || (right < 0) || - (top >= source.getHeight()) || (bottom < 0)) - return; - - if (left < 0) { - x -= left; - left = 0; - } - if (top < 0) { - y -= top; - top = 0; - } - right = CLIP(right, (int16)0, (int16)(source.getWidth() - 1)); - bottom = CLIP(bottom, (int16)0, (int16)(source.getHeight() - 1)); - if (right - left >= source.getWidth()) - right = left + source.getWidth() - 1; - if (bottom - top >= source.getHeight()) - bottom = top + source.getHeight() - 1; - - if (x < 0) { - left -= x; - x = 0; - } - if (y < 0) { - top -= y; - y = 0; - } - if ((x >= dest.getWidth()) || (left > right) || - (y >= dest.getHeight()) || (top > bottom)) - return; - - destRight = x + right - left; - destBottom = y + bottom - top; - if (destRight >= dest.getWidth()) - right -= destRight - dest.getWidth() + 1; - - if (destBottom >= dest.getHeight()) - bottom -= destBottom - dest.getHeight() + 1; } - - _videoDriver->drawSprite(source, dest, left, top, right, bottom, x, y, transp); -} - -void Video::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, - int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { - - _videoDriver->drawSpriteDouble(source, dest, left, top, right, bottom, x, y, transp); -} - -void Video::drawLetter(int16 item, int16 x, int16 y, const Font &font, - int16 color1, int16 color2, int16 transp, SurfaceDesc &dest) { - assert(item != 0x00); - _videoDriver->drawLetter((unsigned char)item, x, y, font, color1, color2, transp, dest); } void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, int16 transp, SurfaceDesc &dest) { + int16 x, int16 y, int16 transp, Surface &dest) { if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest)) return; - _vm->validateVideoMode(dest._vidMode); - - _videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest); + drawPacked(sprBuf, width, height, x, y, transp, dest); } -void Video::drawPackedSprite(const char *path, SurfaceDesc &dest, int width) { +void Video::drawPackedSprite(const char *path, Surface &dest, int width) { byte *data; data = _vm->_dataIO->getData(path); @@ -521,7 +349,8 @@ void Video::setPalElem(int16 index, char red, char green, char blue, _vm->_global->_bluePalette[index] = blue; setPalColor(pal, red, green, blue); - g_system->setPalette(pal, index, 1); + if (_vm->getPixelFormat().bytesPerPixel == 1) + g_system->setPalette(pal, index, 1); } void Video::setPalette(PalDesc *palDesc) { @@ -534,7 +363,8 @@ void Video::setPalette(PalDesc *palDesc) { for (int i = 0; i < numcolors; i++) setPalColor(pal + i * 4, palDesc->vgaPal[i]); - g_system->setPalette(pal, 0, numcolors); + if (_vm->getPixelFormat().bytesPerPixel == 1) + g_system->setPalette(pal, 0, numcolors); } void Video::setFullPalette(PalDesc *palDesc) { @@ -549,7 +379,8 @@ void Video::setFullPalette(PalDesc *palDesc) { setPalColor(pal + i * 4, colors[i]); } - g_system->setPalette(pal, 0, 256); + if (_vm->getPixelFormat().bytesPerPixel == 1) + g_system->setPalette(pal, 0, 256); } else Video::setPalette(palDesc); } @@ -587,61 +418,26 @@ void Video::dirtyRectsAdd(int16 left, int16 top, int16 right, int16 bottom) { } void Video::dirtyRectsApply(int left, int top, int width, int height, int x, int y) { - byte *vidMem = _vm->_global->_primarySurfDesc->getVidMem(); - if (_dirtyAll) { - g_system->copyRectToScreen(vidMem + top * _surfWidth + left, - _surfWidth, x, y, width, height); + _vm->_global->_primarySurfDesc->blitToScreen(left, top, left + width - 1, top + height - 1, x, y); return; } - int right = left + width; - int bottom = top + height; + int right = left + width; + int bottom = top + height; Common::List<Common::Rect>::const_iterator it; for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) { - int l = MAX<int>(left, it->left); - int t = MAX<int>(top, it->top); - int r = MIN<int>(right, it->right); + int l = MAX<int>(left , it->left); + int t = MAX<int>(top , it->top); + int r = MIN<int>(right , it->right); int b = MIN<int>(bottom, it->bottom); - int w = r - l; - int h = b - t; - if ((w <= 0) || (h <= 0)) + if ((r <= l) || (b <= t)) continue; - byte *v = vidMem + t * _surfWidth + l; - - g_system->copyRectToScreen(v, _surfWidth, x + (l - left), y + (t - top), w, h); + _vm->_global->_primarySurfDesc->blitToScreen(l, t, r - 1, b - 1, x + (l - left), y + (t - top)); } } -void Video::initOSD() { - const byte palOSD[] = { - 0, 0, 0, 0, - 0, 0, 171, 0, - 0, 171, 0, 0, - 0, 171, 171, 0, - 171, 0, 0, 0 - }; - - g_system->setPalette(palOSD, 0, 5); -} - -void Video::drawOSDText(const char *text) { - const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kOSDFont)); - uint32 color = 0x2; - Graphics::Surface surf; - - surf.create(g_system->getWidth(), font.getFontHeight(), 1); - - font.drawString(&surf, text, 0, 0, surf.w, color, Graphics::kTextAlignCenter); - - int y = g_system->getHeight() / 2 - font.getFontHeight() / 2; - g_system->copyRectToScreen((byte *)surf.pixels, surf.pitch, 0, y, surf.w, surf.h); - g_system->updateScreen(); - - surf.free(); -} - } // End of namespace Gob diff --git a/engines/gob/video.h b/engines/gob/video.h index b8a46598b7..5c49042496 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -31,29 +31,23 @@ #include "common/ptr.h" #include "gob/gob.h" - -namespace Graphics { - class PaletteLUT; -} +#include "gob/surface.h" namespace Gob { class Font { public: + Font(const byte *data); + ~Font(); + uint8 getCharWidth (uint8 c) const; uint8 getCharWidth () const; uint8 getCharHeight() const; - uint16 getCharCount () const; - uint8 getFirstChar () const; - uint8 getLastChar () const; - uint8 getCharSize () const; bool isMonospaced() const; - const byte *getCharData(uint8 c) const; - - Font(const byte *data); - ~Font(); + void drawLetter(Surface &surf, uint8 c, uint16 x, uint16 y, + uint32 color1, uint32 color2, bool transp) const; private: const byte *_dataPtr; @@ -66,46 +60,19 @@ private: uint8 _endItem; int8 _itemSize; int8 _bitWidth; -}; - -// Some Surfaces are simultaneous in Draw::spritesArray and discrete -// variables, so if in doubt you should use a SurfaceDescPtr shared -// pointer object to refer to any SurfaceDesc. -class SurfaceDesc { -public: - int16 _vidMode; - - int16 getWidth() const { return _width; } - int16 getHeight() const { return _height; } - byte *getVidMem() { return _vidMem; } - const byte *getVidMem() const { return _vidMem; } - bool hasOwnVidMem() const { return _ownVidMem; } - void setVidMem(byte *vidMem); - void resize(int16 width, int16 height); - void swap(SurfaceDesc &surf); - - SurfaceDesc(int16 vidMode, int16 width, int16 height, byte *vidMem = 0); - ~SurfaceDesc() { if (_ownVidMem) delete[] _vidMem; } - -private: - int16 _width; - int16 _height; - byte *_vidMem; - bool _ownVidMem; + uint16 getCharCount() const; + const byte *getCharData(uint8 c) const; }; -typedef Common::SharedPtr<SurfaceDesc> SurfaceDescPtr; - - class Video { public: -#define GDR_VERSION 4 +#define GDR_VERSION 4 -#define PRIMARY_SURFACE 0x80 -#define RETURN_PRIMARY 0x01 -#define DISABLE_SPR_ALLOC 0x20 -#define SCUMMVM_CURSOR 0x100 +#define PRIMARY_SURFACE 0x80 +#define RETURN_PRIMARY 0x01 +#define DISABLE_SPR_ALLOC 0x20 +#define SCUMMVM_CURSOR 0x100 #include "common/pack-start.h" // START STRUCT PACKING @@ -132,7 +99,7 @@ public: int16 _scrollOffsetX; int16 _scrollOffsetY; - SurfaceDescPtr _splitSurf; + SurfacePtr _splitSurf; int16 _splitHeight1; int16 _splitHeight2; int16 _splitStart; @@ -140,11 +107,8 @@ public: int16 _screenDeltaX; int16 _screenDeltaY; - Graphics::PaletteLUT *_palLUT; - - void freeDriver(); void initPrimary(int16 mode); - SurfaceDescPtr initSurfDesc(int16 vidMode, int16 width, + SurfacePtr initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); void setSize(bool defaultTo1XScaler); @@ -154,25 +118,9 @@ public: void waitRetrace(bool mouse = true); void sparseRetrace(int max); - void putPixel(int16 x, int16 y, int16 color, SurfaceDesc &dest); - virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, - int16 right, int16 bottom, int16 color); - void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, - int16 color); - void drawCircle(SurfaceDesc &dest, int16 x0, int16 y0, - int16 radius, int16 color); - void clearSurf(SurfaceDesc &dest); - void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, - int16 left, int16 top, int16 right, int16 bottom, - int16 x, int16 y, int16 transp); - void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, - int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void drawLetter(int16 item, int16 x, int16 y, const Font &font, - int16 color1, int16 color2, int16 transp, SurfaceDesc &dest); void drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, int16 transp, SurfaceDesc &dest); - void drawPackedSprite(const char *path, SurfaceDesc &dest, - int width = 320); + int16 x, int16 y, int16 transp, Surface &dest); + void drawPackedSprite(const char *path, Surface &dest, int width = 320); void setPalColor(byte *pal, byte red, byte green, byte blue) { pal[0] = red << 2; @@ -196,18 +144,12 @@ public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x, int16 y, int16 transp, - SurfaceDesc &destDesc) = 0; - - virtual void init() {} - - virtual void setPrePalette() { } + Surface &destDesc) = 0; Video(class GobEngine *vm); virtual ~Video(); protected: - class VideoDriver *_videoDriver; - bool _dirtyAll; Common::List<Common::Rect> _dirtyRects; @@ -216,16 +158,13 @@ protected: GobEngine *_vm; - char initDriver(int16 vidMode); - - void initOSD(); - void drawOSDText(const char *text); + void drawPacked(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, Surface &dest); }; class Video_v1 : public Video { public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc &destDesc); + int16 x, int16 y, int16 transp, Surface &destDesc); Video_v1(GobEngine *vm); virtual ~Video_v1() {} @@ -234,7 +173,7 @@ public: class Video_v2 : public Video_v1 { public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc &destDesc); + int16 x, int16 y, int16 transp, Surface &destDesc); Video_v2(GobEngine *vm); virtual ~Video_v2() {} @@ -243,14 +182,7 @@ public: class Video_v6 : public Video_v2 { public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc &destDesc); - - virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, - int16 right, int16 bottom, int16 color); - - virtual void init(); - - virtual void setPrePalette(); + int16 x, int16 y, int16 transp, Surface &destDesc); Video_v6(GobEngine *vm); virtual ~Video_v6() {} @@ -260,30 +192,17 @@ private: void buildPalLUT(); - void shadeRect(SurfaceDesc &dest, + void shadeRect(Surface &dest, int16 left, int16 top, int16 right, int16 bottom, byte color, byte strength); - void drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc &surfDesc); - void drawYUVData(const byte *srcData, SurfaceDesc &destDesc, + void drawPacked(const byte *sprBuf, int16 x, int16 y, Surface &surfDesc); + void drawYUVData(const byte *srcData, Surface &destDesc, int16 width, int16 height, int16 x, int16 y); - void drawYUV(SurfaceDesc &destDesc, int16 x, int16 y, + void drawYUV(Surface &destDesc, int16 x, int16 y, int16 dataWidth, int16 dataHeight, int16 width, int16 height, const byte *dataY, const byte *dataU, const byte *dataV); }; -class VideoDriver { -public: - VideoDriver() {} - virtual ~VideoDriver() {} - virtual void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; - virtual void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; - virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0; - virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest) = 0; - virtual void drawLetter(unsigned char item, int16 x, int16 y, const Font &font, byte color1, byte color2, byte transp, SurfaceDesc &dest) = 0; - virtual void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0; - virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc &dest) = 0; -}; - } // End of namespace Gob #endif // GOB_VIDEO_H diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp index 699ac5f934..5c2f17d7dd 100644 --- a/engines/gob/video_v1.cpp +++ b/engines/gob/video_v1.cpp @@ -34,9 +34,9 @@ Video_v1::Video_v1(GobEngine *vm) : Video(vm) { } char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc &destDesc) { + int16 x, int16 y, int16 transp, Surface &destDesc) { byte *memBuffer; - byte *srcPtr, *destPtr, *linePtr; + byte *srcPtr; byte temp; uint16 sourceLeft; uint16 cmdVar; @@ -46,7 +46,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 bufPos; int16 strLen; - _vm->validateVideoMode(destDesc._vidMode); + //_vm->validateVideoMode(destDesc._vidMode); if (sprBuf[0] != 1) return 0; @@ -55,9 +55,8 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 0; if (sprBuf[2] == 2) { - SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); - Video::drawSprite(sourceDesc, destDesc, 0, 0, srcWidth - 1, - srcHeight - 1, x, y, transp); + Surface sourceDesc(srcWidth, srcHeight, 1, sprBuf + 3); + destDesc.blit(sourceDesc, 0, 0, srcWidth - 1, srcHeight - 1, x, y, (transp == 0) ? -1 : 0); return 1; } else { memBuffer = new byte[4114]; @@ -66,12 +65,12 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, srcPtr = sprBuf + 3; sourceLeft = READ_LE_UINT16(srcPtr); - destPtr = destDesc.getVidMem() + destDesc.getWidth() * y + x; + Pixel destPtr = destDesc.get(x, y); curWidth = 0; curHeight = 0; - linePtr = destPtr; + Pixel linePtr = destPtr; srcPtr += 4; for (offset = 0; offset < 4078; offset++) @@ -88,7 +87,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, if ((cmdVar & 1) != 0) { temp = *srcPtr++; if ((temp != 0) || (transp == 0)) - *destPtr = temp; + destPtr.set(temp); destPtr++; curWidth++; if (curWidth >= srcWidth) { @@ -116,7 +115,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, for (counter2 = 0; counter2 < strLen; counter2++) { temp = memBuffer[(offset + counter2) % 4096]; if ((temp != 0) || (transp == 0)) - *destPtr = temp; + destPtr.set(temp); destPtr++; curWidth++; diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index 98cf4a5d4f..c908ccf7b1 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -34,9 +34,9 @@ Video_v2::Video_v2(GobEngine *vm) : Video_v1(vm) { } char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc &destDesc) { + int16 x, int16 y, int16 transp, Surface &destDesc) { byte *memBuffer; - byte *srcPtr, *destPtr, *linePtr; + byte *srcPtr; byte temp; uint32 sourceLeft; uint16 cmdVar; @@ -47,7 +47,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 strLen; int16 lenCmd; - _vm->validateVideoMode(destDesc._vidMode); + //_vm->validateVideoMode(destDesc._vidMode); if (sprBuf[0] != 1) return 0; @@ -56,9 +56,8 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 0; if (sprBuf[2] == 2) { - SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); - Video::drawSprite(sourceDesc, destDesc, 0, 0, srcWidth - 1, - srcHeight - 1, x, y, transp); + Surface sourceDesc(srcWidth, srcHeight, 1, sprBuf + 3); + destDesc.blit(sourceDesc, 0, 0, srcWidth - 1, srcHeight - 1, x, y, (transp == 0) ? -1 : 0); return 1; } else if (sprBuf[2] == 1) { memBuffer = new byte[4370]; @@ -70,12 +69,12 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, sourceLeft = READ_LE_UINT32(srcPtr); - destPtr = destDesc.getVidMem() + destDesc.getWidth() * y + x; + Pixel destPtr = destDesc.get(x, y); curWidth = 0; curHeight = 0; - linePtr = destPtr; + Pixel linePtr = destPtr; srcPtr += 4; if ((READ_LE_UINT16(srcPtr) == 0x1234) && (READ_LE_UINT16(srcPtr + 2) == 0x5678)) { @@ -99,7 +98,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, temp = *srcPtr++; if ((temp != 0) || (transp == 0)) - *destPtr = temp; + destPtr.set(temp); destPtr++; curWidth++; @@ -133,7 +132,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, temp = memBuffer[(offset + counter2) % 4096]; if ((temp != 0) || (transp == 0)) - *destPtr = temp; + destPtr.set(temp); destPtr++; curWidth++; diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp index 7285cd8958..7bf728034b 100644 --- a/engines/gob/video_v6.cpp +++ b/engines/gob/video_v6.cpp @@ -25,7 +25,8 @@ #include "common/endian.h" #include "common/savefile.h" -#include "graphics/dither.h" + +#include "graphics/conversion.h" #include "gob/gob.h" #include "gob/video.h" @@ -38,46 +39,8 @@ namespace Gob { Video_v6::Video_v6(GobEngine *vm) : Video_v2(vm) { } -void Video_v6::setPrePalette() { - byte *tpal = (byte *)_vm->_draw->_vgaPalette; - const byte *fpal = (const byte *)_ditherPalette; - - for (int i = 0; i < 256; i++) { - byte r, g, b; - - Graphics::PaletteLUT::YUV2RGB(fpal[i * 3 + 0], fpal[i * 3 + 1], fpal[i * 3 + 2], - r, g, b); - - tpal[i * 3 + 0] = r >> 2; - tpal[i * 3 + 1] = g >> 2; - tpal[i * 3 + 2] = b >> 2; - } - _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - -} - -void Video_v6::init() { - initOSD(); - - buildPalLUT(); -} - -void Video_v6::buildPalLUT() { - char text[30]; - - _palLUT->setPalette(_ditherPalette, Graphics::PaletteLUT::kPaletteYUV, 8, 0); - - sprintf(text, "Building palette table"); - drawOSDText(text); - - for (int i = 0; (i < 32) && !_vm->shouldQuit(); i++) - _palLUT->buildNext(); -} - char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc &destDesc) { - _vm->validateVideoMode(destDesc._vidMode); + int16 x, int16 y, int16 transp, Surface &destDesc) { if ((sprBuf[0] == 1) && (sprBuf[1] == 3)) { drawPacked(sprBuf, x, y, destDesc); @@ -93,9 +56,7 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, if (Video_v2::spriteUncompressor(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc)) return 1; - _vm->validateVideoMode(destDesc._vidMode); - - _videoDriver->drawPackedSprite(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc); + Video::drawPacked(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc); return 1; } @@ -104,7 +65,8 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 1; } -void Video_v6::fillRect(SurfaceDesc &dest, +/* +void Video_v6::fillRect(Surface &dest, int16 left, int16 top, int16 right, int16 bottom, int16 color) { if (!(color & 0xFF00)) { @@ -136,17 +98,21 @@ void Video_v6::fillRect(SurfaceDesc &dest, byte strength = 16 - (((uint16) color) >> 12); shadeRect(dest, left, top, right, bottom, color, strength); } +*/ -void Video_v6::shadeRect(SurfaceDesc &dest, +void Video_v6::shadeRect(Surface &dest, int16 left, int16 top, int16 right, int16 bottom, byte color, byte strength) { + warning("TODO: Video_v6::shadeRect()"); + + /* int width = right - left + 1; int height = bottom - top + 1; int dWidth = dest.getWidth(); byte *vidMem = dest.getVidMem() + dWidth * top + left; byte sY, sU, sV; - _palLUT->getEntry(color, sY, sU, sV); + //_palLUT->getEntry(color, sY, sU, sV); int shadeY = sY * (16 - strength); int shadeU = sU * (16 - strength); @@ -176,9 +142,10 @@ void Video_v6::shadeRect(SurfaceDesc &dest, } delete dither; + */ } -void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc &surfDesc) { +void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, Surface &surfDesc) { const byte *data = sprBuf + 2; int16 width = READ_LE_UINT16(data); @@ -204,7 +171,7 @@ void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc &sur delete[] uncBuf; } -void Video_v6::drawYUVData(const byte *srcData, SurfaceDesc &destDesc, +void Video_v6::drawYUVData(const byte *srcData, Surface &destDesc, int16 width, int16 height, int16 x, int16 y) { int16 dataWidth = width; @@ -223,106 +190,46 @@ void Video_v6::drawYUVData(const byte *srcData, SurfaceDesc &destDesc, } -void Video_v6::drawYUV(SurfaceDesc &destDesc, int16 x, int16 y, +void Video_v6::drawYUV(Surface &destDesc, int16 x, int16 y, int16 dataWidth, int16 dataHeight, int16 width, int16 height, const byte *dataY, const byte *dataU, const byte *dataV) { - byte *vidMem = destDesc.getVidMem() + y * destDesc.getWidth() + x; + const Graphics::PixelFormat &pixelFormat = _vm->getPixelFormat(); if ((x + width - 1) >= destDesc.getWidth()) width = destDesc.getWidth() - x; if ((y + height - 1) >= destDesc.getHeight()) height = destDesc.getHeight() - y; - Graphics::SierraLight *dither = - new Graphics::SierraLight(width, _palLUT); + Pixel dst = destDesc.get(x, y); for (int i = 0; i < height; i++) { - byte *dest = vidMem; + Pixel dstRow = dst; + const byte *srcY = dataY + i * dataWidth; const byte *srcU = dataU + (i >> 2) * (dataWidth >> 2); const byte *srcV = dataV + (i >> 2) * (dataWidth >> 2); for (int j = 0; j < (width >> 2); j++, srcU++, srcV++) { - for (int n = 0; n < 4; n++, dest++, srcY++) { + for (int n = 0; n < 4; n++, dstRow++, srcY++) { byte dY = *srcY << 1, dU = *srcU << 1, dV = *srcV << 1; - *dest = (dY == 0) ? 0 : dither->dither(dY, dU, dV, j * 4 + n); + byte r, g, b; + Graphics::YUV2RGB(dY, dU, dV, r, g, b); + + if (dY != 0) { + uint32 c = pixelFormat.RGBToColor(r, g, b); + + dstRow.set((c == 0) ? 1 : c); + } else + dstRow.set(0); + } } - dither->nextLine(); - vidMem += destDesc.getWidth(); + dst += destDesc.getWidth(); } - delete dither; } -const byte Video_v6::_ditherPalette[768] = { - 0x00,0x80,0x80,0x26,0x6B,0xC0,0x4B,0x56,0x4B,0x71,0x41,0x8B, - 0x0E,0xC0,0x76,0x34,0xAB,0xB6,0x59,0x96,0x41,0xBE,0x81,0x81, - 0xCF,0x77,0x75,0xC1,0x9B,0x6C,0x7F,0x81,0x81,0x7F,0x81,0x81, - 0x0A,0x8C,0x8A,0x0A,0xB0,0x79,0x0E,0x9D,0x76,0x0E,0x79,0x76, - 0x10,0x77,0x75,0x09,0x7B,0x8B,0x16,0x74,0xA6,0x16,0x74,0xA6, - 0x12,0x91,0x93,0x13,0xB5,0x72,0x1B,0x9E,0x6D,0x1A,0x7A,0x6D, - 0x1C,0x71,0x6C,0x1B,0x72,0x8C,0x1B,0x71,0xAE,0x1B,0x71,0xAE, - 0x21,0x93,0x93,0x21,0xB8,0x6F,0x27,0xA3,0x64,0x27,0x7F,0x65, - 0x29,0x69,0x68,0x28,0x69,0x8E,0x23,0x6F,0xB7,0x2A,0x69,0xB2, - 0x36,0x94,0x92,0x35,0xB9,0x6E,0x35,0xA6,0x5D,0x34,0x80,0x5D, - 0x39,0x61,0x6B,0x3A,0x60,0x8F,0x34,0x6E,0xB9,0x39,0x60,0xB5, - 0x46,0x93,0x95,0x48,0xB6,0x6F,0x45,0xA6,0x5C,0x47,0x80,0x5C, - 0x4B,0x56,0x6D,0x4B,0x56,0x91,0x47,0x6F,0xB7,0x4A,0x57,0xB5, - 0x5A,0x94,0x92,0x59,0xB9,0x6E,0x59,0xA6,0x5D,0x59,0x82,0x5D, - 0x5B,0x4D,0x6D,0x5A,0x4E,0x92,0x5B,0x6F,0xB7,0x5C,0x4D,0xB6, - 0x6D,0x94,0x93,0x6D,0xB8,0x6F,0x6D,0xA5,0x5D,0x6C,0x7F,0x5E, - 0x6C,0x4A,0x70,0x6D,0x4A,0x94,0x6C,0x6E,0xB9,0x6C,0x4A,0xBA, - 0x7E,0x94,0x93,0x80,0xB6,0x6F,0x7D,0xA6,0x5D,0x7F,0x81,0x5B, - 0x7F,0x4A,0x6F,0x7F,0x4A,0x92,0x7E,0x6F,0xB7,0x7E,0x4B,0xB7, - 0x92,0x94,0x93,0x90,0xB8,0x6F,0x91,0xA5,0x5C,0x90,0x81,0x5D, - 0x91,0x4B,0x6D,0x91,0x4C,0x93,0x93,0x6F,0xB7,0x92,0x4B,0xB7, - 0xA5,0x91,0x93,0xA2,0xB2,0x6F,0xA5,0xA6,0x5D,0xA4,0x80,0x5D, - 0xA3,0x4A,0x6F,0xA4,0x49,0x93,0xA4,0x6F,0xB9,0xA3,0x4B,0xB9, - 0xB6,0x94,0x93,0xB4,0xA9,0x71,0xB6,0xA5,0x5C,0xB8,0x80,0x5C, - 0xB7,0x4B,0x6F,0xB6,0x4C,0x93,0xB5,0x70,0xB3,0xB5,0x4C,0xB3, - 0xC9,0x93,0x92,0xC3,0xA0,0x72,0xC7,0x9E,0x5E,0xC9,0x82,0x5D, - 0xCA,0x4B,0x6E,0xCA,0x4B,0x93,0xC2,0x73,0xA9,0xC2,0x4F,0xA9, - 0xDD,0x92,0x93,0xD4,0x97,0x74,0xD9,0x94,0x60,0xDD,0x80,0x5E, - 0xDB,0x4B,0x6F,0xDD,0x4A,0x93,0xCE,0x76,0xA1,0xCE,0x52,0xA1, - 0xE8,0x8B,0x8E,0xE6,0x8C,0x76,0xE7,0x8C,0x61,0xE6,0x86,0x62, - 0xE3,0x51,0x78,0xEA,0x4D,0x8D,0xDC,0x79,0x97,0xDC,0x55,0x97, - 0xFA,0x81,0x81,0xF8,0x82,0x83,0xF4,0x85,0x77,0xF2,0x79,0x79, - 0xF4,0x65,0x86,0xF8,0x75,0x83,0xEF,0x87,0x89,0xF0,0x67,0x89, - 0xEE,0x81,0x81,0xE8,0x8B,0x85,0xED,0x88,0x71,0xEA,0x71,0x73, - 0xEE,0x5D,0x81,0xEA,0x71,0x8D,0xE4,0x87,0x91,0xE4,0x63,0x91, - 0xDB,0x81,0x81,0xD7,0x95,0x83,0xDB,0x93,0x6F,0xDB,0x6F,0x6F, - 0xDC,0x5C,0x80,0xDD,0x6E,0x93,0xD7,0x83,0x9B,0xD6,0x5F,0x9B, - 0xCA,0x81,0x81,0xC8,0x9D,0x82,0xC8,0x94,0x6E,0xCA,0x6F,0x6E, - 0xC9,0x5D,0x81,0xCA,0x6F,0x93,0xC9,0x82,0xA5,0xC8,0x5E,0xA5, - 0xB6,0x81,0x81,0xB6,0xA5,0x80,0xB7,0x93,0x6F,0xB7,0x6F,0x6F, - 0xB6,0x5D,0x81,0xB6,0x70,0x93,0xB8,0x80,0xA5,0xB7,0x5C,0xA5, - 0xA3,0x81,0x81,0xA4,0xA7,0x81,0xA3,0x92,0x6F,0xA3,0x6E,0x6F, - 0xA5,0x5C,0x7F,0xA5,0x6D,0x93,0xA4,0x80,0xA5,0xA4,0x5C,0xA5, - 0x92,0x81,0x81,0x93,0xA5,0x81,0x90,0x94,0x6F,0x92,0x6F,0x6D, - 0x92,0x5D,0x81,0x92,0x70,0x93,0x91,0x82,0xA7,0x91,0x5E,0xA7, - 0x7F,0x81,0x81,0x7F,0xA5,0x81,0x80,0x92,0x70,0x7F,0x6E,0x6F, - 0x7F,0x5D,0x81,0x7D,0x70,0x93,0x80,0x80,0xA5,0x80,0x5C,0xA5, - 0x6B,0x81,0x81,0x6C,0xA7,0x80,0x6D,0x94,0x6F,0x6C,0x6E,0x6F, - 0x6D,0x5B,0x80,0x6D,0x6E,0x93,0x6C,0x81,0xA5,0x6C,0x5D,0xA5, - 0x5A,0x81,0x81,0x5A,0xA5,0x81,0x59,0x95,0x6E,0x5A,0x6F,0x6E, - 0x5B,0x5D,0x81,0x59,0x70,0x93,0x5A,0x81,0xA7,0x5A,0x5D,0xA7, - 0x47,0x81,0x81,0x47,0xA5,0x80,0x47,0x92,0x6F,0x47,0x6E,0x6F, - 0x46,0x5D,0x81,0x46,0x6F,0x95,0x49,0x81,0xA5,0x48,0x5D,0xA5, - 0x32,0x81,0x81,0x33,0xA7,0x81,0x35,0x95,0x6E,0x34,0x6F,0x6F, - 0x36,0x62,0x7E,0x35,0x6E,0x93,0x34,0x80,0xA5,0x36,0x62,0xA4, - 0x23,0x81,0x81,0x23,0xA5,0x80,0x20,0x94,0x6F,0x22,0x6F,0x6D, - 0x26,0x6B,0x7E,0x21,0x6F,0x93,0x22,0x82,0xA7,0x25,0x6C,0xA4, - 0x0E,0x81,0x81,0x0F,0xA5,0x81,0x13,0x91,0x73,0x15,0x75,0x71, - 0x14,0x75,0x7D,0x11,0x77,0x93,0x15,0x7D,0xA1,0x16,0x74,0xA1, - 0x00,0x80,0x80,0x07,0xA0,0x7B,0x05,0x8F,0x7D,0x09,0x7B,0x7A, - 0x07,0x7D,0x7B,0x07,0x7C,0x8C,0x0E,0x78,0x98,0x0E,0x78,0x98, - 0x7F,0x81,0x81,0x80,0x83,0x81,0xF7,0x7C,0x84,0x9E,0x83,0x80, - 0x7F,0x81,0x81,0x4B,0x56,0xFE,0x93,0x2D,0x17,0xDE,0x03,0x95, - 0x1C,0xFE,0x6C,0x67,0xD4,0xEA,0xAF,0xAB,0x03,0xFA,0x81,0x81 -}; - } // End of namespace Gob diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 9e49bfc092..f349413b93 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -155,8 +155,8 @@ int VideoPlayer::openVideo(bool primary, const Common::String &file, Properties video->decoder->setXY(0, 0); } else { video->surface = _vm->_draw->_spritesArray[properties.sprite]; - video->decoder->setSurfaceMemory(video->surface->getVidMem(), - video->surface->getWidth(), video->surface->getHeight(), 1); + video->decoder->setSurfaceMemory(video->surface->getData(), + video->surface->getWidth(), video->surface->getHeight(), video->surface->getBPP()); if (!ownSurf || (ownSurf && screenSize)) { if ((properties.x >= 0) || (properties.y >= 0)) diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index d91d0a3845..c154254455 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -137,7 +137,7 @@ private: Graphics::CoktelDecoder *decoder; Common::String fileName; - SurfaceDescPtr surface; + SurfacePtr surface; Video(); |