void AGOSEngine::dumpBitmap(const char *filename, const byte *offs, uint16 w, uint16 h, int flags, const byte *palette, byte base) { byte *imageBuffer = (byte *)malloc(w * h); assert(imageBuffer); VC10_state state; state.depack_cont = -0x80; state.srcPtr = offs; state.dh = h; state.height = h; state.width = w / 16; if (getFeatures() & GF_PLANAR) { state.srcPtr = convertImage(&state, (getGameType() == GType_PN || (flags & 0x80) != 0)); flags &= ~0x80; } const byte *src = state.srcPtr; byte *dst = imageBuffer; int i, j; if (w > _screenWidth) { for (i = 0; i < w; i += 8) { decodeColumn(dst, src + readUint32Wrapper(src), h, w); dst += 8; src += 4; } } else if (h > _screenHeight) { for (i = 0; i < h; i += 8) { decodeRow(dst, src + readUint32Wrapper(src), w, w); dst += 8 * w; src += 4; } } else if (getGameType() == GType_FF || getGameType() == GType_PP) { if ((flags & 0x80)) { for (i = 0; i != w; i++) { byte *c = vc10_depackColumn(&state); for (j = 0; j != h; j++) { dst[j * w + i] = c[j]; } } } else { for (j = 0; j != h; j++) { for (i = 0; i != w; i++) { dst[i] = src[i]; } } dst += w; src += w; } } else if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && w == 320 && (h == 134 || h == 200)) { for (j = 0; j != h; j++) { uint16 count = w / 8; byte *dstPtr = dst; do { uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]); dstPtr[0] = (byte)((bits >> (32 - 5)) & 31); dstPtr[1] = (byte)((bits >> (32 - 10)) & 31); dstPtr[2] = (byte)((bits >> (32 - 15)) & 31); dstPtr[3] = (byte)((bits >> (32 - 20)) & 31); dstPtr[4] = (byte)((bits >> (32 - 25)) & 31); dstPtr[5] = (byte)((bits >> (32 - 30)) & 31); bits = (bits << 8) | src[4]; dstPtr[6] = (byte)((bits >> (40 - 35)) & 31); dstPtr[7] = (byte)((bits) & 31); dstPtr += 8; src += 5; } while (--count); dst += w; } } else if (flags & 0x80) {
dstPtr[4] = (byte)((bits >> (32 - 25)) & 31); dstPtr[5] = (byte)((bits >> (32 - 30)) & 31); bits = (bits << 8) | src[4]; dstPtr[6] = (byte)((bits >> (40 - 35)) & 31); dstPtr[7] = (byte)((bits) & 31); dstPtr += 8; src += 5; } while (--count); dst += w; } } else if (flags & 0x80) { for (i = 0; i != w; i += 2) { byte *c = vc10_depackColumn(&state); for (j = 0; j != h; j++) { byte col = c[j]; dst[j * w + i] = (col >> 4) | base; dst[j * w + i + 1] = (col & 0xF) | base; } } } else { for (j = 0; j != h; j++) { for (i = 0; i != w / 2; i ++) { byte col = src[i]; dst[i * 2] = (col >> 4) | base; dst[i * 2 + 1] = (col & 0xF) | base; } dst += w; src += w / 2;
void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) { if (getGameType() == GType_SIMON1 && (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10)) { state->surf2_addr += _videoWindows[17] * 320; } if (getFeatures() & GF_32COLOR) { const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8); byte *src = state->surf2_addr; byte *dst = state->surf_addr; state->draw_width *= 2; uint h = state->draw_height; do { for (uint i = 0; i != state->draw_width; i++) { if (getGameType() == GType_SIMON1 && getBitFlag(88)) { /* transparency */ if (mask[i] && (dst[i] & 16)) dst[i] = src[i]; } else { /* no transparency */ if (mask[i]) dst[i] = src[i]; } } dst += state->surf_pitch; src += state->surf2_pitch; mask += state->width * 16; } while (--h); } else if (state->flags & kDFCompressed) { byte *mask, *src, *dst; byte h; uint w; state->x_skip *= 4; state->dl = state->width; state->dh = state->height; vc10_skip_cols(state); w = 0; do { mask = vc10_depackColumn(state); /* esi */ src = state->surf2_addr + w * 2; /* ebx */ dst = state->surf_addr + w * 2; /* edi */ h = state->draw_height; do { if (getGameType() == GType_SIMON1 && getBitFlag(88)) { /* transparency */ if ((mask[0] & 0xF0) && (dst[0] & 0x0F0) == 0x20) dst[0] = src[0]; if ((mask[0] & 0x0F) && (dst[1] & 0x0F0) == 0x20) dst[1] = src[1]; } else { /* no transparency */ if (mask[0] & 0xF0) dst[0] = src[0]; if (mask[0] & 0x0F) dst[1] = src[1]; } mask++; dst += state->surf_pitch; src += state->surf2_pitch; } while (--h); } while (++w != state->draw_width); } else { const byte *src, *mask; byte *dst; uint count; mask = state->srcPtr + (state->width * state->y_skip) * 8; src = state->surf2_addr; dst = state->surf_addr; state->x_skip *= 4; do { for (count = 0; count != state->draw_width; count++) { if (getGameType() == GType_SIMON1 && getBitFlag(88)) { /* transparency */ if (mask[count + state->x_skip] & 0xF0) if ((dst[count * 2] & 0xF0) == 0x20) dst[count * 2] = src[count * 2]; if (mask[count + state->x_skip] & 0x0F) if ((dst[count * 2 + 1] & 0x0F) == 0x20) dst[count * 2 + 1] = src[count * 2 + 1]; } else { /* no transparency */ if (mask[count + state->x_skip] & 0xF0) dst[count * 2] = src[count * 2]; if (mask[count + state->x_skip] & 0x0F) dst[count * 2 + 1] = src[count * 2 + 1]; } } src += state->surf2_pitch; dst += state->surf_pitch; mask += state->width * 8; } while (--state->draw_height); } }
void vc10_skip_cols(VC10_state *vs) { while (vs->x_skip) { vc10_depackColumn(vs); vs->x_skip--; } }
void AGOSEngine_Feeble::drawImage(VC10_state *state) { state->surf_addr = getBackBuf(); state->surf_pitch = _backBuf->pitch; if (state->flags & kDFCompressed) { if (state->flags & kDFScaled) { state->surf_addr = getScaleBuf(); state->surf_pitch = _scaleBuf->pitch; uint w, h; byte *src, *dst, *dstPtr; state->dl = state->width; state->dh = state->height; dstPtr = state->surf_addr; w = 0; do { src = vc10_depackColumn(state); dst = dstPtr; h = 0; do { *dst = *src; dst += state->surf_pitch; src++; } while (++h != state->draw_height); dstPtr++; } while (++w != state->draw_width); if (_vgaCurSpritePriority % 10 != 9) { _scaleX = state->x; _scaleY = state->y; _scaleWidth = state->width; _scaleHeight = state->height; } else { scaleClip(state->height, state->width, state->y, state->x, state->y + _scrollY); } } else if (state->flags & kDFOverlayed) { state->surf_addr = getScaleBuf(); state->surf_pitch = _scaleBuf->pitch; state->surf_addr += (state->x + _scrollX) + (state->y + _scrollY) * state->surf_pitch; uint w, h; byte *src, *dst, *dstPtr; state->dl = state->width; state->dh = state->height; dstPtr = state->surf_addr; w = 0; do { byte color; src = vc10_depackColumn(state); dst = dstPtr; h = 0; do { color = *src; if (color != 0) *dst = color; dst += state->surf_pitch; src++; } while (++h != state->draw_height); dstPtr++; } while (++w != state->draw_width); if (_vgaCurSpritePriority % 10 == 9) { scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY); } } else { if (!drawImage_clip(state)) { return; } state->surf_addr += state->x + state->y * state->surf_pitch; uint w, h; byte *src, *dst, *dstPtr; state->dl = state->width; state->dh = state->height; vc10_skip_cols(state); if (state->flags & kDFMasked) { if (getGameType() == GType_FF && !getBitFlag(81)) { if (state->x > _feebleRect.right) { return; } if (state->y > _feebleRect.bottom) { return; } if (state->x + state->width < _feebleRect.left) { return; } if (state->y + state->height < _feebleRect.top) { return; } } dstPtr = state->surf_addr; w = 0; do { byte color; src = vc10_depackColumn(state); dst = dstPtr; h = 0; do { color = *src; if (color) *dst = color; dst += state->surf_pitch; src++; } while (++h != state->draw_height); dstPtr++; } while (++w != state->draw_width); } else { dstPtr = state->surf_addr; w = 0; do { byte color; src = vc10_depackColumn(state); dst = dstPtr; h = 0; do { color = *src; if ((state->flags & kDFNonTrans) || color != 0) *dst = color; dst += state->surf_pitch; src++; } while (++h != state->draw_height); dstPtr++; } while (++w != state->draw_width); } } } else { if (!drawImage_clip(state)) { return; } state->surf_addr += state->x + state->y * state->surf_pitch; const byte *src; byte *dst; uint count; src = state->srcPtr + state->width * state->y_skip; dst = state->surf_addr; do { for (count = 0; count != state->draw_width; count++) { byte color; color = src[count + state->x_skip]; if (color) { if ((state->flags & kDFShaded) && color == 220) color = 244; dst[count] = color; } } dst += state->surf_pitch; src += state->width; } while (--state->draw_height); } }