NANCY: Fix The Vampire Diaries's cursors

Fixed the cursors in The Vampire Diaries so they display correctly.
This commit is contained in:
fracturehill 2021-04-24 23:36:47 +03:00
parent 8b8d3b38de
commit c86d46fcde
4 changed files with 39 additions and 18 deletions

View File

@ -31,6 +31,7 @@ const GameConstants gameConstants[] {
120,
{ 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 125, 219, 220, -1 },
{ 110, 111, 112, 113, 114, -1 },
8,
10
},
@ -42,7 +43,8 @@ const GameConstants gameConstants[] {
{ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -1 },
7
12,
7
},
// Nancy Drew: Stay Tuned For Danger
@ -53,7 +55,8 @@ const GameConstants gameConstants[] {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1 },
7 // TODO
12, // TODO
7 // TODO
}
};

View File

@ -33,6 +33,7 @@ struct GameConstants {
uint numEventFlags;
int mapAccessSceneIDs[18];
int eventFlagsToClearOnSceneChange[32];
uint numNonItemCursors;
uint numCurtainAnimationFrames;
};

View File

@ -27,23 +27,27 @@
#include "engines/nancy/graphics.h"
#include "engines/nancy/resource.h"
#include "engines/nancy/util.h"
#include "engines/nancy/constants.h"
namespace Nancy {
void CursorManager::init() {
Common::SeekableReadStream *chunk = g_nancy->getBootChunkStream("INV");
chunk->seek(0x1D2); // TODO
chunk->seek(0xD6 + g_nancy->getConstants().numCurtainAnimationFrames * 0x20 + 0x1C);
Common::String inventoryCursorsImageName = chunk->readString();
chunk = g_nancy->getBootChunkStream("CURS");
_cursors.reserve(56);
for (uint i = 0; i < 56; ++i) {
chunk->seek(0);
uint numCursors = g_nancy->getConstants().numNonItemCursors + g_nancy->getConstants().numItems * 4;
_cursors.reserve(numCursors);
for (uint i = 0; i < numCursors; ++i) {
_cursors.push_back(Cursor());
chunk->seek(i * 16, SEEK_SET);
readRect(*chunk, _cursors[i].bounds);
chunk->seek(0x380 + i * 8, SEEK_SET);
_cursors[i].hotspot.x = chunk->readUint32LE();
_cursors[i].hotspot.y = chunk->readUint32LE();
Cursor &cur = _cursors.back();
readRect(*chunk, cur.bounds);
chunk->seek(numCursors * 16 + i * 8, SEEK_SET);
cur.hotspot.x = chunk->readUint32LE();
cur.hotspot.y = chunk->readUint32LE();
}
readRect(*chunk, _primaryVideoInactiveZone);
@ -103,17 +107,29 @@ void CursorManager::setCursor(CursorType type, int16 itemID) {
surf = &g_nancy->_graphicsManager->_object0;
}
// TODO this is ridiculous, figure out why just calling
// GetBasePtr() results in garbage
Graphics::Surface s;
s.create(bounds.width(), bounds.height(), surf->format);
s.copyRectToSurface(*surf, 0, 0, bounds);
// Create a temporary surface to hold the cursor since giving replaceCursor() a pointer
// to the original surface results in garbage. This also makes it so we don't have to deal
// with TVD's palettes
Graphics::ManagedSurface temp;
temp.create(bounds.width(), bounds.height(), g_nancy->_graphicsManager->getScreenPixelFormat());
temp.blitFrom(*surf, bounds, Common::Point());
// TODO hotspots are terrible for arrow cursors, fix that??
CursorMan.replaceCursor(s.getPixels(), s.w, s.h, hotspot.x, hotspot.y, g_nancy->_graphicsManager->getTransColor(), false, &g_nancy->_graphicsManager->getInputPixelFormat());
s.free();
// Convert the trans color from the original format to the screen format
uint transColor;
if (g_nancy->getGameFlags() & NGF_8BITCOLOR) {
uint8 r, g, b;
uint32 input = surf->getPalette()[1];
r = input & 0xFF;
g = (input & 0xFF00) >> 8;
b = (input & 0xFF0000) >> 16;
transColor = temp.format.RGBToColor(r, g, b);
} else {
uint8 r, g, b;
surf->format.colorToRGB(g_nancy->_graphicsManager->getTransColor(), r, g, b);
transColor = temp.format.RGBToColor(r, g, b);
}
CursorMan.replaceCursor(temp.getPixels(), temp.w, temp.h, hotspot.x, hotspot.y, transColor, false, &temp.format);
}
void CursorManager::setCursorType(CursorType type) {

View File

@ -65,6 +65,7 @@ private:
Common::Point _primaryVideoInitialPos;
Graphics::ManagedSurface _invCursorsSurface;
Graphics::ManagedSurface _object0Copy;
CursorType _curCursorType;
int16 _curItemID;