Skip to content

Commit

Permalink
SCI: some more work on 480x300 mac support
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Kiewitz committed Nov 9, 2014
1 parent 3472d95 commit 72e6a9e
Show file tree
Hide file tree
Showing 8 changed files with 412 additions and 193 deletions.
8 changes: 4 additions & 4 deletions engines/sci/graphics/cursor.cpp
Expand Up @@ -47,7 +47,7 @@ GfxCursor::GfxCursor(ResourceManager *resMan, GfxPalette *palette, GfxScreen *sc
_isVisible = true;

// center mouse cursor
setPosition(Common::Point(_screen->getWidth() / 2, _screen->getHeight() / 2));
setPosition(Common::Point(_screen->getScriptWidth() / 2, _screen->getScriptHeight() / 2));
_moveZoneActive = false;

_zoomZoneActive = false;
Expand Down Expand Up @@ -151,14 +151,14 @@ void GfxCursor::kernelSetShape(GuiResourceId resourceId) {
colorMapping[0] = 0; // Black is hardcoded
colorMapping[1] = _screen->getColorWhite(); // White is also hardcoded
colorMapping[2] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR;
colorMapping[3] = _palette->matchColor(170, 170, 170); // Grey
colorMapping[3] = _palette->matchColor(170, 170, 170) & SCI_PALETTE_MATCH_COLORMASK; // Grey
// TODO: Figure out if the grey color is hardcoded
// HACK for the magnifier cursor in LB1, fixes its color (bug #3487092)
if (g_sci->getGameId() == GID_LAURABOW && resourceId == 1)
colorMapping[3] = _screen->getColorWhite();
// HACK for Longbow cursors, fixes the shade of grey they're using (bug #3489101)
if (g_sci->getGameId() == GID_LONGBOW)
colorMapping[3] = _palette->matchColor(223, 223, 223); // Light Grey
colorMapping[3] = _palette->matchColor(223, 223, 223) & SCI_PALETTE_MATCH_COLORMASK; // Light Grey

// Seek to actual data
resourceData += 4;
Expand Down Expand Up @@ -481,7 +481,7 @@ void GfxCursor::kernelSetPos(Common::Point pos) {

void GfxCursor::kernelMoveCursor(Common::Point pos) {
_coordAdjuster->moveCursor(pos);
if (pos.x > _screen->getWidth() || pos.y > _screen->getHeight()) {
if (pos.x > _screen->getScriptWidth() || pos.y > _screen->getScriptHeight()) {
warning("attempt to place cursor at invalid coordinates (%d, %d)", pos.y, pos.x);
return;
}
Expand Down
8 changes: 4 additions & 4 deletions engines/sci/graphics/font.cpp
Expand Up @@ -48,8 +48,8 @@ GfxFontFromResource::GfxFontFromResource(ResourceManager *resMan, GfxScreen *scr
// filling info for every char
for (int16 i = 0; i < _numChars; i++) {
_chars[i].offset = READ_SCI32ENDIAN_UINT16(_resourceData + 6 + i * 2);
_chars[i].w = _resourceData[_chars[i].offset];
_chars[i].h = _resourceData[_chars[i].offset + 1];
_chars[i].width = _resourceData[_chars[i].offset];
_chars[i].height = _resourceData[_chars[i].offset + 1];
}
}

Expand All @@ -66,10 +66,10 @@ byte GfxFontFromResource::getHeight() {
return _fontHeight;
}
byte GfxFontFromResource::getCharWidth(uint16 chr) {
return chr < _numChars ? _chars[chr].w : 0;
return chr < _numChars ? _chars[chr].width : 0;
}
byte GfxFontFromResource::getCharHeight(uint16 chr) {
return chr < _numChars ? _chars[chr].h : 0;
return chr < _numChars ? _chars[chr].height : 0;
}
byte *GfxFontFromResource::getCharData(uint16 chr) {
return chr < _numChars ? _resourceData + _chars[chr].offset + 2 : 0;
Expand Down
4 changes: 3 additions & 1 deletion engines/sci/graphics/font.h
Expand Up @@ -71,9 +71,11 @@ class GfxFontFromResource : public GfxFont {
byte *_resourceData;

struct Charinfo {
byte w, h;
byte width;
byte height;
int16 offset;
};

byte _fontHeight;
uint16 _numChars;
Charinfo *_chars;
Expand Down
84 changes: 52 additions & 32 deletions engines/sci/graphics/picture.cpp
Expand Up @@ -88,10 +88,13 @@ void GfxPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int1
}

void GfxPicture::reset() {
int16 startY = _ports->getPort()->top;
int16 startX = 0;
int16 x, y;
for (y = _ports->getPort()->top; y < _screen->getHeight(); y++) {
for (x = 0; x < _screen->getWidth(); x++) {
_screen->putPixel(x, y, GFX_SCREEN_MASK_ALL, 255, 0, 0);
_screen->vectorAdjustCoordinate(&startX, &startY);
for (y = startY; y < _screen->getHeight(); y++) {
for (x = startX; x < _screen->getWidth(); x++) {
_screen->vectorPutPixel(x, y, GFX_SCREEN_MASK_ALL, 255, 0, 0);
}
}
}
Expand Down Expand Up @@ -482,6 +485,8 @@ enum {
PIC_OPX_VGA_PRIORITY_TABLE_EXPLICIT = 4
};

//#define DEBUG_PICTURE_DRAW 1

#ifdef DEBUG_PICTURE_DRAW
const char *picOpcodeNames[] = {
"Set color",
Expand Down Expand Up @@ -589,6 +594,9 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
while (curPos < dataSize) {
#ifdef DEBUG_PICTURE_DRAW
debug("Picture op: %X (%s) at %d", data[curPos], picOpcodeNames[data[curPos] - 0xF0], curPos);
_screen->copyToScreen();
g_system->updateScreen();
g_system->delayMillis(400);
#endif
switch (pic_op = data[curPos++]) {
case PIC_OP_SET_COLOR:
Expand Down Expand Up @@ -934,17 +942,17 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
Common::Point p, p1;
byte screenMask = _screen->getDrawingMask(color, priority, control);
byte matchedMask, matchMask;
int16 w, e, a_set, b_set;

bool isEGA = (_resMan->getViewType() == kViewEga);

p.x = x + curPort->left;
p.y = y + curPort->top;
stack.push(p);

byte searchColor = _screen->getVisual(p.x, p.y);
byte searchPriority = _screen->getPriority(p.x, p.y);
byte searchControl = _screen->getControl(p.x, p.y);
_screen->vectorAdjustCoordinate(&p.x, &p.y);

byte searchColor = _screen->vectorGetVisual(p.x, p.y);
byte searchPriority = _screen->vectorGetPriority(p.x, p.y);
byte searchControl = _screen->vectorGetControl(p.x, p.y);

if (isEGA) {
// In EGA games a pixel in the framebuffer is only 4 bits. We store
Expand Down Expand Up @@ -991,22 +999,31 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
}

// hard borders for filling
int l = curPort->rect.left + curPort->left;
int t = curPort->rect.top + curPort->top;
int r = curPort->rect.right + curPort->left - 1;
int b = curPort->rect.bottom + curPort->top - 1;
int16 borderLeft = curPort->rect.left + curPort->left;
int16 borderTop = curPort->rect.top + curPort->top;
int16 borderRight = curPort->rect.right + curPort->left - 1;
int16 borderBottom = curPort->rect.bottom + curPort->top - 1;
int16 curToLeft, curToRight, a_set, b_set;

// Translate coordinates, if required (needed for Macintosh 480x300)
_screen->vectorAdjustCoordinate(&borderLeft, &borderTop);
_screen->vectorAdjustCoordinate(&borderRight, &borderBottom);
//return;

stack.push(p);

while (stack.size()) {
p = stack.pop();
if ((matchedMask = _screen->isFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)) == 0) // already filled
if ((matchedMask = _screen->vectorIsFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)) == 0) // already filled
continue;
_screen->putPixel(p.x, p.y, screenMask, color, priority, control);
w = p.x;
e = p.x;
_screen->vectorPutPixel(p.x, p.y, screenMask, color, priority, control);
curToLeft = p.x;
curToRight = p.x;
// moving west and east pointers as long as there is a matching color to fill
while (w > l && (matchedMask = _screen->isFillMatch(w - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
_screen->putPixel(--w, p.y, screenMask, color, priority, control);
while (e < r && (matchedMask = _screen->isFillMatch(e + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
_screen->putPixel(++e, p.y, screenMask, color, priority, control);
while (curToLeft > borderLeft && (matchedMask = _screen->vectorIsFillMatch(curToLeft - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
_screen->vectorPutPixel(--curToLeft, p.y, screenMask, color, priority, control);
while (curToRight < borderRight && (matchedMask = _screen->vectorIsFillMatch(curToRight + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
_screen->vectorPutPixel(++curToRight, p.y, screenMask, color, priority, control);
#if 0
// debug code for floodfill
_screen->copyToScreen();
Expand All @@ -1015,27 +1032,27 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
#endif
// checking lines above and below for possible flood targets
a_set = b_set = 0;
while (w <= e) {
if (p.y > t && (matchedMask = _screen->isFillMatch(w, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line above
while (curToLeft <= curToRight) {
if (p.y > borderTop && (matchedMask = _screen->vectorIsFillMatch(curToLeft, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line above
if (a_set == 0) {
p1.x = w;
p1.x = curToLeft;
p1.y = p.y - 1;
stack.push(p1);
a_set = 1;
}
} else
a_set = 0;

if (p.y < b && (matchedMask = _screen->isFillMatch(w, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line below
if (p.y < borderBottom && (matchedMask = _screen->vectorIsFillMatch(curToLeft, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line below
if (b_set == 0) {
p1.x = w;
p1.x = curToLeft;
p1.y = p.y + 1;
stack.push(p1);
b_set = 1;
}
} else
b_set = 0;
w++;
curToLeft++;
}
}
}
Expand Down Expand Up @@ -1173,7 +1190,7 @@ void GfxPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte

for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
_screen->putPixel(x, y, flag, color, prio, control);
_screen->vectorPutPixel(x, y, flag, color, prio, control);
}
}
}
Expand All @@ -1186,7 +1203,7 @@ void GfxPicture::vectorPatternTexturedBox(Common::Rect box, byte color, byte pri
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (*textureData) {
_screen->putPixel(x, y, flag, color, prio, control);
_screen->vectorPutPixel(x, y, flag, color, prio, control);
}
textureData++;
}
Expand All @@ -1203,7 +1220,7 @@ void GfxPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, by
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (bitmap & 1) {
_screen->putPixel(x, y, flag, color, prio, control);
_screen->vectorPutPixel(x, y, flag, color, prio, control);
}
bitNo++;
if (bitNo == 8) {
Expand All @@ -1222,12 +1239,12 @@ void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte c
byte bitNo = 0;
const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
int y, x;

for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (bitmap & 1) {
if (*textureData) {
_screen->putPixel(x, y, flag, color, prio, control);
_screen->vectorPutPixel(x, y, flag, color, prio, control);
}
textureData++;
}
Expand All @@ -1252,7 +1269,10 @@ void GfxPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte
rect.top = y; rect.left = x;
rect.setHeight((size*2)+1); rect.setWidth((size*2)+2);
_ports->offsetRect(rect);
rect.clip(_screen->getWidth(), _screen->getHeight());
rect.clip(_screen->getScriptWidth(), _screen->getScriptHeight());

_screen->vectorAdjustCoordinate(&rect.left, &rect.top);
_screen->vectorAdjustCoordinate(&rect.right, &rect.bottom);

if (code & SCI_PATTERN_CODE_RECTANGLE) {
// Rectangle
Expand Down
16 changes: 8 additions & 8 deletions engines/sci/graphics/ports.cpp
Expand Up @@ -63,10 +63,10 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te
openPort(_menuPort);
setPort(_menuPort);
_text16->SetFont(0);
_menuPort->rect = Common::Rect(0, 0, _screen->getWidth(), _screen->getHeight());
_menuBarRect = Common::Rect(0, 0, _screen->getWidth(), 9);
_menuRect = Common::Rect(0, 0, _screen->getWidth(), 10);
_menuLine = Common::Rect(0, 9, _screen->getWidth(), 10);
_menuPort->rect = Common::Rect(0, 0, _screen->getScriptWidth(), _screen->getScriptHeight());
_menuBarRect = Common::Rect(0, 0, _screen->getScriptWidth(), 9);
_menuRect = Common::Rect(0, 0, _screen->getScriptWidth(), 10);
_menuLine = Common::Rect(0, 9, _screen->getScriptWidth(), 10);

_wmgrPort = new Port(1);
_windowsById.resize(2);
Expand Down Expand Up @@ -122,13 +122,13 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te
} else {
_wmgrPort->rect.bottom = _screen->getHeight();
}
_wmgrPort->rect.right = _screen->getWidth();
_wmgrPort->rect.right = _screen->getScriptWidth();
_wmgrPort->rect.moveTo(0, 0);
_wmgrPort->curTop = 0;
_wmgrPort->curLeft = 0;
_windowList.push_front(_wmgrPort);

_picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true);
_picWind = addWindow(Common::Rect(0, offTop, _screen->getScriptWidth(), _screen->getScriptHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true);
// For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead
// Because of the menu/status bar
if (_usesOldGfxFunctions)
Expand Down Expand Up @@ -321,13 +321,13 @@ Window *GfxPorts::addWindow(const Common::Rect &dims, const Common::Rect *restor
// their interpreter even in the newer VGA games.
r.left = r.left & 0xFFFE;

if (r.width() > _screen->getWidth()) {
if (r.width() > _screen->getScriptWidth()) {
// We get invalid dimensions at least at the end of sq3 (script bug!).
// Same happens very often in lsl5, sierra sci didnt fix it but it looked awful.
// Also happens frequently in the demo of GK1.
warning("Fixing too large window, left: %d, right: %d", dims.left, dims.right);
r.left = 0;
r.right = _screen->getWidth() - 1;
r.right = _screen->getScriptWidth() - 1;
if ((style != _styleUser) && !(style & SCI_WINDOWMGR_STYLE_NOFRAME))
r.right--;
}
Expand Down

0 comments on commit 72e6a9e

Please sign in to comment.