diff options
-rw-r--r-- | include/common.h | 1 | ||||
-rw-r--r-- | koopatlas.yaml | 6 | ||||
-rw-r--r-- | src/koopatlas/core.cpp | 14 | ||||
-rw-r--r-- | src/koopatlas/core.h | 2 | ||||
-rw-r--r-- | src/koopatlas/pathmanager.cpp | 6 | ||||
-rw-r--r-- | src/koopatlas/player.cpp | 71 | ||||
-rw-r--r-- | src/koopatlas/player.h | 20 | ||||
-rw-r--r-- | src/koopatlas/subplayer.cpp | 116 | ||||
-rw-r--r-- | src/koopatlas/subplayer.h | 38 | ||||
-rw-r--r-- | tools/UsedProfileAndSpriteList.txt | 3 |
10 files changed, 270 insertions, 7 deletions
diff --git a/include/common.h b/include/common.h index 5b85824..5669a3f 100644 --- a/include/common.h +++ b/include/common.h @@ -82,6 +82,7 @@ void OSReport(const char *format, ...); int sprintf(char *buffer, const char *format, ...);
int snprintf(char *buffer, size_t buff_size, const char *format, ...);
char *strcat(char *destination, const char *source);
+extern "C" void *memcpy(void *dest, const void *src, size_t count);
void *memset(void *ptr, int value, size_t num);
int memcmp(const void *ptr1, const void *ptr2, size_t num);
diff --git a/koopatlas.yaml b/koopatlas.yaml index c21403e..ca0cd63 100644 --- a/koopatlas.yaml +++ b/koopatlas.yaml @@ -7,6 +7,7 @@ source_files: - ../src/levelinfo.cpp - ../src/koopatlas/core.cpp - ../src/koopatlas/player.cpp + - ../src/koopatlas/subplayer.cpp - ../src/koopatlas/hud.cpp - ../src/koopatlas/camera.cpp - ../src/koopatlas/map.cpp @@ -27,6 +28,11 @@ hooks: src_addr_pal: 0x80988DDC target_func: 'daWMPlayer_c::build(void)' + - name: BuildWMSubPlayer # WM_SUBPLAYER + type: add_func_pointer + src_addr_pal: 0x8098586C + target_func: 'daWMSubPlayer_c::build(void)' + - name: BuildWMHud # WM_DANCE_PAKKUN type: add_func_pointer src_addr_pal: 0x80982844 diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index 0a463f5..317c86c 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -1,6 +1,7 @@ #include "koopatlas/core.h" #include "koopatlas/camera.h" #include "koopatlas/player.h" +#include "koopatlas/subplayer.h" extern "C" void LoadMapScene(); @@ -247,6 +248,12 @@ bool WMInit_SetupExtra(void *ptr) { wm->player->modelHandler->mdlClass->setPowerup(Player_Powerup[0]); wm->player->modelHandler->mdlClass->startAnimation(0, 1.2f, 10.0f, 0.0f); + for (int i = 0; i < 3; i++) { + wm->subPlayer[i] = (daWMSubPlayer_c*)CreateParentedObject(WM_SUBPLAYER, wm, i+1, 2); + wm->subPlayer[i]->modelHandler->mdlClass->setPowerup(Player_Powerup[i+1]); + wm->subPlayer[i]->modelHandler->mdlClass->startAnimation(0, 1.2f, 10.0f, 0.0f); + } + // since we've got all the resources, set up the path data too SpammyReport("preparing path manager\n"); wm->pathManager.setup(); @@ -254,6 +261,8 @@ bool WMInit_SetupExtra(void *ptr) { // and put the player into position dKPNode_s *cNode = wm->pathManager.currentNode; wm->player->pos = (Vec){cNode->x, -cNode->y, wm->player->pos.z}; + for (int i = 0; i < 3; i++) + wm->subPlayer[i]->pos = (Vec){cNode->x, -cNode->y, wm->subPlayer[i]->pos.z}; // is last param correct? must check :/ SpammyReport("creating MAP\n"); @@ -736,7 +745,10 @@ void dScKoopatlas_c::executeState_EasyPairingWait() { void dScKoopatlas_c::executeState_PowerupsWait() { if (!STKI_SHOW(this->stockItem)) { - dScKoopatlas_c::instance->player->modelHandler->mdlClass->setPowerup(Player_Powerup[0]); + player->modelHandler->mdlClass->setPowerup(Player_Powerup[0]); + + for (int i = 0; i < 3; i++) + subPlayer[i]->modelHandler->mdlClass->setPowerup(Player_Powerup[i+1]); state.setState(&StateID_Normal); } diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h index e4e0254..3f795cc 100644 --- a/src/koopatlas/core.h +++ b/src/koopatlas/core.h @@ -39,6 +39,7 @@ void NewerMapDrawFunc(); #define WM_STARCOIN WM_GHOST class daWMPlayer_c; +class daWMSubPlayer_c; class dWMMap_c; class dWMHud_c; class dWMShop_c; @@ -99,6 +100,7 @@ class dScKoopatlas_c : public dScene_c { daWMPlayer_c *player; + daWMSubPlayer_c *subPlayer[3]; dWMHud_c *hud; dWMMap_c *map; dWMShop_c *shop; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 5053fb8..155e27c 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -588,11 +588,15 @@ void dWMPathManager_c::startMovementTo(dKPPath_s *path) { player->hasSound = false; } - if (Animations[id].initialEffect) + if (Animations[id].initialEffect) { SpawnEffect(Animations[id].initialEffect, 0, &player->pos, 0, &player->scale); + daWMPlayer_c::instance->nextNowEffect = Animations[id].initialEffect; + } + if (Animations[id].initialSound != SE_NULL) { nw4r::snd::SoundHandle something; PlaySoundWithFunctionB4(SoundRelatedClass, &something, Animations[id].initialSound, 1); + daWMPlayer_c::instance->nextNowSound = Animations[id].initialSound; if (Animations[id].initialSound == SE_PLY_JUMP) { nw4r::snd::SoundHandle something2; diff --git a/src/koopatlas/player.cpp b/src/koopatlas/player.cpp index a3e484a..3a736b4 100644 --- a/src/koopatlas/player.cpp +++ b/src/koopatlas/player.cpp @@ -1,4 +1,5 @@ #include "koopatlas/player.h" +#include "koopatlas/subplayer.h" daWMPlayer_c *daWMPlayer_c::instance; @@ -17,8 +18,6 @@ int daWMPlayer_c::onCreate() { rot = (S16Vec){0x1800,0,0}; scale = (Vec){1.6f,1.6f,1.6f}; - current_param = 0; - hasEffect = false; hasSound = false; step = false; @@ -43,6 +42,38 @@ int daWMPlayer_c::onExecute() { dScKoopatlas_c::instance->pathManager.execute(); + // work out the Z positions first of all + struct ySortThing_s { + float y; int id; + }; + ySortThing_s sorts[4]; + sorts[0].y = pos.y; + sorts[0].id = 0; + for (int i = 1; i < 4; i++) { + sorts[i].y = stateHistory[i * SUBPLAYER_DISTANCE].pos.y; + sorts[i].id = i; + } + + // bubble sort it with an algorithm from wikipedia + bool swapped; + do { + swapped = false; + for (int i = 1; i < 4; i++) { + if (sorts[i-1].y > sorts[i].y) { + ySortThing_s forSwap = sorts[i-1]; + sorts[i-1] = sorts[i]; + sorts[i] = forSwap; + swapped = true; + } + } + } while (swapped); + + // then put together the positions + float chosenZPositions[4]; + for (int i = 0; i < 4; i++) + chosenZPositions[sorts[i].id] = 3100.0f - (i * 25.0f); + pos.z = chosenZPositions[0]; + this->modelHandler->update(); mMtx myMatrix; @@ -70,6 +101,42 @@ int daWMPlayer_c::onExecute() { if (timer > 12) { timer = 0; } } + if (stateHistoryBuilt) { + for (int i = STATE_COUNT - 1; i >= 1; i--) + stateHistory[i] = stateHistory[i - 1]; + } + + state_s *st = &stateHistory[0]; + st->pos = pos; + st->scale = scale; + st->rot = rot; + st->repeatedEffect = (hasEffect ? effectName : 0); + st->nowEffect = nextNowEffect; + st->repeatedSound = (hasSound ? soundName : 0); + st->nowSound = nextNowSound; + st->jumpOffset = jumpOffset; + st->anim = currentAnim; + st->animFrame = currentFrame; + st->animUnk = currentUnk; + st->animUpdateRate = currentUpdateRate; + + if (!stateHistoryBuilt) { + for (int i = 1; i < STATE_COUNT; i++) + stateHistory[i] = stateHistory[0]; + stateHistoryBuilt = true; + } + + nextNowEffect = 0; + nextNowSound = 0; + + for (int i = 0; i < 3; i++) { + daWMSubPlayer_c *sp = dScKoopatlas_c::instance->subPlayer[i]; + + state_s *st = &stateHistory[(i+1) * SUBPLAYER_DISTANCE]; + st->pos.z = chosenZPositions[i+1]; + sp->update(st); + } + return true; } diff --git a/src/koopatlas/player.h b/src/koopatlas/player.h index 7b60f60..70d6bf5 100644 --- a/src/koopatlas/player.h +++ b/src/koopatlas/player.h @@ -15,8 +15,6 @@ class daWMPlayer_c : public dActor_c { int onExecute(); int onDraw(); - int current_param; - int currentAnim; float currentFrame; float currentUnk; @@ -39,6 +37,24 @@ class daWMPlayer_c : public dActor_c { static daWMPlayer_c *build(); static daWMPlayer_c *instance; + + struct state_s { + Vec pos, scale; + S16Vec rot; + const char *repeatedEffect, *nowEffect; + int repeatedSound, nowSound; + int anim; + float animFrame, animUnk, animUpdateRate; + float jumpOffset; + }; + + bool stateHistoryBuilt; + static const int SUBPLAYER_DISTANCE = 15; + static const int STATE_COUNT = (SUBPLAYER_DISTANCE * 3) + 1; + state_s stateHistory[STATE_COUNT]; + + int nextNowSound; + const char *nextNowEffect; }; #endif diff --git a/src/koopatlas/subplayer.cpp b/src/koopatlas/subplayer.cpp new file mode 100644 index 0000000..8f70299 --- /dev/null +++ b/src/koopatlas/subplayer.cpp @@ -0,0 +1,116 @@ +#include "koopatlas/player.h" +#include "koopatlas/subplayer.h" + +daWMSubPlayer_c *daWMSubPlayer_c::instance; + +int daWMSubPlayer_c::onCreate() { + + this->modelHandler = new dPlayerModelHandler_c(settings); + // loadModel(u8 player_id, int powerup_id, int unk); + this->modelHandler->loadModel(settings, 3, 2); + this->modelHandler->mdlClass->startAnimation(0, 1.2, 10.0, 0.0); + this->modelHandler->setSRT((Vec){0.0,100.0,-100.0}, (S16Vec){0,0,0}, (Vec){2.0,2.0,2.0}); + this->modelHandler->draw(); + + hammerSuit.setup(this->modelHandler); + + pos = (Vec){0.0f,0.0f,3000.0f}; + rot = (S16Vec){0x1800,0,0}; + scale = (Vec){1.6f,1.6f,1.6f}; + + step = false; + timer = 0; + + return true; +} + +int daWMSubPlayer_c::onDelete() { + delete modelHandler; + + return true; +} + + +void daWMSubPlayer_c::update(daWMPlayer_c::state_s *st) { + this->modelHandler->update(); + + startAnimation(st->anim, st->animFrame, st->animUnk, st->animUpdateRate); + + pos = st->pos; + scale = st->scale; + rot = st->rot; + + mMtx myMatrix; + myMatrix.scale(scale.x, scale.y, scale.z); + myMatrix.applyTranslation(pos.x, pos.y + st->jumpOffset, pos.z); + myMatrix.applyRotationX(&rot.x); + myMatrix.applyRotationY(&rot.y); + // Z is unused for now + modelHandler->setMatrix(myMatrix); + + if (st->repeatedEffect) { + Vec effPos = {pos.x, pos.y, 3300.0f}; + effect.spawn(st->repeatedEffect, 0, &effPos, &rot, &scale); + } + + if (st->repeatedSound) { + timer++; + + if (timer == 12) { + if (step) { MapSoundPlayer(SoundRelatedClass, st->repeatedSound, 1); step = false; } + else { MapSoundPlayer(SoundRelatedClass, st->repeatedSound+1, 1); step = true; } + timer = 0; + } + + if (timer > 12) { timer = 0; } + } + + if (st->nowEffect) { + SpawnEffect(st->nowEffect, 0, &pos, 0, &scale); + } + + if (st->nowSound != SE_NULL) { + nw4r::snd::SoundHandle something; + PlaySoundWithFunctionB4(SoundRelatedClass, &something, st->nowSound, 1); + + if (st->nowSound == SE_PLY_JUMP) { + nw4r::snd::SoundHandle something2; + PlaySoundWithFunctionB4(SoundRelatedClass, &something2, SE_VOC_MA_CS_JUMP, 1); + } + } +} + +int daWMSubPlayer_c::onDraw() { + if (!visible) + return true; + + this->modelHandler->draw(); + hammerSuit.draw(); + + return true; +} + + +void daWMSubPlayer_c::startAnimation(int id, float frame, float unk, float updateRate) { + if (id == currentAnim && frame == currentFrame && unk == currentUnk && updateRate == currentUpdateRate) + return; + + currentAnim = id; + currentFrame = frame; + currentUnk = unk; + currentUpdateRate = updateRate; + this->modelHandler->mdlClass->startAnimation(id, frame, unk, updateRate); +} + + + +daWMSubPlayer_c *daWMSubPlayer_c::build() { + + void *buffer = AllocFromGameHeap1(sizeof(daWMSubPlayer_c)); + daWMSubPlayer_c *c = new(buffer) daWMSubPlayer_c; + + + instance = c; + return c; +} + diff --git a/src/koopatlas/subplayer.h b/src/koopatlas/subplayer.h new file mode 100644 index 0000000..d9b1b20 --- /dev/null +++ b/src/koopatlas/subplayer.h @@ -0,0 +1,38 @@ +#ifndef __KOOPATLAS_SUBPLAYER_H +#define __KOOPATLAS_SUBPLAYER_H + +#include "koopatlas/core.h" +#include "poweruphax.h" +#include <playerAnim.h> + + +class daWMSubPlayer_c : public dActor_c { + public: + dPlayerModelHandler_c *modelHandler; + + int onCreate(); + int onDelete(); + int onDraw(); + + void update(daWMPlayer_c::state_s *st); + + int currentAnim; + float currentFrame; + float currentUnk; + float currentUpdateRate; + + bool step; + + int timer; + + mEf::es2 effect; + dHammerSuitRenderer_c hammerSuit; + + void startAnimation(int id, float frame, float unk, float updateRate); + + static daWMSubPlayer_c *build(); + static daWMSubPlayer_c *instance; +}; + +#endif + diff --git a/tools/UsedProfileAndSpriteList.txt b/tools/UsedProfileAndSpriteList.txt index 1b4ba12..ef22308 100644 --- a/tools/UsedProfileAndSpriteList.txt +++ b/tools/UsedProfileAndSpriteList.txt @@ -7,6 +7,7 @@ --- : WM_PLAYER : Player --- : WM_SINKSHIP : Song Prize --- : WM_SMALLCLOUD : Bridge Bowser: Dropped Bomb +--- : WM_SUBPLAYER : SubPlayer --- : WM_TOGEZO : Shop --- : WORLD_CAMERA : World Camera --- : WORLD_MAP : Koopatlas @@ -101,6 +102,7 @@ WM_PUKU WM_PUKU WM_SINKSHIP WM_SMALLCLOUD +WM_SUBPLAYER WM_TOGEZO WORLD_CAMERA WORLD_MAP @@ -146,7 +148,6 @@ WM_PEACH_CASTLE WM_SANDPILLAR WM_START WM_STOP -WM_SUBPLAYER WM_SURRENDER WM_SWITCH WM_TERESA |