home *** CD-ROM | disk | FTP | other *** search
- /* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header: /cvsroot/scummvm/scummvm/gfx.cpp,v 1.16 2001/11/09 18:54:14 strigeus Exp $
- *
- */
-
- #include "stdafx.h"
- #include "scumm.h"
-
- void Scumm::getGraphicsPerformance() {
- int i;
-
- for (i=10; i!=0; i--) {
- initScreens(0, 0, 320, 200);
- }
-
- _vars[VAR_PERFORMANCE_1] = 0;//_scummTimer;
-
- for (i=10; i!=0; i--) {
- setDirtyRange(0, 0, 200);
- drawDirtyScreenParts();
- }
-
- _vars[VAR_PERFORMANCE_2] = 0;//_scummTimer;
-
- initScreens(0, 16, 320, 144);
- }
-
- void Scumm::initScreens(int a, int b, int w, int h) {
- int i;
-
- for (i=0; i<3; i++) {
- nukeResource(rtBuffer, i+1);
- nukeResource(rtBuffer, i+5);
- }
-
- if (!getResourceAddress(rtBuffer,4)) {
- initVirtScreen(3, 80, 13, false, false);
- }
- initVirtScreen(0, b, h-b, true, true);
- initVirtScreen(1, 0, b, false, false);
- initVirtScreen(2, h, 200-h, false, false);
-
- _screenB = b;
- _screenH = h;
-
- }
-
- void Scumm::initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra) {
- VirtScreen *vs = &virtscr[slot];
- int size;
-
- assert(height>=0);
- assert(slot>=0 && slot<4);
-
- vs->number = slot;
- vs->unk1 = 0;
- vs->width = 320;
- vs->topline = top;
- vs->height = height;
- vs->alloctwobuffers = twobufs;
- vs->scrollable = fourextra;
- vs->xstart = 0;
- size = vs->width * vs->height;
- vs->size = size;
- if (vs->scrollable)
- size += 320*4;
-
- createResource(rtBuffer, slot+1, size);
-
- if (twobufs) {
- createResource(rtBuffer, slot+5, size);
- }
-
- if (slot != 3) {
- setDirtyRange(slot, 0, height);
- }
- }
-
- void Scumm::setDirtyRange(int slot, int top, int bottom) {
- int i;
- VirtScreen *vs = &virtscr[slot];
- for (i=0; i<40; i++) {
- vs->tdirty[i] = top;
- vs->bdirty[i] = bottom;
- }
- }
-
- void Scumm::drawDirtyScreenParts() {
- int i;
- VirtScreen *vs;
-
- updateDirtyScreen(2);
-
- if (camera._lastPos == camera._curPos) {
- updateDirtyScreen(0);
- } else {
- vs = &virtscr[0];
-
- blitToScreen(this, getResourceAddress(rtBuffer, 1) + _screenStartStrip*8,
- 0, vs->topline, 320, vs->height);
-
- for (i = 0; i<40; i++) {
- vs->tdirty[i] = (byte)vs->height;
- vs->bdirty[i] = 0;
- }
- }
- }
-
- void Scumm::updateDirtyScreen(int slot) {
- gdi.updateDirtyScreen(&virtscr[slot]);
- }
-
- void Gdi::updateDirtyScreen(VirtScreen *vs) {
- int i;
- int start,w,top,bottom;
-
- if (vs->height==0)
- return;
-
- _readOffs = 0;
- if (vs->scrollable)
- _readOffs = vs->xstart;
-
- w = 8;
- start = 0;
-
- for (i=0; i<40; i++) {
- bottom = vs->bdirty[i];
- if (bottom) {
- top = vs->tdirty[i];
- vs->tdirty[i] = (byte)vs->height;
- vs->bdirty[i] = 0;
- if (i!=39 && vs->bdirty[i+1] == (byte)bottom && vs->tdirty[i+1] == (byte)top) {
- w += 8;
- continue;
- }
- drawStripToScreen(vs, start, w, top, bottom);
- w = 8;
- }
- start = i+1;
- }
- }
-
- void Gdi::drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b) {
- byte *ptr;
-
- if (b <= t)
- return;
-
- if (t > vs->height)
- t = 0;
-
- if (b > vs->height)
- b = vs->height;
-
- ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + (t*40+x)*8 + _readOffs;
- blitToScreen(_vm, ptr, x*8, vs->topline+t, w, b-t);
- }
-
- void blit(byte *dst, byte *src, int w, int h) {
- assert(h>0);
- do {
- memcpy(dst, src, w);
- dst += 320;
- src += 320;
- } while (--h);
- }
-
- /* TODO: writes are being done to this data */
- MouseCursor mouse_cursors[4] = {
- 8,7,{15,15,7,8},
- {
- 0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,
- 0x00,0x80,0x00,0x80,0x00,0x00,0x7E,0x3F,
- 0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,
- 0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,
- },
- 8,7,{15,15,7,8},
- {
- 0x00,0x00,0x7F,0xFE,0x60,0x06,0x30,0x0C,
- 0x18,0x18,0x0C,0x30,0x06,0x60,0x03,0xC0,
- 0x06,0x60,0x0C,0x30,0x19,0x98,0x33,0xCC,
- 0x67,0xE6,0x7F,0xFE,0x00,0x00,0x00,0x00,
- },
-
- 8,7,{15,15,7,8},
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- },
- 8,7,{15,15,7,8},
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- },
-
- };
-
- void Scumm::setCursor(int cursor) {
- MouseCursor *cur = &mouse_cursors[cursor];
- int i,j;
- byte *mask;
- const byte *src;
- byte shramount;
- uint32 data;
-
- debug(1,"Loading cursor %d", cursor);
- gdi._hotspot_x = cur->hotspot_x;
- gdi._hotspot_y = cur->hotspot_y;
- gdi._currentCursor = cursor;
-
- for (i=0; i<4; i++)
- gdi._mouseColors[i] = cur->colors[i];
-
- mask = gdi._mouseMask;
- shramount = 0;
-
- for(j=0; j<8; j++) {
- src = cur->data;
- i=16;
- do {
- data = ((src[0]<<16) | (src[1]<<8))>>shramount;
- src += 2;
- mask[0] = (byte)(data>>24);
- mask[1] = (byte)(data>>16);
- mask[2] = (byte)(data>>8);
- mask[3] = (byte)(data);
- mask += 4;
- } while (--i);
- shramount++;
- }
- }
-
- void Scumm::setCameraAt(int dest) {
- int t;
- CameraData *cd = &camera;
-
- if (cd->_mode!=2 || abs(dest - cd->_curPos) > 160) {
- cd->_curPos = dest;
- }
- cd->_destPos = dest;
-
- t = _vars[VAR_CAMERA_MIN];
- if (cd->_curPos < t) cd->_curPos = t;
-
- t = _vars[VAR_CAMERA_MAX];
- if (cd->_curPos > t) cd->_curPos = t;
-
- if (_vars[VAR_SCROLL_SCRIPT]) {
- _vars[VAR_CAMERA_CUR_POS] = cd->_curPos;
- runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
- }
-
- if (cd->_curPos != cd->_lastPos && charset._hasMask)
- stopTalk();
- }
-
- void Scumm::setCameraFollows(Actor *a) {
- int t,i;
- CameraData *cd = &camera;
-
- cd->_mode = 2;
- cd->_follows = a->number;
-
- if (a->room != _currentRoom) {
- startScene(a->room, 0, 0);
- cd->_mode = 2;
- cd->_curPos = a->x;
- setCameraAt(cd->_curPos);
- }
-
- t = (a->x >> 3);
-
- if (t-_screenStartStrip < cd->_leftTrigger ||
- t-_screenStartStrip > cd->_rightTrigger)
- setCameraAt(a->x);
-
- for (i=1,a=getFirstActor(); ++a,i<13; i++) {
- if (a->room==_currentRoom)
- a->needRedraw = true;
- }
- runHook(0);
- }
-
- void Scumm::initBGBuffers() {
- byte *ptr;
- int size, itemsize, i;
- byte *room;
-
- room = getResourceAddress(rtRoom, _roomResource);
-
- ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room, 0), 0);
-
- gdi._numZBuffer = READ_LE_UINT16(ptr+8) + 1;
-
- assert(gdi._numZBuffer>=1 && gdi._numZBuffer<=4);
-
- itemsize = (_scrHeight + 4) * 40;
- size = itemsize * gdi._numZBuffer;
-
- createResource(rtBuffer, 9, size);
-
- for (i=0; i<4; i++)
- gdi._imgBufOffs[i] = i*itemsize;
- }
-
- void Scumm::setPaletteFromPtr(byte *ptr) {
- uint32 size = READ_BE_UINT32_UNALIGNED(ptr+4);
- int i, r, g, b;
- byte *dest, *epal;
- int numcolor;
-
- numcolor = (size-8) / 3;
-
- ptr += 8;
-
- checkRange(256, 0, numcolor, "Too many colors (%d) in Palette");
-
- dest = _currentPalette;
-
- for (i=0; i<numcolor; i++) {
- r = *ptr++;
- g = *ptr++;
- b = *ptr++;
- if (i<=15 || r<252 || g<252 || b<252) {
- *dest++ = r>>2;
- *dest++ = g>>2;
- *dest++ = b>>2;
- } else {
- dest += 3;
- }
- }
-
- #if 0
- if (_videoMode==0xE) {
- epal = getResourceAddress(rtRoom, _roomResource) + _EPAL_offs + 8;
- for (i=0; i<256; i++,epal++) {
- _currentPalette[i] = *epal&0xF;
- _currentPalette[i+256] = *epal>>4;
- }
- }
- #endif
-
- setDirtyColors(0, numcolor-1);
- }
-
- void Scumm::setPaletteFromRes() {
- byte *ptr;
- ptr = getResourceAddress(rtRoom, _roomResource) + _CLUT_offs;
- setPaletteFromPtr(ptr);
- }
-
-
- void Scumm::setDirtyColors(int min, int max) {
- if (_palDirtyMin > min)
- _palDirtyMin = min;
- if (_palDirtyMax < max)
- _palDirtyMax = max;
- }
-
- void Scumm::initCycl(byte *ptr) {
- int i, j;
- ColorCycle *cycl;
-
- for (i=0,cycl=_colorCycle; i<16; i++,cycl++)
- cycl->delay = 0;
-
- while ((j=*ptr++) != 0) {
- if (j<1 || j>16) {
- error("Invalid color cycle index %d", j);
- }
- cycl = &_colorCycle[j-1];
-
- ptr += 2;
- cycl->counter = 0;
- cycl->delay = 16384 / READ_BE_UINT16_UNALIGNED(ptr);
- ptr += 2;
- cycl->flags = READ_BE_UINT16_UNALIGNED(ptr);
- ptr += 2;
- cycl->start = *ptr++;
- cycl->end = *ptr++;
- }
- }
-
- void Scumm::stopCycle(int i) {
- ColorCycle *cycl;
-
- checkRange(16, 0, i, "Stop Cycle %d Out Of Range");
- if (i!=0) {
- _colorCycle[i-1].delay = 0;
- return;
- }
-
- for (i=0,cycl=_colorCycle; i<16; i++,cycl++)
- cycl->delay = 0;
- }
-
- void Scumm::cyclePalette() {
- ColorCycle *cycl;
- int valueToAdd;
- int i, num;
- byte *start, *end;
- byte tmp[3];
-
- valueToAdd = _vars[VAR_TIMER];
- if (valueToAdd < _vars[VAR_TIMER_NEXT])
- valueToAdd = _vars[VAR_TIMER_NEXT];
-
- for (i=0,cycl=_colorCycle; i<16; i++,cycl++) {
- if (cycl->delay &&
- (cycl->counter+=valueToAdd) >= cycl->delay) {
- do {
- cycl->counter -= cycl->delay;
- } while (cycl->delay <= cycl->counter);
-
- setDirtyColors(cycl->start, cycl->end);
- moveMemInPalRes(cycl->start, cycl->end, cycl->flags&2);
- start = &_currentPalette[cycl->start*3];
- end = &_currentPalette[cycl->end*3];
-
- num = cycl->end - cycl->start;
-
- if (!(cycl->flags&2)) {
- memmove(tmp, end, 3);
- memmove(start+3, start, num*3);
- memmove(start, tmp, 3);
- } else {
- memmove(tmp, start, 3);
- memmove(start, start+3, num*3);
- memmove(end, tmp, 3);
- }
- }
- }
- }
-
- void Scumm::moveMemInPalRes(int start, int end, byte direction) {
- byte *startptr, *endptr;
- byte *startptr2, *endptr2;
- int num;
- byte tmp[6];
- byte tmp2[6];
-
- if (!_palManipCounter)
- return;
-
- startptr = getResourceAddress(rtTemp, 4) + start * 6;
- endptr = getResourceAddress(rtTemp, 4) + end * 6;
-
- startptr2 = getResourceAddress(rtTemp, 5) + start * 6;
- endptr2 = getResourceAddress(rtTemp, 5) + end * 6;
-
- num = end - start;
-
- if (!direction) {
- memmove(tmp, endptr, 6);
- memmove(startptr+6, startptr, num*6);
- memmove(startptr, tmp, 6);
- memmove(tmp2, endptr2, 6);
- memmove(startptr2+6, startptr2, num*6);
- memmove(startptr2, tmp2, 6);
- } else {
- memmove(tmp, startptr, 6);
- memmove(startptr, startptr+6, num*6);
- memmove(endptr, tmp, 6);
- memmove(tmp2, startptr2, 6);
- memmove(startptr2, startptr2+6, num*6);
- memmove(endptr2, tmp2, 6);
- }
- }
-
- void Scumm::unkVirtScreen4(int a) {
- VirtScreen *vs;
-
- setDirtyRange(0, 0, 0);
- camera._lastPos = camera._curPos;
- if (!_screenEffectFlag)
- return;
- _screenEffectFlag = false;
-
- if (a==0)
- return;
-
- vs = &virtscr[0];
- gdi._backbuff_ptr = getResourceAddress(rtBuffer, 1) + vs->xstart;
- memset(gdi._backbuff_ptr, 0, vs->size);
-
- switch(a) {
- case 1: case 2: case 3:
- unkScreenEffect7(a-1);
- break;
- case 128:
- unkScreenEffect6();
- break;
- case 129:
- setDirtyRange(0, 0, vs->height);
- updateDirtyScreen(0);
- /* XXX: EGA_proc4(0); */
- break;
- case 134:
- unkScreenEffect5(0);
- break;
- case 135:
- unkScreenEffect5(1);
- break;
- default:
- error("unkVirtScreen4: default case %d", a);
- }
- }
-
- void Scumm::redrawBGAreas() {
- int i;
- int val;
- CameraData *cd = &camera;
-
- if (cd->_curPos!=cd->_lastPos && charset._hasMask)
- stopTalk();
-
- val = 0;
-
- if (_fullRedraw==0 && _BgNeedsRedraw) {
- for (i=0; i<40; i++) {
- if (actorDrawBits[_screenStartStrip + i]&0x8000) {
- redrawBGStrip(i, 1);
- }
- }
- }
-
- if (_fullRedraw==0 && cd->_curPos - cd->_lastPos == 8) {
- val = 2;
- redrawBGStrip(39, 1);
- } else if (_fullRedraw==0 && cd->_curPos - cd->_lastPos == -8) {
- val = 1;
- redrawBGStrip(0, 1);
- } else if (_fullRedraw!=0 || cd->_curPos != cd->_lastPos) {
- _BgNeedsRedraw = 0;
- redrawBGStrip(0, 40);
- }
-
- drawRoomObjects(val);
- _BgNeedsRedraw = 0;
- }
-
- const uint32 zplane_tags[] = {
- MKID('ZP00'),
- MKID('ZP01'),
- MKID('ZP02'),
- MKID('ZP03')
- };
-
- void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr, int numstrip, bool flag) {
- byte *smap_ptr,*where_draw_ptr;
- int i;
- byte *zplane_list[4];
- int bottom;
- byte twobufs;
- int numzbuf;
- int sx;
-
- CHECK_HEAP
-
- smap_ptr = findResource(MKID('SMAP'), ptr, 0);
-
- numzbuf = _disable_zbuffer ? 0 : _numZBuffer;
-
- for(i=1; i<numzbuf; i++) {
- zplane_list[i] = findResource(zplane_tags[i], ptr, 0);
- }
-
- bottom = y + h;
- if (bottom > vs->height) {
- error("Gdi::drawBitmap, strip drawn to %d below window bottom %d", bottom, vs->height);
- }
-
- twobufs = vs->alloctwobuffers;
-
- _vertStripNextInc = h * 320 - 1;
-
- _numLinesToProcess = h;
-
- do {
- _smap_ptr = smap_ptr + READ_LE_UINT32(smap_ptr + stripnr*4 + 8);
-
- CHECK_HEAP
-
- sx = x;
- if (vs->scrollable)
- sx -= vs->xstart>>3;
-
- if ((uint)sx >= 40)
- return;
-
- if (y < vs->tdirty[sx])
- vs->tdirty[sx]=y;
-
- if (bottom > vs->bdirty[sx])
- vs->bdirty[sx] = bottom;
-
- _backbuff_ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + (y*40+x)*8;
- _bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number+5) + (y*40+x)*8;
- if (!twobufs) {
- _bgbak_ptr = _backbuff_ptr;
- }
- _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + (y*40+x);
-
- where_draw_ptr = _bgbak_ptr;
- decompressBitmap();
-
- CHECK_HEAP
-
- if (twobufs) {
- _bgbak_ptr = where_draw_ptr;
-
- if (_vm->hasCharsetMask(sx<<3, y, (sx+1)<<3, bottom)) {
- if (_vm->_vars[VAR_V5_DRAWFLAGS]&2)
- draw8ColWithMasking();
- else
- clear8ColWithMasking();
- } else {
- if (_vm->_vars[VAR_V5_DRAWFLAGS]&2)
- blit(_backbuff_ptr, _bgbak_ptr, 8, h);
- else
- clear8Col();
- }
- }
- CHECK_HEAP
-
- for (i=1; i<numzbuf; i++) {
- if (!zplane_list[i])
- continue;
- _z_plane_ptr = zplane_list[i] + READ_LE_UINT16(zplane_list[i] + stripnr*2 + 8);
- _mask_ptr_dest = _vm->getResourceAddress(rtBuffer, 9) + y*40 + x + _imgBufOffs[i];
- if (_useOrDecompress && flag)
- decompressMaskImgOr();
- else
- decompressMaskImg();
- }
- CHECK_HEAP
- x++;
- stripnr++;
- } while (--numstrip);
- }
-
-
- void Gdi::decompressBitmap() {
- const byte decompress_table[] = {
- 0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x0,
- };
-
- _useOrDecompress = false;
-
- byte code = *_smap_ptr++;
-
- assert(_numLinesToProcess);
-
- switch(code) {
- case 1:
- unkDecode7();
- break;
- case 14: case 15: case 16: case 17: case 18:
- _decomp_shr = code - 10;
- _decomp_mask = decompress_table[code - 10];
- unkDecode6();
- break;
-
- case 24: case 25: case 26: case 27: case 28:
- _decomp_shr = code - 20;
- _decomp_mask = decompress_table[code - 20];
- unkDecode5();
- break;
-
- case 34: case 35: case 36: case 37: case 38:
- _useOrDecompress = true;
- _decomp_shr = code - 30;
- _decomp_mask = decompress_table[code - 30 ];
- unkDecode4();
- break;
-
- case 44: case 45: case 46: case 47: case 48:
- _useOrDecompress = true;
- _decomp_shr = code - 40;
- _decomp_mask = decompress_table[code - 40];
- unkDecode2();
- break;
-
- case 64: case 65: case 66: case 67: case 68:
- _decomp_shr = code - 60;
- _decomp_mask = decompress_table[code - 60];
- unkDecode1();
- break;
-
- case 84: case 85: case 86: case 87: case 88:
- _useOrDecompress = true;
- _decomp_shr = code - 80;
- _decomp_mask = decompress_table[code - 80];
- unkDecode3();
- break;
-
- /* New since version 6 */
- case 104: case 105: case 106: case 107: case 108:
- _decomp_shr = code - 100;
- _decomp_mask = decompress_table[code - 100];
- unkDecode1();
- break;
-
- /* New since version 6 */
- case 124: case 125: case 126: case 127: case 128:
- _useOrDecompress = true;
- _decomp_shr = code - 120;
- _decomp_mask = decompress_table[code - 120];
- unkDecode3();
- break;
-
- default:
- error("Gdi::decompressBitmap: default case %d", code);
- }
- }
-
- int Scumm::hasCharsetMask(int x, int y, int x2, int y2) {
- if (!charset._hasMask || y > gdi._mask_bottom || x > gdi._mask_right ||
- y2 < gdi._mask_top || x2 < gdi._mask_left )
- return 0;
- return 1;
- }
-
- void Gdi::draw8ColWithMasking() {
- int height = _numLinesToProcess;
- byte *mask = _mask_ptr;
- byte *dst = _backbuff_ptr;
- byte *src = _bgbak_ptr;
- byte maskbits;
-
- do {
- maskbits = *mask;
- if (maskbits) {
- if (!(maskbits&0x80)) dst[0] = src[0];
- if (!(maskbits&0x40)) dst[1] = src[1];
- if (!(maskbits&0x20)) dst[2] = src[2];
- if (!(maskbits&0x10)) dst[3] = src[3];
- if (!(maskbits&0x08)) dst[4] = src[4];
- if (!(maskbits&0x04)) dst[5] = src[5];
- if (!(maskbits&0x02)) dst[6] = src[6];
- if (!(maskbits&0x01)) dst[7] = src[7];
- } else {
- /* alignment safe */
- ((uint32*)dst)[0] = ((uint32*)src)[0];
- ((uint32*)dst)[1] = ((uint32*)src)[1];
- }
- src += 320;
- dst += 320;
- mask += 40;
- } while (--height);
- }
-
- void Gdi::clear8ColWithMasking() {
- int height = _numLinesToProcess;
- byte *mask = _mask_ptr;
- byte *dst = _backbuff_ptr;
- byte maskbits;
-
- do {
- maskbits = *mask;
- if (!maskbits) {
- ((uint32*)dst)[1] = ((uint32*)dst)[0] = 0;
- } else {
- if (!(maskbits&0x80)) dst[0] = 0;
- if (!(maskbits&0x40)) dst[1] = 0;
- if (!(maskbits&0x20)) dst[2] = 0;
- if (!(maskbits&0x10)) dst[3] = 0;
- if (!(maskbits&0x08)) dst[4] = 0;
- if (!(maskbits&0x04)) dst[5] = 0;
- if (!(maskbits&0x02)) dst[6] = 0;
- if (!(maskbits&0x01)) dst[7] = 0;
- }
- dst += 320;
- mask += 40;
- } while (--height);
- }
-
- void Gdi::clear8Col() {
- int height = _numLinesToProcess;
- byte *dst = _backbuff_ptr;
- do {
- ((uint32*)dst)[1] = ((uint32*)dst)[0] = 0;
- dst += 320;
- } while (--height);
- }
-
- void Gdi::decompressMaskImg() {
- byte *src = _z_plane_ptr;
- byte *dst = _mask_ptr_dest;
- int height = _numLinesToProcess;
- byte b, c;
-
- while(1) {
- b = *src++;
-
- if (b&0x80) {
- b&=0x7F;
- c = *src++;
-
- do {
- *dst = c;
- dst += 40;
- if (!--height)
- return;
- } while (--b);
- } else {
- do {
- *dst = *src++;
- dst += 40;
- if (!--height)
- return;
- } while (--b);
- }
- }
- }
-
- void Gdi::decompressMaskImgOr() {
- byte *src = _z_plane_ptr;
- byte *dst = _mask_ptr_dest;
- int height = _numLinesToProcess;
- byte b, c;
-
- while(1) {
- b = *src++;
- if (b&0x80) {
- b&=0x7F;
- c = *src++;
-
- do {
- *dst |= c;
- dst += 40;
- if (!--height)
- return;
- } while (--b);
- } else {
- do {
- *dst |= *src++;
- dst += 40;
- if (!--height)
- return;
- } while (--b);
- }
- }
- }
-
- void Scumm::redrawBGStrip(int start, int num) {
- int s = _screenStartStrip + start;
-
- assert(s>=0 && s<sizeof(actorDrawBits)/sizeof(actorDrawBits[0]));
-
- _curVirtScreen = &virtscr[0];
-
- actorDrawBits[s]|=0x8000;
- if (_curVirtScreen->height > _scrHeight) {
- error("Screen Y size %d < Room height %d",
- _curVirtScreen->height,
- _scrHeight);
- }
-
- gdi.drawBitmap(getResourceAddress(rtRoom, _roomResource)+_IM00_offs,
- _curVirtScreen, s, 0, _curVirtScreen->height, s, num, 0);
- }
-
- #define READ_BIT (cl--,bit = bits&1, bits>>=1,bit)
- #define FILL_BITS if (cl <= 8) { bits |= (*src++ << cl); cl += 8;}
-
- void Gdi::unkDecode1() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- byte color = *src++;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
- byte incm,reps;
- _tempNumLines = _numLinesToProcess;
-
- do {
- _currentX = 8;
- do {
- FILL_BITS
- *dst++=color;
-
- againPos:;
-
- if (!READ_BIT) {}
- else if (READ_BIT) {
- incm = (bits&7)-4;
- cl-=3;
- bits>>=3;
- if (!incm) {
- FILL_BITS
- reps = bits&0xFF;
- do {
- if (!--_currentX) {
- _currentX = 8;
- dst += 312;
- if (!--_tempNumLines)
- return;
- }
- *dst++=color;
- } while (--reps);
- bits>>=8;
- bits |= (*src++)<<(cl-8);
- goto againPos;
- } else {
- color += incm;
- }
- } else {
- FILL_BITS
- color = bits&_decomp_mask;
- cl -= _decomp_shr;
- bits >>= _decomp_shr;
- }
- } while (--_currentX);
- dst += 312;
- } while (--_tempNumLines);
- }
-
- void Gdi::unkDecode2() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- byte color = *src++;
- int8 inc = -1;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
-
- _tempNumLines = _numLinesToProcess;
-
- do {
- _currentX = 8;
- do {
- FILL_BITS
- if (color!=_transparency)
- *dst=color;
- dst++;
- if (!READ_BIT) {}
- else if (!READ_BIT) {
- FILL_BITS
- color = bits&_decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- inc = -1;
- } else if (!READ_BIT) {
- color += inc;
- } else {
- inc = -inc;
- color += inc;
- }
- } while (--_currentX);
- dst += 312;
- } while (--_tempNumLines);
- }
-
- void Gdi::unkDecode3() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- byte color = *src++;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
- byte incm,reps;
-
- _tempNumLines = _numLinesToProcess;
-
- do {
- _currentX = 8;
- do {
- FILL_BITS
- if (color!=_transparency) *dst=color;
- dst++;
-
- againPos:;
- if (!READ_BIT) {}
- else if (READ_BIT) {
- incm = (bits&7)-4;
-
- cl-=3;
- bits>>=3;
- if (incm) {
- color += incm;
- } else {
- FILL_BITS
- reps = bits&0xFF;
- if (color==_transparency) {
- do {
- if (!--_currentX) {
- _currentX = 8;
- dst += 312;
- if (!--_tempNumLines)
- return;
- }
- dst++;
- } while (--reps);
- } else {
- do {
- if (!--_currentX) {
- _currentX = 8;
- dst += 312;
- if (!--_tempNumLines)
- return;
- }
- *dst++=color;
- } while (--reps);
- }
- bits>>=8;
- bits |= (*src++)<<(cl-8);
- goto againPos;
- }
- } else {
- FILL_BITS
- color = bits&_decomp_mask;
- cl -= _decomp_shr;
- bits >>= _decomp_shr;
- }
- } while (--_currentX);
- dst += 312;
- } while (--_tempNumLines);
- }
-
-
- void Gdi::unkDecode4() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- byte color = *src++;
- int8 inc = -1;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
-
- _currentX = 8;
- do {
- _tempNumLines = _numLinesToProcess;
- do {
- FILL_BITS
- if (color!=_transparency)
- *dst=color;
- dst+=320;
- if (!READ_BIT) {}
- else if (!READ_BIT) {
- FILL_BITS
- color = bits&_decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- inc = -1;
- } else if (!READ_BIT) {
- color += inc;
- } else {
- inc = -inc;
- color += inc;
- }
- } while (--_tempNumLines);
- dst -= _vertStripNextInc;
- } while (--_currentX);
- }
-
- void Gdi::unkDecode5() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- byte color = *src++;
- int8 inc = -1;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
-
- _tempNumLines = _numLinesToProcess;
-
- do {
- _currentX = 8;
- do {
- FILL_BITS
- *dst++=color;
- if (!READ_BIT) {}
- else if (!READ_BIT) {
- FILL_BITS
- color = bits&_decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- inc = -1;
- } else if (!READ_BIT) {
- color += inc;
- } else {
- inc = -inc;
- color += inc;
- }
- } while (--_currentX);
- dst += 312;
- } while (--_tempNumLines);
- }
-
- void Gdi::unkDecode6() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- byte color = *src++;
- int8 inc = -1;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
-
- _currentX = 8;
- do {
- _tempNumLines = _numLinesToProcess;
- do {
- FILL_BITS
- *dst=color;
- dst+=320;
- if (!READ_BIT) {}
- else if (!READ_BIT) {
- FILL_BITS
- color = bits&_decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- inc = -1;
- } else if (!READ_BIT) {
- color += inc;
- } else {
- inc = -inc;
- color += inc;
- }
- } while (--_tempNumLines);
- dst -= _vertStripNextInc;
- } while (--_currentX);
- }
-
- void Gdi::unkDecode7() {
- byte *src = _smap_ptr;
- byte *dst = _bgbak_ptr;
- int height = _numLinesToProcess;
- do {
- /* Endian safe */
- #if defined(SCUMM_NEED_ALIGNMENT)
- memcpy(dst, src, 8);
- #else
- ((uint32*)dst)[0] = ((uint32*)src)[0];
- ((uint32*)dst)[1] = ((uint32*)src)[1];
- #endif
- dst += 320;
- src += 8;
- } while (--height);
- }
-
- #undef READ_BIT
- #undef FILL_BITS
-
- void Scumm::restoreCharsetBg() {
- _bkColor = 0;
- if (gdi._mask_left != -1) {
- restoreBG(gdi._mask_left, gdi._mask_top, gdi._mask_right, gdi._mask_bottom);
- charset._hasMask = false;
- gdi._mask_left = -1;
- charset._strLeft = -1;
- charset._left = -1;
- }
-
- charset._xpos2 = string[0].xpos;
- charset._ypos2 = string[0].ypos;
- }
-
- void Scumm::restoreBG(int left, int top, int right, int bottom) {
- VirtScreen *vs;
- int topline, height, width, widthmod;
- byte *backbuff,*bgbak,*mask;
-
- if (left==right || top==bottom)
- return;
- if (top<0) top=0;
-
- if ((vs=findVirtScreen(top)) == NULL)
- return;
-
- topline = vs->topline;
- height = topline + vs->height;
- if (vs->number==0) {
- left += _lastXstart - vs->xstart;
- right += _lastXstart - vs->xstart;
- }
-
- right++;
- if (left<0) left=0;
- if (right<0)right=0;
- if (left>320)
- return;
- if (right>320)
- right=320;
- if (bottom>=height)
- bottom=height;
-
- updateDirtyRect(vs->number, left, right, top-topline,bottom-topline, 0x4000);
-
- height = (top-topline) * 320 + vs->xstart + left;
-
- backbuff = getResourceAddress(rtBuffer, vs->number+1) + height;
- bgbak = getResourceAddress(rtBuffer, vs->number+5) + height;
- mask = getResourceAddress(rtBuffer, 9) + top * 40 + (left>>3) + _screenStartStrip;
- if (vs->number==0) {
- mask += vs->topline * 216;
- }
-
- height = bottom - top;
- width = right - left;
- widthmod = (width >> 2) + 2;
-
- if (vs->alloctwobuffers && _currentRoom!=0 && _vars[VAR_V5_DRAWFLAGS]&2) {
- blit(backbuff, bgbak, width, height);
- if (vs->number==0 && charset._hasMask && height) {
- do {
- memset(mask, 0, widthmod);
- mask += 40;
- } while (--height);
- }
- } else {
- if (height) {
- do {
- memset(backbuff, _bkColor, width);
- backbuff+=320;
- } while (--height);
- }
- }
- }
-
- void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom, uint16 dirtybits) {
- VirtScreen *vs = &virtscr[virt];
- int lp,rp;
- uint16 *sp;
- int num;
-
- if (top > vs->height || bottom < 0)
- return;
-
- if (top<0)
- top=0;
- if (bottom > vs->height)
- bottom = vs->height;
-
- if (virt==0 && dirtybits) {
- rp = (right >> 3) + _screenStartStrip;
- lp = (left >> 3) + _screenStartStrip;
- if (lp<0) lp=0;
- if (rp >= 200)
- rp = 200;
- if (lp <= rp) {
- num = rp - lp + 1;
- sp = &actorDrawBits[lp];
- do {
- *sp++ |= dirtybits;
- } while (--num);
- }
- }
-
- setVirtscreenDirty(vs, left, top, right, bottom);
- }
-
- void Scumm::setVirtscreenDirty(VirtScreen *vs, int left, int top, int right, int bottom) {
- int lp = left >> 3;
- int rp = right >> 3;
-
- if (lp>=40 || rp<0)
- return;
- if (lp<0) lp=0;
- if (rp>=40) rp=39;
-
- while (lp<=rp) {
- if (top < vs->tdirty[lp])
- vs->tdirty[lp] = top;
- if (bottom > vs->bdirty[lp])
- vs->bdirty[lp] = bottom;
- lp++;
- }
- }
-
- VirtScreen *Scumm::findVirtScreen(int y) {
- VirtScreen *vs = virtscr;
- int i;
-
- for(i=0; i<3; i++,vs++) {
- if (y >= vs->topline && y < vs->topline+vs->height) {
- return _curVirtScreen=vs;
- }
- }
- return _curVirtScreen=NULL;
- }
-
- void Scumm::unkScreenEffect1() {
- /* XXX: not implemented */
- warning("stub unkScreenEffect1()");
- }
-
- void Scumm::unkScreenEffect2() {
- /* XXX: not implemented */
- warning("stub unkScreenEffect2()");
- }
-
- void Scumm::unkScreenEffect3() {
- /* XXX: not implemented */
- warning("stub unkScreenEffect3()");
- }
-
- void Scumm::unkScreenEffect4() {
- /* XXX: not implemented */
- warning("stub unkScreenEffect4()");
- }
-
- static const int8 screen_eff7_table1[4][16] = {
- {1,1,-1,1,-1,1,-1,-1,
- 1,-1,-1,-1,1,1,1,-1},
- {0,1,2,1,2,0,2,1,
- 2,0,2,1,0,0,0,0},
- {-2,-1,0,-1,-2,-1,-2,0
- -2,-1,-2,0,0,0,0,0},
- {0,-1,-2,-1,-2,0,-2,-1
- -2,0,-2,-1,0,0,0,0}
- };
-
- static const byte screen_eff7_table2[4][16] = {
- {0,0,39,0,39,0,39,24,
- 0,24,39,24,0,0,0,24},
- {0,0,0,0,0,0,0,0,
- 1,0,1,0,255,0,0,0},
- {39,24,39,24,39,24,39,24,
- 38,24,38,24,255,0,0,0},
- {0,24,39,24,39,0,39,24,
- 38,0,38,24,255,0,0,0}
- };
-
- static const byte screen_eff7_table3[4] = {
- 13,25,25,25
- };
-
- void Scumm::unkScreenEffect7(int a) {
- int tab_1[16];
- int tab_2[16];
- int i,j;
- int bottom;
- int *tab2_ptr;
- int l,t,r,b;
-
- for (i=0; i<16; i++) {
- tab_1[i] = screen_eff7_table1[a][i];
- j = screen_eff7_table2[a][i];
- if (j==24)
- j = (virtscr[0].height>>3)-1;
- tab_2[i] = j;
- }
-
- bottom = virtscr[0].height >> 3;
- for (j=0; j < screen_eff7_table3[a]; j++) {
- for (i=0; i<4; i++) {
- l = tab_2[i*4];
- t = tab_2[i*4+1];
- r = tab_2[i*4+2];
- b = tab_2[i*4+3];
- if (t==b) {
- while (l <= r) {
- if (l>=0 && l<40 && (uint)t<(uint)bottom) {
- virtscr[0].tdirty[l] = t<<3;
- virtscr[0].bdirty[l] = (t+1)<<3;
- }
- l++;
- }
- } else {
- /* DE92 */
- if (l<0 || l>=40 || b<=t)
- continue;
- if (b>bottom)
- b=bottom;
- virtscr[0].tdirty[l] = t<<3;
- virtscr[0].bdirty[l] = (b+1)<<3;
- }
- updateDirtyScreen(0);
- }
-
- for (i=0; i<16; i++)
- tab_2[i] += tab_1[i];
-
- updateScreen(this);
- waitForTimer(this);
- }
- }
-
- void Scumm::unkScreenEffect6() {
- /* XXX: not implemented */
- warning("stub unkScreenEffect6");
- }
-
- void Scumm::unkScreenEffect5(int a) {
- /* XXX: not implemented */
- warning("stub unkScreenEffect5(%d)",a);
- }
-
- void Scumm::setShake(int mode) {
- if (mode!=-1)
- _shakeMode = mode;
- else
- mode = 0;
- /* XXX: not implemented */
- warning("stub setShake(%d)",mode);
- }
-
- void Gdi::clearUpperMask() {
- memset(
- _vm->getResourceAddress(rtBuffer, 9),
- 0,
- _imgBufOffs[1] - _imgBufOffs[0]
- );
- }
-
- void Scumm::moveCamera() {
- CameraData *cd = &camera;
- int pos = cd->_curPos;
- int actorx, t;
- Actor *a;
-
- cd->_curPos &= 0xFFF8;
-
- if (cd->_curPos < _vars[VAR_CAMERA_MIN]) {
- if (_vars[VAR_CAMERA_FAST])
- cd->_curPos = _vars[VAR_CAMERA_MIN];
- else
- cd->_curPos += 8;
- cameraMoved();
- return;
- }
-
- if (cd->_curPos > _vars[VAR_CAMERA_MAX]) {
- if (_vars[VAR_CAMERA_FAST])
- cd->_curPos = _vars[VAR_CAMERA_MAX];
- else
- cd->_curPos-=8;
- cameraMoved();
- return;
- }
-
- if (cd->_mode==2) {
- a = derefActorSafe(cd->_follows, "moveCamera");
-
- actorx = a->x;
- t = (actorx>>3) - _screenStartStrip;
-
- if (t < cd->_leftTrigger || t > cd->_rightTrigger) {
- if (_vars[VAR_CAMERA_FAST]) {
- if (t > 35)
- cd->_destPos = actorx + 80;
- if (t < 5)
- cd->_destPos = actorx - 80;
- } else
- cd->_movingToActor = 1;
- }
- }
-
- if (cd->_movingToActor) {
- a = derefActorSafe(cd->_follows, "moveCamera(2)");
- cd->_destPos = a->x;
- }
-
- if (cd->_destPos < _vars[VAR_CAMERA_MIN])
- cd->_destPos = _vars[VAR_CAMERA_MIN];
-
- if (cd->_destPos > _vars[VAR_CAMERA_MAX])
- cd->_destPos = _vars[VAR_CAMERA_MAX];
-
- if (_vars[VAR_CAMERA_FAST]) {
- cd->_curPos = cd->_destPos;
- } else {
- if (cd->_curPos < cd->_destPos)
- cd->_curPos+=8;
- if (cd->_curPos > cd->_destPos)
- cd->_curPos-=8;
- }
-
- /* a is set a bit above */
- if (cd->_movingToActor && cd->_curPos>>3 == a->x>>3) {
- cd->_movingToActor = 0;
- }
-
- cameraMoved();
-
- if (pos != cd->_curPos && _vars[VAR_SCROLL_SCRIPT]) {
- _vars[VAR_CAMERA_CUR_POS] = cd->_curPos;
- runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
- }
- }
-
- void Scumm::cameraMoved() {
- CameraData *cd = &camera;
-
- if (cd->_curPos < 160) {
- cd->_curPos = 160;
- } else if (cd->_curPos + 160 >= _scrWidthIn8Unit<<3) {
- cd->_curPos = (_scrWidthIn8Unit-20)<<3;
- }
-
- _screenStartStrip = (cd->_curPos >> 3) - 20;
- _screenEndStrip = _screenStartStrip + 39;
- virtscr[0].xstart = _screenStartStrip << 3;
- }
-
- void Scumm::panCameraTo(int x) {
- CameraData *cd = &camera;
- cd->_destPos = x;
- cd->_mode = 3;
- cd->_movingToActor = 0;
- }
-
- void Scumm::actorFollowCamera(int act) {
- int old;
- CameraData *cd = &camera;
-
- /* mi1 compatibilty */
- if (act==0) {
- cd->_mode = 1;
- cd->_follows = 0;
- cd->_movingToActor = 0;
- return;
- }
-
- old = cd->_follows;
- setCameraFollows(derefActorSafe(act, "actorFollowCamera"));
- if (cd->_follows != old)
- runHook(0);
-
- cd->_movingToActor = 0;
- }
-
- void Scumm::setCameraAtEx(int at) {
- CameraData *cd = &camera;
- cd->_mode = 1;
- cd->_curPos = at;
- setCameraAt(at);
- cd->_movingToActor = 0;
- }
-
- void Scumm::palManipulate() {
- byte *srcptr, *destptr;
- byte *pal;
- int i,j;
-
- if (!_palManipCounter)
- return;
- srcptr = getResourceAddress(rtTemp, 4) + _palManipStart*6;
- destptr = getResourceAddress(rtTemp, 5) + _palManipStart*6;
- pal = _currentPalette + _palManipStart * 3;
-
- i = _palManipStart;
- while (i < _palManipEnd) {
- j = (*((uint16*)srcptr) += *(uint16*)destptr );
- *pal++ = j>>8;
- srcptr += 2;
- destptr += 2;
-
- j = (*((uint16*)srcptr) += *(uint16*)destptr );
- *pal++ = j>>8;
- srcptr += 2;
- destptr += 2;
-
- j = (*((uint16*)srcptr) += *(uint16*)destptr );
- *pal++ = j>>8;
- srcptr += 2;
- destptr += 2;
-
- i++;
- }
- setDirtyColors(_palManipStart, _palManipEnd);
- if (!--_palManipCounter) {
- nukeResource(rtTemp, 4);
- nukeResource(rtTemp, 5);
- }
- }
-
- void Scumm::screenEffect(int effect) {
- switch(effect) {
- case 1:
- case 2:
- case 3: unkScreenEffect7(effect-1); break;
- case 128: unkScreenEffect6(); break;
- case 130: unkScreenEffect1(); break;
- case 131: unkScreenEffect2(); break;
- case 132: unkScreenEffect3(); break;
- case 133: unkScreenEffect4(); break;
- case 134: unkScreenEffect5(0); break;
- case 135: unkScreenEffect5(1); break;
- case 129: break;
- default:
- warning("Unknown screen effect, %d", effect);
- }
- _screenEffectFlag = true;
- }
-
- void Scumm::resetActorBgs() {
- Actor *a;
- int i,bitpos;
- int top,bottom;
- uint16 onlyActorFlags;
- int offs;
-
- for(i=0; i<40; i++) {
- onlyActorFlags = (actorDrawBits[_screenStartStrip + i]&=0x3FFF);
- a = getFirstActor();
- bitpos = 1;
-
- while (onlyActorFlags) {
- if(onlyActorFlags&1 && a->top!=0xFF && a->needBgReset) {
- top = a->top;
- bottom = a->bottom;
- actorDrawBits[_screenStartStrip + i] ^= bitpos;
- gdi.resetBackground(a->top, a->bottom, i);
-
- }
- bitpos<<=1;
- onlyActorFlags>>=1;
- a++;
- }
- }
-
- for(i=1,a=getFirstActor(); ++a,i<13; i++) {
- a->needBgReset = false;
- }
- }
-
- void Gdi::resetBackground(byte top, byte bottom, int strip) {
- VirtScreen *vs = &_vm->virtscr[0];
- int offs;
-
- if (top < vs->tdirty[strip])
- vs->tdirty[strip] = top;
-
- if (bottom > vs->bdirty[strip])
- vs->bdirty[strip] = bottom;
-
- offs = (top * 40 + _vm->_screenStartStrip + strip);
- _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + offs;
- _bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + (offs<<3);
- _backbuff_ptr = _vm->getResourceAddress(rtBuffer, 1) + (offs<<3);
-
- _numLinesToProcess = bottom - top;
- if (_numLinesToProcess) {
- if (_vm->_vars[VAR_V5_DRAWFLAGS]&2) {
- if(_vm->hasCharsetMask(strip<<3, top, (strip+1)<<3, bottom))
- draw8ColWithMasking();
- else
- blit(_backbuff_ptr, _bgbak_ptr, 8, _numLinesToProcess);
- } else {
- clear8Col();
- }
- }
- }
-
- void Scumm::setPalColor(int index, int r, int g, int b) {
- _currentPalette[index*3+0] = r>>2;
- _currentPalette[index*3+1] = g>>2;
- _currentPalette[index*3+2] = b>>2;
- setDirtyColors(index,index);
- }
-
- void Scumm::drawMouse() {
- /* TODO: handle shake here */
-
- if (_cursorAnimate) {
- if (!(_cursorAnimateIndex&0x3))
- decompressDefaultCursor((_cursorAnimateIndex>>2)&3);
- _cursorAnimateIndex++;
-
- }
-
- ::drawMouse(this,
- mouse.x - _cursorHotspotX,
- mouse.y - _cursorHotspotY,
- _cursorWidth,
- _cursorHeight,
- _grabbedCursor,
- gdi._cursorActive>0
- );
- }
-
- void Scumm::setCursorHotspot(int cursor, int x, int y) {
- MouseCursor *cur = &mouse_cursors[cursor];
- cur->hotspot_x = x;
- cur->hotspot_y = y;
- }
-
- void Scumm::setCursorHotspot2(int x,int y) {
- _cursorHotspotX = x;
- _cursorHotspotY = y;
- }
-
- byte Scumm::isMaskActiveAt(int l, int t, int r, int b, byte *mem) {
- int w,h,i;
-
- l>>=3;
- if (l<0) l = 0;
- if (t<0) t = 0;
-
- r>>=3;
- if (r>39) r=39;
-
- mem += l + t*40;
-
- w = r-l;
- h = b-t+1;
-
- do {
- for(i=0; i<=w; i++)
- if (mem[i])
- return true;
- mem += 40;
- } while (--h);
-
- return false;
- }
-
- void Scumm::setPalette(int palindex) {
- byte *pals;
-
- _curPalIndex = palindex;
- pals = getPalettePtr();
- if (pals==NULL)
- error("invalid palette %d", palindex);
- setPaletteFromPtr(pals);
- }
-
- byte *Scumm::findPalInPals(byte *pal, int index) {
- byte *offs;
- uint32 size;
-
- pal = findResource(MKID('WRAP'), pal, 0);
- if (pal==NULL)
- return NULL;
-
- offs = findResource(MKID('OFFS'),pal, 0);
- if (offs==NULL)
- return NULL;
-
- size = (READ_BE_UINT32_UNALIGNED(offs+4)-8) >> 2;
-
- if ((uint32)index >= (uint32)size)
- return NULL;
-
- return offs + READ_LE_UINT32(offs + 8 + index * sizeof(uint32));
- }
-
- byte *Scumm::getPalettePtr() {
- byte *cptr;
-
- cptr = getResourceAddress(rtRoom, _roomResource);
- if (_CLUT_offs) {
- cptr += _CLUT_offs;
- } else {
- cptr = findPalInPals(cptr + _PALS_offs, _curPalIndex);
- }
- return cptr;
- }
-
- void Scumm::darkenPalette(int a, int b, int c, int d, int e) {
- byte *cptr, *cur;
- int num;
- byte color;
-
- cptr = getPalettePtr();
- cptr += 8 + a*3;
- cur = _currentPalette + a*3;
- if (a <= b) {
- num = b - a + 1;
-
- do {
- if (c != 0xFF) {
- color = *cptr++ * (c>>2) / 0xFF;
- } else {
- color = *cptr++ >> 2;
- }
- if(color>63) color = 63;
- *cur++=color;
-
- if (d != 0xFF) {
- color = *cptr++ * (d>>2) / 0xFF;
- } else {
- color = *cptr++ >> 2;
- }
- if(color>63) color = 63;
- *cur++=color;
-
- if (e != 0xFF) {
- color = *cptr++ * (e>>2) / 0xFF;
- } else {
- color = *cptr++ >> 2;
- }
- if(color>63) color = 63;
- *cur++=color;
- } while (--num);
- }
- setDirtyColors(a,b);
- }
-
- void Scumm::grabCursor(int x, int y, int w, int h) {
- VirtScreen *vs = findVirtScreen(y);
-
- if (vs==NULL) {
- warning("grabCursor: invalid Y %d", y);
- return;
- }
-
- grabCursor(
- getResourceAddress(rtBuffer, vs->number+1) + (y-vs->topline)*320 + x,
- w,h);
-
- }
-
- void Scumm::decompressBomp(byte *dst, byte *src, int w, int h) {
- int len,num;
- byte code,color;
-
- src += 8;
-
- do {
- len = w;
- src += 2;
- while (len) {
- code = *src++;
- num = (code>>1)+1;
- if (num>len) num=len;
- len -= num;
- if (code&1) {
- color = *src++;
- do *dst++ = color; while (--num);
- } else {
- do *dst++ = *src++; while (--num);
- }
- }
- } while (--h);
- }
-
- void Scumm::grabCursor(byte *ptr, int width, int height) {
- uint size;
- byte *dst;
-
- size = width * height;
- if (size > sizeof(_grabbedCursor))
- error("grabCursor: grabbed cursor too big");
-
- _cursorWidth = width;
- _cursorHeight = height;
- _cursorAnimate = 0;
-
- dst = _grabbedCursor;
- for(;height;height--) {
- memcpy(dst, ptr, width);
- dst += width;
- ptr += 320;
- }
-
- }
-
- void Scumm::useIm01Cursor(byte *im, int w, int h) {
- VirtScreen *vs = &virtscr[0];
-
- w<<=3;
- h<<=3;
-
- drawBox(0,0,w-1,h-1,0xFF);
-
- vs->alloctwobuffers = false;
- gdi._disable_zbuffer = true;
- gdi.drawBitmap(im, vs, _screenStartStrip, 0, h, 0, w>>3, 0);
- vs->alloctwobuffers = true;
- gdi._disable_zbuffer = false;
-
- grabCursor(getResourceAddress(rtBuffer, 1) + vs->xstart, w, h);
-
- blit(getResourceAddress(rtBuffer, 1) + vs->xstart, getResourceAddress(rtBuffer, 5) + vs->xstart, w, h);
- }
-
- void Scumm::useBompCursor(byte *im, int width, int height) {
- uint size;
-
- width<<=3;
- height<<=3;
-
- size = width * height;
- if (size > sizeof(_grabbedCursor))
- error("useBompCursor: cursor too big");
-
- _cursorWidth = width;
- _cursorHeight = height;
- _cursorAnimate = 0;
-
- decompressBomp(_grabbedCursor, im+10, width, height);
- }
-
- static const byte default_cursor_colors[4] = {
- 15,15,7,8
- };
-
- void Scumm::decompressDefaultCursor(int index) {
- int i;
- byte color;
-
- memset(_grabbedCursor, 0xFF, sizeof(_grabbedCursor));
- _cursorWidth = 16;
- _cursorHeight = 16;
- _cursorHotspotX = 8;
- _cursorHotspotY = 7;
-
- color = default_cursor_colors[index];
-
- for(i=0; i<16; i++) {
- _grabbedCursor[16*8+i] = color;
- _grabbedCursor[16*i+8] = color;
- }
- }
-