diff options
-rw-r--r-- | engines/simon/simon.cpp | 22 | ||||
-rw-r--r-- | engines/simon/simon.h | 11 | ||||
-rw-r--r-- | engines/simon/vga.cpp | 120 | ||||
-rw-r--r-- | engines/simon/vga.h | 5 |
4 files changed, 150 insertions, 8 deletions
diff --git a/engines/simon/simon.cpp b/engines/simon/simon.cpp index 1bedd667bc..c81cc90ec2 100644 --- a/engines/simon/simon.cpp +++ b/engines/simon/simon.cpp @@ -357,6 +357,20 @@ SimonEngine::SimonEngine(OSystem *syst) _vgaWaitFor = 0; _vgaCurFileId = 0; _vgaCurSpriteId = 0; + _vgaCurSpritePriority = 0; + + _baseY = 0; + _scale = 0; + + _feebleRect.left = 0; + _feebleRect.right = 0; + _feebleRect.top = 0; + _feebleRect.bottom = 0; + + _scaleX = 0; + _scaleY = 0; + _scaleWidth = 0; + _scaleHeight = 0; _nextVgaTimerToProcess = 0; @@ -429,6 +443,7 @@ SimonEngine::SimonEngine(OSystem *syst) _sdl_buf_3 = 0; _sdl_buf = 0; _sdl_buf_attached = 0; + _sdl_buf_scaled = 0; _vc10BasePtrOld = 0; memcpy (_hebrew_char_widths, @@ -2694,6 +2709,7 @@ void SimonEngine::timer_vga_sprites() { _curSfxFile = vpe->sfxFile; _windowNum = vsp->windowNum; _vgaCurSpriteId = vsp->id; + _vgaCurSpritePriority = vsp->priority; params[0] = readUint16Wrapper(&vsp->image); params[1] = readUint16Wrapper(&vsp->palette); @@ -3912,6 +3928,7 @@ int SimonEngine::go() { _sdl_buf_3 = (byte *)calloc(_screenWidth * _screenHeight, 1); _sdl_buf = (byte *)calloc(_screenWidth * _screenHeight, 1); _sdl_buf_attached = (byte *)calloc(_screenWidth * _screenHeight, 1); + _sdl_buf_scaled = (byte *)calloc(_screenWidth * _screenHeight, 1); allocItemHeap(); allocTablesHeap(); @@ -4184,6 +4201,11 @@ void SimonEngine::set_volume(int volume) { _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume); } +byte *SimonEngine::dx_lock_scaled() { + _dxSurfacePitch = _screenWidth; + return _sdl_buf_scaled; +} + byte SimonEngine::getByte() { return *_codePtr++; } diff --git a/engines/simon/simon.h b/engines/simon/simon.h index 617d2ed634..0c2636b612 100644 --- a/engines/simon/simon.h +++ b/engines/simon/simon.h @@ -24,8 +24,12 @@ #define SIMON_H #include <stdio.h> + #include "base/engine.h" + +#include "common/rect.h" #include "common/util.h" + #include "simon/midi.h" #include "simon/sound.h" #include "simon/vga.h" @@ -340,9 +344,12 @@ protected: uint16 _vgaCurFile2; uint16 _vgaWaitFor, _vgaCurFileId; uint16 _vgaCurSpriteId; + uint16 _vgaCurSpritePriority; int16 _baseY; float _scale; + Common::Rect _feebleRect; + int _scaleX, _scaleY, _scaleWidth, _scaleHeight; VgaTimerEntry *_nextVgaTimerToProcess; @@ -424,6 +431,7 @@ protected: byte *_sdl_buf_3; byte *_sdl_buf; byte *_sdl_buf_attached; + byte *_sdl_buf_scaled; Common::RandomSource _rnd; @@ -766,6 +774,7 @@ protected: void drawImages(VC10_state *state); void drawImages_Feeble(VC10_state *state); bool drawImages_clip(VC10_state *state); + void scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY); void delete_vga_timer(VgaTimerEntry * vte); void vcResumeSprite(const byte *code_ptr, uint16 cur_file, uint16 cur_sprite); @@ -811,6 +820,8 @@ protected: byte *dx_lock_attached(); void dx_unlock_attached(); + byte *dx_lock_scaled(); + byte *read_vga_from_datfile_2(uint id, uint type); void resfile_read(void *dst, uint32 offs, uint32 size); diff --git a/engines/simon/vga.cpp b/engines/simon/vga.cpp index 5c322fce65..ec08feaeea 100644 --- a/engines/simon/vga.cpp +++ b/engines/simon/vga.cpp @@ -707,8 +707,6 @@ void SimonEngine::vc10_draw() { if (_dumpImages) dump_single_bitmap(_vgaCurFileId, state.image, state.depack_src, width * 16, height, state.palette); - // TODO::Add support for image overlay and scaling in Feeble Files - if (getGameType() == GType_FF) { if (flags & 0x80) { state.flags |= 0x8; @@ -854,11 +852,80 @@ bool SimonEngine::drawImages_clip(VC10_state *state) { void SimonEngine::drawImages_Feeble(VC10_state *state) { if (state->flags & 0x8) { if (state->flags & 0x40) { - // TODO::Add support for image scaling in Feeble Files + state->surf_addr = dx_lock_scaled(); + state->surf_pitch = _dxSurfacePitch; + + uint w, h; + byte *src, *dst, *dst_org; + + state->dl = state->width; + state->dh = state->height; + + vc10_skip_cols(state); + + dst_org = state->surf_addr; + w = 0; + do { + byte color; + + src = vc10_depack_column(state); + dst = dst_org; + h = 0; + do { + color = *src; + *dst = color; + dst += _screenWidth; + src++; + } while (++h != state->draw_height); + dst_org++; + } while (++w != state->draw_width); + + _vgaCurSpritePriority /= 10; + if (_vgaCurSpritePriority != 900) { + _scaleX = state->x; + _scaleY = state->y; + _scaleWidth = state->width; + _scaleHeight = state->width; + } else { + scaleClip(state->height, state->width, state->y, state->x, _scrollY); + } } else if (state->flags & 0x10) { - // TODO::Add support for image overlay in Feeble Files + state->surf_addr = dx_lock_scaled(); + state->surf_pitch = _dxSurfacePitch; + state->surf_addr += state->x + state->y * state->surf_pitch; + uint w, h; + byte *src, *dst, *dst_org; + + state->dl = state->width; + state->dh = state->height; + + vc10_skip_cols(state); + + dst_org = state->surf_addr; + w = 0; + do { + byte color; + + src = vc10_depack_column(state); + dst = dst_org; + + h = 0; + do { + color = *src; + if (color != 0) + *dst = color; + dst += _screenWidth; + src++; + } while (++h != state->draw_height); + dst_org++; + } while (++w != state->draw_width); + + _vgaCurSpritePriority /= 10; + if (_vgaCurSpritePriority != 900) { + scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scrollY); + } } else { if (drawImages_clip(state) == 0) return; @@ -871,7 +938,14 @@ void SimonEngine::drawImages_Feeble(VC10_state *state) { if (state->flags & 0x20) { if (vcGetBit(81) == false) { - // TODO: Compare Feeble rect + 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; } state->dl = state->width; @@ -953,6 +1027,42 @@ void SimonEngine::drawImages_Feeble(VC10_state *state) { } } +void SimonEngine::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) { + Common::Rect srcRect, dstRect; + float factor, xscale; + + srcRect.left = 0; + srcRect.top = 0; + srcRect.right = w; + srcRect.bottom = h; + + if (scrollY > _baseY) + factor= 1+ ((scrollY - _baseY) * _scale); + else + factor= 1 - ((_baseY - scrollY) * _scale); + + xscale = ((w * factor) / 2); + + dstRect.left = (int16)(x - xscale); + if (dstRect.left > 639) + return; + dstRect.top = (int16)(y - (h * factor)); + if (dstRect.top > 479) + return; + + dstRect.right = (int16)(x + xscale); + dstRect.bottom = y; + + _feebleRect = dstRect; + + _variableArray[20] = _feebleRect.top; + _variableArray[21] = _feebleRect.left; + _variableArray[22] = _feebleRect.bottom; + _variableArray[23] = _feebleRect.right; + + // TODO +} + void SimonEngine::drawImages(VC10_state *state) { const uint16 *vlut = &_video_windows[_windowNum * 4]; diff --git a/engines/simon/vga.h b/engines/simon/vga.h index 2dd77633de..9f257a104a 100644 --- a/engines/simon/vga.h +++ b/engines/simon/vga.h @@ -100,11 +100,10 @@ struct AnimationHeader_Simon { struct VC10_state { int image; uint16 flags; - int x, y; - byte palette; - uint width, height; + int x, y; + int width, height; uint draw_width, draw_height; uint x_skip, y_skip; |