PRINCE: Hero drawing - memory leak fix, shadow palette working

This commit is contained in:
lukaslw 2014-05-14 00:21:59 +02:00
parent 07b232804f
commit 2c9559b620
5 changed files with 134 additions and 101 deletions

View File

@ -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);
}
}

View File

@ -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;
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++;
}
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++;
}
xDest = 0;
yDest++;
xSource = 0;
ySource++;
}
return zoomedFrame;
// 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++;
}
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;
}

View File

@ -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();

View File

@ -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();

View File

@ -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;