mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-11 03:01:01 +00:00
more cleanup; fixes out of bound access to _charsetData (but I am not sure if that will be visible anywhere
svn-id: r5833
This commit is contained in:
parent
bb2d559d13
commit
77a64e0217
34
scumm/gfx.h
34
scumm/gfx.h
@ -114,17 +114,18 @@ class Gdi {
|
|||||||
public:
|
public:
|
||||||
Scumm *_vm;
|
Scumm *_vm;
|
||||||
|
|
||||||
protected:
|
|
||||||
byte *_readPtr;
|
|
||||||
uint _readOffs;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int _numZBuffer;
|
int _numZBuffer;
|
||||||
int _imgBufOffs[5];
|
int _imgBufOffs[5];
|
||||||
byte _disable_zbuffer;
|
byte _disable_zbuffer;
|
||||||
int32 _numStrips;
|
int32 _numStrips;
|
||||||
|
public:
|
||||||
|
int16 _mask_top, _mask_bottom, _mask_right, _mask_left;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
byte *_readPtr;
|
||||||
|
uint _readOffs;
|
||||||
|
|
||||||
bool _useOrDecompress;
|
bool _useOrDecompress;
|
||||||
int _numLinesToProcess;
|
int _numLinesToProcess;
|
||||||
int _tempNumLines;
|
int _tempNumLines;
|
||||||
@ -135,9 +136,6 @@ protected:
|
|||||||
|
|
||||||
int16 _drawMouseX;
|
int16 _drawMouseX;
|
||||||
int16 _drawMouseY;
|
int16 _drawMouseY;
|
||||||
public:
|
|
||||||
int16 _mask_top, _mask_bottom, _mask_right, _mask_left;
|
|
||||||
protected:
|
|
||||||
byte _mouseColors[4];
|
byte _mouseColors[4];
|
||||||
byte _mouseColor;
|
byte _mouseColor;
|
||||||
byte _mouseClipMask1, _mouseClipMask2, _mouseClipMask3;
|
byte _mouseClipMask1, _mouseClipMask2, _mouseClipMask3;
|
||||||
@ -169,14 +167,6 @@ protected:
|
|||||||
void unkDecode10();
|
void unkDecode10();
|
||||||
void unkDecode11();
|
void unkDecode11();
|
||||||
|
|
||||||
public:
|
|
||||||
void drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr, int numstrip, byte flag);
|
|
||||||
void clearUpperMask();
|
|
||||||
|
|
||||||
void disableZBuffer() { _disable_zbuffer++; }
|
|
||||||
void enableZBuffer() { _disable_zbuffer--; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void draw8ColWithMasking(byte *dst, byte *src, int height, byte *mask);
|
void draw8ColWithMasking(byte *dst, byte *src, int height, byte *mask);
|
||||||
void draw8Col(byte *dst, byte *src, int height);
|
void draw8Col(byte *dst, byte *src, int height);
|
||||||
void clear8ColWithMasking(byte *dst, int height, byte *mask);
|
void clear8ColWithMasking(byte *dst, int height, byte *mask);
|
||||||
@ -185,15 +175,21 @@ protected:
|
|||||||
void decompressMaskImg(byte *dst, byte *src, int height);
|
void decompressMaskImg(byte *dst, byte *src, int height);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr, int numstrip, byte flag);
|
||||||
|
void clearUpperMask();
|
||||||
|
|
||||||
|
void disableZBuffer() { _disable_zbuffer++; }
|
||||||
|
void enableZBuffer() { _disable_zbuffer--; }
|
||||||
|
|
||||||
|
void resetBackground(int top, int bottom, int strip);
|
||||||
|
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
|
||||||
|
void updateDirtyScreen(VirtScreen *vs);
|
||||||
|
|
||||||
enum DrawBitmapFlags {
|
enum DrawBitmapFlags {
|
||||||
dbAllowMaskOr = 1,
|
dbAllowMaskOr = 1,
|
||||||
dbDrawMaskOnAll = 2,
|
dbDrawMaskOnAll = 2,
|
||||||
dbClear = 4
|
dbClear = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
void resetBackground(int top, int bottom, int strip);
|
|
||||||
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
|
|
||||||
void updateDirtyScreen(VirtScreen *vs);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -455,6 +455,8 @@ void Scumm::loadCharset(int no)
|
|||||||
|
|
||||||
// ensureResourceLoaded(rtCharset, no);
|
// ensureResourceLoaded(rtCharset, no);
|
||||||
ptr = getResourceAddress(rtCharset, no);
|
ptr = getResourceAddress(rtCharset, no);
|
||||||
|
if (_features & GF_SMALL_HEADER)
|
||||||
|
ptr -= 12;
|
||||||
|
|
||||||
for (i = 0; i < 15; i++) {
|
for (i = 0; i < 15; i++) {
|
||||||
_charsetData[no][i + 1] = ptr[i + 14];
|
_charsetData[no][i + 1] = ptr[i + 14];
|
||||||
|
@ -171,7 +171,12 @@ enum {
|
|||||||
|
|
||||||
#define _roomFileOffsets res.roomoffs[rtRoom]
|
#define _roomFileOffsets res.roomoffs[rtRoom]
|
||||||
|
|
||||||
struct CharsetRenderer {
|
class CharsetRenderer {
|
||||||
|
protected:
|
||||||
|
byte _curId;
|
||||||
|
byte *_fontPtr;
|
||||||
|
|
||||||
|
public:
|
||||||
Scumm *_vm;
|
Scumm *_vm;
|
||||||
int _top;
|
int _top;
|
||||||
int _drawTop;
|
int _drawTop;
|
||||||
@ -183,7 +188,6 @@ struct CharsetRenderer {
|
|||||||
bool _blitAlso;
|
bool _blitAlso;
|
||||||
|
|
||||||
int _strLeft, _strRight, _strTop, _strBottom;
|
int _strLeft, _strRight, _strTop, _strBottom;
|
||||||
byte _curId;
|
|
||||||
|
|
||||||
int _xpos2, _ypos2;
|
int _xpos2, _ypos2;
|
||||||
|
|
||||||
@ -209,6 +213,12 @@ struct CharsetRenderer {
|
|||||||
int getSpacing(byte chr, byte *charset);
|
int getSpacing(byte chr, byte *charset);
|
||||||
int getStringWidth(int a, byte *str, int pos);
|
int getStringWidth(int a, byte *str, int pos);
|
||||||
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
|
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
|
||||||
|
|
||||||
|
void setCurID(byte id);
|
||||||
|
int getCurID() { return _curId; }
|
||||||
|
|
||||||
|
byte *getFontPtr() { return _fontPtr; }
|
||||||
|
byte *getFontPtr(byte id);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ARRAY_HDR_SIZE 6
|
#define ARRAY_HDR_SIZE 6
|
||||||
|
586
scumm/string.cpp
586
scumm/string.cpp
@ -27,6 +27,51 @@
|
|||||||
#include "verbs.h"
|
#include "verbs.h"
|
||||||
#include "scumm/sound.h"
|
#include "scumm/sound.h"
|
||||||
|
|
||||||
|
void CharsetRenderer::setCurID(byte id) {
|
||||||
|
_curId = id;
|
||||||
|
_fontPtr = getFontPtr(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *CharsetRenderer::getFontPtr(byte id)
|
||||||
|
{
|
||||||
|
byte *ptr = _vm->getResourceAddress(rtCharset, id);
|
||||||
|
assert(ptr);
|
||||||
|
if (_vm->_features & GF_SMALL_HEADER)
|
||||||
|
ptr += 17;
|
||||||
|
else
|
||||||
|
ptr += 29;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do spacing for variable width old-style font
|
||||||
|
int CharsetRenderer::getSpacing(byte chr, byte *charset)
|
||||||
|
{
|
||||||
|
int spacing = 0;
|
||||||
|
|
||||||
|
if (_vm->_features & GF_OLD256) {
|
||||||
|
spacing = *(charset - 11 + chr);
|
||||||
|
} else {
|
||||||
|
int offs = READ_LE_UINT32(charset + chr * 4 + 4);
|
||||||
|
if (offs) {
|
||||||
|
spacing = charset[offs];
|
||||||
|
if (charset[offs + 2] >= 0x80) {
|
||||||
|
spacing += charset[offs + 2] - 0x100;
|
||||||
|
} else {
|
||||||
|
spacing += charset[offs + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME - this fixes the inventory icons in Zak256/Indy3
|
||||||
|
// see bug #613109.
|
||||||
|
// chars 1,2: up arrow chars 3,4: down arrow
|
||||||
|
if ((_vm->_gameId == GID_ZAK256 || _vm->_gameId == GID_INDY3_256)
|
||||||
|
&& (chr >= 1 && chr <= 4))
|
||||||
|
spacing = 6;
|
||||||
|
|
||||||
|
return spacing;
|
||||||
|
}
|
||||||
|
|
||||||
int CharsetRenderer::getStringWidth(int arg, byte *text, int pos)
|
int CharsetRenderer::getStringWidth(int arg, byte *text, int pos)
|
||||||
{
|
{
|
||||||
byte *ptr;
|
byte *ptr;
|
||||||
@ -34,9 +79,7 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos)
|
|||||||
byte chr;
|
byte chr;
|
||||||
|
|
||||||
width = 1;
|
width = 1;
|
||||||
ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;
|
ptr = _fontPtr;
|
||||||
if (_vm->_features & GF_SMALL_HEADER)
|
|
||||||
ptr -= 12;
|
|
||||||
|
|
||||||
while ((chr = text[pos++]) != 0) {
|
while ((chr = text[pos++]) != 0) {
|
||||||
if (chr == 0xD)
|
if (chr == 0xD)
|
||||||
@ -63,9 +106,7 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos)
|
|||||||
if (chr == 14) {
|
if (chr == 14) {
|
||||||
int set = text[pos] | (text[pos + 1] << 8);
|
int set = text[pos] | (text[pos + 1] << 8);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
ptr = _vm->getResourceAddress(rtCharset, set) + 29;
|
ptr = getFontPtr(set);
|
||||||
if (_vm->_features & GF_SMALL_HEADER)
|
|
||||||
ptr -= 12;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,9 +123,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth)
|
|||||||
byte *ptr;
|
byte *ptr;
|
||||||
byte chr;
|
byte chr;
|
||||||
|
|
||||||
ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;
|
ptr = _fontPtr;
|
||||||
if (_vm->_features & GF_SMALL_HEADER)
|
|
||||||
ptr -= 12;
|
|
||||||
|
|
||||||
while ((chr = str[pos++]) != 0) {
|
while ((chr = str[pos++]) != 0) {
|
||||||
if (chr == '@')
|
if (chr == '@')
|
||||||
@ -117,9 +156,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth)
|
|||||||
if (chr == 14) {
|
if (chr == 14) {
|
||||||
int set = str[pos] | (str[pos + 1] << 8);
|
int set = str[pos] | (str[pos + 1] << 8);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
ptr = _vm->getResourceAddress(rtCharset, set) + 29;
|
ptr = getFontPtr(set);
|
||||||
if (_vm->_features & GF_SMALL_HEADER)
|
|
||||||
ptr -= 12;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,6 +176,220 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CharsetRenderer::printCharOld(int chr)
|
||||||
|
{ // Indy3 / Zak256
|
||||||
|
VirtScreen *vs;
|
||||||
|
byte *char_ptr, *dest_ptr;
|
||||||
|
unsigned int buffer = 0, mask = 0, x = 0, y = 0;
|
||||||
|
unsigned char color;
|
||||||
|
|
||||||
|
_vm->checkRange(_vm->_maxCharsets - 1, 0, _curId, "Printing with bad charset %d");
|
||||||
|
|
||||||
|
if ((vs = _vm->findVirtScreen(_top)) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (chr == '@')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_firstChar) {
|
||||||
|
_strLeft = _left;
|
||||||
|
_strTop = _top;
|
||||||
|
_strRight = _left;
|
||||||
|
_strBottom = _top;
|
||||||
|
_firstChar = false;
|
||||||
|
}
|
||||||
|
char_ptr = _fontPtr + 207 + (chr + 1) * 8;
|
||||||
|
dest_ptr = vs->screenPtr + vs->xstart + (_top - vs->topline) * _vm->_realWidth + _left;
|
||||||
|
_vm->updateDirtyRect(vs->number, _left, _left + 8, _top - vs->topline, _top - vs->topline + 8, 0);
|
||||||
|
|
||||||
|
for (y = 0; y < 8; y++) {
|
||||||
|
for (x = 0; x < 8; x++) {
|
||||||
|
if ((mask >>= 1) == 0) {
|
||||||
|
buffer = *char_ptr++;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
color = ((buffer & mask) != 0);
|
||||||
|
if (color)
|
||||||
|
*(dest_ptr + y * _vm->_realWidth + x) = _color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
_left += getSpacing(chr, _fontPtr);
|
||||||
|
|
||||||
|
if (_left > _strRight)
|
||||||
|
_strRight = _left;
|
||||||
|
|
||||||
|
if (_top + 8 > _strBottom)
|
||||||
|
_strBottom = _top + 8;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CharsetRenderer::printChar(int chr)
|
||||||
|
{
|
||||||
|
int d, right;
|
||||||
|
VirtScreen *vs;
|
||||||
|
|
||||||
|
_vm->checkRange(_vm->_maxCharsets - 1, 1, _curId, "Printing with bad charset %d");
|
||||||
|
|
||||||
|
if ((vs = _vm->findVirtScreen(_top)) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (chr == '@')
|
||||||
|
return;
|
||||||
|
|
||||||
|
_bpp = *_fontPtr;
|
||||||
|
_colorMap[1] = _color;
|
||||||
|
|
||||||
|
_charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
|
||||||
|
|
||||||
|
if (!_charOffs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(_charOffs < 0x10000);
|
||||||
|
|
||||||
|
_charPtr = _fontPtr + _charOffs;
|
||||||
|
|
||||||
|
_width = _charPtr[0];
|
||||||
|
_height = _charPtr[1];
|
||||||
|
if (_firstChar) {
|
||||||
|
_strLeft = 0;
|
||||||
|
_strTop = 0;
|
||||||
|
_strRight = 0;
|
||||||
|
_strBottom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_disableOffsX) {
|
||||||
|
_offsX = 0;
|
||||||
|
} else {
|
||||||
|
d = _charPtr[2];
|
||||||
|
if (d >= 0x80)
|
||||||
|
d -= 0x100;
|
||||||
|
_offsX = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = _charPtr[3];
|
||||||
|
if (d >= 0x80)
|
||||||
|
d -= 0x100;
|
||||||
|
_offsY = d;
|
||||||
|
|
||||||
|
_top += _offsY;
|
||||||
|
_left += _offsX;
|
||||||
|
|
||||||
|
right = _left + _width;
|
||||||
|
|
||||||
|
if (right > _right + 1 || _left < 0) {
|
||||||
|
_left = right;
|
||||||
|
_top -= _offsY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_disableOffsX = false;
|
||||||
|
|
||||||
|
if (_firstChar) {
|
||||||
|
_strLeft = _left;
|
||||||
|
_strTop = _top;
|
||||||
|
_strRight = _left;
|
||||||
|
_strBottom = _top;
|
||||||
|
_firstChar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_left < _strLeft)
|
||||||
|
_strLeft = _left;
|
||||||
|
|
||||||
|
if (_top < _strTop)
|
||||||
|
_strTop = _top;
|
||||||
|
|
||||||
|
_drawTop = _top - vs->topline;
|
||||||
|
if (_drawTop < 0)
|
||||||
|
_drawTop = 0;
|
||||||
|
|
||||||
|
_bottom = _drawTop + _height + _offsY;
|
||||||
|
|
||||||
|
_vm->updateDirtyRect(vs->number, _left, right, _drawTop, _bottom, 0);
|
||||||
|
|
||||||
|
if (vs->number != 0)
|
||||||
|
_blitAlso = false;
|
||||||
|
if (vs->number == 0 && _blitAlso == 0)
|
||||||
|
_hasMask = true;
|
||||||
|
|
||||||
|
_virtScreenHeight = vs->height;
|
||||||
|
_charPtr += 4;
|
||||||
|
|
||||||
|
byte *mask = _vm->getResourceAddress(rtBuffer, 9)
|
||||||
|
+ _drawTop * _vm->gdi._numStrips + _left / 8 + _vm->_screenStartStrip;
|
||||||
|
|
||||||
|
byte *dst = vs->screenPtr + vs->xstart + _drawTop * _vm->_realWidth + _left;
|
||||||
|
|
||||||
|
if (_blitAlso) {
|
||||||
|
byte *back = dst;
|
||||||
|
dst = _vm->getResourceAddress(rtBuffer, vs->number + 5)
|
||||||
|
+ vs->xstart + _drawTop * _vm->_realWidth + _left;
|
||||||
|
|
||||||
|
drawBits(dst, mask);
|
||||||
|
|
||||||
|
_vm->blit(back, dst, _width, _height);
|
||||||
|
} else {
|
||||||
|
drawBits(dst, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
_left += _width;
|
||||||
|
if (_left > _strRight)
|
||||||
|
_strRight = _left;
|
||||||
|
|
||||||
|
if (_top + _height > _strBottom)
|
||||||
|
_strBottom = _top + _height;
|
||||||
|
|
||||||
|
_top -= _offsY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharsetRenderer::drawBits(byte *dst, byte *mask)
|
||||||
|
{
|
||||||
|
bool usemask;
|
||||||
|
byte maskmask;
|
||||||
|
int y, x;
|
||||||
|
int maskpos;
|
||||||
|
int color;
|
||||||
|
byte numbits, bits;
|
||||||
|
|
||||||
|
usemask = (_vm->_curVirtScreen->number == 0 && _ignoreCharsetMask == 0);
|
||||||
|
|
||||||
|
bits = *_charPtr++;
|
||||||
|
numbits = 8;
|
||||||
|
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
for (y = 0; y < _height && y + _drawTop < _virtScreenHeight;) {
|
||||||
|
maskmask = revBitMask[_left & 7];
|
||||||
|
maskpos = 0;
|
||||||
|
|
||||||
|
for (x = 0; x < _width; x++) {
|
||||||
|
color = (bits >> (8 - _bpp)) & 0xFF;
|
||||||
|
if (color) {
|
||||||
|
if (usemask) {
|
||||||
|
mask[maskpos] |= maskmask;
|
||||||
|
}
|
||||||
|
*dst = _colorMap[color];
|
||||||
|
}
|
||||||
|
dst++;
|
||||||
|
bits <<= _bpp;
|
||||||
|
if ((numbits -= _bpp) == 0) {
|
||||||
|
bits = *_charPtr++;
|
||||||
|
numbits = 8;
|
||||||
|
}
|
||||||
|
if ((maskmask >>= 1) == 0) {
|
||||||
|
maskmask = 0x80;
|
||||||
|
maskpos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += _vm->_realWidth - _width;
|
||||||
|
mask += _vm->gdi._numStrips;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Scumm::unkMessage1()
|
void Scumm::unkMessage1()
|
||||||
{
|
{
|
||||||
byte buffer[100];
|
byte buffer[100];
|
||||||
@ -243,10 +494,12 @@ void Scumm::CHARSET_1()
|
|||||||
charset._top = _string[0].ypos;
|
charset._top = _string[0].ypos;
|
||||||
charset._left = _string[0].xpos;
|
charset._left = _string[0].xpos;
|
||||||
charset._startLeft = _string[0].xpos;
|
charset._startLeft = _string[0].xpos;
|
||||||
charset._curId = _string[0].charset;
|
|
||||||
|
|
||||||
if (a && a->charset)
|
if (a && a->charset)
|
||||||
charset._curId = a->charset;
|
charset.setCurID(a->charset);
|
||||||
|
else
|
||||||
|
charset.setCurID(_string[0].charset);
|
||||||
|
|
||||||
|
|
||||||
charset._center = _string[0].center;
|
charset._center = _string[0].center;
|
||||||
charset._right = _string[0].right;
|
charset._right = _string[0].right;
|
||||||
@ -254,10 +507,7 @@ void Scumm::CHARSET_1()
|
|||||||
|
|
||||||
if (!(_features & GF_OLD256)) // FIXME
|
if (!(_features & GF_OLD256)) // FIXME
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
if (_features & GF_SMALL_HEADER)
|
charset._colorMap[i] = _charsetData[charset.getCurID()][i];
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i - 12]; // FIXME - do we really want to access index -12 to -9 ?
|
|
||||||
else
|
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i];
|
|
||||||
|
|
||||||
if (_keepText) {
|
if (_keepText) {
|
||||||
charset._strLeft = gdi._mask_left;
|
charset._strLeft = gdi._mask_left;
|
||||||
@ -342,10 +592,7 @@ void Scumm::CHARSET_1()
|
|||||||
if (charset._center) {
|
if (charset._center) {
|
||||||
charset._xpos2 -= charset.getStringWidth(0, buffer, 0) >> 1;
|
charset._xpos2 -= charset.getStringWidth(0, buffer, 0) >> 1;
|
||||||
}
|
}
|
||||||
if (_features & GF_SMALL_HEADER)
|
charset._ypos2 += charset.getFontPtr()[1];
|
||||||
charset._ypos2 += getResourceAddress(rtCharset, charset._curId)[30 - 12];
|
|
||||||
else
|
|
||||||
charset._ypos2 += getResourceAddress(rtCharset, charset._curId)[30];
|
|
||||||
charset._disableOffsX = true;
|
charset._disableOffsX = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -416,23 +663,13 @@ void Scumm::CHARSET_1()
|
|||||||
buffer += 2;
|
buffer += 2;
|
||||||
break;
|
break;
|
||||||
case 14: {
|
case 14: {
|
||||||
int oldy;
|
int oldy = charset.getFontPtr()[1];
|
||||||
if (_features & GF_SMALL_HEADER)
|
|
||||||
oldy = getResourceAddress(rtCharset, charset._curId)[30 - 12];
|
|
||||||
else
|
|
||||||
oldy = getResourceAddress(rtCharset, charset._curId)[30];
|
|
||||||
|
|
||||||
charset._curId = *buffer++;
|
charset.setCurID(*buffer++);
|
||||||
buffer += 2;
|
buffer += 2;
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
if (_features & GF_SMALL_HEADER)
|
charset._colorMap[i] = _charsetData[charset.getCurID()][i];
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i - 12]; // FIXME - do we really want to access index -12 to -9 ?
|
charset._ypos2 -= charset.getFontPtr()[1] - oldy;
|
||||||
else
|
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i];
|
|
||||||
if (_features & GF_SMALL_HEADER)
|
|
||||||
charset._ypos2 -= getResourceAddress(rtCharset, charset._curId)[30 - 12] - oldy;
|
|
||||||
else
|
|
||||||
charset._ypos2 -= getResourceAddress(rtCharset, charset._curId)[30] - oldy;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -480,7 +717,7 @@ void Scumm::description()
|
|||||||
charset._xpos2 = _string[0].xpos;
|
charset._xpos2 = _string[0].xpos;
|
||||||
charset._ypos2 = _string[0].ypos;
|
charset._ypos2 = _string[0].ypos;
|
||||||
charset._disableOffsX = charset._firstChar = true;
|
charset._disableOffsX = charset._firstChar = true;
|
||||||
charset._curId = 3;
|
charset.setCurID(3);
|
||||||
charset._center = false;
|
charset._center = false;
|
||||||
charset._color = 15;
|
charset._color = 15;
|
||||||
// FIXME: _talkdelay = 1 - display description, not correct ego actor talking,
|
// FIXME: _talkdelay = 1 - display description, not correct ego actor talking,
|
||||||
@ -527,7 +764,7 @@ void Scumm::drawDescString(byte *msg)
|
|||||||
charset._right = _realWidth - 1;
|
charset._right = _realWidth - 1;
|
||||||
charset._xpos2 = _string[0].xpos;
|
charset._xpos2 = _string[0].xpos;
|
||||||
charset._ypos2 = _string[0].ypos;
|
charset._ypos2 = _string[0].ypos;
|
||||||
charset._curId = _string[0].charset;
|
charset.setCurID(_string[0].charset);
|
||||||
charset._center = _string[0].center;
|
charset._center = _string[0].center;
|
||||||
charset._color = _string[0].color;
|
charset._color = _string[0].color;
|
||||||
|
|
||||||
@ -566,7 +803,7 @@ void Scumm::drawDescString(byte *msg)
|
|||||||
void Scumm::drawString(int a)
|
void Scumm::drawString(int a)
|
||||||
{
|
{
|
||||||
byte buf[256];
|
byte buf[256];
|
||||||
byte *charsetptr, *space;
|
byte *space;
|
||||||
int i;
|
int i;
|
||||||
byte fontHeight = 0, chr;
|
byte fontHeight = 0, chr;
|
||||||
uint color;
|
uint color;
|
||||||
@ -576,26 +813,17 @@ void Scumm::drawString(int a)
|
|||||||
|
|
||||||
charset._startLeft = charset._left = _string[a].xpos;
|
charset._startLeft = charset._left = _string[a].xpos;
|
||||||
charset._top = _string[a].ypos;
|
charset._top = _string[a].ypos;
|
||||||
charset._curId = _string[a].charset;
|
charset.setCurID(_string[a].charset);
|
||||||
charset._center = _string[a].center;
|
charset._center = _string[a].center;
|
||||||
charset._right = _string[a].right;
|
charset._right = _string[a].right;
|
||||||
charset._color = _string[a].color;
|
charset._color = _string[a].color;
|
||||||
charset._disableOffsX = charset._firstChar = true;
|
charset._disableOffsX = charset._firstChar = true;
|
||||||
|
|
||||||
if (!(_features & GF_OLD256)) {
|
if (!(_features & GF_OLD256)) {
|
||||||
charsetptr = getResourceAddress(rtCharset, charset._curId);
|
|
||||||
assert(charsetptr);
|
|
||||||
charsetptr += 29;
|
|
||||||
if (_features & GF_SMALL_HEADER)
|
|
||||||
charsetptr -= 12;
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
if (_features & GF_SMALL_HEADER)
|
charset._colorMap[i] = _charsetData[charset.getCurID()][i];
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i - 12]; // FIXME - do we really want to access index -12 to -9 ?
|
|
||||||
else
|
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i];
|
|
||||||
|
|
||||||
fontHeight = charsetptr[1];
|
fontHeight = charset.getFontPtr()[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
_msgPtrToAdd = buf;
|
_msgPtrToAdd = buf;
|
||||||
@ -873,262 +1101,8 @@ void Scumm::initCharset(int charsetno)
|
|||||||
_string[1].t_charset = charsetno;
|
_string[1].t_charset = charsetno;
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
if (_features & GF_SMALL_HEADER)
|
charset._colorMap[i] = _charsetData[charset.getCurID()][i];
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i - 12]; // FIXME - do we really want to access index -12 to -9 ?
|
|
||||||
else
|
|
||||||
charset._colorMap[i] = _charsetData[charset._curId][i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharsetRenderer::printCharOld(int chr)
|
|
||||||
{ // Indy3 / Zak256
|
|
||||||
VirtScreen *vs;
|
|
||||||
byte *char_ptr, *dest_ptr;
|
|
||||||
unsigned int buffer = 0, mask = 0, x = 0, y = 0;
|
|
||||||
unsigned char color;
|
|
||||||
|
|
||||||
_vm->checkRange(_vm->_maxCharsets - 1, 0, _curId, "Printing with bad charset %d");
|
|
||||||
|
|
||||||
if ((vs = _vm->findVirtScreen(_top)) == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (chr == '@')
|
|
||||||
return;
|
|
||||||
|
|
||||||
byte *ptr = _vm->getResourceAddress(rtCharset, _curId);
|
|
||||||
|
|
||||||
if (_firstChar) {
|
|
||||||
_strLeft = _left;
|
|
||||||
_strTop = _top;
|
|
||||||
_strRight = _left;
|
|
||||||
_strBottom = _top;
|
|
||||||
_firstChar = false;
|
|
||||||
}
|
|
||||||
char_ptr = ptr + 224 + (chr + 1) * 8;
|
|
||||||
dest_ptr = vs->screenPtr + vs->xstart + (_top - vs->topline) * _vm->_realWidth + _left;
|
|
||||||
_vm->updateDirtyRect(vs->number, _left, _left + 8, _top - vs->topline, _top - vs->topline + 8, 0);
|
|
||||||
|
|
||||||
for (y = 0; y < 8; y++) {
|
|
||||||
for (x = 0; x < 8; x++) {
|
|
||||||
if ((mask >>= 1) == 0) {
|
|
||||||
buffer = *char_ptr++;
|
|
||||||
mask = 0x80;
|
|
||||||
}
|
|
||||||
color = ((buffer & mask) != 0);
|
|
||||||
if (color)
|
|
||||||
*(dest_ptr + y * _vm->_realWidth + x) = _color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME
|
|
||||||
_left += getSpacing(chr, ptr + 29 - 12);
|
|
||||||
|
|
||||||
if (_left > _strRight)
|
|
||||||
_strRight = _left;
|
|
||||||
|
|
||||||
if (_top + 8 > _strBottom)
|
|
||||||
_strBottom = _top + 8;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CharsetRenderer::printChar(int chr)
|
|
||||||
{
|
|
||||||
int d, right;
|
|
||||||
VirtScreen *vs;
|
|
||||||
|
|
||||||
_vm->checkRange(_vm->_maxCharsets - 1, 1, _curId, "Printing with bad charset %d");
|
|
||||||
|
|
||||||
if ((vs = _vm->findVirtScreen(_top)) == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (chr == '@')
|
|
||||||
return;
|
|
||||||
|
|
||||||
byte *ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;
|
|
||||||
if (_vm->_features & GF_SMALL_HEADER)
|
|
||||||
ptr -= 12;
|
|
||||||
|
|
||||||
_bpp = *ptr;
|
|
||||||
_colorMap[1] = _color;
|
|
||||||
|
|
||||||
_charOffs = READ_LE_UINT32(ptr + chr * 4 + 4);
|
|
||||||
|
|
||||||
if (!_charOffs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
assert(_charOffs < 0x10000);
|
|
||||||
|
|
||||||
_charPtr = ptr + _charOffs;
|
|
||||||
|
|
||||||
_width = _charPtr[0];
|
|
||||||
_height = _charPtr[1];
|
|
||||||
if (_firstChar) {
|
|
||||||
_strLeft = 0;
|
|
||||||
_strTop = 0;
|
|
||||||
_strRight = 0;
|
|
||||||
_strBottom = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_disableOffsX) {
|
|
||||||
_offsX = 0;
|
|
||||||
} else {
|
|
||||||
d = _charPtr[2];
|
|
||||||
if (d >= 0x80)
|
|
||||||
d -= 0x100;
|
|
||||||
_offsX = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = _charPtr[3];
|
|
||||||
if (d >= 0x80)
|
|
||||||
d -= 0x100;
|
|
||||||
_offsY = d;
|
|
||||||
|
|
||||||
_top += _offsY;
|
|
||||||
_left += _offsX;
|
|
||||||
|
|
||||||
right = _left + _width;
|
|
||||||
|
|
||||||
if (right > _right + 1 || _left < 0) {
|
|
||||||
_left = right;
|
|
||||||
_top -= _offsY;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_disableOffsX = false;
|
|
||||||
|
|
||||||
if (_firstChar) {
|
|
||||||
_strLeft = _left;
|
|
||||||
_strTop = _top;
|
|
||||||
_strRight = _left;
|
|
||||||
_strBottom = _top;
|
|
||||||
_firstChar = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_left < _strLeft)
|
|
||||||
_strLeft = _left;
|
|
||||||
|
|
||||||
if (_top < _strTop)
|
|
||||||
_strTop = _top;
|
|
||||||
|
|
||||||
_drawTop = _top - vs->topline;
|
|
||||||
if (_drawTop < 0)
|
|
||||||
_drawTop = 0;
|
|
||||||
|
|
||||||
_bottom = _drawTop + _height + _offsY;
|
|
||||||
|
|
||||||
_vm->updateDirtyRect(vs->number, _left, right, _drawTop, _bottom, 0);
|
|
||||||
|
|
||||||
if (vs->number != 0)
|
|
||||||
_blitAlso = false;
|
|
||||||
if (vs->number == 0 && _blitAlso == 0)
|
|
||||||
_hasMask = true;
|
|
||||||
|
|
||||||
byte *_backbuff_ptr;
|
|
||||||
byte *_mask_ptr;
|
|
||||||
byte *_dest_ptr;
|
|
||||||
|
|
||||||
_dest_ptr = _backbuff_ptr = vs->screenPtr + vs->xstart + _drawTop * _vm->_realWidth + _left;
|
|
||||||
|
|
||||||
if (_blitAlso) {
|
|
||||||
_dest_ptr = _vm->getResourceAddress(rtBuffer, vs->number + 5)
|
|
||||||
+ vs->xstart + _drawTop * _vm->_realWidth + _left;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mask_ptr = _vm->getResourceAddress(rtBuffer, 9)
|
|
||||||
+ _drawTop * _vm->gdi._numStrips + _left / 8 + _vm->_screenStartStrip;
|
|
||||||
|
|
||||||
_virtScreenHeight = vs->height;
|
|
||||||
_charPtr += 4;
|
|
||||||
|
|
||||||
drawBits(_dest_ptr, _mask_ptr);
|
|
||||||
|
|
||||||
if (_blitAlso)
|
|
||||||
_vm->blit(_backbuff_ptr, _dest_ptr, _width, _height);
|
|
||||||
|
|
||||||
_left += _width;
|
|
||||||
if (_left > _strRight)
|
|
||||||
_strRight = _left;
|
|
||||||
|
|
||||||
if (_top + _height > _strBottom)
|
|
||||||
_strBottom = _top + _height;
|
|
||||||
|
|
||||||
_top -= _offsY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharsetRenderer::drawBits(byte *dst, byte *mask)
|
|
||||||
{
|
|
||||||
bool usemask;
|
|
||||||
byte maskmask;
|
|
||||||
int y, x;
|
|
||||||
int maskpos;
|
|
||||||
int color;
|
|
||||||
byte numbits, bits;
|
|
||||||
|
|
||||||
usemask = (_vm->_curVirtScreen->number == 0 && _ignoreCharsetMask == 0);
|
|
||||||
|
|
||||||
bits = *_charPtr++;
|
|
||||||
numbits = 8;
|
|
||||||
|
|
||||||
y = 0;
|
|
||||||
|
|
||||||
for (y = 0; y < _height && y + _drawTop < _virtScreenHeight;) {
|
|
||||||
maskmask = revBitMask[_left & 7];
|
|
||||||
maskpos = 0;
|
|
||||||
|
|
||||||
for (x = 0; x < _width; x++) {
|
|
||||||
color = (bits >> (8 - _bpp)) & 0xFF;
|
|
||||||
if (color) {
|
|
||||||
if (usemask) {
|
|
||||||
mask[maskpos] |= maskmask;
|
|
||||||
}
|
|
||||||
*dst = _colorMap[color];
|
|
||||||
}
|
|
||||||
dst++;
|
|
||||||
bits <<= _bpp;
|
|
||||||
if ((numbits -= _bpp) == 0) {
|
|
||||||
bits = *_charPtr++;
|
|
||||||
numbits = 8;
|
|
||||||
}
|
|
||||||
if ((maskmask >>= 1) == 0) {
|
|
||||||
maskmask = 0x80;
|
|
||||||
maskpos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst += _vm->_realWidth - _width;
|
|
||||||
mask += _vm->gdi._numStrips;
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do spacing for variable width old-style font
|
|
||||||
int CharsetRenderer::getSpacing(byte chr, byte *charset)
|
|
||||||
{
|
|
||||||
int spacing = 0;
|
|
||||||
|
|
||||||
if (_vm->_features & GF_OLD256) {
|
|
||||||
spacing = *(charset - 11 + chr);
|
|
||||||
} else {
|
|
||||||
int offs = READ_LE_UINT32(charset + chr * 4 + 4);
|
|
||||||
if (offs) {
|
|
||||||
spacing = charset[offs];
|
|
||||||
if (charset[offs + 2] >= 0x80) {
|
|
||||||
spacing += charset[offs + 2] - 0x100;
|
|
||||||
} else {
|
|
||||||
spacing += charset[offs + 2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME - this fixes the inventory icons in Zak256/Indy3
|
|
||||||
// see bug #613109.
|
|
||||||
// chars 1,2: up arrow chars 3,4: down arrow
|
|
||||||
if ((_vm->_gameId == GID_ZAK256 || _vm->_gameId == GID_INDY3_256)
|
|
||||||
&& (chr >= 1 && chr <= 4))
|
|
||||||
spacing = 6;
|
|
||||||
|
|
||||||
return spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scumm::loadLanguageBundle() {
|
void Scumm::loadLanguageBundle() {
|
||||||
File file;
|
File file;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user