Add LOOM cursor support
svn-id: r14703
This commit is contained in:
parent
5f3009d7d0
commit
28c32a9fb7
5 changed files with 106 additions and 65 deletions
|
@ -74,10 +74,10 @@ void CharsetRendererV3::setCurID(byte id) {
|
|||
if (_fontPtr == 0)
|
||||
error("CharsetRendererCommon::setCurID: charset %d not found!", id);
|
||||
|
||||
_nbChars = _fontPtr[4];
|
||||
_numChars = _fontPtr[4];
|
||||
_fontPtr += 6;
|
||||
_widthTable = _fontPtr;
|
||||
_fontPtr += _nbChars;
|
||||
_fontPtr += _numChars;
|
||||
}
|
||||
|
||||
// do spacing for variable width old-style font
|
||||
|
@ -981,12 +981,12 @@ void CharsetRendererV3::printChar(int chr) {
|
|||
}
|
||||
if (_ignoreCharsetMask || !vs->hasTwoBuffers) {
|
||||
dest_ptr = vs->getPixels(_left, drawTop);
|
||||
drawBits1(*vs, dest_ptr, char_ptr, drawTop, 8, 8);
|
||||
} else {
|
||||
dest_ptr = (byte *)_vm->gdi._textSurface.pixels + _top * _vm->gdi._textSurface.pitch + _left;
|
||||
drawBits1(_vm->gdi._textSurface, dest_ptr, char_ptr, drawTop, 8, 8);
|
||||
}
|
||||
|
||||
drawBits1(vs, dest_ptr, char_ptr, drawTop, 8, 8);
|
||||
|
||||
if (_str.left > _left)
|
||||
_str.left = _left;
|
||||
|
||||
|
@ -1002,6 +1002,14 @@ void CharsetRendererV3::printChar(int chr) {
|
|||
_str.bottom = _top + height;
|
||||
}
|
||||
|
||||
void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
|
||||
byte *char_ptr, *dest_ptr;
|
||||
char_ptr = _fontPtr + chr * 8;
|
||||
dest_ptr = (byte *)s.pixels + y * s.pitch + x;
|
||||
drawBits1(s, dest_ptr, char_ptr, y, 8, 8);
|
||||
}
|
||||
|
||||
|
||||
void CharsetRendererClassic::printChar(int chr) {
|
||||
int width, height, origWidth, origHeight;
|
||||
int offsX, offsY;
|
||||
|
@ -1101,15 +1109,15 @@ void CharsetRendererClassic::printChar(int chr) {
|
|||
dst = (byte *)_vm->gdi._textSurface.pixels + (_top - _vm->_screenTop) * _vm->gdi._textSurface.pitch + _left;
|
||||
}
|
||||
|
||||
back = dst;
|
||||
if (_blitAlso && vs->hasTwoBuffers) {
|
||||
back = dst;
|
||||
dst = vs->getBackPixels(_left, drawTop);
|
||||
}
|
||||
|
||||
if (is2byte) {
|
||||
drawBits1(vs, dst, charPtr, drawTop, origWidth, origHeight);
|
||||
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
|
||||
} else {
|
||||
drawBitsN(vs, dst, charPtr, *_fontPtr, drawTop, origWidth, origHeight);
|
||||
drawBitsN(*vs, dst, charPtr, *_fontPtr, drawTop, origWidth, origHeight);
|
||||
}
|
||||
|
||||
if (_blitAlso && vs->hasTwoBuffers) {
|
||||
|
@ -1143,7 +1151,26 @@ void CharsetRendererClassic::printChar(int chr) {
|
|||
_top -= offsY;
|
||||
}
|
||||
|
||||
void CharsetRendererClassic::drawBitsN(VirtScreen *vs, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) {
|
||||
void CharsetRendererClassic::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
|
||||
const byte *charPtr;
|
||||
byte *dst;
|
||||
|
||||
uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
|
||||
assert(charOffs < 0x10000);
|
||||
if (!charOffs)
|
||||
return;
|
||||
charPtr = _fontPtr + charOffs;
|
||||
|
||||
int width = charPtr[0];
|
||||
int height = charPtr[1];
|
||||
|
||||
charPtr += 4; // Skip over char header
|
||||
|
||||
dst = (byte *)s.pixels + y * s.pitch + x;
|
||||
drawBitsN(s, dst, charPtr, *_fontPtr, y, width, height);
|
||||
}
|
||||
|
||||
void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) {
|
||||
int y, x;
|
||||
int color;
|
||||
byte numbits, bits;
|
||||
|
@ -1152,7 +1179,7 @@ void CharsetRendererClassic::drawBitsN(VirtScreen *vs, byte *dst, const byte *sr
|
|||
bits = *src++;
|
||||
numbits = 8;
|
||||
|
||||
for (y = 0; y < height && y + drawTop < vs->h; y++) {
|
||||
for (y = 0; y < height && y + drawTop < s.h; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
color = (bits >> (8 - bpp)) & 0xFF;
|
||||
|
||||
|
@ -1167,30 +1194,30 @@ void CharsetRendererClassic::drawBitsN(VirtScreen *vs, byte *dst, const byte *sr
|
|||
numbits = 8;
|
||||
}
|
||||
}
|
||||
dst += vs->pitch - width;
|
||||
dst += s.pitch - width;
|
||||
}
|
||||
}
|
||||
|
||||
void CharsetRendererCommon::drawBits1(VirtScreen *vs, byte *dst, const byte *src, int drawTop, int width, int height) {
|
||||
void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
|
||||
int y, x;
|
||||
byte bits = 0;
|
||||
|
||||
for (y = 0; y < height && y + drawTop < vs->h; y++) {
|
||||
for (y = 0; y < height && y + drawTop < s.h; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
if ((x % 8) == 0)
|
||||
bits = *src++;
|
||||
if ((bits & revBitMask[x % 8]) && y + drawTop >= 0) {
|
||||
if (_dropShadow) {
|
||||
*(dst + 1) = _shadowColor;
|
||||
*(dst + vs->pitch) = _shadowColor;
|
||||
*(dst + vs->pitch + 1) = _shadowColor;
|
||||
*(dst + s.pitch) = _shadowColor;
|
||||
*(dst + s.pitch + 1) = _shadowColor;
|
||||
}
|
||||
*dst = _color;
|
||||
}
|
||||
dst++;
|
||||
}
|
||||
|
||||
dst += vs->pitch - width;
|
||||
dst += s.pitch - width;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ protected:
|
|||
ScummEngine *_vm;
|
||||
byte _curId;
|
||||
|
||||
virtual int getCharWidth(byte chr) = 0;
|
||||
|
||||
public:
|
||||
CharsetRenderer(ScummEngine *vm);
|
||||
virtual ~CharsetRenderer() {}
|
||||
|
@ -71,6 +69,7 @@ public:
|
|||
void clearCharsetMask();
|
||||
|
||||
virtual void printChar(int chr) = 0;
|
||||
virtual void drawChar(int chr, const Graphics::Surface &s, int x, int y) {}
|
||||
|
||||
int getStringWidth(int a, const byte *str);
|
||||
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
|
||||
|
@ -79,6 +78,7 @@ public:
|
|||
int getCurID() { return _curId; }
|
||||
|
||||
virtual int getFontHeight() = 0;
|
||||
virtual int getCharWidth(byte chr) = 0;
|
||||
|
||||
virtual void setColor(byte color) { _color = color; }
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ class CharsetRendererCommon : public CharsetRenderer {
|
|||
protected:
|
||||
byte *_fontPtr;
|
||||
|
||||
void drawBits1(VirtScreen *vs, byte *dst, const byte *src, int drawTop, int width, int height);
|
||||
void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height);
|
||||
|
||||
public:
|
||||
CharsetRendererCommon(ScummEngine *vm) : CharsetRenderer(vm) {}
|
||||
|
@ -99,46 +99,43 @@ public:
|
|||
|
||||
class CharsetRendererClassic : public CharsetRendererCommon {
|
||||
protected:
|
||||
int getCharWidth(byte chr);
|
||||
|
||||
void drawBitsN(VirtScreen *vs, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height);
|
||||
void drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height);
|
||||
|
||||
public:
|
||||
CharsetRendererClassic(ScummEngine *vm) : CharsetRendererCommon(vm) {}
|
||||
|
||||
void printChar(int chr);
|
||||
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
|
||||
|
||||
int getCharWidth(byte chr);
|
||||
};
|
||||
|
||||
class CharsetRendererV3 : public CharsetRendererCommon {
|
||||
protected:
|
||||
int _nbChars;
|
||||
int _numChars;
|
||||
byte *_widthTable;
|
||||
|
||||
int getCharWidth(byte chr);
|
||||
|
||||
public:
|
||||
CharsetRendererV3(ScummEngine *vm) : CharsetRendererCommon(vm) {}
|
||||
|
||||
void printChar(int chr);
|
||||
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
|
||||
void setCurID(byte id);
|
||||
void setColor(byte color);
|
||||
int getFontHeight() { return 8; }
|
||||
int getCharWidth(byte chr);
|
||||
};
|
||||
|
||||
class CharsetRendererV2 : public CharsetRendererV3 {
|
||||
protected:
|
||||
int getCharWidth(byte chr) { return 8; }
|
||||
|
||||
public:
|
||||
CharsetRendererV2(ScummEngine *vm, Common::Language language);
|
||||
|
||||
void setCurID(byte id) {}
|
||||
int getCharWidth(byte chr) { return 8; }
|
||||
};
|
||||
|
||||
class CharsetRendererNut : public CharsetRenderer {
|
||||
protected:
|
||||
int getCharWidth(byte chr);
|
||||
|
||||
NutRenderer *_fr[5];
|
||||
NutRenderer *_current;
|
||||
|
||||
|
@ -151,6 +148,7 @@ public:
|
|||
void setCurID(byte id);
|
||||
|
||||
int getFontHeight();
|
||||
int getCharWidth(byte chr);
|
||||
};
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "scumm/bomp.h"
|
||||
#include "scumm/charset.h"
|
||||
#include "scumm/intern.h"
|
||||
#include "scumm/object.h"
|
||||
#include "scumm/scumm.h"
|
||||
|
@ -41,7 +42,7 @@ static const byte default_cursor_colors[4] = {
|
|||
|
||||
|
||||
|
||||
static const uint16 default_cursor_images[5][16] = {
|
||||
static uint16 default_cursor_images[5][16] = {
|
||||
/* cross-hair */
|
||||
{ 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000, 0x7e3f,
|
||||
0x0000, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000 },
|
||||
|
@ -81,13 +82,6 @@ void ScummEngine::animateCursor() {
|
|||
}
|
||||
}
|
||||
|
||||
void ScummEngine::setCursor(int cursor) {
|
||||
if (cursor >= 0 && cursor <= 3)
|
||||
_currentCursor = cursor;
|
||||
else
|
||||
warning("setCursor(%d)", cursor);
|
||||
}
|
||||
|
||||
void ScummEngine::setCursorHotspot(int x, int y) {
|
||||
_cursor.hotspotX = x;
|
||||
_cursor.hotspotY = y;
|
||||
|
@ -259,6 +253,48 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
|
|||
updateCursor();
|
||||
}
|
||||
|
||||
void ScummEngine::redefineBuiltinCursorFromChar(int index, int chr) {
|
||||
// Cursor image in both Looms are based on images from charset.
|
||||
// For now we don't handle them.
|
||||
if (_gameId != GID_LOOM && _gameId != GID_LOOM256) {
|
||||
// FIXME: Actually: is this opcode ever called by a non-Loom game?
|
||||
// Which V3-V5 game besides Loom makes use of custom cursors, ever?
|
||||
warning("V3--V5 SO_CURSOR_IMAGE(%d,%d) called - tell Fingolfin where you saw this!", index, chr);
|
||||
}
|
||||
|
||||
// const int oldID = _charset->getCurID();
|
||||
|
||||
if (_version == 3) {
|
||||
_charset->setCurID(0);
|
||||
} else if (_version >= 4) {
|
||||
_charset->setCurID(1);
|
||||
}
|
||||
|
||||
Graphics::Surface s;
|
||||
byte buf[16*16];
|
||||
memset(buf, 123, 16*16);
|
||||
s.pixels = buf;
|
||||
s.w = _charset->getCharWidth(chr);
|
||||
s.h = _charset->getFontHeight();
|
||||
s.pitch = s.w;
|
||||
assert(s.w <= 16 && s.h <= 16);
|
||||
s.bytesPerPixel = 1;
|
||||
|
||||
_charset->drawChar(chr, s, 0, 0);
|
||||
|
||||
uint16 *ptr = default_cursor_images[index];
|
||||
memset(ptr, 0, 16 * sizeof(uint16));
|
||||
for (int h = 0; h < s.h; h++) {
|
||||
for (int w = 0; w < s.w; w++) {
|
||||
if (buf[s.pitch * h + w] != 123)
|
||||
*ptr |= 1 << (16 - w);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
// _charset->setCurID(oldID);
|
||||
}
|
||||
|
||||
void ScummEngine::setBuiltinCursor(int idx) {
|
||||
int i, j;
|
||||
byte color;
|
||||
|
@ -270,25 +306,7 @@ void ScummEngine::setBuiltinCursor(int idx) {
|
|||
else
|
||||
color = default_cursor_colors[idx];
|
||||
|
||||
// FIXME: None of the stock cursors are right for Loom. Why is that?
|
||||
// Fingolfing says: because it sets different cursor shapes --
|
||||
// check the SO_CURSOR_IMAGE opcode in script_v5.cpp; if we implement
|
||||
// that, this problem should be gone...
|
||||
|
||||
if (_gameId == GID_LOOM || _gameId == GID_LOOM256) {
|
||||
int w = 0;
|
||||
|
||||
_cursor.width = 8;
|
||||
_cursor.height = 8;
|
||||
_cursor.hotspotX = 0;
|
||||
_cursor.hotspotY = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
w += (i >= 6) ? -2 : 1;
|
||||
for (j = 0; j < w; j++)
|
||||
_grabbedCursor[i * 8 + j] = color;
|
||||
}
|
||||
} else if (_version <= 2) {
|
||||
if (_version <= 2) {
|
||||
_cursor.width = 23;
|
||||
_cursor.height = 21;
|
||||
_cursor.hotspotX = 11;
|
||||
|
|
|
@ -677,13 +677,7 @@ void ScummEngine_v5::o5_cursorCommand() {
|
|||
case 10: // SO_CURSOR_IMAGE
|
||||
i = getVarOrDirectByte(PARAM_1); // Cursor number
|
||||
j = getVarOrDirectByte(PARAM_2); // Charset letter to use
|
||||
// Cursor image in both Looms are based on images from charset.
|
||||
// For now we don't handle them.
|
||||
if (_gameId != GID_LOOM && _gameId != GID_LOOM256) {
|
||||
// FIXME: Actually: is this opcode ever called by a non-Loom game?
|
||||
// Which V3-V5 game besides Loom makes use of custom cursors, ever?
|
||||
warning("V3--V5 SO_CURSOR_IMAGE(%d,%d) called - tell Fingolfin where you saw this!", i, j);
|
||||
}
|
||||
redefineBuiltinCursorFromChar(i, j);
|
||||
break;
|
||||
case 11: // SO_CURSOR_HOTSPOT
|
||||
i = getVarOrDirectByte(PARAM_1);
|
||||
|
@ -692,7 +686,11 @@ void ScummEngine_v5::o5_cursorCommand() {
|
|||
setCursorHotspot(j, k);
|
||||
break;
|
||||
case 12: // SO_CURSOR_SET
|
||||
setCursor(getVarOrDirectByte(PARAM_1));
|
||||
i = getVarOrDirectByte(PARAM_1);
|
||||
if (i >= 0 && i <= 3)
|
||||
_currentCursor = i;
|
||||
else
|
||||
error("SO_CURSOR_SET: unsupported cursor id %d", i);
|
||||
break;
|
||||
case 13: // SO_CHARSET_SET
|
||||
initCharset(getVarOrDirectByte(PARAM_1));
|
||||
|
|
|
@ -936,12 +936,12 @@ protected:
|
|||
void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
|
||||
void desaturatePalette(int hueScale, int satScale, int lightScale, int startColor, int endColor);
|
||||
|
||||
void setCursor(int cursor);
|
||||
void setCursorHotspot(int x, int y);
|
||||
void setCursorTransparency(int a);
|
||||
void setupCursor();
|
||||
|
||||
void setBuiltinCursor(int index);
|
||||
void redefineBuiltinCursorFromChar(int index, int chr);
|
||||
void grabCursor(int x, int y, int w, int h);
|
||||
void setCursorFromBuffer(byte *ptr, int width, int height, int pitch);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue