void SmushPlayer::init(int32 speed) { VirtScreen *vs = &_vm->_virtscr[kMainVirtScreen]; _frame = 0; _speed = speed; _endOfFile = false; _vm->_smushVideoShouldFinish = false; _vm->_smushActive = true; _vm->setDirtyColors(0, 255); _dst = vs->getPixels(0, 0); // HACK HACK HACK: This is an *evil* trick, beware! // We do this to fix bug #1037052. A proper solution would change all the // drawing code to use the pitch value specified by the virtual screen. // However, since a lot of the SMUSH code currently assumes the screen // width and pitch to be equal, this will require lots of changes. So // we resort to this hackish solution for now. _origPitch = vs->pitch; _origNumStrips = _vm->_gdi->_numStrips; vs->pitch = vs->w; _vm->_gdi->_numStrips = vs->w / 8; _vm->_mixer->stopHandle(_compressedFileSoundHandle); _vm->_mixer->stopHandle(_IACTchannel); _IACTpos = 0; _vm->_smixer->stop(); }
void MoviePlayer::handleNextFrame() { if (!_video->isVideoLoaded()) return; VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen]; if (_flags & 2) { uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum); assert(dstPtr); uint8 *dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0); assert(dst); copyFrameToBuffer(dst, kDstResource, 0, 0, _vm->_screenWidth * _vm->_bytesPerPixel); } else if (_flags & 1) { copyFrameToBuffer(pvs->getBackPixels(0, 0), kDstScreen, 0, 0, pvs->pitch); Common::Rect imageRect(_video->getWidth(), _video->getHeight()); _vm->restoreBackgroundHE(imageRect); } else { copyFrameToBuffer(pvs->getPixels(0, 0), kDstScreen, 0, 0, pvs->pitch); Common::Rect imageRect(_video->getWidth(), _video->getHeight()); _vm->markRectAsDirty(kMainVirtScreen, imageRect); } if (_video->endOfVideo()) _video->close(); }
static void hlineColor(ScummEngine *scumm, int x1, int x2, int y, byte color) { VirtScreen *vs = &scumm->_virtscr[kMainVirtScreen]; byte *ptr; // Clip y y += scumm->_screenTop; if (y < 0 || y >= scumm->_screenHeight) return; if (x2 < x1) SWAP(x2, x1); // Clip x1 / x2 const int left = scumm->_screenStartStrip * 8; const int right = scumm->_screenEndStrip * 8; if (x1 < left) x1 = left; if (x2 >= right) x2 = right - 1; ptr = (byte *)vs->getBasePtr(x1, y); while (x1++ <= x2) { *ptr++ = color; } }
void MoviePlayer::handleNextFrame() { if (_fd.isOpen() == false) { return; } VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen]; uint8 *dst; decodeFrame(); if (_flags & 2) { uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum); assert(dstPtr); dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); assert(dst); copyFrame(dst, 0, 0); } else if (_flags & 1) { dst = pvs->getBackPixels(0, 0); copyFrame(dst, 0, 0); Common::Rect imageRect(_width, _height); _vm->gdi.copyVirtScreenBuffers(imageRect); } else { dst = pvs->getPixels(0, 0); copyFrame(dst, 0, 0); _vm->markRectAsDirty(kMainVirtScreen, 0, 0, _width, _height); } _frameNum++; if (_frameNum == _framesCount) { close(); } }
void ScummEngine_v2::checkV2MouseOver(Common::Point pos) { VirtScreen *vs = &_virtscr[kVerbVirtScreen]; Common::Rect rect; byte *ptr, *dst; int i, x, y, new_box = -1; // Don't do anything unless the inventory is active if (!(_userState & USERSTATE_IFACE_INVENTORY)) { _mouseOverBoxV2 = -1; return; } if (_cursor.state > 0) { for (i = 0; i < ARRAYSIZE(_mouseOverBoxesV2); i++) { if (_mouseOverBoxesV2[i].rect.contains(pos.x, pos.y - vs->topline)) { new_box = i; break; } } } if ((new_box != _mouseOverBoxV2) || (_game.version == 0)) { if (_mouseOverBoxV2 != -1) { rect = _mouseOverBoxesV2[_mouseOverBoxV2].rect; dst = ptr = vs->getPixels(rect.left, rect.top); // Remove highlight. for (y = rect.height() - 1; y >= 0; y--) { for (x = rect.width() - 1; x >= 0; x--) { if (dst[x] == _mouseOverBoxesV2[_mouseOverBoxV2].hicolor) dst[x] = _mouseOverBoxesV2[_mouseOverBoxV2].color; } dst += vs->pitch; } markRectAsDirty(kVerbVirtScreen, rect); } if (new_box != -1) { rect = _mouseOverBoxesV2[new_box].rect; dst = ptr = vs->getPixels(rect.left, rect.top); // Apply highlight for (y = rect.height() - 1; y >= 0; y--) { for (x = rect.width() - 1; x >= 0; x--) { if (dst[x] == _mouseOverBoxesV2[new_box].color) dst[x] = _mouseOverBoxesV2[new_box].hicolor; } dst += vs->pitch; } markRectAsDirty(kVerbVirtScreen, rect); } _mouseOverBoxV2 = new_box; } }
void ScummEngine_v4::o4_oldRoomEffect() { int a; _opcode = fetchScriptByte(); if ((_opcode & 0x1F) == 3) { a = getVarOrDirectWord(PARAM_1); #if 1 if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) { // FIXME / TODO: OK the first thing to note is: at least in Zak256, // maybe also in other games, this opcode does a bit more. I added // some stubs here, but somebody with a full IDA or more knowledge // about this will have to fill in the gaps. At least now we know // that something is missing here :-) if (a == 4) { //printf("o5_oldRoomEffect ODDBALL: _opcode = 0x%x, a = 0x%x\n", _opcode, a); // No idea what byte_2FCCF is, but it's a globale boolean flag. // I only add it here as a temporary hack to make the pseudo code compile. // Maybe it is just there as a reentry protection guard, given // how it is used? It might also correspond to _screenEffectFlag. int byte_2FCCF = 0; // For now, we force a redraw of the screen background. This // way the Zak end credits seem to work mostly correct. VirtScreen *vs = &_virtscr[kMainVirtScreen]; restoreBackground(Common::Rect(0, vs->topline, vs->w, vs->topline + vs->h)); vs->setDirtyRange(0, vs->h); updateDirtyScreen(kMainVirtScreen); if (byte_2FCCF) { // Here now "sub_1C44" is called, which sets byte_2FCCF to 0 then // calls yet another sub (which also reads byte_2FCCF): byte_2FCCF = 0; //call sub_0BB3 // Now sub_085C is called. This is quite simply: it sets // 0xF000 bytes. starting at 0x40000 to 0. No idea what that // buffer is, maybe a screen buffer, though. Note that // 0xF000 = 320*192. // Maybe this is also the charset mask being cleaned? // call sub_085C // And then sub_1C54 is called, which is almost identical to // the above sub_1C44, only it sets byte_2FCCF to 1: byte_2FCCF = 1; // call sub_0BB3 } else { // Here only sub_085C is called (see comment above) // call sub_085C } return; } #endif } if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); } else {
void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { // WORKAROUND for bug #1509509: Indy3 Mac does not show black // characters (such as in the grail diary) if ignoreCharsetMask // is true. See also patch #1851568. if (_vm->_game.id == GID_INDY3 && _vm->_game.platform == Common::kPlatformMacintosh && _color == 0) ignoreCharsetMask = false; // Indy3 / Zak256 / Loom int width, height, origWidth = 0, origHeight; VirtScreen *vs; const byte *charPtr; byte *dst; int is2byte = (chr >= 256 && _vm->_useCJKMode) ? 1 : 0; assertRange(0, _curId, _vm->_numCharsets - 1, "charset"); if ((vs = _vm->findVirtScreen(_top)) == NULL) return; if (chr == '@') return; if (_vm->_useCJKMode && chr > 127) { if (_vm->_game.platform == Common::kPlatformFMTowns) { charPtr = 0; width = _vm->_cjkFont->getCharWidth(chr); height = _vm->_cjkFont->getFontHeight(); } else { width = _vm->_2byteWidth; height = _vm->_2byteHeight; charPtr = _vm->get2byteCharPtr(chr); } } else { charPtr = _fontPtr + chr * 8; width = getCharWidth(chr); height = 8; } // Clip at the right side (to avoid drawing "outside" the screen bounds). if (_left + origWidth > _right + 1) return; origWidth = width; origHeight = height; if (_shadowMode != kNoShadowMode) { width++; height++; } if (_firstChar) { _str.left = _left; _str.top = _top; _str.right = _left; _str.bottom = _top; _firstChar = false; } int drawTop = _top - vs->topline; _vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height); if (!ignoreCharsetMask) { _hasMask = true; _textScreenID = vs->number; } if ( #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE (_vm->_game.platform != Common::kPlatformFMTowns) && #endif (ignoreCharsetMask || !vs->hasTwoBuffers)) { dst = vs->getPixels(_left, drawTop); if (charPtr) drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel); else if (_vm->_cjkFont) _vm->_cjkFont->drawChar(vs, chr, _left, drawTop, _color, _shadowColor); } else { dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier); if (charPtr) drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte)); else if (_vm->_cjkFont) _vm->_cjkFont->drawChar(_vm->_textSurface, chr, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor); if (is2byte) origWidth /= _vm->_textSurfaceMultiplier; } if (_str.left > _left) _str.left = _left; _left += origWidth; if (_str.right < _left) { _str.right = _left; if (_shadowMode != kNoShadowMode) _str.right++; } if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier) _str.bottom = _top + height / _vm->_textSurfaceMultiplier; }