From 2bf4f9ef114e667aa8a230b169e05f1edf005107 Mon Sep 17 00:00:00 2001 From: Treeki Date: Mon, 16 Jan 2012 01:49:43 +0100 Subject: added doodads + animation, plus bugfixes --- src/koopatlas/camera.cpp | 2 +- src/koopatlas/map.cpp | 162 +++++++++++++++++++++++++++++++++++++++++++---- src/koopatlas/map.h | 4 +- src/koopatlas/mapdata.h | 7 +- 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}; -- cgit v1.2.3