diff options
| author | Treeki <treeki@gmail.com> | 2012-01-16 01:49:43 +0100 | 
|---|---|---|
| committer | Treeki <treeki@gmail.com> | 2012-01-16 01:49:43 +0100 | 
| commit | 2bf4f9ef114e667aa8a230b169e05f1edf005107 (patch) | |
| tree | 7a5af201c753c274db243a4eea2798899ccd147d /src | |
| parent | 663c7538e18aaeeb460cffd7700e8caff1420f8a (diff) | |
| download | kamek-2bf4f9ef114e667aa8a230b169e05f1edf005107.tar.gz kamek-2bf4f9ef114e667aa8a230b169e05f1edf005107.zip  | |
added doodads + animation, plus bugfixes
Diffstat (limited to 'src')
| -rw-r--r-- | src/koopatlas/camera.cpp | 2 | ||||
| -rw-r--r-- | src/koopatlas/map.cpp | 162 | ||||
| -rw-r--r-- | src/koopatlas/map.h | 4 | ||||
| -rw-r--r-- | src/koopatlas/mapdata.h | 7 | ||||
| -rw-r--r-- | src/koopatlas/player.cpp | 2 | 
5 files changed, 159 insertions, 18 deletions
diff --git a/src/koopatlas/camera.cpp b/src/koopatlas/camera.cpp index a4c642f..0e6e320 100644 --- a/src/koopatlas/camera.cpp +++ b/src/koopatlas/camera.cpp @@ -33,7 +33,7 @@ dWorldCamera_c::dWorldCamera_c() {  	currentX = 0;  	currentY = 0; -	zoomLevel = 1; +	zoomLevel = 1.5f;  } diff --git a/src/koopatlas/map.cpp b/src/koopatlas/map.cpp index ef63eb1..d78aad4 100644 --- a/src/koopatlas/map.cpp +++ b/src/koopatlas/map.cpp @@ -3,6 +3,7 @@  //#define TILE_DEBUGGING  //#define BOUND_DEBUGGING +//#define DOODAD_DEBUGGING  #ifdef TILE_DEBUGGING  #define TileReport OSReport @@ -16,6 +17,12 @@ inline void TileReport(const char *str, ...) { }  inline void BoundReport(const char *str, ...) { }  #endif +#ifdef DOODAD_DEBUGGING +#define DoodadReport OSReport +#else +inline void DoodadReport(const char *str, ...) { } +#endif +  dWMMap_c *dWMMap_c::instance = 0;  dWMMap_c *dWMMap_c::build() { @@ -61,29 +68,32 @@ int dWMMap_c::onDraw() {  void dWMMap_c::renderer_c::drawOpa() { -	//drawTiles(); +	//drawLayers();  }  void dWMMap_c::renderer_c::drawXlu() { -	drawTiles(); +	drawLayers();  } -void dWMMap_c::renderer_c::drawTiles() { -	beginRendering(); - +void dWMMap_c::renderer_c::drawLayers() {  	dKPMapData_c *dataCls = &dScKoopatlas_c::instance->mapData;  	dKPMapFile_s *data = dataCls->data;  	baseZ = 1000 - (10 * data->layerCount); +	beginRendering(); +  	for (int iLayer = data->layerCount - 1; iLayer >= 0; iLayer--) {  		dKPLayer_s *layer = data->layers[iLayer]; +		renderMtx[2][3] += 10;  		TileReport("Checking layer %d with type %d\n", iLayer, layer->type);  		if (layer->type == dKPLayer_s::OBJECTS)  			renderTileLayer(layer, data->sectors); +		else if (layer->type == dKPLayer_s::DOODADS) +			renderDoodadLayer(layer);  	}  	endRendering(); @@ -104,9 +114,9 @@ void dWMMap_c::renderer_c::beginRendering() {  	dWorldCamera_c *camObj = dWorldCamera_c::instance;  	minX = ((int)camObj->screenLeft) / 16; -	minY = ((int)(-camObj->screenTop)) / 16; +	minY = ((int)(-camObj->screenTop) - 15) / 16;  	maxX = (((int)(camObj->screenLeft + camObj->screenWidth)) + 15) / 16; -	maxY = (((int)(-camObj->screenTop + camObj->screenHeight)) + 15) / 16; +	maxY = ((int)(-camObj->screenTop + camObj->screenHeight)) / 16;  	GXClearVtxDesc(); @@ -116,6 +126,9 @@ void dWMMap_c::renderer_c::beginRendering() {  	GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);  	GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 8); +	GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XY, GX_F32, 0); +	GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_U8, 8); +  	GXSetNumIndStages(0);  	for (int i = 0; i < 0x10; i++)  		GXSetTevDirect((GXTevStageID)i); @@ -154,7 +167,6 @@ void dWMMap_c::renderer_c::beginRendering() {  void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors) {  	//TileReport("Rendering layer %p\n", layer); -	renderMtx[2][3] += 10;  	// don't render it if we don't need to  	if (maxX < layer->left || minX > layer->right) @@ -215,21 +227,21 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector  					if (tileID == 0xFFFF)  						continue; -					s16 worldX = (worldSectorX | inX) << 4; -					s16 worldY = -((worldSectorY | inY) << 4); +					s16 worldX = (worldSectorX | inX) * 24; +					s16 worldY = -((worldSectorY | inY) * 24);  					u8 tileX = (tileID & 0x1F) * 8;  					u8 tileY = ((tileID & 0x1E0) / 32) * 16;  					TileReport("Drawing tile %d at %d,%d\n", tileID, worldX, worldY);  					GXBegin(GX_QUADS, GX_VTXFMT0, 4); -					GXPosition2s16(worldX + 16, worldY - 16); +					GXPosition2s16(worldX + 24, worldY - 24);  					GXTexCoord2u8(tileX + 7, tileY + 14); -					GXPosition2s16(worldX + 16, worldY); +					GXPosition2s16(worldX + 24, worldY);  					GXTexCoord2u8(tileX + 7, tileY + 2);  					GXPosition2s16(worldX, worldY);  					GXTexCoord2u8(tileX + 1, tileY + 2); -					GXPosition2s16(worldX, worldY - 16); +					GXPosition2s16(worldX, worldY - 24);  					GXTexCoord2u8(tileX + 1, tileY + 14);//*/  					GXEnd();  				} @@ -242,6 +254,126 @@ 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) { +	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); + +		// ANIMATE THE FUCKER +		float effectiveX = doodad->x, effectiveY = doodad->y; +		float effectiveWidth = doodad->width, effectiveHeight = doodad->height; +		float effectiveAngle = doodad->angle; + +		if (doodad->animationCount > 0) { +			for (int j = 0; j < doodad->animationCount; j++) { +				dKPDoodad_s::animation_s *anim = &doodad->animations[j]; + +				u32 baseTick = anim->baseTick; +				if (baseTick == 0) { +					anim->baseTick = baseTick = GlobalTickCount; +				} + +				u32 elapsed = GlobalTickCount - baseTick; +				if (anim->isReversed) +					elapsed = anim->frameCount - 1 - elapsed; + +				if (elapsed >= anim->frameCount) { +					// we've reached the end +					switch (anim->loop) { +						case dKPDoodad_s::animation_s::CONTIGUOUS: +							// Stop here +							elapsed = anim->frameCount - 1; +							break; + +						case dKPDoodad_s::animation_s::LOOP: +							// Start over +							elapsed = 0; +							anim->baseTick = GlobalTickCount; +							break; + +						case dKPDoodad_s::animation_s::REVERSE_LOOP: +							// Change direction +							anim->isReversed = !anim->isReversed; +							elapsed = (anim->isReversed) ? (anim->frameCount - 1) : 0; +							anim->baseTick = GlobalTickCount; +							break; +					} +				} + +				// now calculate the thing +				float progress = elapsed / (float)anim->frameCount; +				float value; + +				switch (anim->curve) { +					case dKPDoodad_s::animation_s::LINEAR: +						value = progress; +						break; +					case dKPDoodad_s::animation_s::SIN: +						value = (sin(((progress * M_PI * 2)) - M_PI_2) + 1) / 2; +						break; +					case dKPDoodad_s::animation_s::COS: +						value = (cos(((progress * M_PI * 2)) - M_PI_2) + 1) / 2; +						break; +				} + +				float delta = anim->end - anim->start; +				float frame; + +				if (anim->isReversed) +					frame = anim->start + ceil(delta * value); +				else +					frame = anim->start + (delta * value); + +				// and apply it! +				switch (anim->type) { +					case dKPDoodad_s::animation_s::X_POS: +						effectiveX += frame; +						break; +					case dKPDoodad_s::animation_s::Y_POS: +						effectiveY += frame; +						break; +					case dKPDoodad_s::animation_s::ANGLE: +						effectiveAngle += frame; +						break; +					case dKPDoodad_s::animation_s::X_SCALE: +						effectiveWidth = (effectiveWidth * frame / 100.0); +						break; +					case dKPDoodad_s::animation_s::Y_SCALE: +						effectiveHeight = (effectiveHeight * frame / 100.0); +						break; +					case dKPDoodad_s::animation_s::OPACITY: +						// TODO +						break; +				} +			} +		} + +		float halfW = effectiveWidth * 0.5f, halfH = effectiveHeight * 0.5f; + +		Mtx doodadMtx; +		MTXTransApply(renderMtx, doodadMtx, effectiveX + halfW, -effectiveY - halfH, 0); +		 +		Mtx rotMtx; +		MTXRotDeg(rotMtx, 'z', -effectiveAngle); + +		MTXConcat(doodadMtx, rotMtx, doodadMtx); + +		loadCamera(doodadMtx); +		loadTexture(doodad->texObj); + +		GXBegin(GX_QUADS, GX_VTXFMT1, 4); +		GXPosition2f32(halfW, -halfH); +		GXTexCoord2u8(255, 255); +		GXPosition2f32(halfW, halfH); +		GXTexCoord2u8(255, 0); +		GXPosition2f32(-halfW, halfH); +		GXTexCoord2u8(0, 0); +		GXPosition2f32(-halfW, -halfH); +		GXTexCoord2u8(0, 255); +		GXEnd(); +	} +} +  void dWMMap_c::renderer_c::endRendering() {  } @@ -257,3 +389,7 @@ void dWMMap_c::renderer_c::loadCamera() {  	GXLoadPosMtxImm(renderMtx, GX_PNMTX0);  } +void dWMMap_c::renderer_c::loadCamera(Mtx m) { +	GXLoadPosMtxImm(m, GX_PNMTX0); +} + diff --git a/src/koopatlas/map.h b/src/koopatlas/map.h index 6f07ddf..2e7b7b6 100644 --- a/src/koopatlas/map.h +++ b/src/koopatlas/map.h @@ -34,16 +34,18 @@ class dWMMap_c : public dBase_c {  				void drawXlu();  			private: -				void drawTiles(); +				void drawLayers();  				void beginRendering();  				void endRendering();  				void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector); +				void renderDoodadLayer(dKPLayer_s *layer);  				void loadTexture(GXTexObj *obj);  				void loadCamera(); +				void loadCamera(Mtx m);  				GXTexObj *currentTexture;  				Mtx renderMtx; diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index 2b643bd..b6d1838 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -22,9 +22,12 @@ struct dKPDoodad_s {  		LoopTypes loop;  		CurveTypes curve; -		float frameCount; +		int frameCount;  		AnimTypes type; -		float start, end; +		int start, end; + +		u32 baseTick; +		bool isReversed;  	};  	float x, y; diff --git a/src/koopatlas/player.cpp b/src/koopatlas/player.cpp index ee881ab..f754a9b 100644 --- a/src/koopatlas/player.cpp +++ b/src/koopatlas/player.cpp @@ -13,7 +13,7 @@ int daWMPlayer_c::onCreate() {  	this->modelHandler->draw();  	OSReport("Init done!\n"); -	pos = (Vec){0.0f,-32.0f,0.0f}; +	pos = (Vec){0.0f,0.0f,0.0f};  	rot = (S16Vec){0,0,0};  	scale = (Vec){1.0f,1.0f,1.0f};  | 
