From 42bdde956a6cba01ea5712c9fbdd8ee0b7ccbb36 Mon Sep 17 00:00:00 2001
From: lukaslw
Date: Thu, 15 May 2014 15:12:56 +0200
Subject: PRINCE: loadShadow() fix, begin of drawing shadows on walls

---
 engines/prince/animation.cpp |   5 --
 engines/prince/hero.cpp      | 148 ++++++++++++++++++++++++++++++-------------
 engines/prince/hero.h        |   5 +-
 engines/prince/prince.cpp    |  30 +++++++--
 engines/prince/prince.h      |   1 +
 5 files changed, 133 insertions(+), 56 deletions(-)

(limited to 'engines/prince')

diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp
index 9911f5f99e..e27d556f1b 100644
--- a/engines/prince/animation.cpp
+++ b/engines/prince/animation.cpp
@@ -58,11 +58,6 @@ void Animation::clear() {
 }
 
 // TEMP
-/*
-int8 Animation::getZoom(uint16 offset) const {
-	return *(uint8*)(_data+offset);
-}
-*/
 int16 Animation::getZoom(uint16 offset) const {
 	return READ_LE_UINT16(_data + offset);
 }
diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp
index 2b4f156df2..8afa0ca372 100644
--- a/engines/prince/hero.cpp
+++ b/engines/prince/hero.cpp
@@ -40,13 +40,13 @@ Hero::Hero(PrinceEngine *vm, GraphicsMan *graph) : _vm(vm), _graph(graph)
 	, _frameXSize(0), _frameYSize(0), _scaledFrameXSize(0), _scaledFrameYSize(0)
 {
 	_zoomBitmap = new Animation();
-	_shadowBitmap = new Animation();
+	_shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize);
 	_shadowLine = new byte[kShadowLineArraySize];
 }
 
 Hero::~Hero() {
 	delete _zoomBitmap;
-	delete _shadowBitmap;
+	free(_shadowBitmap);
 	delete[] _shadowLine;
 }
 
@@ -280,7 +280,12 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) {
 		int shadMinY = _shadDrawY;
 		int shadMaxY = _shadDrawY;
 		int shadBitAddr = destY * kMaxPicWidth / 8 + destX / 8;
+		debug("destX: %d", destX);
+		debug("destY: %d", destY);
+		debug("shadBitmap: %d", _shadowBitmap[shadBitAddr]);
+		debug("shadBitmap2: %d", _shadowBitmap[shadBitAddr + kShadowBitmapSize]);
 		int shadBitMask = 128 >> (destX % 8);
+		debug("shadBitMask: %d", shadBitMask);
 
 		int shadZoomY2 = _shadScaleValue;
 		int shadZoomY = _scaleValue;
@@ -299,10 +304,18 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) {
 		// banked2
 		byte *shadowLineStart = _shadowLine + 8;
 
+		int shadWallBitAddr = 0;
+		int shadWallBitMask = 0;
+		byte *shadWallDestAddr = 0;
+		int shadWallPosY = 0;
+		int shadWallSkipX = 0;
+		int shadWallModulo = 0;
+
 		// linear_loop
 		for(int i = 0; i < _frameYSize; i++) {
 			int shadSkipX = 0;
 			int ct_loop = 0;
+			int sprModulo = 0;
 
 			int ebxOnStack;
 			//retry_line:
@@ -356,6 +369,7 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) {
 					//x1_ok
 					if (shadPosX + _frameXSize > 640) {
 						ct_loop = 640 - shadPosX; // test it
+						sprModulo = shadPosX + _frameXSize - 640;
 					} else {
 						//draw_line
 						ct_loop = _frameXSize;
@@ -400,14 +414,14 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) {
 					break;
 				}
 				//line_y_ok_2:
-				// push esi
-				// push ecx
-				// lineDestAddr = eax;
+				// push esi - background
+				// push ecx - ct_loop
+				byte *lineDestAddr = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY);
 				// edi = eax -> needed in copy trans
 				// push shadBitMask
-				// lineBitAddr = shadBitMask;
+				int lineBitMask = shadBitMask; // before copy_trans ct_loop
 				// push shadBitAddr;
-				// lineBitAddr = shadBitAddr;
+				int lineBitAddr = shadBitAddr; // before copy_trans ct_loop
 
 				//copy_trans
 				//push eax, ebx, edx, ebp
@@ -422,17 +436,21 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) {
 						shadowStart = (byte *)makeShadow->getBasePtr(blackHeroX, blackHeroY);
 						shadZoomX += _scaleValue;
 					} else {
-						//point_ok:
 						if (*shadowStart == kShadowColor) {
-							if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr)) { //tofix
+							if (shadBitMask != _shadowBitmap[shadBitAddr]) {
+								//debug("shadBitMask: %d", shadBitMask);
+								//debug("_shadBitmap: %d", _shadowBitmap->getShadow(shadBitAddr));
 								if (shadWallDown == 0) {
-									if (shadBitMask != _shadowBitmap->getZoom(shadBitAddr + kShadowBitmapSize)) { //tofix
+									if (shadBitMask != _shadowBitmap[shadBitAddr + kShadowBitmapSize]) {
 										shadWDFlag = 1;
+										//shadow
+										*background = *(sprShadow + *background);
 									}
 								}
+							} else {
+								//shadow
+								*background = *(sprShadow + *background);
 							}
-							//shadow
-							*background = *(sprShadow + *background);
 						}
 						//ct_next
 						//ror(shadBitMask, 1)
@@ -449,59 +467,99 @@ void Hero::showHeroShadow(Graphics::Surface *heroFrame) {
 						background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY);
 					}
 				}
+				/*
 				//byebyebye
 				if (shadWallDown == 0 && shadWDFlag != 0) {
-					//shadWallDown = shadPosX;
-					//shadWallBitAddr = lineBitAddr;
-					//shadWallDestAddr = lineDestAddr;
-					//shadWallBitMask = lineBitMask;
-					//shadWallPosY = shadPosY;
-					//shadWallSkipX = shadSkipX;
-					//shadWallModulo = sprModulo;
+					shadWallDown = shadPosX;
+					shadWallBitAddr = lineBitAddr;
+					shadWallDestAddr = lineDestAddr;
+					shadWallBitMask = lineBitMask;
+					shadWallPosY = shadPosY;
+					shadWallSkipX = shadSkipX;
+					shadWallModulo = sprModulo;
 				}
 				//byebye
 				//pop ebp edx ebx eax
 				//pop shadBitAddr
 				//pop shadBitMask
-				//pop ecx
-				//pop edi
+				//pop ecx - ct_loop
+				//pop edi - shadowStart
 				if (shadDirection != 0 && shadWallDown != 0) {
 					//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) {
+					//esi = edi; // shadowStart
+					//push shadBitMask
+					//push shadBitAddr
+					shadBitMask = shadWallBitMask;
+					shadBitAddr = shadWallBitAddr;
+					//eax = shadWallSkipX; -not needed in wall_copy_trans
+					background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX, _shadDrawY + diffY); //edi = shadWallDestAddr;
+					shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX, blackHeroY); //esi += shadWallSkipX;
+
+					if (ct_loop > shadWallSkipX && ct_loop - shadWallSkipX > shadWallModulo) {
 						//WALL_copy_trans
-					//} else {
+						//push eax, ebx, edx, ebp
+						//ebx = SprShadow;
+						//ebp = ShadBitAddr;
+						//ah = ShadBitMask;
+						shadWDFlag = 0;
+						int shadZoomX = _scaleValue;
+						int backgroundDiff = 0;
+						int blackHeroXWall = 0;
+						//ct_loop:
+						for (int j = 0; j < ct_loop; j++) {
+							shadZoomX -= 100;
+							if (shadZoomX < 0 && _scaleValue != 10000) {
+								blackHeroXWall++;
+								shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY);
+								shadZoomX += _scaleValue;
+							} else {
+								//point_ok:
+								if (*shadowStart == kShadowColor) {
+									if (shadBitMask != _shadowBitmap->getShadow(shadBitAddr + kShadowBitmapSize)) {
+										//*background = *(sprShadow + *background);	
+										*background = 50;
+									}
+								}
+								//ct_next
+								//ror(shadBitMask, 1)
+								if (shadBitMask == 1) {
+									shadBitMask = 128;
+									shadBitAddr++;
+								} else {
+									shadBitMask /= 2;
+								}
+								//okok
+								blackHeroXWall++;
+								shadowStart = (byte *)makeShadow->getBasePtr(shadWallSkipX + blackHeroXWall, blackHeroY);
+								backgroundDiff++;
+								background = (byte *)_graph->_frontScreen->getBasePtr(_shadDrawX + diffX + backgroundDiff, _shadDrawY + diffY);
+							}
+						}
+					} else {
 						//krap2
 						//pop shadBitAddr
 						//pop shadBitMask
 						//pop esi
-						//ebx = VESA_ScanLine
 						if (shadDirection != 0) {
-							//shadWallDestAddr -= ebx; //SCREENWIDTH
-							//shadWallBitAddr -= kMaxPicWidth / 8;
-							//shadWallPosY--;
+							shadWallDestAddr -= kScreenWidth;
+							shadWallBitAddr -= kMaxPicWidth / 8;
+							shadWallPosY--;
 						} else {
 							//down_direct
-							//shadWallDestAddr += ebx; //SCREENWIDTH
-							//shadWallBitAddr += kMaxPicWidth / 8;
-							//shadWallPosY++;
+							shadWallDestAddr += kScreenWidth;
+							shadWallBitAddr += kMaxPicWidth / 8;
+							shadWallPosY++;
 						}
 						//compareagain
-						//if (shadWallPosY < shadMinY) {
-						//	shadMinY = shadWallPosY;
-						//}
-						//if (shadWallPosY > shadMaxY) {
-						//	shadMaxY = shadWallPosY;
-						//}
-					//}
+						if (shadWallPosY < shadMinY) {
+							shadMinY = shadWallPosY;
+						}
+						if (shadWallPosY > shadMaxY) {
+							shadMaxY = shadWallPosY;
+						}
+					}
 				}
+				*/
 			}
 			//skip_line
 			//add esi, sprWidth - don't need it?
diff --git a/engines/prince/hero.h b/engines/prince/hero.h
index 28b97d9b68..7fe3218b91 100644
--- a/engines/prince/hero.h
+++ b/engines/prince/hero.h
@@ -45,7 +45,8 @@ public:
 	static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep;
 	static const int16 kNormalWidth = 640;
 	static const int16 kShadowLineArraySize = 2 * 1280 * 4;
-	static const int16 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8;
+	static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8;
+	static const int16 kScreenWidth = 640;
 
 	static const byte kShadowColor = 191;
 
@@ -182,7 +183,7 @@ public:
 	Common::Array<Animation *> _moveSet; // MoveAnims MoveSet
 	// TurnAnim ??
 	Animation *_zoomBitmap; // change to sth else, not Animation ??
-	Animation *_shadowBitmap;
+	byte *_shadowBitmap;
 	byte *_shadowLine;
 	
 	uint32 _moveDelay;
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index f987ff222f..98f9689b9a 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -294,10 +294,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
 	_mainHero->_zoomBitmap->clear();
 	Resource::loadResource(_mainHero->_zoomBitmap, "zoom", false);
 
-	_mainHero->_shadowBitmap->clear();
-	if (Resource::loadResource(_mainHero->_shadowBitmap, "shadow", false) == false) {
-		Resource::loadResource(_mainHero->_shadowBitmap, "shadow2", false);
-	}
+	loadShadow(_mainHero->_shadowBitmap, _mainHero->kShadowBitmapSize, "shadow", "shadow2");
 
 	_picWindowX = 0;
 
@@ -471,6 +468,31 @@ bool PrinceEngine::loadAnim(uint16 animNr, bool loop) {
 	return true;
 }
 
+bool PrinceEngine::loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2) {
+
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName1);
+	if (!stream) {
+		return false;
+	}
+
+	if (stream->read(shadowBitmap, dataSize) != dataSize) {
+		free(shadowBitmap);
+		return false;
+	}
+
+	stream = SearchMan.createReadStreamForMember(resourceName2);
+	if (!stream) {
+		return false;
+	}
+
+	byte *shadowBitmap2 = shadowBitmap + dataSize;
+	if (stream->read(shadowBitmap2, dataSize) != dataSize) {
+		free(shadowBitmap);
+		return false;
+	}
+	return true;
+}
+
 void PrinceEngine::scrollCameraLeft(int16 delta) {
     if (_newCameraX > 0) {
         if (_newCameraX < delta)
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index e7cdce5af1..dd00abb788 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -124,6 +124,7 @@ public:
 	bool loadAnim(uint16 animNr, bool loop);
 	bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name);
 	bool loadSample(uint32 sampleSlot, const Common::String &name);
+	bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2);
 
 	void playSample(uint16 sampleId, uint16 loopType);
 	void stopSample(uint16 sampleId);
-- 
cgit v1.2.3