From 2c9559b620def087f1d7e9bff3b2a07686c946f6 Mon Sep 17 00:00:00 2001 From: lukaslw Date: Wed, 14 May 2014 00:21:59 +0200 Subject: PRINCE: Hero drawing - memory leak fix, shadow palette working --- engines/prince/graphics.cpp | 13 ++-- engines/prince/hero.cpp | 170 +++++++++++++++++++++++++------------------- engines/prince/hero.h | 4 +- engines/prince/prince.cpp | 46 ++++++++---- engines/prince/prince.h | 2 +- 5 files changed, 134 insertions(+), 101 deletions(-) (limited to 'engines/prince') diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index ab6eec3d0b..5b66994b47 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -63,8 +63,7 @@ void GraphicsMan::change() { _changed = true; } -void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) -{ +void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) { uint16 w = MIN(_frontScreen->w, s->w); for (uint y = 0; y < s->h; y++) { if (y < _frontScreen->h) { @@ -74,18 +73,16 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) change(); } -void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) -{ +void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) { for (uint y = 0; y < s->h; ++y) { for (uint x = 0; x < s->w; ++x) { byte pixel = *((byte*)s->getBasePtr(x, y)); if (pixel != 255) { - //*((byte*)_frontScreen->getBasePtr(x, y)) = pixel; *((byte*)_frontScreen->getBasePtr(x + posX, y + posY)) = pixel; } } } - change(); + change(); } void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { @@ -98,9 +95,8 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { int32 currColor; int shadow = brightness * 256 / 100; - byte *originalPalette = (byte *)malloc(256 * 3); - _vm->_system->getPaletteManager()->grabPalette(originalPalette, 0, 256); + const byte *originalPalette = _vm->_roomBmp->getPalette(); for (int i = 0; i < 256; i++) { redFirstOrg = originalPalette[3 * i] * shadow / 256; @@ -136,7 +132,6 @@ void GraphicsMan::makeShadowTable(int brightness, byte *shadowPalette) { } shadowPalette[i] = currColor; } - free(originalPalette); } } diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 884c9b9adf..de4a3524cd 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -57,7 +57,7 @@ bool Hero::loadAnimSet(uint32 animSetNr) { _shadMinus = heroSetBack[animSetNr]; - for (uint32 i = 0; i < _moveSet.size(); ++i) { + for (uint32 i = 0; i < _moveSet.size(); i++) { delete _moveSet[i]; } @@ -77,22 +77,11 @@ bool Hero::loadAnimSet(uint32 animSetNr) { return true; } -const Graphics::Surface * Hero::getSurface() { +Graphics::Surface *Hero::getSurface() { if (_moveSet[_moveSetType]) { - debug("BaseX: %d", _moveSet[_moveSetType]->getBaseX()); - debug("BaseY: %d", _moveSet[_moveSetType]->getBaseY()); - //debug("FrameCount: %d", _moveSet[_moveSetType]->getFrameCount()); - //debug("LoopCount: %d", _moveSet[_moveSetType]->getLoopCount()); - //debug("PhaseCount: %d", _moveSet[_moveSetType]->getPhaseCount()); - //debug("PhaseFrameIndex(%d): %d", _frame, _moveSet[_moveSetType]->getPhaseFrameIndex(_frame)); - //debug("PhaseOffsetX(%d): %d", _frame, _moveSet[_moveSetType]->getPhaseOffsetX(_frame)); - //debug("PhaseOffsetY(%d) %d", _frame, _moveSet[_moveSetType]->getPhaseOffsetY(_frame)); - //debug("FrameSizeX(%d) %d", _frame, _moveSet[_moveSetType]->getFrameWidth(_frame)); - //debug("FrameSizeY(%d) %d", _frame, _moveSet[_moveSetType]->getFrameHeight(_frame)); - //getState(); int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); - return zoomSprite(heroFrame); + return heroFrame; } return NULL; } @@ -173,49 +162,46 @@ Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { Graphics::Surface *zoomedFrame = new Graphics::Surface(); zoomedFrame->create(scaledXSize, scaledYSize, Graphics::PixelFormat::createFormatCLUT8()); - if (_zoomFactor != 0) { - int sprZoomX; - int sprZoomY = _scaleValue; - uint xSource = 0; - uint ySource = 0; - uint xDest = 0; - uint yDest = 0; - - for (int i = 0; i < scaledYSize; i++) { - // linear_loop: - while(1) { - sprZoomY -= 100; - if (sprZoomY >= 0 || _scaleValue == 10000) { - // all_r_y - sprZoomX = _scaleValue; - break; // to loop_lin - } else { - sprZoomY += _scaleValue; - xSource = 0; - ySource++; - } + int sprZoomX; + int sprZoomY = _scaleValue; + uint xSource = 0; + uint ySource = 0; + uint xDest = 0; + uint yDest = 0; + + for (int i = 0; i < scaledYSize; i++) { + // linear_loop: + while(1) { + sprZoomY -= 100; + if (sprZoomY >= 0 || _scaleValue == 10000) { + // all_r_y + sprZoomX = _scaleValue; + break; // to loop_lin + } else { + sprZoomY += _scaleValue; + xSource = 0; + ySource++; } - // loop_lin: - for (int j = 0; j < scaledXSize; j++) { - sprZoomX -= 100; - if (sprZoomX >= 0) { - // its_all_r - memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); - xDest++; - } else { - sprZoomX += _scaleValue; - j--; - } - xSource++; + } + // loop_lin: + for (int j = 0; j < scaledXSize; j++) { + sprZoomX -= 100; + if (sprZoomX >= 0) { + // its_all_r + memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); + xDest++; + } else { + sprZoomX += _scaleValue; + j--; } - xDest = 0; - yDest++; - xSource = 0; - ySource++; + xSource++; } - return zoomedFrame; + xDest = 0; + yDest++; + xSource = 0; + ySource++; } - return heroFrame; + return zoomedFrame; } void Hero::countDrawPosition() { @@ -243,8 +229,6 @@ void Hero::countDrawPosition() { if (_zoomFactor != 0) { //notfullSize - debug("scaledX: %d", scaledX); - debug("scaledY: %d", scaledY); _drawX = _middleX - scaledX / 2; _drawY = tempMiddleY + 1 - scaledY; } else { @@ -265,9 +249,7 @@ static void plot(int x, int y, int color, void *data) { shadowLine->_shadowLineLen++; } -void Hero::showHeroShadow() { - int16 phaseFrameIndex = _moveSet[_moveSetType]->getPhaseFrameIndex(_phase); - Graphics::Surface *heroFrame = _moveSet[_moveSetType]->getFrame(phaseFrameIndex); +void Hero::showHeroShadow(Graphics::Surface *heroFrame) { int16 frameXSize = _moveSet[_moveSetType]->getFrameWidth(_phase); int16 frameYSize = _moveSet[_moveSetType]->getFrameHeight(_phase); @@ -419,7 +401,7 @@ void Hero::showHeroShadow() { //smaller_y //retry_line2 int ebxOnStack2; - for(ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { + for (ebxOnStack2 = ebxOnStack; ebxOnStack2 > 0; ebxOnStack2--) { shadZoomY2 -= 100; if (shadZoomY2 < 0 && _shadScaleValue != 10000) { shadZoomY2 += _shadScaleValue; @@ -441,14 +423,12 @@ void Hero::showHeroShadow() { //line_y_ok_2: // push esi // push ecx - // int lineDestAddr = eax; - // edi = eax - // eax = shadBitMask - // push eax // push shadBitMask - // lineBitAddr = shadBitMask - // eax = shadBitAddr - // push eax - // LineBitAddr = eax + // lineDestAddr = eax; + // edi = eax -> needed in copy trans + // push shadBitMask + // lineBitAddr = shadBitMask; + // push shadBitAddr; + // lineBitAddr = shadBitAddr; //copy_trans //push eax, ebx, edx, ebp @@ -473,8 +453,7 @@ void Hero::showHeroShadow() { } } //shadow - //*background = *(sprShadow + *background); //wrong color - *background = 0; + *background = *(sprShadow + *background); } //ct_next //ror(shadBitMask, 1) @@ -493,14 +472,56 @@ void Hero::showHeroShadow() { } //byebyebye if (shadWallDown == 0 && shadWDFlag != 0) { - //shadWall etc + //shadWallDown = shadPosX; + //shadWallBitAddr = lineBitAddr; + //shadWallDestAddr = lineDestAddr; + //shadWallBitMask = lineBitMask; + //shadWallPosY = shadPosY; + //shadWallSkipX = shadSkipX; + //shadWallModulo = sprModulo; } //byebye - // pop ... + //pop ebp edx ebx eax + //pop shadBitAddr + //pop shadBitMask + //pop ecx + //pop edi if (shadDirection != 0 && shadWallDown != 0) { - // push... - // krap2 - // WALL_copy_trans + //push esi + //esi = edi; + //push shadBitMask + //push shadBitAddr + //shadBitMask = shadWallBitMask; + //shadBitAddr = shadWallBitAddr; + //eax = shadWallSkipX; + //edi = shadWallDestAddr; + //esi += shadWallSkipX; + //if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) { + //WALL_copy_trans + //} else { + //krap2 + //pop shadBitAddr + //pop shadBitMask + //pop esi + //ebx = VESA_ScanLine + if (shadDirection != 0) { + //shadWallDestAddr -= ebx; //SCREENWIDTH + //shadWallBitAddr -= kMaxPicWidth / 8; + //shadWallPosY--; + } else { + //down_direct + //shadWallDestAddr += ebx; //SCREENWIDTH + //shadWallBitAddr += kMaxPicWidth / 8; + //shadWallPosY++; + } + //compareagain + //if (shadWallPosY < shadMinY) { + // shadMinY = shadWallPosY; + //} + //if (shadWallPosY > shadMaxY) { + // shadMaxY = shadWallPosY; + //} + //} } } //skip_line @@ -553,6 +574,7 @@ void Hero::showHeroShadow() { } //koniec_bajki } + makeShadow->free(); delete makeShadow; } diff --git a/engines/prince/hero.h b/engines/prince/hero.h index 75f6a3a78b..9e67cda6c3 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -103,7 +103,7 @@ public: Common::RandomSource _randomSource; bool loadAnimSet(uint32 heroAnimNumber); - const Graphics::Surface * getSurface(); + Graphics::Surface *getSurface(); void setPos(int16 x, int16 y) { _middleX = x; _middleY = y; } void setVisible(bool flag) { _visible = flag; } @@ -121,7 +121,7 @@ public: void showHeroAnimFrame(); void line(int x1, int y1, int x2, int y2); void plotPoint(int x, int y); - void showHeroShadow(); + void showHeroShadow(Graphics::Surface *heroFrame); void setShadowScale(int32 shadowScale); void specialAnim(); void getState(); diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 533d2f4c57..f987ff222f 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -108,13 +108,22 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; - delete _mainHero; - delete _secondHero; - for (uint i = 0; i < _objList.size(); ++i) { + for (uint i = 0; i < _objList.size(); i++) { delete _objList[i]; } _objList.clear(); + + for (uint i = 0; i < _mainHero->_moveSet.size(); i++) { + delete _mainHero->_moveSet[i]; + } + + for (uint i = 0; i < _secondHero->_moveSet.size(); i++) { + delete _secondHero->_moveSet[i]; + } + + delete _mainHero; + delete _secondHero; } GUI::Debugger *PrinceEngine::getDebugger() { @@ -189,7 +198,8 @@ void PrinceEngine::init() { _mainHero = new Hero(this, _graph); _secondHero = new Hero(this, _graph); - _mainHero->loadAnimSet(0); + _mainHero->loadAnimSet(1); + _secondHero->loadAnimSet(3); } void PrinceEngine::showLogo() { @@ -278,6 +288,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { Resource::loadResource(_roomBmp, "room"); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; + _graph->setPalette(_roomBmp->getPalette()); } _mainHero->_zoomBitmap->clear(); @@ -532,16 +543,16 @@ void PrinceEngine::keyHandler(Common::Event event) { debugEngine("%d", _mainHero->_state); break; case Common::KEYCODE_i: - _mainHero->_middleY -= 10; + _mainHero->_middleY -= 5; break; case Common::KEYCODE_k: - _mainHero->_middleY += 10; + _mainHero->_middleY += 5; break; case Common::KEYCODE_j: - _mainHero->_middleX -= 10; + _mainHero->_middleX -= 5; break; case Common::KEYCODE_l: - _mainHero->_middleX += 10; + _mainHero->_middleX += 5; break; } } @@ -633,20 +644,25 @@ void PrinceEngine::showTexts() { void PrinceEngine::drawScreen() { const Graphics::Surface *roomSurface = _roomBmp->getSurface(); if (roomSurface) { - _graph->setPalette(_roomBmp->getPalette()); const Graphics::Surface visiblePart = roomSurface->getSubArea(Common::Rect(_picWindowX, 0, roomSurface->w, roomSurface->h)); _graph->draw(0, 0, &visiblePart); } if (_mainHero->_visible) { - const Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); - //const Graphics::Surface *mainHeroShadow = _mainHero->showHeroShadow(); - + Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); if (mainHeroSurface) { - _mainHero->showHeroShadow(); - _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); - //_graph->drawTransparent(_mainHero->_shadowDrawX, _mainHero->_shadowDrawY, mainHeroShadow); + _mainHero->showHeroShadow(mainHeroSurface); + if (_mainHero->_zoomFactor != 0) { + Graphics::Surface *zoomedHeroSurface = _mainHero->zoomSprite(mainHeroSurface); + _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, zoomedHeroSurface); + zoomedHeroSurface->free(); + delete zoomedHeroSurface; + } else { + _graph->drawTransparent(_mainHero->_drawX, _mainHero->_drawY, mainHeroSurface); + } } + mainHeroSurface->free(); + delete mainHeroSurface; } playNextFrame(); diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 7793545526..e7cdce5af1 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -145,6 +145,7 @@ public: uint16 _sceneWidth; uint32 _picWindowX; uint32 _picWindowY; + Image::BitmapDecoder *_roomBmp; private: bool playNextFrame(); @@ -165,7 +166,6 @@ private: uint8 _cursorNr; Common::RandomSource *_rnd; - Image::BitmapDecoder *_roomBmp; Cursor *_cursor1; Cursor *_cursor2; MhwanhDecoder *_suitcaseBmp; -- cgit v1.2.3