summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common.h1
-rw-r--r--koopatlas.yaml6
-rw-r--r--src/koopatlas/core.cpp14
-rw-r--r--src/koopatlas/core.h2
-rw-r--r--src/koopatlas/pathmanager.cpp6
-rw-r--r--src/koopatlas/player.cpp71
-rw-r--r--src/koopatlas/player.h20
-rw-r--r--src/koopatlas/subplayer.cpp116
-rw-r--r--src/koopatlas/subplayer.h38
-rw-r--r--tools/UsedProfileAndSpriteList.txt3
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