GOB: fix a few cursor glitches in Adibou2

Try to mimic more closely what is done in the executable.

Fixes black squares sometimes blinking around the cursor (just after selecting the character, when hoovering seeds bags in the vegetable garden...), and fix a temporarily disappearing "waiting" cursor in some "change CD" screens.
This commit is contained in:
Simon Delamarre 2022-11-16 01:52:01 +01:00 committed by Eugene Sandulenko
parent abade0260d
commit 988d4882a2
No known key found for this signature in database
GPG Key ID: 014D387312D34F08
7 changed files with 397 additions and 188 deletions

View File

@ -386,6 +386,103 @@ void Draw::adjustCoords(char adjust, int16 *coord1, int16 *coord2) {
}
}
void Draw::resizeCursors(int16 width, int16 height, int16 count, bool transparency) {
if (width <= 0)
width = _vm->_draw->_cursorWidth;
if (height <= 0)
height = _vm->_draw->_cursorHeight;
_vm->_draw->_transparentCursor = transparency;
bool sameCursorDimensions = (_vm->_draw->_cursorWidth == width) && (_vm->_draw->_cursorHeight == height);
// Cursors sprite already big enough
if (sameCursorDimensions &&
_vm->_draw->_cursorCount >= count &&
_vm->_draw->_doCursorPalettes != nullptr)
return;
debugC(5, kDebugGraphics, "Resizing cursors: size %dx%d -> %dx%d, cursor count %d -> %d)",
_vm->_draw->_cursorWidth,
width,
_vm->_draw->_cursorHeight,
height,
_vm->_draw->_cursorCount,
count);
SurfacePtr oldCursorsSprites = _vm->_draw->_cursorSprites;
int oldCursorCount = _vm->_draw->_cursorCount;
_vm->_draw->_cursorCount = count;
_vm->_draw->_cursorWidth = width;
_vm->_draw->_cursorHeight = height;
_vm->_draw->freeSprite(Draw::kCursorSurface);
_vm->_draw->_cursorSprites.reset();
_vm->_draw->_cursorSpritesBack.reset();
_vm->_draw->_scummvmCursor.reset();
_vm->_draw->initSpriteSurf(Draw::kCursorSurface, width * count, height, 2);
_vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface];
_vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack;
if (sameCursorDimensions && oldCursorCount < count)
_vm->_draw->_cursorSprites->blit(*oldCursorsSprites);
oldCursorsSprites.reset();
_vm->_draw->_scummvmCursor = _vm->_video->initSurfDesc(width, height, SCUMMVM_CURSOR);
if (oldCursorCount < count || _vm->_draw->_doCursorPalettes == nullptr) {
bool *oldDoCursorPalettes = _vm->_draw->_doCursorPalettes;
byte *oldCursorPalettes = _vm->_draw->_cursorPalettes;
byte *oldCursorKeyColors = _vm->_draw->_cursorKeyColors;
uint16 *oldCursorPaletteStarts = _vm->_draw->_cursorPaletteStarts;
uint16 *oldCursorPaletteCounts = _vm->_draw->_cursorPaletteCounts;
int32 *oldCursorHotspotsX = _vm->_draw->_cursorHotspotsX;
int32 *oldCursorHotspotsY = _vm->_draw->_cursorHotspotsY;
_vm->_draw->_cursorPalettes = new byte[256 * 3 * count];
_vm->_draw->_doCursorPalettes = new bool[count];
_vm->_draw->_cursorKeyColors = new byte[count];
_vm->_draw->_cursorPaletteStarts = new uint16[count];
_vm->_draw->_cursorPaletteCounts = new uint16[count];
_vm->_draw->_cursorHotspotsX = new int32[count];
_vm->_draw->_cursorHotspotsY = new int32[count];
memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3);
memset(_vm->_draw->_doCursorPalettes , 0, count * sizeof(bool));
memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte));
memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16));
memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16));
memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32));
memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32));
if (sameCursorDimensions && oldCursorCount < count) {
if (oldCursorPalettes != nullptr)
memcpy(_vm->_draw->_cursorPalettes, oldCursorPalettes, oldCursorCount * 256 * 3);
if (oldDoCursorPalettes != nullptr)
memcpy(_vm->_draw->_doCursorPalettes, oldDoCursorPalettes, oldCursorCount * sizeof(bool));
if (oldCursorKeyColors != nullptr)
memcpy(_vm->_draw->_cursorKeyColors, oldCursorKeyColors, oldCursorCount * sizeof(byte));
if (oldCursorPaletteStarts != nullptr)
memcpy(_vm->_draw->_cursorPaletteStarts, oldCursorPaletteStarts, oldCursorCount * sizeof(uint16));
if (oldCursorPaletteCounts != nullptr)
memcpy(_vm->_draw->_cursorPaletteCounts, oldCursorPaletteCounts, oldCursorCount * sizeof(uint16));
if (oldCursorHotspotsX != nullptr)
memcpy(_vm->_draw->_cursorHotspotsX, oldCursorHotspotsX, oldCursorCount * sizeof(int32));
if (oldCursorHotspotsY != nullptr)
memcpy(_vm->_draw->_cursorHotspotsY, oldCursorHotspotsY, oldCursorCount * sizeof(int32));
}
delete[] oldDoCursorPalettes;
delete[] oldCursorPalettes;
delete[] oldCursorKeyColors;
delete[] oldCursorPaletteStarts;
delete[] oldCursorPaletteCounts;
delete[] oldCursorHotspotsX;
delete[] oldCursorHotspotsY;
}
}
int Draw::stringLength(const char *str, uint16 fontIndex) {
static const int8 japaneseExtraCharLen[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

View File

@ -22,6 +22,7 @@
#ifndef GOB_DRAW_H
#define GOB_DRAW_H
#include "common/winexe.h"
#include "gob/video.h"
namespace Gob {
@ -143,6 +144,9 @@ public:
int8 _cursorAnimLow[40];
int8 _cursorAnimHigh[40];
int8 _cursorAnimDelays[40];
Common::String _cursorNames[40];
Common::String _cursorName;
bool _isCursorFromExe;
int32 _cursorCount;
bool *_doCursorPalettes;
@ -191,6 +195,7 @@ public:
void adjustCoords(char adjust, uint16 *coord1, uint16 *coord2) {
adjustCoords(adjust, (int16 *)coord1, (int16 *)coord2);
}
void resizeCursors(int16 width, int16 height, int16 count, bool transparency);
int stringLength(const char *str, uint16 fontIndex);
void printTextCentered(int16 id, int16 left, int16 top, int16 right,
int16 bottom, const char *str, int16 fontIndex, int16 color);
@ -208,6 +213,7 @@ public:
virtual void initScreen() = 0;
virtual void closeScreen() = 0;
virtual void blitCursor() = 0;
virtual void animateCursor(int16 cursor) = 0;
virtual void printTotText(int16 id) = 0;
virtual void spriteOperation(int16 operation) = 0;
@ -298,6 +304,21 @@ public:
void spriteOperation(int16 operation) override;
};
class Draw_v7: public Draw_Playtoons {
public:
Draw_v7(GobEngine *vm);
~Draw_v7() override;
void animateCursor(int16 cursor) override;
private:
Common::WinResources *_cursors;
bool loadCursorFile();
bool loadCursorFromFile(int32 cursorIndex);
};
// Draw operations
#define DRAW_BLITSURF 0

269
engines/gob/draw_v7.cpp Normal file
View File

@ -0,0 +1,269 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/winexe_ne.h"
#include "common/winexe_pe.h"
#include "graphics/cursorman.h"
#include "gob/dataio.h"
#include "gob/draw.h"
#include "gob/game.h"
#include "gob/global.h"
#include "gob/hotspots.h"
#include "gob/inter.h"
#include "gob/resources.h"
#include "gob/scenery.h"
#include "gob/script.h"
#include "graphics/wincursor.h"
namespace Gob {
Draw_v7::Draw_v7(GobEngine *vm) : Draw_Playtoons(vm), _cursors(nullptr) {
}
Draw_v7::~Draw_v7() {
delete _cursors;
}
bool Draw_v7::loadCursorFile() {
if (_cursors)
return true;
if (_vm->_dataIO->hasFile("cursor32.dll")) {
_cursors = new Common::PEResources();
if (_cursors->loadFromEXE("cursor32.dll"))
return true;
}
else if (_vm->_dataIO->hasFile("cursor.dll")) {
_cursors = new Common::NEResources();
if (_cursors->loadFromEXE("cursor.dll"))
return true;
}
delete _cursors;
_cursors = nullptr;
return false;
}
bool Draw_v7::loadCursorFromFile(int cursorIndex) {
if (cursorIndex < 0 || cursorIndex >= 40)
return false;
Common::String cursorName = _cursorNames[cursorIndex];
Graphics::WinCursorGroup *cursorGroup = nullptr;
Graphics::Cursor *defaultCursor = nullptr;
// Load the cursor file and cursor group
if (loadCursorFile())
cursorGroup = Graphics::WinCursorGroup::createCursorGroup(_cursors, Common::WinResourceID(cursorName));
// If the requested cursor does not exist, create a default one
const Graphics::Cursor *cursor = nullptr;
if (!cursorGroup || cursorGroup->cursors.empty() || !cursorGroup->cursors[0].cursor) {
defaultCursor = Graphics::makeDefaultWinCursor();
cursor = defaultCursor;
} else
cursor = cursorGroup->cursors[0].cursor;
// Make sure the cursors sprite it big enough
resizeCursors(cursor->getWidth(), cursor->getHeight(), cursorIndex + 1, true);
Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface());
_vm->_draw->_cursorSprites->blit(cursorSurf, cursorIndex * _vm->_draw->_cursorWidth, 0);
memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3);
_vm->_draw->_doCursorPalettes [cursorIndex] = true;
_vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor();
_vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex();
_vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount();
_vm->_draw->_cursorHotspotsX [cursorIndex] = cursor->getHotspotX();
_vm->_draw->_cursorHotspotsY [cursorIndex] = cursor->getHotspotY();
delete cursorGroup;
delete defaultCursor;
return true;
}
void Draw_v7::animateCursor(int16 cursor) {
if (!_cursorSprites)
return;
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
uint16 hotspotX, hotspotY;
_showCursor |= 1;
// .-- _draw_animateCursorSUB1 ---
if (cursorIndex == -1) {
cursorIndex =
_vm->_game->_hotspots->findCursor(_vm->_global->_inter_mouseX,
_vm->_global->_inter_mouseY);
if (_cursorAnimLow[cursorIndex] == -1)
cursorIndex = 1;
}
// '------
if (_cursorAnimLow[cursorIndex] != -1) {
// .-- _draw_animateCursorSUB2 ---
if (cursorIndex == _cursorIndex) {
if ((_cursorAnimDelays[_cursorIndex] != 0) &&
((_cursorTimeKey + (_cursorAnimDelays[_cursorIndex] * 10)) <=
_vm->_util->getTimeKey())) {
_cursorAnim++;
if ((_cursorAnimHigh[_cursorIndex] < _cursorAnim) ||
(_cursorAnimLow[_cursorIndex] > _cursorAnim))
_cursorAnim = _cursorAnimLow[_cursorIndex];
_cursorTimeKey = _vm->_util->getTimeKey();
} else {
if (_noInvalidated && (_vm->_global->_inter_mouseX == _cursorX) &&
(_vm->_global->_inter_mouseY == _cursorY)) {
_vm->_video->waitRetrace();
return;
}
}
} else {
_cursorIndex = cursorIndex;
if (_cursorAnimDelays[cursorIndex] != 0) {
_cursorAnim = _cursorAnimLow[cursorIndex];
_cursorTimeKey = _vm->_util->getTimeKey();
}
}
if (_cursorAnimDelays[_cursorIndex] != 0) {
if ((_cursorAnimHigh[_cursorIndex] < _cursorAnim) ||
(_cursorAnimLow[_cursorIndex] > _cursorAnim))
_cursorAnim = _cursorAnimLow[_cursorIndex];
//debugC(1, kDebugGraphics, "Draw_v7::animateCursor() - cursor index %d replaced by cursor anim '%d'", cursorIndex, _cursorAnim);
cursorIndex = _cursorAnim;
}
// '------
bool cursorChanged = _cursorNames[cursorIndex] != _cursorName;
if (((!_cursorNames[cursorIndex].empty() || _isCursorFromExe)) && cursorChanged) {
_cursorName = _cursorNames[cursorIndex];
// Clear the cursor sprite at that index
_vm->_draw->_cursorSprites->fillRect(cursorIndex * _vm->_draw->_cursorWidth, 0,
cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
_vm->_draw->_cursorHeight - 1, 0);
// If the cursor name is empty, that cursor will be drawn by the scripts
if (_cursorNames[cursorIndex].empty() || _cursorNames[cursorIndex] == "VIDE") { // "VIDE" is "empty" in french
for (int i = 0; i < 40; i++) {
_cursorNames[i].clear();
}
_isCursorFromExe = false;
// Make sure the cursors sprite is big enough and set to non-extern palette
resizeCursors(-1, -1, cursorIndex + 1, true);
_vm->_draw->_doCursorPalettes[cursorIndex] = false;
_cursorX = _vm->_global->_inter_mouseX;
_cursorY = _vm->_global->_inter_mouseY;
_showCursor &= ~1;
return;
}
else {
if (!loadCursorFromFile(cursorIndex)) {
_cursorX = _vm->_global->_inter_mouseX;
_cursorY = _vm->_global->_inter_mouseY;
return;
}
_isCursorFromExe = true;
}
}
if (cursorChanged || !_isCursorFromExe) {
hotspotX = 0;
hotspotY = 0;
if (_cursorHotspotXVar != -1) {
hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar);
hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar);
} else if (_cursorHotspotX != -1) {
hotspotX = _cursorHotspotX;
hotspotY = _cursorHotspotY;
} else if (_cursorHotspotsX != nullptr) {
hotspotX = _cursorHotspotsX[_cursorIndex];
hotspotY = _cursorHotspotsY[_cursorIndex];
}
newX = _vm->_global->_inter_mouseX - hotspotX;
newY = _vm->_global->_inter_mouseY - hotspotY;
_scummvmCursor->clear();
_scummvmCursor->blit(*_cursorSprites,
cursorIndex * _cursorWidth, 0,
(cursorIndex + 1) * _cursorWidth - 1,
_cursorHeight - 1, 0, 0);
uint32 keyColor = 0;
if (_doCursorPalettes && _cursorKeyColors && _doCursorPalettes[cursorIndex])
keyColor = _cursorKeyColors[cursorIndex];
CursorMan.replaceCursor(_scummvmCursor->getData(),
_cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, false, &_vm->getPixelFormat());
if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) {
CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3),
_cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]);
CursorMan.disableCursorPalette(false);
} else
CursorMan.disableCursorPalette(true);
}
if (_frontSurface != _backSurface) {
if (!_noInvalidated) {
int16 tmp = _cursorIndex;
_cursorIndex = -1;
blitInvalidated();
_cursorIndex = tmp;
} else {
_showCursor = 3;
_vm->_video->waitRetrace();
if (MIN(newY, _cursorY) < 50)
_vm->_util->delay(5);
}
if (!cursorChanged)
return;
}
} else {
blitCursor();
_cursorX = newX;
_cursorY = newY;
}
_showCursor &= ~1;
}
} // End of namespace Gob

View File

@ -627,7 +627,7 @@ Common::Error GobEngine::initGameParts() {
_video = new Video_v6(this);
_inter = new Inter_v7(this);
_mult = new Mult_v2(this);
_draw = new Draw_Playtoons(this);
_draw = new Draw_v7(this);
_map = new Map_v2(this);
_goblin = new Goblin_v7(this);
_scenery = new Scenery_v2(this);

View File

@ -671,7 +671,7 @@ protected:
class Inter_v7 : public Inter_Playtoons {
public:
Inter_v7(GobEngine *vm);
~Inter_v7() override;
~Inter_v7() override {};
protected:
void setupOpcodesDraw() override;
@ -679,7 +679,7 @@ protected:
void setupOpcodesGob() override;
void o7_draw0x0C();
void o7_loadCursorFromExec();
void o7_setCursorToLoadFromExec();
void o7_freeMult();
void o7_loadMultObject();
void o7_displayWarning();
@ -722,16 +722,12 @@ private:
INIConfig _inis;
Databases _databases;
Common::WinResources *_cursors;
Common::ArchiveMemberList _remainingFilesFromPreviousSearch;
Common::String _currentCDPath;
Common::String findFile(const Common::String &mask, const Common::String &previousFile);
void copyFile(const Common::String &sourceFile, const Common::String &destFile);
bool loadCursorFile();
void resizeCursors(int16 width, int16 height, int16 count, bool transparency);
bool setCurrentCDPath(const Common::FSNode &dir);
Common::Array<uint32> getAdibou2InstalledApplications();
};

View File

@ -52,18 +52,14 @@ namespace Gob {
#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x)
#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x)
Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm), _cursors(nullptr) {
}
Inter_v7::~Inter_v7() {
delete _cursors;
Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm) {
}
void Inter_v7::setupOpcodesDraw() {
Inter_Playtoons::setupOpcodesDraw();
OPCODEDRAW(0x0C, o7_draw0x0C);
OPCODEDRAW(0x0D, o7_loadCursorFromExec);
OPCODEDRAW(0x0D, o7_setCursorToLoadFromExec);
OPCODEDRAW(0x15, o7_freeMult);
OPCODEDRAW(0x17, o7_loadMultObject);
OPCODEDRAW(0x44, o7_displayWarning);
@ -114,110 +110,6 @@ void Inter_v7::o7_draw0x0C() {
WRITE_VAR(17, 0);
}
void Inter_v7::resizeCursors(int16 width, int16 height, int16 count, bool transparency) {
if (width <= 0)
width = _vm->_draw->_cursorWidth;
if (height <= 0)
height = _vm->_draw->_cursorHeight;
_vm->_draw->_transparentCursor = transparency;
bool sameCursorDimensions = (_vm->_draw->_cursorWidth == width) && (_vm->_draw->_cursorHeight == height);
// Cursors sprite already big enough
if (sameCursorDimensions &&
_vm->_draw->_cursorCount >= count &&
_vm->_draw->_doCursorPalettes != nullptr)
return;
debugC(5, kDebugGraphics, "Resizing cursors: size %dx%d -> %dx%d, cursor count %d -> %d)",
_vm->_draw->_cursorWidth,
width,
_vm->_draw->_cursorHeight,
height,
_vm->_draw->_cursorCount,
count);
SurfacePtr oldCursorsSprites = _vm->_draw->_cursorSprites;
int oldCursorCount = _vm->_draw->_cursorCount;
_vm->_draw->_cursorCount = count;
_vm->_draw->_cursorWidth = width;
_vm->_draw->_cursorHeight = height;
_vm->_draw->freeSprite(Draw::kCursorSurface);
_vm->_draw->_cursorSprites.reset();
_vm->_draw->_cursorSpritesBack.reset();
_vm->_draw->_scummvmCursor.reset();
_vm->_draw->initSpriteSurf(Draw::kCursorSurface, width * count, height, 2);
_vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface];
_vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack;
if (sameCursorDimensions && oldCursorCount < count)
_vm->_draw->_cursorSprites->blit(*oldCursorsSprites);
oldCursorsSprites.reset();
_vm->_draw->_scummvmCursor = _vm->_video->initSurfDesc(width, height, SCUMMVM_CURSOR);
for (int i = sameCursorDimensions ? oldCursorCount : 0; i < count; i++) {
_vm->_draw->_cursorAnimLow[i] = -1;
_vm->_draw->_cursorAnimDelays[i] = 0;
_vm->_draw->_cursorAnimHigh[i] = 0;
}
_vm->_draw->_cursorAnimLow[1] = 0;
if (oldCursorCount < count || _vm->_draw->_doCursorPalettes == nullptr) {
bool *oldDoCursorPalettes = _vm->_draw->_doCursorPalettes;
byte *oldCursorPalettes = _vm->_draw->_cursorPalettes;
byte *oldCursorKeyColors = _vm->_draw->_cursorKeyColors;
uint16 *oldCursorPaletteStarts = _vm->_draw->_cursorPaletteStarts;
uint16 *oldCursorPaletteCounts = _vm->_draw->_cursorPaletteCounts;
int32 *oldCursorHotspotsX = _vm->_draw->_cursorHotspotsX;
int32 *oldCursorHotspotsY = _vm->_draw->_cursorHotspotsY;
_vm->_draw->_cursorPalettes = new byte[256 * 3 * count];
_vm->_draw->_doCursorPalettes = new bool[count];
_vm->_draw->_cursorKeyColors = new byte[count];
_vm->_draw->_cursorPaletteStarts = new uint16[count];
_vm->_draw->_cursorPaletteCounts = new uint16[count];
_vm->_draw->_cursorHotspotsX = new int32[count];
_vm->_draw->_cursorHotspotsY = new int32[count];
memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3);
memset(_vm->_draw->_doCursorPalettes , 0, count * sizeof(bool));
memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte));
memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16));
memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16));
memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32));
memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32));
if (sameCursorDimensions && oldCursorCount < count) {
if (oldCursorPalettes != nullptr)
memcpy(_vm->_draw->_cursorPalettes, oldCursorPalettes, oldCursorCount * 256 * 3);
if (oldDoCursorPalettes != nullptr)
memcpy(_vm->_draw->_doCursorPalettes, oldDoCursorPalettes, oldCursorCount * sizeof(bool));
if (oldCursorKeyColors != nullptr)
memcpy(_vm->_draw->_cursorKeyColors, oldCursorKeyColors, oldCursorCount * sizeof(byte));
if (oldCursorPaletteStarts != nullptr)
memcpy(_vm->_draw->_cursorPaletteStarts, oldCursorPaletteStarts, oldCursorCount * sizeof(uint16));
if (oldCursorPaletteCounts != nullptr)
memcpy(_vm->_draw->_cursorPaletteCounts, oldCursorPaletteCounts, oldCursorCount * sizeof(uint16));
if (oldCursorHotspotsX != nullptr)
memcpy(_vm->_draw->_cursorHotspotsX, oldCursorHotspotsX, oldCursorCount * sizeof(int32));
if (oldCursorHotspotsY != nullptr)
memcpy(_vm->_draw->_cursorHotspotsY, oldCursorHotspotsY, oldCursorCount * sizeof(int32));
}
delete[] oldDoCursorPalettes;
delete[] oldCursorPalettes;
delete[] oldCursorKeyColors;
delete[] oldCursorPaletteStarts;
delete[] oldCursorPaletteCounts;
delete[] oldCursorHotspotsX;
delete[] oldCursorHotspotsY;
}
}
void Inter_v7::o7_loadCursor(OpFuncParams &params) {
int16 id = _vm->_game->_script->readInt16();
@ -275,7 +167,7 @@ void Inter_v7::o7_loadCursor(OpFuncParams &params) {
int16 cursorWidth = MAX(_vm->_draw->_cursorWidth, resource->getWidth());
int16 cursorHeight = MAX(_vm->_draw->_cursorHeight, resource->getHeight());
resizeCursors(cursorWidth, cursorHeight, index + 1, true);
_vm->_draw->resizeCursors(cursorWidth, cursorHeight, index + 1, true);
if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth())
return;
@ -291,57 +183,12 @@ void Inter_v7::o7_loadCursor(OpFuncParams &params) {
delete resource;
}
void Inter_v7::o7_loadCursorFromExec() {
void Inter_v7::o7_setCursorToLoadFromExec() {
int16 cursorIndex = _vm->_game->_script->readValExpr();
Common::String cursorName = _vm->_game->_script->evalString();
debugC(1, kDebugGraphics, "o7_setCursorToLoadFromExec : index=%d, cursorName=%s", cursorIndex, cursorName.c_str());
// Clear the cursor sprite at that index
_vm->_draw->_cursorSprites->fillRect(cursorIndex * _vm->_draw->_cursorWidth, 0,
cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
_vm->_draw->_cursorHeight - 1, 0);
// If the cursor name is empty, that cursor will be drawn by the scripts
if (cursorName.empty() || cursorName == "VIDE") { // "VIDE" is "empty" in french
// Make sure the cursors sprite is big enough and set to non-extern palette
resizeCursors(-1, -1, cursorIndex + 1, true);
_vm->_draw->_doCursorPalettes[cursorIndex] = false;
return;
}
Graphics::WinCursorGroup *cursorGroup = nullptr;
Graphics::Cursor *defaultCursor = nullptr;
// Load the cursor file and cursor group
if (loadCursorFile())
cursorGroup = Graphics::WinCursorGroup::createCursorGroup(_cursors, Common::WinResourceID(cursorName));
// If the requested cursor does not exist, create a default one
const Graphics::Cursor *cursor = nullptr;
if (!cursorGroup || cursorGroup->cursors.empty() || !cursorGroup->cursors[0].cursor) {
defaultCursor = Graphics::makeDefaultWinCursor();
cursor = defaultCursor;
} else
cursor = cursorGroup->cursors[0].cursor;
// Make sure the cursors sprite it big enough
resizeCursors(cursor->getWidth(), cursor->getHeight(), cursorIndex + 1, true);
Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface());
_vm->_draw->_cursorSprites->blit(cursorSurf, cursorIndex * _vm->_draw->_cursorWidth, 0);
memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3);
_vm->_draw->_doCursorPalettes [cursorIndex] = true;
_vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor();
_vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex();
_vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount();
_vm->_draw->_cursorHotspotsX [cursorIndex] = cursor->getHotspotX();
_vm->_draw->_cursorHotspotsY [cursorIndex] = cursor->getHotspotY();
delete cursorGroup;
delete defaultCursor;
_vm->_draw->_cursorNames[cursorIndex] = cursorName;
}
void Inter_v7::o7_freeMult() {
@ -1537,26 +1384,4 @@ void Inter_v7::o7_gob0x201(OpGobParams &params) {
WRITE_VAR(varIndex, 1);
}
bool Inter_v7::loadCursorFile() {
if (_cursors)
return true;
if (_vm->_dataIO->hasFile("cursor32.dll")) {
_cursors = new Common::PEResources();
if (_cursors->loadFromEXE("cursor32.dll"))
return true;
}
else if (_vm->_dataIO->hasFile("cursor.dll")) {
_cursors = new Common::NEResources();
if (_cursors->loadFromEXE("cursor.dll"))
return true;
}
delete _cursors;
_cursors = nullptr;
return false;
}
} // End of namespace Gob

View File

@ -15,6 +15,7 @@ MODULE_OBJS := \
draw.o \
draw_v1.o \
draw_v2.o \
draw_v7.o \
draw_bargon.o \
draw_fascin.o \
draw_playtoons.o \