diff options
| author | Treeki <treeki@gmail.com> | 2012-09-24 05:40:39 +0200 | 
|---|---|---|
| committer | Treeki <treeki@gmail.com> | 2012-09-24 05:40:39 +0200 | 
| commit | 245bb3325f613f81973866100e86ee681b0fde9d (patch) | |
| tree | 7837866a91fc6c422ffb9b730c2fdbbb6577ea53 /src | |
| parent | aafa2a57c88c01067266244eae2a906d8771c065 (diff) | |
| parent | 4f567256d015cf7a835ac03b9e5abb8a2a7eb12a (diff) | |
| download | kamek-245bb3325f613f81973866100e86ee681b0fde9d.tar.gz kamek-245bb3325f613f81973866100e86ee681b0fde9d.zip | |
Merge branch 'level-select' into new-hud
Diffstat (limited to '')
| -rw-r--r-- | src/apDebug.cpp | 222 | ||||
| -rw-r--r-- | src/koopatlas/core.cpp | 9 | ||||
| -rw-r--r-- | src/koopatlas/core.h | 2 | ||||
| -rw-r--r-- | src/koopatlas/map.cpp | 10 | ||||
| -rw-r--r-- | src/koopatlas/map.h | 2 | ||||
| -rw-r--r-- | src/koopatlas/mapdata.h | 11 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 335 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.h | 13 | ||||
| -rw-r--r-- | src/koopatlas/player.cpp | 8 | ||||
| -rw-r--r-- | src/koopatlas/player.h | 181 | ||||
| -rw-r--r-- | src/randomcrap.S | 44 | ||||
| -rw-r--r-- | src/shyguy.cpp | 15 | ||||
| -rwxr-xr-x | src/spritetex.S | 26 | 
13 files changed, 526 insertions, 352 deletions
| diff --git a/src/apDebug.cpp b/src/apDebug.cpp new file mode 100644 index 0000000..f534e58 --- /dev/null +++ b/src/apDebug.cpp @@ -0,0 +1,222 @@ +#include <game.h> +#define GEKKO +#include "rvl/mtx.h" +#include "rvl/GXEnum.h" +#include "rvl/GXStruct.h" +#include "rvl/GXTransform.h" +#include "rvl/GXGeometry.h" +#include "rvl/GXDispList.h" +#include "rvl/GXLighting.h" +#include "rvl/GXTev.h" +#include "rvl/GXTexture.h" +#include "rvl/GXCull.h" +#include "rvl/GXPixel.h" +#include "rvl/GXBump.h" +#include "rvl/GXVert.h" +#include "rvl/vifuncs.h" + +class APDebugDrawer : public m3d::proc_c { +	public: +		APDebugDrawer(); + +		bool amISetUp; +		mHeapAllocator_c allocator; + +		void setMeUp(); + +		void drawMe(); + +		void drawOpa(); +		void drawXlu(); +}; + + +static APDebugDrawer defaultInstance; + +int APDebugDraw() { +	defaultInstance.drawMe(); +	return 1; +} + + +APDebugDrawer::APDebugDrawer() { +	amISetUp = false; +} + +void APDebugDrawer::setMeUp() { +	allocator.setup(GameHeaps[0], 0x20); +	setup(&allocator); +} + +void APDebugDrawer::drawMe() { +	if (!amISetUp) { +		setMeUp(); +		amISetUp = true; +	} + +	scheduleForDrawing(); +} + +void APDebugDrawer::drawOpa() { +} +void APDebugDrawer::drawXlu() { +	GXClearVtxDesc(); + +	GXSetVtxDesc(GX_VA_POS, GX_DIRECT); +	GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + +	GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); +	GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + +	GXSetNumIndStages(0); +	for (int i = 0; i < 0x10; i++) +		GXSetTevDirect((GXTevStageID)i); + +	GXSetNumChans(1); +	GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); +	GXSetChanAmbColor(GX_COLOR0A0, (GXColor){255,255,255,255}); +	GXSetChanMatColor(GX_COLOR0A0, (GXColor){255,255,255,255}); +	GXSetNumTexGens(0); + +	GXSetNumTevStages(1); +	GXSetNumIndStages(0); + +	GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + +	GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); +	GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); +//	GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, GX_CC_C0, GX_CC_RASC, GX_CC_ZERO); +//	GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); +//	GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_RASA, GX_CA_ZERO); +//	GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + +	GXSetZCompLoc(GX_FALSE); +	GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); +	GXSetZMode(GX_TRUE, GX_LEQUAL, GX_FALSE); +	GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); + +	GXSetFog(GX_FOG_NONE, 0, 0, 0, 0, (GXColor){0,0,0,0}); +	GXSetFogRangeAdj(GX_FALSE, 0, 0); + +	GXSetCullMode(GX_CULL_NONE); + +	GXSetDither(GX_TRUE); +	GXSetLineWidth(18, GX_TO_ZERO); + +	GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,255}); +	GXSetTevColor(GX_TEVREG1, (GXColor){0,0,0,255}); + +	ActivePhysics *ap = ActivePhysics::globalListHead; + +	while (ap) { +		u32 uptr = (u32)ap; +		u8 r = (uptr>>16)&0xFF; +		u8 g = (uptr>>8)&0xFF; +		u8 b = uptr&0xFF; +		u8 a = 0xFF; + +		GXBegin(GX_LINES, GX_VTXFMT0, 10); + +		float centreX = ap->owner->pos.x + ap->info.xDistToCenter; +		float centreY = ap->owner->pos.y + ap->info.yDistToCenter; +		float edgeDistX = ap->info.xDistToEdge; +		float edgeDistY = ap->info.yDistToEdge; + +		float tlX = centreX - edgeDistX, tlY = centreY + edgeDistY; +		float trX = centreX + edgeDistX, trY = centreY + edgeDistY; + +		float blX = centreX - edgeDistX, blY = centreY - edgeDistY; +		float brX = centreX + edgeDistX, brY = centreY - edgeDistY; + +		// Top +		GXPosition3f32(tlX, tlY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(trX, trY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Left +		GXPosition3f32(tlX, tlY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(blX, blY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Right +		GXPosition3f32(trX, trY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(brX, brY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Bottom +		GXPosition3f32(blX, blY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(brX, brY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Diagonal +		GXPosition3f32(trX, trY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(blX, blY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		GXEnd(); + +		ap = ap->listPrev; +	} + +	Physics *p = Physics::globalListHead; + +	while (p) { +		u32 uptr = (u32)p; +		u8 r = (uptr>>16)&0xFF; +		u8 g = (uptr>>8)&0xFF; +		u8 b = uptr&0xFF; +		u8 a = 0xFF; + +		GXBegin(GX_LINES, GX_VTXFMT0, 10); + +		float centreX = p->owner->pos.x; +		float centreY = p->owner->pos.y; +		float edgeDistX = p->_88; +		float edgeDistY = p->_8C; + +		float tlX = centreX + p->x, tlY = centreY + p->y; +		float trX = centreX + p->_88, trY = centreY + p->y; + +		float blX = centreX + p->x, blY = centreY + p->_8C; +		float brX = centreX + p->_88, brY = centreY + p->_8C; + +		// Top +		GXPosition3f32(tlX, tlY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(trX, trY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Left +		GXPosition3f32(tlX, tlY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(blX, blY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Right +		GXPosition3f32(trX, trY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(brX, brY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Bottom +		GXPosition3f32(blX, blY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(brX, brY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		// Diagonal +		GXPosition3f32(trX, trY, 8000.0f); +		GXColor4u8(r,g,b,a); +		GXPosition3f32(blX, blY, 8000.0f); +		GXColor4u8(r,g,b,a); + +		GXEnd(); + +		p = p->next; +	} +} diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index 164ea89..c20d715 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -46,6 +46,7 @@ dScKoopatlas_c *dScKoopatlas_c::build() {  }  bool WMInit_StartLoading(void*); +bool StockWMInit_LoadEffects(void*);  bool WMInit_LoadSIAnims(void*);  bool WMInit_EndLoading(void*);  bool WMInit_LoadResources1(void*); @@ -56,6 +57,7 @@ bool WMInit_SetupWipe(void*);  ChainedFunc initFunctions[] = {  	WMInit_StartLoading, +	StockWMInit_LoadEffects,  	WMInit_LoadSIAnims,  	WMInit_EndLoading,  	WMInit_LoadResources1, @@ -409,6 +411,11 @@ int dScKoopatlas_c::onDelete() {  	FreeScene(0);  	FreeScene(1); +	CleanUpEffectThings(); +	FreeEffects(1); +	FreeBreff(1); +	FreeBreft(1); +  	DVD_FreeFile(GetDVDClass2(), "SI_kinoko");  	DVD_FreeFile(GetDVDClass2(), "SI_fireflower");  	DVD_FreeFile(GetDVDClass2(), "SI_iceflower"); @@ -419,6 +426,8 @@ int dScKoopatlas_c::onDelete() {  	levelInfoLoader.unload();  	mapListLoader.unload(); +	CleanUpEffectThings(); +  	return true;  } diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h index 2a69927..41fba45 100644 --- a/src/koopatlas/core.h +++ b/src/koopatlas/core.h @@ -18,7 +18,7 @@  #include "koopatlas/pathmanager.h"  #define WM_DEBUGGING -// #define WM_SPAMMY_DEBUGGING +#define WM_SPAMMY_DEBUGGING  #ifdef WM_DEBUGGING  #define MapReport OSReport diff --git a/src/koopatlas/map.cpp b/src/koopatlas/map.cpp index 316c001..ff28e19 100644 --- a/src/koopatlas/map.cpp +++ b/src/koopatlas/map.cpp @@ -62,6 +62,12 @@ int dWMMap_c::onCreate() {  	bgSrtAnm.bindEntry(&bgModel, anmRes, 0, 0);  	bgModel.bindAnim(&bgSrtAnm, 0.0f); +	static int EffectGroups[] = {1,0,4,5,7,8,9,10,11,12,13,14}; +	static int EffectPrios[] = {141,142,143,129,144,145,146,147,148,149,150,151}; +	for (int i = 0; i < EFFECT_RENDERER_COUNT; i++) { +		effectRenderers[i].setupEffectRenderer(&allocator, -1, EffectPrios[i], EffectGroups[i]); +	} +  	allocator.unlink();  	return true; @@ -83,6 +89,10 @@ int dWMMap_c::onDraw() {  	renderer.scheduleForDrawing();  	bgModel.scheduleForDrawing(); +	for (int i = 0; i < EFFECT_RENDERER_COUNT; i++) { +		effectRenderers[i].scheduleForDrawing(); +	} +  	dKPMapData_c *dataCls = &dScKoopatlas_c::instance->mapData;  	renderPathLayer(dataCls->pathLayer); diff --git a/src/koopatlas/map.h b/src/koopatlas/map.h index 8d3e2ae..82bee1f 100644 --- a/src/koopatlas/map.h +++ b/src/koopatlas/map.h @@ -58,6 +58,8 @@ class dWMMap_c : public dBase_c {  		};  		renderer_c renderer; +		enum EffRenderCount { EFFECT_RENDERER_COUNT = 12 }; +		BGGMEffectRenderer effectRenderers[EFFECT_RENDERER_COUNT];  		mHeapAllocator_c allocator;  		m3d::mdl_c bgModel; diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index 70c31ee..bc0c599 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -112,6 +112,15 @@ struct dKPPath_s {  		ALWAYS_AVAILABLE = 3  	}; +	enum Animation { +		WALK = 0, WALK_SAND = 1, WALK_SNOW = 2, WALK_WATER = 3, +		JUMP = 4, JUMP_SAND = 5, JUMP_SNOW = 6, JUMP_WATER = 7, +		LADDER = 8, LADDER_LEFT = 9, LADDER_RIGHT = 10, FALL = 11, +		SWIM = 12, RUN = 13, PIPE = 14, DOOR = 15, +		TJUMPED = 16, ENTER_CAVE_UP = 17, RESERVED_18 = 18, INVISIBLE = 19, +		MAX_ANIM = 20 +	}; +  	dKPNode_s *start, *end;  	dKPLayer_s *tileLayer, *doodadLayer; @@ -119,7 +128,7 @@ struct dKPPath_s {  	u8 isSecret;  	u8 _padding[2];  	float speed; -	int animation; +	Animation animation;  	void setLayerAlpha(u8 alpha);  }; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 9525732..e42246e 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -7,6 +7,7 @@  void dWMPathManager_c::setup() {  	isMoving = false;  	isJumping = false; +	scaleAnimProgress = -1;  	timer = 0.0;  	currentPath = 0;  	reverseThroughPath = false; @@ -20,6 +21,7 @@ void dWMPathManager_c::setup() {  	SpammyReport("Unlocking paths\n");  	isEnteringLevel = false; +	levelStartWait = -1;  	unlockPaths();  	SpammyReport("done\n"); @@ -61,7 +63,7 @@ void dWMPathManager_c::setup() {  						//OSReport("Path: %p nodes %p to %p\n", path, srcNode, destNode);  						int ct = destNode->getAvailableExitCount();  						//OSReport("Dest Node available exits: %d; type: %d\n", ct, destNode->type); -						if (destNode == node || ct > 2 || destNode->type == dKPNode_s::LEVEL) { +						if (destNode == node || ct > 2 || destNode->type == dKPNode_s::LEVEL || destNode->type == dKPNode_s::CHANGE) {  							exitTo = candidateExit;  							//OSReport("Accepting this node\n");  							break; @@ -151,36 +153,36 @@ void dWMPathManager_c::unlockPaths() {  	int cmdID = 0;  	while (*in != 0) { -		SpammyReport("[%p] Cmd %d: Evaluating condition\n", in, cmdID); +		UnlockCmdReport("[%p] Cmd %d: Evaluating condition\n", in, cmdID);  		// begin processing a block  		bool value = evaluateUnlockCondition(in, save, 0); -		SpammyReport("[%p] Cmd %d: Condition evaluated, result: %d\n", in, cmdID, value); -		//SpammyReport("Unlock condition: %d\n", value); +		UnlockCmdReport("[%p] Cmd %d: Condition evaluated, result: %d\n", in, cmdID, value); +		//UnlockCmdReport("Unlock condition: %d\n", value);  		// get what it's supposed to affect  		// for now we'll assume that it affects one or more paths  		u8 affectedCount = *(in++); -		SpammyReport("[%p] Cmd %d: Affects %d path(s)\n", in, cmdID, affectedCount); +		UnlockCmdReport("[%p] Cmd %d: Affects %d path(s)\n", in, cmdID, affectedCount);  		for (int i = 0; i < affectedCount; i++) {  			u8 one = *(in++);  			u8 two = *(in++);  			u16 pathID = (one << 8) | two; -			SpammyReport("[%p] Cmd %d: Affected %d: PathID: %d\n", in, cmdID, i, pathID); +			UnlockCmdReport("[%p] Cmd %d: Affected %d: PathID: %d\n", in, cmdID, i, pathID);  			dKPPath_s *path = pathLayer->paths[pathID]; -			SpammyReport("[%p] Cmd %d: Affected %d: Path: %p\n", in, cmdID, i, path); +			UnlockCmdReport("[%p] Cmd %d: Affected %d: Path: %p\n", in, cmdID, i, path);  			path->isAvailable = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE; -			SpammyReport("[%p] Cmd %d: Affected %d: IsAvailable written\n", in, cmdID, i); +			UnlockCmdReport("[%p] Cmd %d: Affected %d: IsAvailable written\n", in, cmdID, i);  			PathAvailabilityData[pathID] = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE; -			SpammyReport("[%p] Cmd %d: Affected %d: AvailabilityData written\n", in, cmdID, i); +			UnlockCmdReport("[%p] Cmd %d: Affected %d: AvailabilityData written\n", in, cmdID, i);  			// NEWLY_AVAILABLE is set later, when that stuff is figured out  			path->setLayerAlpha(value ? 255 : 0); -			SpammyReport("[%p] Cmd %d: Affected %d: Layer alpha applied\n", in, cmdID, i); +			UnlockCmdReport("[%p] Cmd %d: Affected %d: Layer alpha applied\n", in, cmdID, i);  		} -		SpammyReport("[%p] Cmd %d: %d affected path(s) processed\n", in, cmdID, affectedCount); +		UnlockCmdReport("[%p] Cmd %d: %d affected path(s) processed\n", in, cmdID, affectedCount);  		cmdID++;  	} @@ -230,14 +232,14 @@ void dWMPathManager_c::unlockPaths() {  }  bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int stack) { -	SpammyReport("[%p] CondStk:%d begin\n", in, stack); +	UnlockCmdReport("[%p] CondStk:%d begin\n", in, stack);  	u8 controlByte = *(in++);  	u8 conditionType = (controlByte >> 6); -	SpammyReport("[%p] CondStk:%d control byte: %d; condition type: %d\n", in, stack, controlByte, conditionType); +	UnlockCmdReport("[%p] CondStk:%d control byte: %d; condition type: %d\n", in, stack, controlByte, conditionType);  	if (conditionType == 0) { -		SpammyReport("[%p] CondStk:%d end, returning CONSTANT 1\n", in, stack); +		UnlockCmdReport("[%p] CondStk:%d end, returning CONSTANT 1\n", in, stack);  		return true;  	} @@ -247,10 +249,10 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta  		bool isSecret = (controlByte & 0x10);  		u8 worldNumber = controlByte & 0xF;  		u8 levelNumber = *(in++); -		SpammyReport("[%p] CondStk:%d level, w:%d l:%d secret:%d\n", in, stack, worldNumber, levelNumber, isSecret); +		UnlockCmdReport("[%p] CondStk:%d level, w:%d l:%d secret:%d\n", in, stack, worldNumber, levelNumber, isSecret);  		u32 conds = save->GetLevelCondition(worldNumber, levelNumber); -		SpammyReport("[%p] CondStk:%d returning for level conditions: %d / %x\n", in, stack, conds, conds); +		UnlockCmdReport("[%p] CondStk:%d returning for level conditions: %d / %x\n", in, stack, conds, conds);  		if (isSecret)  			return (conds & COND_SECRET) != 0; @@ -265,7 +267,7 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta  	bool value = isOr ? false : true;  	u8 termCount = (controlByte & 0x3F) + 1; -	SpammyReport("[%p] CondStk:%d and:%d or:%d startValue:%d termCount:%d\n", in, stack, isAnd, isOr, value, termCount); +	UnlockCmdReport("[%p] CondStk:%d and:%d or:%d startValue:%d termCount:%d\n", in, stack, isAnd, isOr, value, termCount);  	for (int i = 0; i < termCount; i++) {  		bool what = evaluateUnlockCondition(in, save, stack+1); @@ -276,27 +278,20 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta  			value &= what;  	} -	SpammyReport("[%p] CondStk:%d end, returning %d\n", in, stack, value); +	UnlockCmdReport("[%p] CondStk:%d end, returning %d\n", in, stack, value);  	return value;  }  void dWMPathManager_c::execute() { -	int nowPressed = Remocon_GetPressed(GetActiveRemocon()); - -	if (isMoving) { -		moveThroughPath(); -	} else { -		if (nowPressed & WPAD_LEFT && canUseExit(currentNode->leftExit)) -			startMovementTo(currentNode->leftExit); -		else if (nowPressed & WPAD_RIGHT && canUseExit(currentNode->rightExit)) -			startMovementTo(currentNode->rightExit); -		else if (nowPressed & WPAD_UP && canUseExit(currentNode->upExit)) -			startMovementTo(currentNode->upExit); -		else if (nowPressed & WPAD_DOWN && canUseExit(currentNode->downExit)) -			startMovementTo(currentNode->downExit); -		else if (nowPressed & WPAD_TWO) -			activatePoint(); +	if (isEnteringLevel) { +		if (levelStartWait > 0) { +			levelStartWait--; +			if (levelStartWait == 0) { +				dScKoopatlas_c::instance->startLevel(enteredLevel); +			} +		} +		return;  	}  	// handle path fading @@ -305,6 +300,8 @@ void dWMPathManager_c::execute() {  		if (countdownToFadeIn <= 0) {  			unlockingAlpha = 0;  			MapSoundPlayer(SoundRelatedClass, SE_SYS_NEW_POINT, 1); +		} else { +			return;  		}  	} @@ -329,13 +326,46 @@ void dWMPathManager_c::execute() {  			// we've reached the end  			unlockingAlpha = -1;  			MapSoundPlayer(SoundRelatedClass, SE_SYS_NEW_POINT_END, 1); +			waitAfterUnlock = 15; +		} + +		return; +	} + +	if (waitAfterUnlock > 0) { +		waitAfterUnlock--; +		return; +	} + +	int nowPressed = Remocon_GetPressed(GetActiveRemocon()); + +	if (isMoving) { +		moveThroughPath(); +	} else { +		// Left, right, up, down +		int pressedDir = -1; +		if (nowPressed & WPAD_LEFT) pressedDir = 0; +		else if (nowPressed & WPAD_RIGHT) pressedDir = 1; +		else if (nowPressed & WPAD_UP) pressedDir = 2; +		else if (nowPressed & WPAD_DOWN) pressedDir = 3; +		else if (nowPressed & WPAD_TWO) +			activatePoint(); + +		if (pressedDir >= 0) { +			if (canUseExit(currentNode->exits[pressedDir])) { +				startMovementTo(currentNode->exits[pressedDir]); +			} else { +				// TODO: maybe remove this? got to see how it looks +				static u16 directions[] = {-0x4000,0x4000,-0x7FFF,0}; +				daWMPlayer_c::instance->rot.y = directions[pressedDir]; +			}  		}  	}  }  void dWMPathManager_c::startMovementTo(dKPPath_s *path) { -	SpammyReport("moving to path %p\n", path); +	SpammyReport("moving to path %p [%d,%d to %d,%d]\n", path, path->start->x, path->start->y, path->end->x, path->end->y);  	if (!path->isAvailable) { return; }  	if (currentNode) @@ -375,131 +405,94 @@ void dWMPathManager_c::startMovementTo(dKPPath_s *path) {  	// hang_walk_l = 65,  	// hang_walk_r = 66, -	SpammyReport("h\n"); -	player->rot.y = direction; -	player->hasSound = false; -	player->hasEffect = false; -	moveSpeed = 3.0f; - -	switch (path->animation) { - -		// Running -		case 0: -			player->startAnimation(run, 2.0, 10.0, 0.0); -			player->hasSound = true; -			player->soundName = SE_PLY_FOOTNOTE_DIRT; -			break; -		case 1: -			player->startAnimation(run, 2.0, 10.0, 0.0); -			player->hasSound = true; -			player->hasEffect = true; -			player->soundName = SE_PLY_FOOTNOTE_CS_SAND; -			player->effectName = "Wm_mr_foot_sand"; -			break; -		case 2: -			player->startAnimation(run, 2.0, 10.0, 0.0); -			player->hasSound = true; -			player->hasEffect = true; -			player->soundName = SE_PLY_FOOTNOTE_CS_SNOW; -			player->effectName = "Wm_mr_foot_snow"; -			break; -		case 3: -			player->startAnimation(run, 2.0, 10.0, 0.0); -			player->hasSound = true; -			player->hasEffect = true; -			player->soundName = SE_PLY_FOOTNOTE_CS_WATER; -			player->effectName = "Wm_mr_foot_water"; -			break; +	static const struct { +		PlayerAnim anim; +		float animParam1, animParam2; +		s16 forceRotation; +		float forceSpeed; +		SFX repeatSound, initialSound; +		const char *repeatEffect, *initialEffect; +	} Animations[] = { +		// Walking +		{run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_DIRT,SE_NULL, 0,0}, +		{run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_CS_SAND,SE_NULL, "Wm_mr_foot_sand",0}, +		{run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_CS_SNOW,SE_NULL, "Wm_mr_foot_snow",0}, +		{run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_CS_WATER,SE_NULL, "Wm_mr_foot_water",0},  		// Jumping -		case 4: -			player->startAnimation(jump, 1.0, 1.0, 0.0); -			MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1); -			isJumping = true; -			moveSpeed = 2.5f; -			break; -		case 5: -			player->startAnimation(jump, 1.0, 10.0, 0.0); -			MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1); -			isJumping = true; -			moveSpeed = 2.5f; -			break; -		case 6: -			player->startAnimation(jump, 1.0, 10.0, 0.0); -			MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1); -			isJumping = true; -			moveSpeed = 2.5f; -			break; -		case 7: -			player->startAnimation(jump, 1.0, 10.0, 0.0); -			MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1); -			isJumping = true; -			SpawnEffect("Wm_mr_waterwave_out", 0, &player->pos, 0, &player->scale); -			moveSpeed = 2.0f; -			break; - -		// Climbing -		case 8: -			player->startAnimation(pea_plant, 1.2, 10.0, 0.0); -			player->rot.y = 0x8000; -			player->hasSound = true; -			player->soundName = SE_PLY_FOOTNOTE_CS_ROCK_CLIMB; -			moveSpeed = 1.5f; -			break; -		case 9: -			player->startAnimation(tree_climb, 1.2, 10.0, 0.0); -			player->rot.y = 0xC000; -			player->hasSound = true; -			player->soundName = SE_PLY_FOOTNOTE_CS_ROCK_CLIMB; -			moveSpeed = 1.5f; -			break; -		case 10: -			player->startAnimation(tree_climb, 1.2, 10.0, 0.0); -			player->rot.y = 0x4000; -			player->hasSound = true; -			player->soundName = SE_PLY_FOOTNOTE_CS_ROCK_CLIMB; -			moveSpeed = 1.5f; -			break; - -		// Others -		case 12: -			player->startAnimation(swim_wait, 1.2, 10.0, 0.0); -			player->hasSound = true; -			player->hasEffect = true; -			player->soundName = SE_PLY_SWIM; -			player->effectName = "Wm_mr_waterswim"; -			moveSpeed = 2.0f; -			break; -		case 13: -			player->startAnimation(b_dash2, 3.0, 10.0, 0.0); -			player->hasSound = true; -			player->soundName = SE_PLY_FOOTNOTE_DIRT; -			moveSpeed = 5.0f; -			break; -		case 14: -			player->startAnimation(wait, 2.0, 10.0, 0.0); -			player->rot.y = 0x0000; -			MapSoundPlayer(SoundRelatedClass, SE_PLY_DOKAN_IN_OUT, 1); -			moveSpeed = 1.0f; -			break; -		case 15: -			player->startAnimation(wait, 2.0, 10.0, 0.0); -			player->rot.y = 0x8000;			 -			MapSoundPlayer(SoundRelatedClass, SE_OBJ_DOOR_OPEN, 1); -			moveSpeed = 0.2f; -			break; -		case 16: -			player->startAnimation(Tjumped, 2.0, 0.0, 0.0); -			break; -		default: -			SpammyReport("No animtaion?!"); -			player->startAnimation(run, 2.0, 10.0, 0.0); -			player->hasSound = true; -			player->soundName = SE_PLY_FOOTNOTE_DIRT; -			break; +		{jump,1.0f,1.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,0}, +		{jump,1.0f,10.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,0}, +		{jump,1.0f,10.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,0}, +		{jump,1.0f,10.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,"Wm_mr_waterwave_out"}, + +		// Ladder up, left, right +		{pea_plant,1.2f,10.0f, -0x7FFF,1.5f, SE_PLY_FOOTNOTE_CS_ROCK_CLIMB,SE_NULL, 0,0}, +		{tree_climb,1.2f,10.0f, -0x4000,1.5f, SE_PLY_FOOTNOTE_CS_ROCK_CLIMB,SE_NULL, 0,0}, +		{tree_climb,1.2f,10.0f, 0x4000,1.5f, SE_PLY_FOOTNOTE_CS_ROCK_CLIMB,SE_NULL, 0,0}, +		// Fall (default?) +		{run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_DIRT,SE_NULL, 0,0}, + +		// Swim +		{swim_wait,1.2f,10.0f, -1,2.0f, SE_PLY_SWIM,SE_NULL, "Wm_mr_waterswim",0}, +		// Run +		{b_dash2,3.0f,10.0f, -1,5.0f, SE_PLY_FOOTNOTE_DIRT,SE_NULL, 0,0}, +		// Pipe +		{wait,2.0f,10.0f, 0,1.0f, SE_NULL,SE_PLY_DOKAN_IN_OUT, 0,0}, +		// Door +		{wait,2.0f,10.0f, -0x7FFF,0.2f, SE_NULL,SE_OBJ_DOOR_OPEN, 0,0}, + +		// TJumped +		{Tjumped,2.0f,0.0f, -1,-1.0f, SE_NULL,SE_NULL, 0,0}, + +		// Enter cave, this is handled specially +		{run,1.0f,10.0f, -1,1.0f, SE_NULL,SE_NULL, 0,0}, +		{run,1.0f,10.0f, -1,1.0f, SE_NULL,SE_NULL, 0,0}, + +		// Invisible, this is handled specially +		{wait,2.0f,10.0f, -1,1.0f, SE_NULL,SE_NULL, 0,0}, +	}; + +	isJumping = (path->animation >= dKPPath_s::JUMP && path->animation <= dKPPath_s::JUMP_WATER); + +	float playerScale = 1.6f; + +	if (path->animation == dKPPath_s::ENTER_CAVE_UP) { +		scaleAnimProgress = 60; +		// what direction does this path go in? +		isScalingUp = (deltaY < 0) ^ reverseThroughPath; + +		if (!isScalingUp) +			playerScale = 0.0f;  	} -	 -	SpammyReport("i\n"); + +	player->visible = (path->animation != dKPPath_s::INVISIBLE); +	player->scale.x = player->scale.y = player->scale.z = playerScale; + +	int id = (path->animation >= dKPPath_s::MAX_ANIM) ? 0 : (int)path->animation; + +	player->startAnimation(Animations[id].anim, Animations[id].animParam1, Animations[id].animParam2, 0.0f); + +	player->rot.y = (Animations[id].forceRotation != -1) ? Animations[id].forceRotation : direction; +	moveSpeed = (Animations[id].forceSpeed >= 0.0f) ? Animations[id].forceSpeed : 3.0f; + +	if (Animations[id].repeatEffect) { +		player->hasEffect = true; +		player->effectName = Animations[id].repeatEffect; +	} else { +		player->hasEffect = false; +	} + +	if (Animations[id].repeatSound != SE_NULL) { +		player->hasSound = true; +		player->soundName = Animations[id].repeatSound; +	} else { +		player->hasSound = false; +	} + +	if (Animations[id].initialEffect) +		SpawnEffect(Animations[id].initialEffect, 0, &player->pos, 0, &player->scale); +	if (Animations[id].initialSound != SE_NULL) +		MapSoundPlayer(SoundRelatedClass, Animations[id].initialSound, 1);  }  void dWMPathManager_c::moveThroughPath() { @@ -508,12 +501,22 @@ void dWMPathManager_c::moveThroughPath() {  	from = reverseThroughPath ? currentPath->end : currentPath->start;  	to = reverseThroughPath ? currentPath->start : currentPath->end; +	daWMPlayer_c *player = daWMPlayer_c::instance; + + +	if (scaleAnimProgress >= 0) { +		float soFar = scaleAnimProgress * (1.6f / 60.0f); +		float sc = isScalingUp ? soFar : (1.6f - soFar); +		player->scale.x = player->scale.y = player->scale.z = sc; + +		scaleAnimProgress--; +	} + +  	Vec move = (Vec){to->x - from->x, to->y - from->y, 0};  	VECNormalize(&move, &move);  	VECScale(&move, &move, moveSpeed); -	daWMPlayer_c *player = daWMPlayer_c::instance; -  	if (isJumping) {  		float ys = (float)from->y;  		float ye = (float)to->y; @@ -550,8 +553,10 @@ void dWMPathManager_c::moveThroughPath() {  	// Check if we've reached the end yet  	if ( -			((move.x > 0) ? (player->pos.x >= to->x) : (player->pos.x <= to->x)) && -			((move.y > 0) ? (-player->pos.y >= to->y) : (-player->pos.y <= to->y)) +			(((move.x > 0) ? (player->pos.x >= to->x) : (player->pos.x <= to->x)) && +			((move.y > 0) ? (-player->pos.y >= to->y) : (-player->pos.y <= to->y))) +			|| +			(from->x == to->x && from->y == to->y)  	   ) {     		currentNode = to; @@ -603,6 +608,7 @@ void dWMPathManager_c::moveThroughPath() {  			SpammyReport("Change to map ID %d (%s), entrance ID %d\n", save->current_world, to->destMap, to->foreignID); +			ActivateWipe(to->transition);  			DoSceneChange(WORLD_MAP, 0x10000000 | (to->foreignID << 20), 0);  		} else if (reallyStop) { @@ -634,6 +640,9 @@ void dWMPathManager_c::moveThroughPath() {  }  void dWMPathManager_c::activatePoint() { +	if (levelStartWait >= 0) +		return; +  	if (currentNode->type == dKPNode_s::LEVEL) {  		int w = currentNode->levelNumber[0] - 1;  		int l = currentNode->levelNumber[1] - 1; @@ -657,11 +666,11 @@ void dWMPathManager_c::activatePoint() {  		MapSoundPlayer(SoundRelatedClass, SE_SYS_GAME_START, 1);  		daWMPlayer_c::instance->startAnimation(170, 1.2, 10.0, 0.0); +		daWMPlayer_c::instance->rot.y = 0;  		isEnteringLevel = true; - -		dLevelInfo_c::entry_s *level = dScKoopatlas_c::instance->levelInfo.search(w, l); -		dScKoopatlas_c::instance->startLevel(level); +		levelStartWait = 40; +		enteredLevel = dScKoopatlas_c::instance->levelInfo.search(w, l);  	}  } diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h index cae96ba..5579f66 100644 --- a/src/koopatlas/pathmanager.h +++ b/src/koopatlas/pathmanager.h @@ -1,6 +1,13 @@  #ifndef __KOOPATLAS_PATH_MANAGER_H  #define __KOOPATLAS_PATH_MANAGER_H +//#define WM_UNLOCK_DEBUGGING +#ifdef WM_UNLOCK_DEBUGGING +#define UnlockCmdReport OSReport +#else +#define UnlockCmdReport(...) +#endif +  #include "koopatlas/mapdata.h"  extern "C" void *SoundRelatedClass; @@ -35,6 +42,9 @@ class dWMPathManager_c {  		bool isJumping;  		float moveSpeed; +		int scaleAnimProgress; +		bool isScalingUp; +  		dKPPath_s *currentPath;  		bool reverseThroughPath; // direction we are going through the path @@ -45,6 +55,7 @@ class dWMPathManager_c {  		int unlockingAlpha; // -1 if not used  		int countdownToFadeIn; +		int waitAfterUnlock;  	private:  		void unlockPaths(); @@ -53,6 +64,8 @@ class dWMPathManager_c {  		bool isEnteringLevel;  		bool calledEnteredNode; +		int levelStartWait; +		dLevelInfo_c::entry_s *enteredLevel;  };  #endif diff --git a/src/koopatlas/player.cpp b/src/koopatlas/player.cpp index ebd0124..3f791b6 100644 --- a/src/koopatlas/player.cpp +++ b/src/koopatlas/player.cpp @@ -48,8 +48,9 @@ int daWMPlayer_c::onExecute() {  	this->modelHandler->setSRT(modifiedPos, this->rot, this->scale);	  	if (hasEffect) {  -		Vec effPos = {pos.x, pos.y, -1000.0}; -		effect.spawn(effectName, 0, &effPos, &rot, &scale); } +		Vec effPos = {pos.x, pos.y, 3300.0f}; +		effect.spawn(effectName, 0, &effPos, &rot, &scale); +	}  	if (hasSound) {  		timer++; @@ -67,6 +68,9 @@ int daWMPlayer_c::onExecute() {  }  int daWMPlayer_c::onDraw() { +	if (!visible) +		return true; +  	this->modelHandler->draw();  	hammerSuit.draw(); diff --git a/src/koopatlas/player.h b/src/koopatlas/player.h index 6fbbf5a..d553afb 100644 --- a/src/koopatlas/player.h +++ b/src/koopatlas/player.h @@ -3,186 +3,7 @@  #include "koopatlas/core.h"  #include "poweruphax.h" - -enum PlayerAnim {  -	wait = 0, -	walk = 1, -	run = 2, -	b_dash = 3, -	b_dash2 = 4, -	jump = 5, -	jump2 = 6, -	jumped = 7, -	Tjmp_c_1 = 8, -	Tjmp_c_2 = 9, -	Tjumped = 10, -	roll_jump = 11, -	Tjump2 = 12, -	mame_jump2 = 13, -	turn = 14, -	turned = 15, -	hipsr = 16, -	hipat = 17, -	hiped = 18, -	hip_to_stoop = 19, -	stoop = 20, -	stoop_start = 21, -	slip = 22, -	sliped = 23, -	slip_to_stoop = 24, -	carry_wait = 25, -	carry_walk = 26, -	carry_throw = 27, -	Rcarry_wait = 28, -	wsld = 29, -	fire_at = 30, -	swim_fire_at = 31, -	swim_fire_at2 = 32, -	star_roll = 33, -	P_swim = 34, -	swim = 35, -	swim_wait = 36, -	swim_throw = 37, -	swim_walk = 38, -	swim_standing = 39, -	paddle_1 = 40, -	paddle_2 = 41, -	paddle_carry = 42, -	tree_start = 43, -	tree_wait = 44, -	tree_climb = 45, -	tree_pose = 46, -	monkey_start = 47, -	monkey_wait_r = 48, -	monkey_wait_l = 49, -	monkey_r_to_l = 50, -	monkey_l_to_r = 51, -	net_wait = 52, -	net_walk1 = 53, -	net_walk2 = 54, -	net_attack = 55, -	pea_plant = 56, -	pea_plant_st = 57, -	pea_plant_wait = 58, -	wall_wait = 59, -	wall_walk_l = 60, -	wall_walk_r = 61, -	hang_start = 62, -	hang_up = 63, -	hang_wait = 64, -	hang_walk_l = 65, -	hang_walk_r = 66, -	w_jump1 = 67, -	w_jump2 = 68, -	RTjumped = 69, -	jump_hang = 70, -	spin_st = 71, -	spin_end = 72, -	spin_low_st = 73, -	spin_low_ed = 74, -	spin_jump2 = 75, -	spin_jump_end = 76, -	damF = 77, -	damB = 78, -	dowF = 79, -	dowB = 80, -	firejmp = 81, -	e_shock = 82, -	dead = 83, -	dead_pose = 84, -	Rtree_start = 85, -	Rtree_wait = 86, -	Rtree_pose = 87, -	goal_jump = 88, -	goal_jump_ed = 89, -	goal_puton_capA = 90, -	goal_puton_capB = 91, -	goal_puton_capC = 92, -	PL_Rgoal_puton_cap = 93, -	P_Rgoal_puton_cap = 94, -	goal_puton_capF = 95, -	waitB = 96, -	eat_out = 97, -	eat_success = 98, -	eat_fail = 99, -	eat_successB = 100, -	eat_successC = 101, -	Seat = 102, -	Seat_out = 103, -	Seat_success = 104, -	Seat_fail = 105, -	Seat_successB = 106, -	Seat_successC = 107, -	carryP_start = 108, -	carryP_wait = 109, -	carryP_walk = 110, -	carryP_throw = 111, -	carryP_waitR = 112, -	ride_on = 113, -	Fjump = 114, -	waitC = 115, -	set_to_wait = 116, -	star_rollB = 117, -	Sjump = 118, -	Sjump2 = 119, -	Sjumped = 120, -	get_down = 121, -	turnB = 122, -	turnedB = 123, -	ice_slipF = 124, -	ice_slipB = 125, -	rope_swing = 126, -	shoot = 127, -	shoot_slip = 128, -	shoot_slip_end = 129, -	low_walk_start = 130, -	low_walk = 131, -	swim_pipe = 132, -	door_walk = 133, -	PL_spin_jump = 134, -	waitL = 135, -	waitR = 136, -	fire_at2 = 137, -	blow_up = 138, -	P_slip = 139, -	P_slip_jump = 140, -	P_slip_jump2 = 141, -	FjumpB = 142, -	stamp = 143, -	waitRB = 144, -	waitLB = 145, -	waitR3 = 146, -	waitL3 = 147, -	boss_key_get = 148, -	balloon_wait = 149, -	slope_waitL = 150, -	slope_waitR = 151, -	slope_waitL2 = 152, -	slope_waitR2 = 153, -	carryP_waitLB = 154, -	carryP_waitRB = 155, -	carry_waitL = 156, -	carry_waitR = 157, -	spin_jump3 = 158, -	ride_wait = 159, -	P_paddle_1 = 160, -	P_paddle_2 = 161, -	poseL = 162, -	poseR = 163, -	gorl_wait = 164, -	dm_notice = 165, -	dm_noti_wait = 166, -	dm_surprise = 167, -	dm_surp_wait = 168, -	wait_select = 169, -	course_in = 170, -	waitD = 171, -	waitE = 172, -	dm_escort = 173, -	dm_glad = 174, -	ending_wait = 175, -	coin_comp = 176 -}; +#include <playeranim.h>  class daWMPlayer_c : public dActor_c { diff --git a/src/randomcrap.S b/src/randomcrap.S index 808009b..36bbde7 100644 --- a/src/randomcrap.S +++ b/src/randomcrap.S @@ -6,3 +6,47 @@ HeapChangeAttempt:  	lwz 4, 0(4)  	blr + +.extern OSReport +.global UniversalFunctionLog +UniversalFunctionLog: +	stwu r1, -0x10(r1) +	stw r0, 0x14(r1) +	stw r31, 0xC(r1) +	stw r30, 0x8(r1) +	mr r31, r3 +	mr r30, r4 + +	crclr 4*cr1+eq +	mr r4, r31 +	#Loop through callstack, kind of +	lwz r3, 0(r1) +	lwz r5, 4(r3) +	lwz r3, 0(r3) +	lwz r6, 4(r3) +	lwz r3, 0(r3) +	lwz r7, 4(r3) +	lwz r3, 0(r3) +	lwz r8, 4(r3) +	lwz r3, 0(r3) +	lwz r9, 4(r3) +	lwz r3, 0(r3) +	lwz r10, 4(r3) +	#lwz r10, 0x14(r29) + +	lis r3, UniLogStr@h +	ori r3, r3, UniLogStr@l +	bl OSReport +	 +	mr r3, r31 +	mr r4, r30 +	lwz r30, 0x8(r1) +	lwz r31, 0xC(r1) +	lwz r0, 0x14(r1) +	mtlr r0 +	addi r1, r1, 0x10 +	blr + +.data +UniLogStr: .string "[ULog] returning %8x to: %x > %x > %x > %x > %x > %x\n" + diff --git a/src/shyguy.cpp b/src/shyguy.cpp index 174b075..5a21e6c 100644 --- a/src/shyguy.cpp +++ b/src/shyguy.cpp @@ -114,6 +114,7 @@ class daShyGuy : public dEn_c {  	void _vf148();  	void _vf14C(); +	bool CreateIceActors();  	USING_STATES(daShyGuy);  	DECLARE_STATE(Walk); @@ -354,6 +355,20 @@ daShyGuy *daShyGuy::build() {  		doStateChange(&StateID_Die);  	} +	extern "C" void sub_80024C20(void); +	extern "C" void __destroy_arr(void*, void(*)(void), int, int); +	//extern "C" __destroy_arr(struct DoSomethingCool, void(*)(void), int cnt, int bar); + +	bool daShyGuy::CreateIceActors() +	{ +	    struct DoSomethingCool my_struct = { 0, this->pos, {1.0, 1.5, 1.5}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +	    this->frzMgr.Create_ICEACTORs( (void*)&my_struct, 1 ); +	    __destroy_arr( (void*)&my_struct, sub_80024C20, 0x3C, 1 ); +	    return true; +	} + + +  	void daShyGuy::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) {  		doStateChange(&StateID_Die);  	} diff --git a/src/spritetex.S b/src/spritetex.S index 692a381..7c9f505 100755 --- a/src/spritetex.S +++ b/src/spritetex.S @@ -638,13 +638,10 @@ SnowmanSandToSnowB: -  SnowmanPokeyRotate: - -	lha r3, 0x102(r30) +	li r5, 0x100  	blr -  .global TEX_PokeySnowmanRotate  TEX_PokeySnowmanRotate: @@ -655,10 +652,29 @@ TEX_PokeySnowmanRotate:  	cmpwi r10, 0x2  	bne SnowmanPokeyRotate +	li r5, 0 +	blr + + +PokeySnowmanImmuneToIce: +	lwz r31, 4(r5) +	blr + +.global TEX_PokeySnowmanImmuneToIce +TEX_PokeySnowmanImmuneToIce: +	lwz r10, 4(r3) +	srwi r10, r10, 24 +	andi. r10, r10, 0xF +	 +	cmpwi r10, 0x2 +	bne PokeySnowmanImmuneToIce +  	li r3, 0 -	sth r3, 0x102(r30) +	mtlr r0  	blr +          +  .global TEX_PokeySnowman  TEX_PokeySnowman: | 
