diff options
Diffstat (limited to 'engines/scumm/he/moonbase/moonbase.cpp')
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.cpp | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/engines/scumm/he/moonbase/moonbase.cpp b/engines/scumm/he/moonbase/moonbase.cpp new file mode 100644 index 0000000000..15ababd321 --- /dev/null +++ b/engines/scumm/he/moonbase/moonbase.cpp @@ -0,0 +1,223 @@ +/* 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 "scumm/he/intern_he.h" +#include "scumm/he/moonbase/moonbase.h" +#include "scumm/he/moonbase/ai_main.h" + +namespace Scumm { + +Moonbase::Moonbase(ScummEngine_v100he *vm) : _vm(vm) { + initFOW(); + + _ai = new AI(_vm); +} + +Moonbase::~Moonbase() { + delete _ai; +} + +int Moonbase::readFromArray(int array, int y, int x) { + _vm->VAR(_vm->VAR_U32_ARRAY_UNK) = array; + + return _vm->readArray(_vm->VAR_U32_ARRAY_UNK, y, x); +} + +void Moonbase::deallocateArray(int array) { + _vm->VAR(_vm->VAR_U32_ARRAY_UNK) = array; + + return _vm->nukeArray(_vm->VAR_U32_ARRAY_UNK); +} + +int Moonbase::callScummFunction(int scriptNumber, int paramCount,...) { + va_list va_params; + va_start(va_params, paramCount); + int args[25]; + + memset(args, 0, sizeof(args)); + + Common::String str; + str = Common::String::format("callScummFunction(%d, [", scriptNumber); + + for (int i = 0; i < paramCount; i++) { + args[i] = va_arg(va_params, int); + + str += Common::String::format("%d ", args[i]); + } + str += "])"; + + debug(0, "%s", str.c_str()); + + + va_end(va_params); + + _vm->runScript(scriptNumber, 0, 1, args); + + return _vm->pop(); +} + + +void Moonbase::blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox, + uint8 *wizd, int x, int y, int rawROP, int paramROP) { + bool premulAlpa = false; + + if (rawROP == 1) + premulAlpa = true; + + Common::Rect clippedDstRect(dstw, dsth); + if (clipBox) { + Common::Rect clip(clipBox->left, clipBox->top, clipBox->right, clipBox->bottom); + if (clippedDstRect.intersects(clip)) { + clippedDstRect.clip(clip); + } else { + return; + } + } + + int width = READ_LE_UINT16(wizd + 0x8 + 0); + int height = READ_LE_UINT16(wizd + 0x8 + 2); + + Common::Rect srcLimitsRect(width, height); + Common::Rect dstOperation(x, y, x + width, y + height); + if (!clippedDstRect.intersects(dstOperation)) + return; + Common::Rect clippedRect = clippedDstRect.findIntersectingRect(dstOperation); + + int cx = clippedRect.right - clippedRect.left; + int cy = clippedRect.bottom - clippedRect.top; + + int sx = ((clippedRect.left - x) + srcLimitsRect.left); + int sy = ((clippedRect.top - y) + srcLimitsRect.top); + + dst += clippedRect.top * dstPitch + clippedRect.left * 2; + + int headerSize = READ_LE_UINT32(wizd + 0x4); + uint8 *dataPointer = wizd + 0x8 + headerSize; + + for (int i = 0; i < sy; i++) { + uint16 lineSize = READ_LE_UINT16(dataPointer + 0); + + dataPointer += lineSize; + } + + for (int i = 0; i < cy; i++) { + uint16 lineSize = READ_LE_UINT16(dataPointer + 0); + uint8 *singlesOffset = READ_LE_UINT16(dataPointer + 2) + dataPointer; + uint8 *quadsOffset = READ_LE_UINT16(dataPointer + 4) + dataPointer; + + int pixels = 0; + byte *dst1 = dst; + byte *codes = dataPointer + 6; + + while (1) { + int code = *codes - 2; + codes++; + + if (code <= 0) { // quad or single + uint8 *src; + int cnt; + if (code == 0) { // quad + src = quadsOffset; + quadsOffset += 8; + cnt = 4; // 4 pixels + } else { // single + src = singlesOffset; + singlesOffset += 2; + cnt = 1; + } + + for (int c = 0; c < cnt; c++) { + if (pixels >= sx) { + if (rawROP == 1) { // MMX_PREMUL_ALPHA_COPY + WRITE_LE_UINT16(dst1, READ_LE_UINT16(src)); + } else if (rawROP == 2) { // MMX_ADDITIVE + uint16 color = READ_LE_UINT16(src); + uint16 orig = READ_LE_UINT16(dst1); + + uint32 r = MIN<uint32>(0x7c00, (orig & 0x7c00) + (color & 0x7c00)); + uint32 g = MIN<uint32>(0x03e0, (orig & 0x03e0) + (color & 0x03e0)); + uint32 b = MIN<uint32>(0x001f, (orig & 0x001f) + (color & 0x001f)); + WRITE_LE_UINT16(dst1, (r | g | b)); + } else if (rawROP == 5) { // MMX_CHEAP_50_50 + uint16 color = (READ_LE_UINT16(src) >> 1) & 0x3DEF; + uint16 orig = (READ_LE_UINT16(dst1) >> 1) & 0x3DEF; + WRITE_LE_UINT16(dst1, (color + orig)); + } + dst1 += 2; + } + src += 2; + pixels++; + } + } else { // skip + if ((code & 1) == 0) { + code >>= 1; + + for (int j = 0; j < code; j++) { + if (pixels >= sx) + dst1 += 2; + pixels++; + } + } else { // special case + if (pixels >= sx) { + int alpha = code >> 1; + uint16 color = READ_LE_UINT16(singlesOffset); + uint32 orig = READ_LE_UINT16(dst1); + + if (!premulAlpa) { + WRITE_LE_UINT16(dst1, color); // ENABLE_PREMUL_ALPHA = 0 + } else { + if (alpha > 32) { + alpha -= 32; + + uint32 oR = orig & 0x7c00; + uint32 oG = orig & 0x03e0; + uint32 oB = orig & 0x1f; + uint32 dR = ((((color & 0x7c00) - oR) * alpha) >> 5) + oR; + uint32 dG = ((((color & 0x3e0) - oG) * alpha) >> 5) + oG; + uint32 dB = ((((color & 0x1f) - oB) * alpha) >> 5) + oB; + + WRITE_LE_UINT16(dst1, (dR & 0x7c00) | (dG & 0x3e0) | (dB & 0x1f)); + } else { + uint32 pix = ((orig << 16) | orig) & 0x3e07c1f; + pix = (((pix * alpha) & 0xffffffff) >> 5) & 0x3e07c1f; + pix = ((pix >> 16) + pix + color) & 0xffff; + WRITE_LE_UINT16(dst1, pix); + } + } + + dst1 += 2; + } + singlesOffset += 2; + pixels++; + } + } + + if (pixels >= cx + sx) + break; + } + + dataPointer += lineSize; + dst += dstPitch; + } +} + +} // End of namespace Scumm |