diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 0bc3811b5ce..eb8a5f6cd00 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -37,6 +37,7 @@ #include "backends/audiocd/audiocd.h" #include "graphics/surface.h" +#include "graphics/sjis.h" #include "audio/mididrv.h" @@ -140,7 +141,23 @@ AGOSEngine_Elvira2::AGOSEngine_Elvira2(OSystem *system, const AGOSGameDescriptio } AGOSEngine_Elvira1::AGOSEngine_Elvira1(OSystem *system, const AGOSGameDescription *gd) - : AGOSEngine(system, gd) { + : AGOSEngine(system, gd), _sjisCurChar(0), _sjisFont(0) { +} + +AGOSEngine_Elvira1::~AGOSEngine_Elvira1() { + delete _sjisFont; +} + +Common::Error AGOSEngine_Elvira1::init() { + Common::Error ret = AGOSEngine::init(); + if (ret.getCode() == Common::kNoError && getPlatform() == Common::kPlatformPC98) { + _sjisFont = Graphics::FontSJIS::createFont(Common::kPlatformPC98); + if (_sjisFont) + _sjisFont->toggleFatPrint(true); + else + error("AGOSEngine_Elvira1::init(): Failed to load SJIS font."); + } + return ret; } AGOSEngine::AGOSEngine(OSystem *system, const AGOSGameDescription *gd) @@ -541,11 +558,12 @@ AGOSEngine::AGOSEngine(OSystem *system, const AGOSGameDescription *gd) _moveXMax = 0; _moveYMax = 0; + _forceAscii = false; + _vc10BasePtrOld = 0; memcpy (_hebrewCharWidths, "\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32); - const Common::FSNode gameDataDir(ConfMan.get("path")); // Add default file directories for Acorn version of @@ -576,7 +594,15 @@ Common::Error AGOSEngine::init() { _screenHeight = 200; } - initGraphics(_screenWidth, _screenHeight); + _internalWidth = _screenWidth; + _internalHeight = _screenHeight; + + if (getPlatform() == Common::kPlatformPC98) { + _internalWidth <<= 1; + _internalHeight <<= 1; + } + + initGraphics(_internalWidth, _internalHeight); _midi = new MidiPlayer(); @@ -601,11 +627,11 @@ Common::Error AGOSEngine::init() { _backGroundBuf = new Graphics::Surface(); _backGroundBuf->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8()); - if (getGameType() == GType_FF || getGameType() == GType_PP) { + if (getGameType() == GType_FF || getGameType() == GType_PP || (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformPC98)) { _backBuf = new Graphics::Surface(); _backBuf->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8()); _scaleBuf = new Graphics::Surface(); - _scaleBuf->create(_screenWidth, _screenHeight, Graphics::PixelFormat::createFormatCLUT8()); + _scaleBuf->create(_internalWidth, _internalHeight, Graphics::PixelFormat::createFormatCLUT8()); } if (getGameType() == GType_SIMON2) { diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 9da4b0cf91c..553131127ec 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -58,6 +58,7 @@ class SeekableReadStream; namespace Graphics { struct Surface; +class FontSJIS; } namespace AGOS { @@ -202,7 +203,7 @@ protected: friend class Debugger; // Engine APIs - Common::Error init(); + virtual Common::Error init(); virtual Common::Error go(); Common::Error run() override { Common::Error err; @@ -349,6 +350,7 @@ protected: uint16 _scrollWidth, _scrollHeight; const byte *_scrollImage; byte _boxStarHeight; + bool _forceAscii; SubroutineLine *_classLine; int16 _classMask, _classMode1, _classMode2; @@ -445,6 +447,7 @@ protected: volatile uint16 _fastFadeInFlag; uint16 _screenWidth, _screenHeight; + uint16 _internalWidth, _internalHeight; uint16 _noOverWrite; bool _rejectBlock; @@ -1156,6 +1159,10 @@ protected: void horizontalScroll(VC10_state *state); void verticalScroll(VC10_state *state); + Graphics::Surface *getBackendSurface() const; + void updateBackendSurface(Common::Rect *area = 0) const; + virtual void clearHiResTextLayer() {} + int vcReadVarOrWord(); uint vcReadNextWord(bool forceLERead = false); uint vcReadNextByte(); @@ -1552,7 +1559,8 @@ protected: class AGOSEngine_Elvira1 : public AGOSEngine { public: AGOSEngine_Elvira1(OSystem *system, const AGOSGameDescription *gd); - //~AGOSEngine_Elvira1(); + ~AGOSEngine_Elvira1() override; + Common::Error init() override; void setupGame() override; void setupOpcodes() override; @@ -1626,8 +1634,15 @@ protected: const OpcodeEntryElvira1 *_opcodesElvira1; void drawIcon(WindowBlock *window, uint icon, uint x, uint y) override; + void windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) override; + void addHiResTextDirtyRect(Common::Rect rect); + void clearHiResTextLayer() override; Common::String genSaveName(int slot) const override; + + Graphics::FontSJIS *_sjisFont; + Common::Array _sjisTextFields; + uint16 _sjisCurChar; }; class AGOSEngine_Elvira2 : public AGOSEngine_Elvira1 { diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index a2175360812..1d73a7dd2ab 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -344,9 +344,9 @@ void MoviePlayerDXA::handleNextFrame() { } bool MoviePlayerDXA::processFrame() { - Graphics::Surface *screen = _vm->_system->lockScreen(); + Graphics::Surface *screen = _vm->getBackendSurface(); copyFrameToBuffer((byte *)screen->getPixels(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch); - _vm->_system->unlockScreen(); + _vm->updateBackendSurface(); uint32 soundTime = _mixer->getSoundElapsedTime(_bgSound); uint32 nextFrameStartTime = ((Video::VideoDecoder::VideoTrack *)getTrack(0))->getNextFrameStartTime(); @@ -495,9 +495,9 @@ void MoviePlayerSMK::nextFrame() { } bool MoviePlayerSMK::processFrame() { - Graphics::Surface *screen = _vm->_system->lockScreen(); + Graphics::Surface *screen = _vm->getBackendSurface(); copyFrameToBuffer((byte *)screen->getPixels(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch); - _vm->_system->unlockScreen(); + _vm->updateBackendSurface(); uint32 waitTime = getTimeToNextFrame(); diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp index ae31814e43a..a10172647ce 100644 --- a/engines/agos/charset-fontdata.cpp +++ b/engines/agos/charset-fontdata.cpp @@ -28,6 +28,7 @@ #include "agos/intern.h" #include "graphics/surface.h" +#include "graphics/sjis.h" namespace AGOS { @@ -2921,7 +2922,7 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { dst = (byte *)screen->getPixels(); @@ -3019,9 +3020,85 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { dst += dstPitch; } while (--h); - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } +void AGOSEngine_Elvira1::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { + if (_language != Common::JA_JPN || _forceAscii) { + AGOSEngine::windowDrawChar(window, x, y, chr); + return; + } + + if (_sjisCurChar) { + _sjisCurChar |= (chr << 8); + } else { + _sjisCurChar = chr; + if ((chr >= 0x80 && chr < 0xA0) || chr >= 0xE0) + return; + } + + _videoLockOut |= 0x8000; + + x = x & ~7; + y = (y + 4) & ~3; + // PC-98 uses text mode black (hardware colors, not related to the graphics mode palette + // colors) for font drawing, so I just set one of the unused black colors (color 33) here. + _sjisFont->drawChar(*_scaleBuf, _sjisCurChar, x << 1, y << 1, 33, 0); + Common::Rect dirtyRect(x, y, x + (_sjisFont->getCharWidth(_sjisCurChar) >> 1), y + (_sjisFont->getFontHeight() >> 1)); + addHiResTextDirtyRect(dirtyRect); + updateBackendSurface(&dirtyRect); + _sjisCurChar = 0; + + _videoLockOut &= ~0x8000; +} + +void AGOSEngine_Elvira1::addHiResTextDirtyRect(Common::Rect rect) { + rect.left >>= 1; + rect.top <<= 1; + rect.right >>= 1; + rect.bottom <<= 1; + + for (Common::Array::iterator i = _sjisTextFields.begin(); i != _sjisTextFields.end(); ++i) { + // Merge rects if it makes sense, but only once. + if (rect.left <= i->right && rect.right >= i->left && rect.top <= i->bottom && rect.bottom >= i->top) { + i->left = MIN(i->left, rect.left); + i->top = MIN(i->top, rect.top); + i->right = MAX(i->right, rect.right); + i->bottom = MAX(i->bottom, rect.bottom); + return; + } + } + + _sjisTextFields.push_back(rect); +} + +void AGOSEngine_Elvira1::clearHiResTextLayer() { + if (getPlatform() != Common::kPlatformPC98) + return; + + void *p = _scaleBuf->getPixels(); + assert(p); + + if (_sjisTextFields.size() < 10) { + for (Common::Array::iterator i = _sjisTextFields.begin(); i != _sjisTextFields.end(); ++i) { + uint16 w = i->width(); + uint16 ptch = _scaleBuf->pitch >> 2; + uint32 *dst = (uint32*)p + i->top * ptch + i->left; + for (uint32 *end = dst + i->height() * ptch; dst < end; dst += ptch) + Common::fill(dst, &dst[w], 0); + i->left <<= 1; + i->top >>= 1; + i->right <<= 1; + i->bottom >>= 1; + updateBackendSurface(i); + } + } else { + memset(p, 0, _scaleBuf->w * _scaleBuf->h); + updateBackendSurface(); + } + _sjisTextFields.clear(); +} + } // End of namespace AGOS diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp index 4d83a4ef1c5..c3e8e49d63c 100644 --- a/engines/agos/charset.cpp +++ b/engines/agos/charset.cpp @@ -148,6 +148,11 @@ void AGOSEngine::justifyOutPut(byte chr) { _printCharPixelCount = 0; doOutput(&chr, 1); clsCheck(_textWindow); + } else if (getLanguage() == Common::JA_JPN) { + // Japanese has no word wrapping + _lettersToPrintBuf[0] = chr; + _lettersToPrintBuf[1] = '\0'; + doOutput(_lettersToPrintBuf, 1); } else if (chr == 0 || chr == ' ' || chr == 10) { bool fit; @@ -215,6 +220,7 @@ void AGOSEngine_PN::windowPutChar(WindowBlock *window, byte c, byte b) { void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) { byte width = 6; + byte textColumnWidth = 8; if (c == 12) { clearWindow(window); @@ -256,8 +262,9 @@ void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) { return; } - // Ignore invalid characters - if (c - 32 > 98) + if (_language == Common::JA_JPN) + textColumnWidth = width = 4; + else if (c - 32 > 98) // Ignore invalid characters return; if (window->textLength == window->textMaxLength) { @@ -278,16 +285,15 @@ void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) { windowDrawChar(window, (window->width + window->x - window->textColumn) * 8, window->textRow * 8 + window->y, c); window->textLength++; } else { - windowDrawChar(window, (window->textColumn + window->x) * 8, window->textRow * 8 + window->y, c); - + windowDrawChar(window, window->x * 8 + window->textColumn * textColumnWidth, window->textRow * 8 + window->y, c); window->textLength++; - window->textColumnOffset += 6; + window->textColumnOffset += width; if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { if (c == 'i' || c == 'l') window->textColumnOffset -= 2; } - if (window->textColumnOffset >= 8) { - window->textColumnOffset -= 8; + if (window->textColumnOffset >= textColumnWidth) { + window->textColumnOffset -= textColumnWidth; window->textColumn++; } } @@ -354,24 +360,37 @@ void AGOSEngine::windowScroll(WindowBlock *window) { _videoLockOut |= 0x8000; if (window->height != 1) { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *src, *dst; - uint16 w, h; + uint16 w1, h1, w2, h2; - w = window->width * 8; - h = (window->height -1) * 8; + w1 = w2 = window->width * 8; + h1 = h2 = (window->height -1) * 8; dst = (byte *)screen->getBasePtr(window->x * 8, window->y); src = dst + 8 * screen->pitch; do { - memcpy(dst, src, w); + memcpy(dst, src, w1); src += screen->pitch; dst += screen->pitch; - } while (--h); + } while (--h1); - _system->unlockScreen(); + if (getGameId() == GID_ELVIRA1 && getPlatform() == Common::kPlatformPC98) { + w1 = w2 << 1; + h1 = h2 << 1; + dst = (byte *)_scaleBuf->getBasePtr(window->x * 16, window->y * 2); + src = dst + 16 * screen->pitch; + do { + memcpy(dst, src, w1); + src += screen->pitch; + dst += screen->pitch; + } while (--h1); + } + + Common::Rect dirtyRect(window->x * 8, window->y, window->x * 8 + w2, window->y + h2); + updateBackendSurface(&dirtyRect); } colorBlock(window, window->x * 8, (window->height - 1) * 8 + window->y, window->width * 8, 8); diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp index 19a38116cfb..6a16b764b48 100644 --- a/engines/agos/cursor.cpp +++ b/engines/agos/cursor.cpp @@ -559,6 +559,10 @@ void AGOSEngine::handleMouseMoved() { _needHitAreaRecalc++; } } else if (getGameType() == GType_ELVIRA1) { + if (getPlatform() == Common::kPlatformPC98) { + _mouse.x >>= 1; + _mouse.y >>= 1; + } if (_mouseCursor != _variableArray[438]) { _mouseCursor = _variableArray[438]; _needHitAreaRecalc++; @@ -784,6 +788,12 @@ static const byte mouseCursorPalette[] = { void AGOSEngine::initMouse() { _maxCursorWidth = 16; _maxCursorHeight = 16; + + if (getGameId() == GID_ELVIRA1 && getPlatform() == Common::kPlatformPC98) { + _maxCursorWidth <<= 1; + _maxCursorHeight <<= 1; + } + _mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1); memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); @@ -864,7 +874,21 @@ void AGOSEngine::drawMousePointer() { src += 2; } - CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); + if (getGameId() == GID_ELVIRA1 && getPlatform() == Common::kPlatformPC98) { + // Simple 2x upscaling for the cursor in dual layer hi-res mode. + uint8 ptch = 16; + uint16 *dst1 = &((uint16*)_mouseData)[16 * 16 * 2 - 1]; + uint16 *dst2 = dst1 - ptch; + for (const byte *src = &_mouseData[16 * 16 - 1]; src >= _mouseData; --src) { + *dst1-- = *dst2-- = (*src << 8) | *src; + if (!(ptch = (ptch - 1) % 16)) { + dst1 -= 16; + dst2 -= 16; + } + } + } + + CursorMan.replaceCursor(_mouseData, _maxCursorWidth, _maxCursorHeight, 0, 0, 0xFF); } } diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index f7ceeb70c13..a627bb54d89 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -536,7 +536,7 @@ void AGOSEngine::displayBoxStars() { ha = _hitAreas; count = ARRAYSIZE(_hitAreas); - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); do { if (ha->id != 0 && ha->flags & kBFBoxInUse && !(ha->flags & kBFBoxDead)) { @@ -604,7 +604,7 @@ void AGOSEngine::displayBoxStars() { } } while (ha++, --count); - _system->unlockScreen(); + updateBackendSurface(); delay(100); @@ -724,7 +724,7 @@ void AGOSEngine::fillBackFromBackGround(uint16 height, uint16 width) { } void AGOSEngine::fillBackFromFront() { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *src = (byte *)screen->getPixels(); byte *dst = getBackBuf(); @@ -733,7 +733,7 @@ void AGOSEngine::fillBackFromFront() { src += screen->pitch; dst += _backBuf->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine::fillBackGroundFromBack() { @@ -747,7 +747,7 @@ void AGOSEngine::fillBackGroundFromBack() { } void AGOSEngine::fillBackGroundFromFront() { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *src = (byte *)screen->getPixels(); byte *dst = getBackGround(); @@ -756,7 +756,7 @@ void AGOSEngine::fillBackGroundFromFront() { src += screen->pitch; dst += _backGroundBuf->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) { @@ -782,7 +782,7 @@ void AGOSEngine::displayScreen() { } } - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); if (getGameType() == GType_PP || getGameType() == GType_FF) { byte *src = getBackBuf(); byte *dst = (byte *)screen->getPixels(); @@ -841,7 +841,7 @@ void AGOSEngine::displayScreen() { } } - _system->unlockScreen(); + updateBackendSurface(); if (getGameType() == GType_FF && _scrollFlag) { scrollScreen(); diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index 3c16590affa..2708d0a6817 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -365,7 +365,7 @@ static const byte _image4[32] = { void AGOSEngine::drawStuff(const byte *src, uint xoffs) { const uint8 y = (getPlatform() == Common::kPlatformAtariST) ? 132 : 135; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getBasePtr(xoffs, y); for (uint h = 0; h < 6; h++) { @@ -374,7 +374,7 @@ void AGOSEngine::drawStuff(const byte *src, uint xoffs) { dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine::playerDamageEvent(VgaTimerEntry * vte, uint dx) { diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index 8bdcfcfa6d6..07342277a50 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -640,7 +640,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) { if (!drawImage_clip(state)) return; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); if (getFeatures() & GF_32COLOR) state->palette = 0xC0; @@ -738,7 +738,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) { drawVertImage(state); } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine::drawBackGroundImage(VC10_state *state) { @@ -857,7 +857,7 @@ void AGOSEngine::drawImage(VC10_state *state) { if (!drawImage_clip(state)) return; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); uint16 xoffs = 0, yoffs = 0; if (getGameType() == GType_WW) { @@ -951,7 +951,7 @@ void AGOSEngine::drawImage(VC10_state *state) { drawVertImage(state); } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine::horizontalScroll(VC10_state *state) { @@ -1023,6 +1023,61 @@ void AGOSEngine::verticalScroll(VC10_state *state) { } } +Graphics::Surface *AGOSEngine::getBackendSurface() const { + return (getGameId() == GID_ELVIRA1 && getPlatform() == Common::kPlatformPC98) ? _backBuf : _system->lockScreen(); +} + +void AGOSEngine::updateBackendSurface(Common::Rect *area) const { + if (getGameId() == GID_ELVIRA1 && getPlatform() == Common::kPlatformPC98) { + int x = 0; + int y = 0; + int w = _screenWidth; + int h = _screenHeight; + + if (area) { + x = area->left; + y = area->top; + w = area->width(); + h = area->height(); + } + + Graphics::Surface *screen = _system->lockScreen(); + + int src0Pitch = _backBuf->pitch; + int src1Pitch = _scaleBuf->pitch; + int dst1Pitch = screen->pitch; + const byte *src00 = (byte*)_backBuf->getBasePtr(x, y); + const byte *src10 = (byte*)_scaleBuf->getBasePtr(x << 1, y << 1); + const byte *src11 = src10 + src1Pitch; + byte *dst10 = (byte*)screen->getBasePtr(x << 1, y << 1); + byte *dst11 = dst10 + dst1Pitch; + src0Pitch -= w; + src1Pitch += (src1Pitch - (w << 1)); + dst1Pitch += (dst1Pitch - (w << 1)); + + while (h--) { + for (int i = 0; i < w; ++i) { + uint8 v0 = *src00++; + uint8 v1 = *src10++; + *dst10++ = v1 ? v1 : v0; + v1 = *src10++; + *dst10++ = v1 ? v1 : v0; + v1 = *src11++; + *dst11++ = v1 ? v1 : v0; + v1 = *src11++; + *dst11++ = v1 ? v1 : v0; + } + src00 += src0Pitch; + src10 += src1Pitch; + src11 += src1Pitch; + dst10 += dst1Pitch; + dst11 += dst1Pitch; + } + } + + _system->unlockScreen(); +} + void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) { byte *p = palPtr; @@ -1372,7 +1427,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas uint width = _videoWindows[updateWindow * 4 + 2] * 16; uint height = _videoWindows[updateWindow * 4 + 3]; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)_backGroundBuf->getBasePtr(xoffs, yoffs); byte *src = 0; uint srcWidth = 0; @@ -1389,7 +1444,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas src = (byte *)screen->getBasePtr(xoffs, yoffs); srcWidth = screen->pitch; } else { - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x20; return; } @@ -1404,7 +1459,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas src = (byte *)screen->getBasePtr(xoffs, yoffs); srcWidth = screen->pitch; } else { - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x20; return; } @@ -1416,7 +1471,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas src = (byte *)screen->getBasePtr(xoffs, yoffs); srcWidth = screen->pitch; } else { - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x20; return; } @@ -1428,7 +1483,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas src = (byte *)screen->getBasePtr(xoffs, yoffs); srcWidth = screen->pitch; } else { - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x20; return; } @@ -1474,7 +1529,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas } } - _system->unlockScreen(); + updateBackendSurface(); } _videoLockOut &= ~0x20; @@ -1485,7 +1540,7 @@ void AGOSEngine::drawEdging() { byte *dst; uint8 color = (getPlatform() == Common::kPlatformDOS) ? 7 : 15; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getBasePtr(0, 136); uint8 len = 52; @@ -1499,7 +1554,7 @@ void AGOSEngine::drawEdging() { dst = (byte *)screen->getBasePtr(0, 187); memset(dst, color, _screenWidth); - _system->unlockScreen(); + updateBackendSurface(); } } // End of namespace AGOS diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index 364fbf5f15a..3bbec55f3e8 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -202,7 +202,7 @@ void AGOSEngine_Simon2::drawIcon(WindowBlock *window, uint icon, uint x, uint y) _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getPixels(); dst += 110; @@ -217,7 +217,7 @@ void AGOSEngine_Simon2::drawIcon(WindowBlock *window, uint icon, uint x, uint y) src += READ_LE_UINT16(src + icon * 4 + 2); decompressIcon(dst, src, 20, 10, 208, screen->pitch); - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -228,7 +228,7 @@ void AGOSEngine_Simon1::drawIcon(WindowBlock *window, uint icon, uint x, uint y) _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getPixels(); dst += (x + window->x) * 8; @@ -245,7 +245,7 @@ void AGOSEngine_Simon1::drawIcon(WindowBlock *window, uint icon, uint x, uint y) decompressIcon(dst, src, 24, 12, 224, screen->pitch); } - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -256,7 +256,7 @@ void AGOSEngine_Waxworks::drawIcon(WindowBlock *window, uint icon, uint x, uint _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getPixels(); dst += (x + window->x) * 8; @@ -273,7 +273,7 @@ void AGOSEngine_Waxworks::drawIcon(WindowBlock *window, uint icon, uint x, uint decompressIcon(dst, src, 24, 10, color, screen->pitch); } - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -284,7 +284,7 @@ void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getPixels(); dst += (x + window->x) * 8; @@ -301,7 +301,7 @@ void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y decompressIcon(dst, src, 24, 12, color, screen->pitch); } - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -312,7 +312,7 @@ void AGOSEngine_Elvira1::drawIcon(WindowBlock *window, uint icon, uint x, uint y _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getPixels(); dst += (x + window->x) * 8; @@ -328,7 +328,7 @@ void AGOSEngine_Elvira1::drawIcon(WindowBlock *window, uint icon, uint x, uint y decompressIconPlanar(dst, src, 24, 12, 16, screen->pitch, false); } - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -339,7 +339,7 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getBasePtr(x * 8, y); src = _iconFilePtr + icon * 146; @@ -365,7 +365,7 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { } } - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -951,7 +951,7 @@ void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) { src = _arrowImage; } - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getBasePtr(x * 8, y); for (h = 0; h < 19; h++) { @@ -964,7 +964,7 @@ void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) { dst+= screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine_Simon1::removeArrows(WindowBlock *window, uint num) { @@ -1042,7 +1042,7 @@ static const byte hitBarData[12 * 7] = { // Personal Nightmare specific void AGOSEngine_PN::drawIconHitBar() { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getBasePtr(6 * 8, 3); const byte *src = hitBarData; uint8 color = (getPlatform() == Common::kPlatformDOS) ? 7 : 15; @@ -1061,7 +1061,7 @@ void AGOSEngine_PN::drawIconHitBar() { dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine_PN::iconPage() { diff --git a/engines/agos/menus.cpp b/engines/agos/menus.cpp index 77a37cb601f..7de21be1467 100644 --- a/engines/agos/menus.cpp +++ b/engines/agos/menus.cpp @@ -163,7 +163,7 @@ void AGOSEngine::unlightMenuStrip() { mouseOff(); - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); src = (byte *)screen->getBasePtr(272, 8); w = 48; h = 82; @@ -179,7 +179,7 @@ void AGOSEngine::unlightMenuStrip() { for (i = 120; i != 130; i++) disableBox(i); - _system->unlockScreen(); + updateBackendSurface(); mouseOn(); } @@ -191,7 +191,7 @@ void AGOSEngine::lightMenuBox(uint hitarea) { mouseOff(); - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); src = (byte *)screen->getBasePtr(ha->x, ha->y); w = ha->width; h = ha->height; @@ -204,7 +204,7 @@ void AGOSEngine::lightMenuBox(uint hitarea) { src += screen->pitch; } while (--h); - _system->unlockScreen(); + updateBackendSurface(); mouseOn(); } diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp index 38b29d475e9..85f92bcf7a7 100644 --- a/engines/agos/script_e1.cpp +++ b/engines/agos/script_e1.cpp @@ -1166,6 +1166,7 @@ void AGOSEngine::printStats() { window->flags = 1; mouseOff(); + _forceAscii = true; // Strength val = _variableArray[0]; @@ -1215,6 +1216,7 @@ void AGOSEngine::printStats() { val = 99; writeChar(window, 36, 133, 4, val); + _forceAscii = false; mouseOn(); } diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp index fb3878381f8..7f1ff7592cc 100644 --- a/engines/agos/verb.cpp +++ b/engines/agos/verb.cpp @@ -985,7 +985,7 @@ void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) { _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); src = (byte *)screen->getBasePtr(ha->x, ha->y); // WORKAROUND: Hitareas for saved game names aren't adjusted for scrolling locations @@ -1041,7 +1041,7 @@ void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) { src += screen->pitch; } while (--h); - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index 65f3efcd0d8..c3790de4022 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -1182,7 +1182,7 @@ void AGOSEngine::vc31_setWindow() { void AGOSEngine::vc32_saveScreen() { if (getGameType() == GType_PN) { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = getBackGround(); byte *src = (byte *)screen->getPixels(); for (int i = 0; i < _screenHeight; i++) { @@ -1190,7 +1190,7 @@ void AGOSEngine::vc32_saveScreen() { dst += _backGroundBuf->pitch; src += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } else { uint16 xoffs = _videoWindows[4 * 4 + 0] * 16; uint16 yoffs = _videoWindows[4 * 4 + 1]; @@ -1251,13 +1251,14 @@ void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) { } if (getGameType() == GType_ELVIRA1 && num == 3) { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getPixels(); for (int i = 0; i < _screenHeight; i++) { memset(dst, color, _screenWidth); dst += screen->pitch; } - _system->unlockScreen(); + clearHiResTextLayer(); + updateBackendSurface(); } else { const uint16 *vlut = &_videoWindows[num * 4]; uint16 xoffs = (vlut[0] - _videoWindows[16]) * 16; diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index a26f189c43f..f4ecd11a057 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -89,7 +89,7 @@ void AGOSEngine::vc45_setWindowPalette() { dst += width * 2; } } else { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getBasePtr(vlut[0] * 16, vlut[1]); if (getGameType() == GType_ELVIRA2 && num == 7) { @@ -107,7 +107,7 @@ void AGOSEngine::vc45_setWindowPalette() { dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } } @@ -223,7 +223,7 @@ void AGOSEngine::vc53_dissolveIn() { uint16 count = dissolveCheck * 2; while (count--) { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dstPtr = (byte *)screen->getBasePtr(x, y); yoffs = _rnd.getRandomNumber(dissolveY); @@ -264,7 +264,7 @@ void AGOSEngine::vc53_dissolveIn() { *dst &= color; *dst |= *src & 0xF; - _system->unlockScreen(); + updateBackendSurface(); dissolveCount--; if (!dissolveCount) { @@ -296,7 +296,7 @@ void AGOSEngine::vc54_dissolveOut() { uint16 count = dissolveCheck * 2; while (count--) { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dstPtr = (byte *)screen->getBasePtr(x, y); color |= dstPtr[0] & 0xF0; @@ -318,7 +318,7 @@ void AGOSEngine::vc54_dissolveOut() { dst += xoffs; *dst = color; - _system->unlockScreen(); + updateBackendSurface(); dissolveCount--; if (!dissolveCount) { @@ -378,7 +378,7 @@ void AGOSEngine::fullFade() { } void AGOSEngine::vc56_fullScreen() { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getPixels(); byte *src = _curVgaFile2 + 800; @@ -387,7 +387,7 @@ void AGOSEngine::vc56_fullScreen() { src += 320; dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); fullFade(); } diff --git a/engines/agos/vga_pn.cpp b/engines/agos/vga_pn.cpp index 306c41c71c7..629fd2882b8 100644 --- a/engines/agos/vga_pn.cpp +++ b/engines/agos/vga_pn.cpp @@ -154,7 +154,7 @@ void AGOSEngine::vc48_specialEffect() { if (getPlatform() == Common::kPlatformDOS) { if (num == 1) { - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getPixels(); for (uint h = 0; h < _screenHeight; h++) { @@ -164,7 +164,7 @@ void AGOSEngine::vc48_specialEffect() { } dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } else if (num == 2) { const char *str = "There are gurgling noises from the sink."; for (; *str; str++) @@ -204,13 +204,13 @@ void AGOSEngine_PN::clearVideoWindow(uint16 num, uint16 color) { uint16 xoffs = vlut[0] * 16; uint16 yoffs = vlut[1]; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getBasePtr(xoffs, yoffs); for (uint h = 0; h < vlut[3]; h++) { memset(dst, color, vlut[2] * 16); dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } } // End of namespace AGOS diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp index 5bf8f845518..ceffe771017 100644 --- a/engines/agos/vga_ww.cpp +++ b/engines/agos/vga_ww.cpp @@ -142,7 +142,7 @@ void AGOSEngine::vc61() { byte *src, *dst, *dstPtr; uint h, tmp; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dstPtr = (byte *)screen->getPixels(); if (a == 6) { @@ -175,7 +175,7 @@ void AGOSEngine::vc61() { } if (a != 6) { - _system->unlockScreen(); + updateBackendSurface(); return; } @@ -189,7 +189,7 @@ void AGOSEngine::vc61() { dst += screen->pitch; } - _system->unlockScreen(); + updateBackendSurface(); if (a == 6) fullFade(); diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index de0b768d027..8be23ef249a 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -65,11 +65,13 @@ WindowBlock *AGOSEngine::openWindow(uint x, uint y, uint w, uint h, uint flags, window->textRow = 0; window->scrollY = 0; - // Characters are 6 pixels + // Characters are 6 pixels (except Japanese: when downscaled, 1-byte characters are 4 pixels, 2-byte characters are 8 pixels) if (getGameType() == GType_ELVIRA2) window->textMaxLength = (window->width * 8 - 4) / 6; else if (getGameType() == GType_PN) window->textMaxLength = window->width * 8 / 6 + 1; + else if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformPC98) + window->textMaxLength = window->width << 1; else window->textMaxLength = window->width * 8 / 6; @@ -107,6 +109,7 @@ void AGOSEngine::closeWindow(uint a) { } void AGOSEngine::clearWindow(WindowBlock *window) { + clearHiResTextLayer(); if (window->flags & 0x10) restoreWindow(window); else @@ -169,7 +172,7 @@ void AGOSEngine::colorWindow(WindowBlock *window) { void AGOSEngine::colorBlock(WindowBlock *window, uint16 x, uint16 y, uint16 w, uint16 h) { _videoLockOut |= 0x8000; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); byte *dst = (byte *)screen->getBasePtr(x, y); uint8 color = window->fillColor; @@ -181,7 +184,7 @@ void AGOSEngine::colorBlock(WindowBlock *window, uint16 x, uint16 y, uint16 w, u dst += screen->pitch; } while (--h); - _system->unlockScreen(); + updateBackendSurface(); _videoLockOut &= ~0x8000; } @@ -231,7 +234,7 @@ void AGOSEngine::restoreBlock(uint16 x, uint16 y, uint16 w, uint16 h) { byte *dst, *src; uint i; - Graphics::Surface *screen = _system->lockScreen(); + Graphics::Surface *screen = getBackendSurface(); dst = (byte *)screen->getPixels(); src = getBackGround(); @@ -250,7 +253,7 @@ void AGOSEngine::restoreBlock(uint16 x, uint16 y, uint16 w, uint16 h) { src += _backGroundBuf->pitch; } - _system->unlockScreen(); + updateBackendSurface(); } void AGOSEngine::setTextColor(uint color) {