aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/graphics/screen_lok.cpp
diff options
context:
space:
mode:
authorathrxx2019-01-26 01:31:34 +0100
committerathrxx2019-03-06 20:48:15 +0100
commit1dfdcc7252ac83643cae7a7447c025da2af63843 (patch)
treeb6736d006bf67d5264dd171c336f0915695d1f88 /engines/kyra/graphics/screen_lok.cpp
parent8b53d20b51771680c3d31aa02c0285b7a8be4e85 (diff)
downloadscummvm-rg350-1dfdcc7252ac83643cae7a7447c025da2af63843.tar.gz
scummvm-rg350-1dfdcc7252ac83643cae7a7447c025da2af63843.tar.bz2
scummvm-rg350-1dfdcc7252ac83643cae7a7447c025da2af63843.zip
KYRA: cleanup dir
Reorganize all files in sub directories. The file placement isn't as intuitive as it might be for other engines, which is probably the reason why this hasn't been done before.
Diffstat (limited to 'engines/kyra/graphics/screen_lok.cpp')
-rw-r--r--engines/kyra/graphics/screen_lok.cpp447
1 files changed, 447 insertions, 0 deletions
diff --git a/engines/kyra/graphics/screen_lok.cpp b/engines/kyra/graphics/screen_lok.cpp
new file mode 100644
index 0000000000..114382b487
--- /dev/null
+++ b/engines/kyra/graphics/screen_lok.cpp
@@ -0,0 +1,447 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "kyra/graphics/screen_lok.h"
+#include "kyra/engine/kyra_lok.h"
+
+#include "common/system.h"
+
+#include "graphics/palette.h"
+
+namespace Kyra {
+
+Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system)
+ : Screen(vm, system, _screenDimTable, _screenDimTableCount) {
+ _vm = vm;
+ _unkPtr1 = _unkPtr2 = 0;
+ _bitBlitNum = 0;
+}
+
+Screen_LoK::~Screen_LoK() {
+ for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) {
+ delete[] _saveLoadPage[i];
+ _saveLoadPage[i] = 0;
+ }
+
+ for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) {
+ delete[] _saveLoadPageOvl[i];
+ _saveLoadPageOvl[i] = 0;
+ }
+
+ delete[] _unkPtr1;
+ delete[] _unkPtr2;
+}
+
+bool Screen_LoK::init() {
+ if (!Screen::init())
+ return false;
+
+ memset(_bitBlitRects, 0, sizeof(_bitBlitRects));
+ _bitBlitNum = 0;
+ memset(_saveLoadPage, 0, sizeof(_saveLoadPage));
+ memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl));
+
+ _unkPtr1 = new uint8[getRectSize(1, 144)];
+ assert(_unkPtr1);
+ memset(_unkPtr1, 0, getRectSize(1, 144));
+ _unkPtr2 = new uint8[getRectSize(1, 144)];
+ assert(_unkPtr2);
+ memset(_unkPtr2, 0, getRectSize(1, 144));
+
+ return true;
+}
+
+void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return;
+
+ assert(_vm->palTable1()[palIndex]);
+
+ Palette tempPal(getPalette(0).getNumColors());
+ tempPal.copy(getPalette(0));
+ tempPal.copy(_vm->palTable1()[palIndex], 0, size, startIndex);
+
+ fadePalette(tempPal, fadeTime * 18);
+
+ getPalette(0).copy(tempPal, startIndex, size);
+ setScreenPalette(getPalette(0));
+ _system->updateScreen();
+}
+
+void Screen_LoK::addBitBlitRect(int x, int y, int w, int h) {
+ if (_bitBlitNum >= kNumBitBlitRects)
+ error("too many bit blit rects");
+
+ _bitBlitRects[_bitBlitNum].left = x;
+ _bitBlitRects[_bitBlitNum].top = y;
+ _bitBlitRects[_bitBlitNum].right = x + w;
+ _bitBlitRects[_bitBlitNum].bottom = y + h;
+ ++_bitBlitNum;
+}
+
+void Screen_LoK::bitBlitRects() {
+ Common::Rect *cur = _bitBlitRects;
+ while (_bitBlitNum) {
+ _bitBlitNum--;
+ copyRegion(cur->left, cur->top, cur->left, cur->top, cur->width(), cur->height(), 2, 0);
+ ++cur;
+ }
+}
+
+void Screen_LoK::savePageToDisk(const char *file, int page) {
+ if (!_saveLoadPage[page / 2]) {
+ _saveLoadPage[page / 2] = new uint8[SCREEN_W * SCREEN_H];
+ assert(_saveLoadPage[page / 2]);
+ }
+ memcpy(_saveLoadPage[page / 2], getPagePtr(page), SCREEN_W * SCREEN_H);
+
+ if (_useOverlays) {
+ if (!_saveLoadPageOvl[page / 2]) {
+ _saveLoadPageOvl[page / 2] = new uint8[SCREEN_OVL_SJIS_SIZE];
+ assert(_saveLoadPageOvl[page / 2]);
+ }
+
+ uint8 *srcPage = getOverlayPtr(page);
+ if (!srcPage) {
+ warning("trying to save unsupported overlay page %d", page);
+ return;
+ }
+
+ memcpy(_saveLoadPageOvl[page / 2], srcPage, SCREEN_OVL_SJIS_SIZE);
+ }
+}
+
+void Screen_LoK::loadPageFromDisk(const char *file, int page) {
+ if (!_saveLoadPage[page / 2]) {
+ warning("trying to restore page %d, but no backup found", page);
+ return;
+ }
+
+ copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page / 2]);
+ delete[] _saveLoadPage[page / 2];
+ _saveLoadPage[page / 2] = 0;
+
+ if (_saveLoadPageOvl[page / 2]) {
+ uint8 *dstPage = getOverlayPtr(page);
+ if (!dstPage) {
+ warning("trying to restore unsupported overlay page %d", page);
+ return;
+ }
+
+ memcpy(dstPage, _saveLoadPageOvl[page / 2], SCREEN_OVL_SJIS_SIZE);
+ delete[] _saveLoadPageOvl[page / 2];
+ _saveLoadPageOvl[page / 2] = 0;
+ }
+}
+
+void Screen_LoK::queryPageFromDisk(const char *file, int page, uint8 *buffer) {
+ if (!_saveLoadPage[page / 2]) {
+ warning("trying to query page %d, but no backup found", page);
+ return;
+ }
+
+ memcpy(buffer, _saveLoadPage[page / 2], SCREEN_W * SCREEN_H);
+}
+
+void Screen_LoK::deletePageFromDisk(int page) {
+ delete[] _saveLoadPage[page / 2];
+ _saveLoadPage[page / 2] = 0;
+
+ if (_saveLoadPageOvl[page / 2]) {
+ delete[] _saveLoadPageOvl[page / 2];
+ _saveLoadPageOvl[page / 2] = 0;
+ }
+}
+
+void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) {
+ if (x < 1)
+ return;
+
+ int height = 128;
+ if (flag)
+ height += 8;
+ if (!(x & 1))
+ ++x;
+ if (x == 19)
+ x = 17;
+
+ uint8 *ptr1 = _unkPtr1;
+ uint8 *ptr2 = _unkPtr2;
+ int oldVideoPage = _curPage;
+ _curPage = page;
+
+ int curX = x;
+ copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2);
+ for (int i = 0; i < 19; ++i) {
+ int tempX = curX + 1;
+ copyRegionToBuffer(_curPage, tempX << 3, 8, 8, height, ptr1);
+ copyBlockToPage(_curPage, tempX << 3, 8, 8, height, ptr2);
+ int newXPos = curX + x;
+ if (newXPos > 37)
+ newXPos = newXPos % 38;
+
+ tempX = newXPos + 1;
+ copyRegionToBuffer(_curPage, tempX << 3, 8, 8, height, ptr2);
+ copyBlockToPage(_curPage, tempX << 3, 8, 8, height, ptr1);
+ curX += x * 2;
+ if (curX > 37) {
+ curX = curX % 38;
+ }
+ }
+ _curPage = oldVideoPage;
+}
+
+void Screen_LoK::copyBackgroundBlock2(int x) {
+ copyBackgroundBlock(x, 4, 1);
+}
+
+void Screen_LoK::setTextColorMap(const uint8 *cmap) {
+ setTextColor(cmap, 0, 11);
+}
+
+int Screen_LoK::getRectSize(int x, int y) {
+ if (x < 1)
+ x = 1;
+ else if (x > 40)
+ x = 40;
+
+ if (y < 1)
+ y = 1;
+ else if (y > 200)
+ y = 200;
+
+ return ((x * y) << 3);
+}
+
+void Screen_LoK::postProcessCursor(uint8 *data, int width, int height, int pitch) {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga && _interfacePaletteEnabled) {
+ pitch -= width;
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ if (*data != _cursorColorKey)
+ *data += 32;
+ ++data;
+ }
+
+ data += pitch;
+ }
+ }
+}
+
+#pragma mark -
+
+Screen_LoK_16::Screen_LoK_16(KyraEngine_LoK *vm, OSystem *system) : Screen_LoK(vm, system) {
+ memset(_paletteDither, 0, sizeof(_paletteDither));
+}
+
+void Screen_LoK_16::setScreenPalette(const Palette &pal) {
+ _screenPalette->copy(pal);
+
+ for (int i = 0; i < 256; ++i)
+ paletteMap(i, pal[i * 3 + 0] << 2, pal[i * 3 + 1] << 2, pal[i * 3 + 2] << 2);
+
+ set16ColorPalette(_palette16);
+ _forceFullUpdate = true;
+}
+
+void Screen_LoK_16::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc) {
+ uint8 notBlackFlag = 0;
+ for (int i = 0; i < 768; ++i) {
+ if ((*_screenPalette)[i])
+ notBlackFlag |= 1;
+ if (pal[i])
+ notBlackFlag |= 2;
+ }
+
+ if (notBlackFlag == 1 || notBlackFlag == 2) {
+ bool upFade = false;
+
+ for (int i = 0; i < 768; ++i) {
+ if ((*_screenPalette)[i] < pal[i]) {
+ upFade = true;
+ break;
+ }
+ }
+
+ if (upFade) {
+ for (int i = 0; i < 256; ++i)
+ paletteMap(i, pal[i * 3 + 0] << 2, pal[i * 3 + 1] << 2, pal[i * 3 + 2] << 2);
+ _forceFullUpdate = true;
+ }
+
+ uint8 color16Palette[16 * 3];
+
+ if (upFade)
+ memset(color16Palette, 0, sizeof(color16Palette));
+ else
+ memcpy(color16Palette, _palette16, sizeof(color16Palette));
+
+ set16ColorPalette(color16Palette);
+ updateScreen();
+
+ for (int i = 0; i < 16; ++i) {
+ set16ColorPalette(color16Palette);
+
+ for (int k = 0; k < 48; ++k) {
+ if (upFade) {
+ if (color16Palette[k] < _palette16[k])
+ ++color16Palette[k];
+ } else {
+ if (color16Palette[k] > 0)
+ --color16Palette[k];
+ }
+ }
+
+ if (upFunc && upFunc->isValid())
+ (*upFunc)();
+ else
+ _system->updateScreen();
+
+ _vm->delay((delay >> 5) * _vm->tickLength());
+ }
+ }
+
+ setScreenPalette(pal);
+}
+
+void Screen_LoK_16::getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff) {
+ error("Screen_LoK_16::getFadeParams called");
+}
+
+int Screen_LoK_16::fadePalStep(const Palette &pal, int diff) {
+ error("Screen_LoK_16::fadePalStep called");
+ return 0; // for compilers that don't support NORETURN
+}
+
+void Screen_LoK_16::paletteMap(uint8 idx, int r, int g, int b) {
+ const int red = r;
+ const int green = g;
+ const int blue = b;
+
+ uint16 rgbDiff = 1000;
+ int rDiff = 0, gDiff = 0, bDiff = 0;
+
+ int index1 = -1;
+
+ for (int i = 0; i < 16; ++i) {
+ const int realR = _palette16[i * 3 + 0] << 4;
+ const int realG = _palette16[i * 3 + 1] << 4;
+ const int realB = _palette16[i * 3 + 2] << 4;
+
+ uint16 diff = ABS(r - realR) + ABS(g - realG) + ABS(b - realB);
+
+ if (diff < rgbDiff) {
+ rgbDiff = diff;
+ index1 = i;
+
+ rDiff = r - realR;
+ gDiff = g - realG;
+ bDiff = b - realB;
+ }
+ }
+
+ r = rDiff / 4 + red;
+ g = gDiff / 4 + green;
+ b = bDiff / 4 + blue;
+
+ rgbDiff = 1000;
+ int index2 = -1;
+
+ for (int i = 0; i < 16; ++i) {
+ const int realR = _palette16[i * 3 + 0] << 4;
+ const int realG = _palette16[i * 3 + 1] << 4;
+ const int realB = _palette16[i * 3 + 2] << 4;
+
+ uint16 diff = ABS(r - realR) + ABS(g - realG) + ABS(b - realB);
+
+ if (diff < rgbDiff) {
+ rgbDiff = diff;
+ index2 = i;
+ }
+ }
+
+ _paletteDither[idx].bestMatch = index1;
+ _paletteDither[idx].invertMatch = index2;
+}
+
+void Screen_LoK_16::convertTo16Colors(uint8 *page, int w, int h, int pitch, int keyColor) {
+ const int rowAdd = pitch * 2 - w;
+
+ uint8 *row1 = page;
+ uint8 *row2 = page + pitch;
+
+ for (int i = 0; i < h; i += 2) {
+ for (int k = 0; k < w; k += 2) {
+ if (keyColor == -1 || keyColor != *row1) {
+ const PaletteDither &dither = _paletteDither[*row1];
+
+ *row1++ = dither.bestMatch;
+ *row1++ = dither.invertMatch;
+ *row2++ = dither.invertMatch;
+ *row2++ = dither.bestMatch;
+ } else {
+ row1 += 2;
+ row2 += 2;
+ }
+ }
+
+ row1 += rowAdd;
+ row2 += rowAdd;
+ }
+}
+
+void Screen_LoK_16::mergeOverlay(int x, int y, int w, int h) {
+ byte *dst = _sjisOverlayPtrs[0] + y * 640 + x;
+
+ // We do a game screen rect to 16 color dithering here. It is
+ // important that we do not dither the overlay, since else the
+ // japanese fonts will look wrong.
+ convertTo16Colors(dst, w, h, 640);
+
+ const byte *src = _sjisOverlayPtrs[1] + y * 640 + x;
+
+ int add = 640 - w;
+
+ while (h--) {
+ for (x = 0; x < w; ++x, ++dst) {
+ byte col = *src++;
+ if (col != _sjisInvisibleColor)
+ *dst = _paletteDither[col].bestMatch;
+ }
+ dst += add;
+ src += add;
+ }
+}
+
+void Screen_LoK_16::set16ColorPalette(const uint8 *pal) {
+ uint8 palette[16 * 3];
+ for (int i = 0; i < 16; ++i) {
+ palette[i * 3 + 0] = (pal[i * 3 + 0] * 0xFF) / 0x0F;
+ palette[i * 3 + 1] = (pal[i * 3 + 1] * 0xFF) / 0x0F;
+ palette[i * 3 + 2] = (pal[i * 3 + 2] * 0xFF) / 0x0F;
+ }
+
+ _system->getPaletteManager()->setPalette(palette, 0, 16);
+}
+
+} // End of namespace Kyra