diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/koopatlas/core.cpp | 5 | ||||
| -rw-r--r-- | src/koopatlas/map.cpp | 35 | ||||
| -rw-r--r-- | src/koopatlas/map.h | 5 | ||||
| -rw-r--r-- | src/koopatlas/mapdata.cpp | 32 | ||||
| -rw-r--r-- | src/koopatlas/mapdata.h | 29 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 114 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.h | 8 | 
7 files changed, 178 insertions, 50 deletions
| diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index 42bf7c1..2317d00 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -973,6 +973,11 @@ void NewerMapDrawFunc() {  	DrawOpa();  	DrawXlu();  	UnlinkScene(1); +	SetCurrentCameraID(0); +	for (int i = 0; i < 4; i++) +		RenderEffects(0, 0xB+i); +	for (int i = 0; i < 4; i++) +		RenderEffects(0, 7+i);  	GXDrawDone();  	// Leaving out some stuff here  	DrawAllLayoutsAfterX(0x80); diff --git a/src/koopatlas/map.cpp b/src/koopatlas/map.cpp index 4d2bc1d..2486d34 100644 --- a/src/koopatlas/map.cpp +++ b/src/koopatlas/map.cpp @@ -45,7 +45,6 @@ int dWMMap_c::onCreate() {  	renderer.allocator.setup(GameHeaps[0], 0x20);  	bool result = renderer.setup(&renderer.allocator); -	bgMatrix.identity();  	bgMatrix.translation(0.0f, 0.0f, -500.0f);  	allocator.link(-1, GameHeaps[0], 0, 0x20); @@ -112,34 +111,21 @@ void dWMMap_c::renderer_c::drawLayers() {  	beginRendering(); -	bool cont = false;  	for (int iLayer = data->layerCount - 1; iLayer >= 0; iLayer--) {  		dKPLayer_s *layer = data->layers[iLayer];  		renderMtx[2][3] += 2.0f; -		cont = false; -		for (int iNodes = dataCls->pathLayer->nodeCount - 1; iNodes >= 0; iNodes--) { -			dKPNode_s *node = dataCls->pathLayer->nodes[iNodes]; -			bool unlock = node->isUnlocked(); -			if (!unlock) {  -				if (node->tileLayer == layer) { cont = true; break; } -				if (node->doodadLayer == layer) { cont = true; break; } -			} -		} -		for (int iPaths = dataCls->pathLayer->pathCount - 1; iPaths >= 0; iPaths--) { -			dKPPath_s *path = dataCls->pathLayer->paths[iPaths]; -			if (!path->isAvailable) { -				if (path->tileLayer == layer) { cont = true; break; } -				if (path->doodadLayer == layer) { cont = true; break; } -			} -		} +		if (layer->alpha == 0) +			continue; // invisible -		if (cont) { continue; }  		TileReport("Checking layer %d with type %d\n", iLayer, layer->type); + +		GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,layer->alpha}); +  		if (layer->type == dKPLayer_s::OBJECTS) 	 -			renderTileLayer(layer, data->sectors, 255); +			renderTileLayer(layer, data->sectors);  		else if (layer->type == dKPLayer_s::DOODADS) -			renderDoodadLayer(layer, 255); +			renderDoodadLayer(layer);  	}  	endRendering(); @@ -209,7 +195,7 @@ void dWMMap_c::renderer_c::beginRendering() {  	GXSetTevColor(GX_TEVREG1, (GXColor){0,0,0,255});  } -void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors, int alpha) { +void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors) {  	//TileReport("Rendering layer %p\n", layer);  	// don't render it if we don't need to @@ -288,8 +274,6 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector  					float coordY2 = yMult * (tileY + 26.0f); -					GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,alpha}); -  					GXBegin(GX_QUADS, GX_VTXFMT0, 4);  					GXPosition2s16(worldX + 24, worldY - 24);  					GXTexCoord2f32(coordX2, coordY2); @@ -310,7 +294,7 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector  	//TileReport("Layer complete\n");  } -void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer, int alpha) { +void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer) {  	for (int i = 0; i < layer->doodadCount; i++) {  		dKPDoodad_s *doodad = layer->doodads[i];  		DoodadReport("Doodad @ %f,%f sized %f,%f with angle %f\n", doodad->x, doodad->y, doodad->width, doodad->height, doodad->angle); @@ -430,7 +414,6 @@ void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer, int alpha) {  		loadCamera(doodadMtx);  		loadTexture(doodad->texObj); -		GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,alpha});  		GXBegin(GX_QUADS, GX_VTXFMT1, 4);  		GXPosition2f32(halfW, -halfH);  		GXTexCoord2u8(255, 255); diff --git a/src/koopatlas/map.h b/src/koopatlas/map.h index 14c2b87..8d3e2ae 100644 --- a/src/koopatlas/map.h +++ b/src/koopatlas/map.h @@ -42,8 +42,8 @@ class dWMMap_c : public dBase_c {  				void beginRendering();  				void endRendering(); -				void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector, int alpha); -				void renderDoodadLayer(dKPLayer_s *layer, int alpha); +				void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector); +				void renderDoodadLayer(dKPLayer_s *layer);  				void loadTexture(GXTexObj *obj); @@ -55,7 +55,6 @@ class dWMMap_c : public dBase_c {  				float baseZ;  				int minX, minY, maxX, maxY; -				int unlockingAlpha;  		};  		renderer_c renderer; diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp index 650f1e3..63fd0b7 100644 --- a/src/koopatlas/mapdata.cpp +++ b/src/koopatlas/mapdata.cpp @@ -2,17 +2,31 @@  // HELPER FUNCTIONS -dKPPath_s *dKPNode_s::getOppositeExitTo(dKPPath_s *path) { +dKPPath_s *dKPNode_s::getOppositeExitTo(dKPPath_s *path, bool mustBeAvailable) {  	for (int i = 0; i < 4; i++) {  		dKPPath_s *check = exits[i]; -		if (check != 0 && check != path) +		if (check != 0 && check != path) { +			if (mustBeAvailable && !check->isAvailable) +				continue; +  			return check; +		}  	}  	return 0;  } +int dKPNode_s::getExitCount(bool mustBeAvailable) { +	int ct = 0; + +	for (int i = 0; i < 4; i++) +		if (exits[i] && (mustBeAvailable ? exits[i]->isAvailable : true)) +			ct++; + +	return ct; +} +  bool dKPNode_s::isUnlocked() {  	for (int i = 0; i < 4; i++)  		if (exits[i])  @@ -89,6 +103,20 @@ void dKPNode_s::setupNodeExtra() {  	this->extra->mallocator.unlink();  } +void dKPNode_s::setLayerAlpha(u8 alpha) { +	if (tileLayer) +		tileLayer->alpha = alpha; +	if (doodadLayer) +		doodadLayer->alpha = alpha; +} + +void dKPPath_s::setLayerAlpha(u8 alpha) { +	if (tileLayer) +		tileLayer->alpha = alpha; +	if (doodadLayer) +		doodadLayer->alpha = alpha; +} +  int dKPLayer_s::findNodeID(dKPNode_s *node) {  	for (int i = 0; i < nodeCount; i++)  		if (nodes[i] == node) diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index 48a1720..40e1a43 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -70,6 +70,8 @@ struct dKPNode_s {  	NodeTypes type; +	bool isNew; +  	dKPNodeExtra_c *extra;  	// The union is placed at the very end so we can leave out padding in the @@ -89,24 +91,37 @@ struct dKPNode_s {  	bool isUnlocked();  	void setupNodeExtra(); -	dKPPath_s *getOppositeExitTo(dKPPath_s *path); +	dKPPath_s *getOppositeExitTo(dKPPath_s *path, bool mustBeAvailable=false); +	dKPPath_s *getOppositeAvailableExitTo(dKPPath_s *path) { +		return getOppositeExitTo(path, true); +	} + +	int getExitCount(bool mustBeAvailable=false); +	int getAvailableExitCount() { +		return getExitCount(true); +	} + +	void setLayerAlpha(u8 alpha);  };  struct dKPPath_s {  	enum Availability {  		NOT_AVAILABLE = 0,  		AVAILABLE = 1, -		NEWLY_AVAILABLE = 2 +		NEWLY_AVAILABLE = 2, +		ALWAYS_AVAILABLE = 3  	};  	dKPNode_s *start, *end;  	dKPLayer_s *tileLayer, *doodadLayer; -	u8 isAvailable; // computed on-the-fly - default from Koopatlas is 1 -	u8 hasSecret; +	u8 isAvailable; // computed on-the-fly - default from Koopatlas is NOT or ALWAYS +	u8 isSecret;  	u8 _padding[2];  	float speed;  	int animation; + +	void setLayerAlpha(u8 alpha);  };  /****************************************************************************** @@ -118,6 +133,8 @@ struct dKPLayer_s {  	};  	LayerTypes type; +	u8 alpha; +	u8 _padding[3];  	typedef u16 sector_s[16][16]; @@ -180,7 +197,7 @@ class dKPMapData_c {  		template <typename T>  			inline T* fixRef(T*& indexAsPtr) {  				unsigned int index = (unsigned int)indexAsPtr; -				if (index == 0xFFFFFFFF) +				if (index == 0xFFFFFFFF || index == 0)  					indexAsPtr = 0;  				else  					indexAsPtr = (T*)(((char*)data) + index); @@ -190,7 +207,7 @@ class dKPMapData_c {  		template <typename T>  			inline T* fixRefSafe(T*& indexAsPtr) {  				unsigned int index = (unsigned int)indexAsPtr; -				if (index == 0xFFFFFFFF) +				if (index == 0xFFFFFFFF || index == 0)  					indexAsPtr = 0;  				else if (index < 0x80000000)  					indexAsPtr = (T*)(((char*)data) + index); diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 4eb6c2d..ee7b596 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -68,21 +68,40 @@ void dWMPathManager_c::setup() {  }  static u8 *PathAvailabilityData = 0; +static u8 *NodeAvailabilityData = 0;  dWMPathManager_c::~dWMPathManager_c() {  	if (PathAvailabilityData && !isEnteringLevel) {  		delete[] PathAvailabilityData;  		PathAvailabilityData = 0; + +		delete[] NodeAvailabilityData; +		NodeAvailabilityData = 0;  	}  }  void dWMPathManager_c::unlockPaths() { -	u8 *oldAvData = PathAvailabilityData; +	u8 *oldPathAvData = PathAvailabilityData;  	PathAvailabilityData = new u8[pathLayer->pathCount]; +	u8 *oldNodeAvData = NodeAvailabilityData; +	NodeAvailabilityData = new u8[pathLayer->nodeCount]; + +	OSReport("Unlocking paths\n"); +  	// unlock all needed paths -	for (int i = 0; i < pathLayer->pathCount; i++) -		PathAvailabilityData[i] = dKPPath_s::NOT_AVAILABLE; +	for (int i = 0; i < pathLayer->pathCount; i++) { +		dKPPath_s *path = pathLayer->paths[i]; + +		PathAvailabilityData[i] = path->isAvailable; + +		//OSReport("Path %d: %d\n", i, path->isAvailable); +		// if this path is not "always available", then nuke its alpha +		path->setLayerAlpha((path->isAvailable == dKPPath_s::ALWAYS_AVAILABLE) ? 255 : 0); +	} + +	for (int i = 0; i < pathLayer->nodeCount; i++) +		NodeAvailabilityData[i] = pathLayer->nodes[i]->isUnlocked();  	SaveBlock *save = GetSaveFile()->GetBlock(-1); @@ -91,6 +110,7 @@ void dWMPathManager_c::unlockPaths() {  	while (*in != 0) {  		// begin processing a block  		bool value = evaluateUnlockCondition(in, save); +		//OSReport("Unlock condition: %d\n", value);  		// get what it's supposed to affect  		// for now we'll assume that it affects one or more paths @@ -102,27 +122,55 @@ void dWMPathManager_c::unlockPaths() {  			u16 pathID = (one << 8) | two;  			dKPPath_s *path = pathLayer->paths[pathID]; -			path->isAvailable = dKPPath_s::AVAILABLE; -			PathAvailabilityData[pathID] = dKPPath_s::AVAILABLE; +			path->isAvailable = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE; +			PathAvailabilityData[pathID] = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE; +			//OSReport("Applied to path %p[%d]\n", path, pathID);  			// NEWLY_AVAILABLE is set later, when that stuff is figured out + +			path->setLayerAlpha(value ? 255 : 0);  		}  	}  	// did anything become newly available?! -	int whatsNew = 0; +	newlyAvailablePaths = 0; +	newlyAvailableNodes = 0; -	if (oldAvData) { +	if (oldPathAvData) {  		for (int i = 0; i < pathLayer->pathCount; i++) { -			if ((PathAvailabilityData[i] > 0) && (oldAvData[i] == 0)) { +			if ((PathAvailabilityData[i] > 0) && (oldPathAvData[i] == 0)) {  				dKPPath_s *path = pathLayer->paths[i];  				path->isAvailable = dKPPath_s::NEWLY_AVAILABLE; -				whatsNew++; +				newlyAvailablePaths++; + +				// set this path's alpha to 0, we'll fade it in later +				path->setLayerAlpha(0);  			}  		} -		delete[] oldAvData; +		delete[] oldPathAvData; + +		// check nodes too +		for (int i = 0; i < pathLayer->nodeCount; i++) { +			if ((NodeAvailabilityData[i] > 0) && (oldNodeAvData[i] == 0)) { +				dKPNode_s *node = pathLayer->nodes[i]; +				node->isNew = true; +				newlyAvailableNodes++; +			} +		} +		delete[] oldNodeAvData; +	} + +	// now set all node alphas +	for (int i = 0; i < pathLayer->nodeCount; i++) { +		dKPNode_s *node = pathLayer->nodes[i]; +		 +		node->setLayerAlpha((node->isUnlocked() & !node->isNew) ? 255 : 0);  	} -	// todo: set a flag on Map to do the path fade/sound, with whatsNew +	// if anything was new, set it as such +	if (newlyAvailablePaths || newlyAvailableNodes) { +		countdownToFadeIn = 30; +	} +	unlockingAlpha = -1;  }  bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save) { @@ -186,6 +234,36 @@ void dWMPathManager_c::execute() {  		else if (nowPressed & WPAD_TWO)  			activatePoint();  	} + +	// handle path fading +	if (countdownToFadeIn > 0) { +		countdownToFadeIn--; +		if (countdownToFadeIn <= 0) +			unlockingAlpha = 0; +	} + +	if (unlockingAlpha != -1) { +		unlockingAlpha += 3; + +		for (int i = 0; i < pathLayer->pathCount; i++) { +			dKPPath_s *path = pathLayer->paths[i]; + +			if (path->isAvailable == dKPPath_s::NEWLY_AVAILABLE) +				path->setLayerAlpha(unlockingAlpha); +		} + +		for (int i = 0; i < pathLayer->nodeCount; i++) { +			dKPNode_s *node = pathLayer->nodes[i]; +			 +			if (node->isNew) +				node->setLayerAlpha(unlockingAlpha); +		} + +		if (unlockingAlpha == 255) { +			// we've reached the end +			unlockingAlpha = -1; +		} +	}  } @@ -404,6 +482,16 @@ void dWMPathManager_c::moveThroughPath() {     		SpammyReport("reached path end (%p)\n", to); +   		// Quick check: do we *actually* need to stop on this node? +   		// If it's a junction with more than two exits, but only two are open, +   		// take the opposite open one +   		bool stopOverride = false; + +   		if (to->type == dKPNode_s::STOP) { +   			if (to->getExitCount() > 2 && to->getAvailableExitCount() == 2) +   				stopOverride = true; +		} +  		if (to->type == dKPNode_s::CHANGE) {  			// Go to another map  			isMoving = false; @@ -415,7 +503,7 @@ void dWMPathManager_c::moveThroughPath() {  			DoSceneChange(WORLD_MAP, 0x10000000 | to->foreignID, 0); -		} else if (to->type != dKPNode_s::PASS_THROUGH) { +		} else if (to->type != dKPNode_s::PASS_THROUGH && !stopOverride) {  	   		// Stop here  	   		player->startAnimation(0, 1.2, 10.0, 0.0);  	   		player->hasEffect = false; @@ -431,7 +519,7 @@ void dWMPathManager_c::moveThroughPath() {  			dWMHud_c::instance->showPointBar();  			SpammyReport("Point bar shown\n");  		} else { -			startMovementTo(to->getOppositeExitTo(currentPath)); +			startMovementTo(to->getOppositeAvailableExitTo(currentPath));  			SpammyReport("passthrough node, continuing to next path\n");  		}  	} diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h index 5d35f4c..2ce0e9c 100644 --- a/src/koopatlas/pathmanager.h +++ b/src/koopatlas/pathmanager.h @@ -14,6 +14,8 @@ class dWMPathManager_c {  		void execute();  		bool canUseExit(dKPPath_s *path) { +			OSReport("Checking usability of path %p\n", path); +			if (path) OSReport("Availability: %d\n", path->isAvailable);  			return (path != 0) && (path->isAvailable);  		} @@ -38,6 +40,12 @@ class dWMPathManager_c {  		bool mustComplainToMapCreator; +		int newlyAvailablePaths; +		int newlyAvailableNodes; + +		int unlockingAlpha; // -1 if not used +		int countdownToFadeIn; +  	private:  		void unlockPaths();  		bool evaluateUnlockCondition(u8 *&in, SaveBlock *save); | 
