diff options
| author | Treeki <treeki@gmail.com> | 2012-02-07 04:42:46 +0100 | 
|---|---|---|
| committer | Treeki <treeki@gmail.com> | 2012-02-07 04:42:46 +0100 | 
| commit | dd8e68c2d5e71f4ad0b2fb74911d704a8ea699ce (patch) | |
| tree | e6504261cdc8659a2133c1943ecb8fecbd88c82a /src | |
| parent | c6192702e683e1557f6fcc4393cab6363fd1bc0a (diff) | |
| download | kamek-dd8e68c2d5e71f4ad0b2fb74911d704a8ea699ce.tar.gz kamek-dd8e68c2d5e71f4ad0b2fb74911d704a8ea699ce.zip  | |
Magic Platform added
Diffstat (limited to 'src')
| -rw-r--r-- | src/magicplatform.cpp | 281 | 
1 files changed, 281 insertions, 0 deletions
diff --git a/src/magicplatform.cpp b/src/magicplatform.cpp new file mode 100644 index 0000000..924d849 --- /dev/null +++ b/src/magicplatform.cpp @@ -0,0 +1,281 @@ +#include <game.h> +#include <dCourse.h> + +class daEnMagicPlatform_c : public dEn_c { +	public: +		static daEnMagicPlatform_c *build(); + +		int onCreate(); +		int onExecute(); +		int onDelete(); + +		// Settings +		u8 rectID, moveSpeed, moveDirection, moveLength; + +		float moveMin, moveMax, moveDelta, moveBaseDelta; +		float *moveTarget; + +		bool isMoving; +		void setupMovement(); +		void handleMovement(); + +		Physics physics; + +		TileRenderer *renderers; +		int rendererCount; + +		void findSourceArea(); +		void createTiles(); +		void deleteTiles(); +		void updateTilePositions(); + +		int srcX, srcY; +		int width, height; +}; + +/*****************************************************************************/ +// Glue Code +daEnMagicPlatform_c *daEnMagicPlatform_c::build() { +	void *buffer = AllocFromGameHeap1(sizeof(daEnMagicPlatform_c)); +	daEnMagicPlatform_c *c = new(buffer) daEnMagicPlatform_c; +	return c; +} + +int daEnMagicPlatform_c::onCreate() { +	rectID = settings & 0xFF; +	moveSpeed = (settings & 0xF00) >> 8; +	moveDirection = (settings & 0x3000) >> 12; +	moveLength = ((settings & 0xF0000) >> 16) + 1; + +	setupMovement(); + +	findSourceArea(); +	createTiles(); + +	float fWidth = width * 16.0f; +	float fHeight = height * 16.0f; +	physics.setup(this, +			0.0f, 0.0f, fWidth, -fHeight, +			0, 0, 0/*&PhysCB1, &PhysCB2, &PhysCB3*/, 1, 0, 0); + +	physics.addToList(); + +	return 1; +} + +int daEnMagicPlatform_c::onDelete() { +	deleteTiles(); + +	physics.removeFromList(); + +	return 1; +} + +int daEnMagicPlatform_c::onExecute() { +	handleMovement(); + +	updateTilePositions(); +	physics.update(); + +	return 1; +} + +/*****************************************************************************/ +// Movement +void daEnMagicPlatform_c::setupMovement() { +	float fMoveLength = 16.0f * moveLength; +	float fMoveSpeed = 0.2f * moveSpeed; + +	switch (moveDirection) { +		case 0: // RIGHT +			moveTarget = &pos.x; +			moveMin = pos.x; +			moveMax = pos.x + fMoveLength; +			moveBaseDelta = fMoveSpeed; +			break; +		case 1: // LEFT +			moveTarget = &pos.x; +			moveMin = pos.x - fMoveLength; +			moveMax = pos.x; +			moveBaseDelta = -fMoveSpeed; +			break; +		case 2: // UP +			moveTarget = &pos.y; +			moveMin = pos.y; +			moveMax = pos.y + fMoveLength; +			moveBaseDelta = fMoveSpeed; +			break; +		case 3: // DOWN +			moveTarget = &pos.y; +			moveMin = pos.y - fMoveLength; +			moveMax = pos.y; +			moveBaseDelta = -fMoveSpeed; +			break; +	} + +	if (spriteFlagNum == 0) { +		isMoving = (moveSpeed > 0); +		moveDelta = moveBaseDelta; +	} else { +		isMoving = false; +	} +} + +void daEnMagicPlatform_c::handleMovement() { +	if (spriteFlagNum > 0) { +		// Do event checks +		bool flagOn = ((dFlagMgr_c::instance->flags & spriteFlagMask) != 0); + +		if (isMoving) { +			if (!flagOn) { +				// Flag was turned off while moving, so go back +				moveDelta = -moveBaseDelta; +			} else { +				moveDelta = moveBaseDelta; +			} +		} else { +			if (flagOn) { +				// Flag was turned on, so start moving +				moveDelta = moveBaseDelta; +				isMoving = true; +			} +		} +	} + +	if (!isMoving) +		return; + +	// Do it +	bool goesForward = (moveDelta > 0.0f); +	bool reachedEnd = false; + +	*moveTarget += moveDelta; + +	if (goesForward) { +		if (*moveTarget >= moveMax) { +			*moveTarget = moveMax; +			reachedEnd = true; +		} +	} else { +		if (*moveTarget <= moveMin) { +			*moveTarget = moveMin; +			reachedEnd = true; +		} +	} + +	if (reachedEnd) { +		if (spriteFlagNum > 0) { +			// If event, just do nothing.. depending on what side we are on +			if ((moveDelta > 0.0f && moveBaseDelta > 0.0f) || (moveDelta < 0.0f && moveBaseDelta < 0.0f)) { +				// We reached the end, so keep isMoving on for when we need to reverse +			} else { +				// We're back at the start, so turn it off +				isMoving = false; +			} +		} else { +			// Otherwise, reverse +			moveDelta = -moveDelta; +		} +	} +} + +/*****************************************************************************/ +// Tile Renderers + +void daEnMagicPlatform_c::findSourceArea() { +	mRect rect; +	dCourseFull_c::instance->get(GetAreaNum())->getRectByID(rectID, &rect); + +	// Round the positions down/up to get the rectangle +	int left = rect.x; +	int right = left + rect.width; +	int top = -rect.y; +	int bottom = top + rect.height; + +	left &= 0xFFF0; +	right = (right + 15) & 0xFFF0; + +	top &= 0xFFF0; +	bottom = (bottom + 15) & 0xFFF0; + +	// Calculate the actual stuff +	srcX = left >> 4; +	srcY = top >> 4; +	width = (right - left) >> 4; +	height = (bottom - top) >> 4; + +	//OSReport("Area: %f, %f ; %f x %f\n", rect.x, rect.y, rect.width, rect.height); +	//OSReport("Source: %d, %d ; Size: %d x %d\n", srcX, srcY, width, height); +} + + +void daEnMagicPlatform_c::createTiles() { +	TileRenderer::List *list = dBgGm_c::instance->getTileRendererList(0); + +	rendererCount = width * height; +	renderers = new TileRenderer[rendererCount]; + +	// copy all the fuckers over +	int baseWorldX = srcX << 4, worldY = srcY << 4, rendererID = 0; + +	for (int y = 0; y < height; y++) { +		int worldX = baseWorldX; + +		for (int x = 0; x < width; x++) { +			u16 *pExistingTile = dBgGm_c::instance->getPointerToTile(worldX, worldY, 0); + +			if (*pExistingTile > 0) { +				TileRenderer *r = &renderers[rendererID]; +				r->tileNumber = *pExistingTile; +				r->z = pos.z; +				list->add(r); +			} + +			worldX += 16; +			rendererID++; +		} + +		worldY += 16; +	} + +} + +void daEnMagicPlatform_c::deleteTiles() { +	if (renderers != 0) { +		TileRenderer::List *list = dBgGm_c::instance->getTileRendererList(0); + +		for (int i = 0; i < rendererCount; i++) { +			if (renderers[i].isInList()) +				list->remove(&renderers[i]); +		} + +		delete[] renderers; +		renderers = 0; +	} +} + +void daEnMagicPlatform_c::updateTilePositions() { +	float baseX = pos.x; +	 +	float y = -pos.y; + +	int rendererID = 0; + +	for (int yIdx = 0; yIdx < height; yIdx++) { +		float x = baseX; + +		for (int xIdx = 0; xIdx < width; xIdx++) { +			TileRenderer *r = &renderers[rendererID]; +			r->x = x; +			r->y = y; + +			x += 16.0f; +			rendererID++; +		} + +		y += 16.0f; +	} +} + + +  | 
