GOB: Hook up the PE cursors to v7 loadCursor

Addy Junior / Adibou2 now shows proper cursors.
Thanks to clone2727 for the constant nagging. :P
This commit is contained in:
Sven Hesse 2012-05-29 14:16:31 +02:00
parent e35e4a1f68
commit aa7c44a070
8 changed files with 182 additions and 31 deletions

View File

@ -117,6 +117,13 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
_cursorAnimDelays[i] = 0;
}
_cursorPalettes = 0;
_cursorKeyColors = 0;
_cursorPaletteStarts = 0;
_cursorPaletteCounts = 0;
_cursorHotspotsX = 0;
_cursorHotspotsY = 0;
_palLoadData1[0] = 0;
_palLoadData1[1] = 17;
_palLoadData1[2] = 34;
@ -134,6 +141,13 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
}
Draw::~Draw() {
delete[] _cursorPalettes;
delete[] _cursorKeyColors;
delete[] _cursorPaletteStarts;
delete[] _cursorPaletteCounts;
delete[] _cursorHotspotsX;
delete[] _cursorHotspotsY;
for (int i = 0; i < kFontCount; i++)
delete _fonts[i];
}

View File

@ -145,6 +145,13 @@ public:
int8 _cursorAnimHigh[40];
int8 _cursorAnimDelays[40];
byte *_cursorPalettes;
byte *_cursorKeyColors;
uint16 *_cursorPaletteStarts;
uint16 *_cursorPaletteCounts;
int32 *_cursorHotspotsX;
int32 *_cursorHotspotsY;
int16 _palLoadData1[4];
int16 _palLoadData2[4];

View File

@ -83,7 +83,7 @@ void Draw_v2::blitCursor() {
void Draw_v2::animateCursor(int16 cursor) {
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
uint16 hotspotX = 0, hotspotY = 0;
uint16 hotspotX, hotspotY;
_showCursor |= 1;
@ -133,27 +133,42 @@ void Draw_v2::animateCursor(int16 cursor) {
}
// '------
newX = _vm->_global->_inter_mouseX;
newY = _vm->_global->_inter_mouseY;
hotspotX = 0;
hotspotY = 0;
if (_cursorHotspotXVar != -1) {
newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar);
newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar);
hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar);
hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar);
} else if (_cursorHotspotX != -1) {
newX -= hotspotX = _cursorHotspotX;
newY -= hotspotY = _cursorHotspotY;
hotspotX = _cursorHotspotX;
hotspotY = _cursorHotspotY;
} else if (_cursorHotspotsX != 0) {
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);
if ((_vm->getGameType() != kGameTypeAdibou2) &&
(_vm->getGameType() != kGameTypeAdi2) &&
(_vm->getGameType() != kGameTypeAdi4))
CursorMan.replaceCursor(_scummvmCursor->getData(),
_cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat());
uint32 keyColor = 0;
if (_cursorKeyColors)
keyColor = _cursorKeyColors[cursorIndex];
CursorMan.replaceCursor(_scummvmCursor->getData(),
_cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat());
if (_cursorPalettes) {
CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3),
_cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]);
CursorMan.disableCursorPalette(false);
} else
CursorMan.disableCursorPalette(true);
if (_frontSurface != _backSurface) {
if (!_noInvalidated) {

View File

@ -31,6 +31,10 @@
#include "gob/iniconfig.h"
#include "gob/databases.h"
namespace Common {
class PEResources;
}
namespace Gob {
class Cheater_Geisha;
@ -648,7 +652,7 @@ private:
class Inter_v7 : public Inter_Playtoons {
public:
Inter_v7(GobEngine *vm);
virtual ~Inter_v7() {}
virtual ~Inter_v7();
protected:
virtual void setupOpcodesDraw();
@ -684,7 +688,11 @@ private:
INIConfig _inis;
Databases _databases;
Common::PEResources *_cursors;
Common::String findFile(const Common::String &mask);
bool loadCursorFile();
};
} // End of namespace Gob

View File

@ -22,8 +22,11 @@
#include "common/endian.h"
#include "common/archive.h"
#include "common/winexe.h"
#include "common/winexe_pe.h"
#include "graphics/cursorman.h"
#include "graphics/wincursor.h"
#include "gob/gob.h"
#include "gob/global.h"
@ -42,7 +45,11 @@ 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) {
Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm), _cursors(0) {
}
Inter_v7::~Inter_v7() {
delete _cursors;
}
void Inter_v7::setupOpcodesDraw() {
@ -88,25 +95,100 @@ void Inter_v7::o7_draw0x0C() {
void Inter_v7::o7_loadCursor() {
int16 cursorIndex = _vm->_game->_script->readValExpr();
Common::String cursorFile = _vm->_game->_script->evalString();
Common::String cursorName = _vm->_game->_script->evalString();
warning("Addy Stub: Load cursor \"%s\" to %d", cursorFile.c_str(), 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);
byte cursor[9];
byte palette[6];
Graphics::WinCursorGroup *cursorGroup = 0;
Graphics::Cursor *defaultCursor = 0;
cursor[0] = 0; cursor[1] = 0; cursor[2] = 0;
cursor[3] = 0; cursor[4] = 1; cursor[5] = 0;
cursor[6] = 0; cursor[7] = 0; cursor[8] = 0;
// Load the cursor file and cursor group
if (loadCursorFile())
cursorGroup = Graphics::WinCursorGroup::createCursorGroup(*_cursors, Common::WinResourceID(cursorName));
palette[0] = 0; palette[1] = 0; palette[2] = 0;
palette[3] = 255; palette[4] = 255; palette[5] = 255;
// If the requested cursor does not exist, create a default one
const Graphics::Cursor *cursor = 0;
if (!cursorGroup || cursorGroup->cursors.empty() || !cursorGroup->cursors[0].cursor) {
defaultCursor = Graphics::makeDefaultWinCursor();
CursorMan.pushCursorPalette(palette, 0, 2);
CursorMan.disableCursorPalette(false);
CursorMan.replaceCursor(cursor, 3, 3, 1, 1, 255);
cursor = defaultCursor;
} else
cursor = cursorGroup->cursors[0].cursor;
CursorMan.showMouse(true);
// Cursor sprite dimensions mismatch, recreate the cursor sprites
if ((cursor->getWidth() > _vm->_draw->_cursorWidth ) ||
(cursor->getHeight() > _vm->_draw->_cursorHeight) ||
(_vm->_draw->_cursorSprites->getWidth() < ((cursorIndex + 1) * _vm->_draw->_cursorWidth)) ||
!_vm->_draw->_cursorPalettes) {
const int count = cursorIndex + 1;
_vm->_draw->freeSprite(Draw::kCursorSurface);
_vm->_draw->_cursorSprites.reset();
_vm->_draw->_cursorSpritesBack.reset();
_vm->_draw->_scummvmCursor.reset();
_vm->_draw->_cursorWidth = MAX<uint16>(cursor->getWidth() , _vm->_draw->_cursorWidth);
_vm->_draw->_cursorHeight = MAX<uint16>(cursor->getHeight(), _vm->_draw->_cursorHeight);
_vm->_draw->_transparentCursor = 1;
_vm->_draw->initSpriteSurf(Draw::kCursorSurface, _vm->_draw->_cursorWidth * count,
_vm->_draw->_cursorHeight, 2);
_vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface];
_vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack;
_vm->_draw->_scummvmCursor =
_vm->_video->initSurfDesc(_vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, SCUMMVM_CURSOR);
for (int i = 0; i < 40; i++) {
_vm->_draw->_cursorAnimLow[i] = -1;
_vm->_draw->_cursorAnimDelays[i] = 0;
_vm->_draw->_cursorAnimHigh[i] = 0;
}
_vm->_draw->_cursorAnimLow[1] = 0;
delete[] _vm->_draw->_cursorPalettes;
delete[] _vm->_draw->_cursorKeyColors;
delete[] _vm->_draw->_cursorPaletteStarts;
delete[] _vm->_draw->_cursorPaletteCounts;
delete[] _vm->_draw->_cursorHotspotsX;
delete[] _vm->_draw->_cursorHotspotsY;
_vm->_draw->_cursorPalettes = new byte[256 * 3 * 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->_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));
}
Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface());
_vm->_draw->_cursorSprites->blit(cursorSurf, 0, 0, cursor->getWidth() - 1, cursor->getHeight() - 1,
cursorIndex * _vm->_draw->_cursorWidth, 0, 0);
memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3);
_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;
}
void Inter_v7::o7_displayWarning() {
@ -529,4 +611,19 @@ Common::String Inter_v7::findFile(const Common::String &mask) {
return files.front()->getName();
}
bool Inter_v7::loadCursorFile() {
if (_cursors)
return true;
_cursors = new Common::PEResources();
if (_cursors->loadFromEXE("cursor32.dll"))
return true;
delete _cursors;
_cursors = 0;
return false;
}
} // End of namespace Gob

View File

@ -280,6 +280,18 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) :
_ownVidMem = false;
}
Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) :
_width(width), _height(height), _bpp(bpp), _vidMem(0) {
assert((_width > 0) && (_height > 0));
assert((_bpp == 1) || (_bpp == 2));
_vidMem = new byte[_bpp * _width * _height];
_ownVidMem = true;
memcpy(_vidMem, vidMem, _bpp * _width * _height);
}
Surface::~Surface() {
if (_ownVidMem)
delete[] _vidMem;

View File

@ -122,6 +122,7 @@ private:
class Surface {
public:
Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem = 0);
Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem);
~Surface();
uint16 getWidth () const;

View File

@ -226,10 +226,7 @@ void Video::setSize(bool defaultTo1XScaler) {
void Video::retrace(bool mouse) {
if (mouse)
if ((_vm->getGameType() != kGameTypeAdibou2) &&
(_vm->getGameType() != kGameTypeAdi2) &&
(_vm->getGameType() != kGameTypeAdi4))
CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
if (_vm->_global->_primarySurfDesc) {
int screenX = _screenDeltaX;