diff options
author | Treeki <treeki@gmail.com> | 2012-09-01 05:09:47 +0200 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2012-09-01 05:09:47 +0200 |
commit | f1d937694dc9d9f9637af8c72293dab9edeaf7a2 (patch) | |
tree | d02dca08e9077b77f3ce85516689110f3825dce8 | |
parent | fbcd0d0d86409976ab22caeea25dc934486345a1 (diff) | |
download | kamek-f1d937694dc9d9f9637af8c72293dab9edeaf7a2.tar.gz kamek-f1d937694dc9d9f9637af8c72293dab9edeaf7a2.zip |
the beginnings of a working cutscene player
-rw-r--r-- | NewerProjectKP.yaml | 1 | ||||
-rw-r--r-- | cutScene.yaml | 8 | ||||
-rwxr-xr-x | include/game.h | 70 | ||||
-rw-r--r-- | kamek_pal.x | 1 | ||||
-rw-r--r-- | src/cutScene.cpp | 130 | ||||
-rw-r--r-- | src/cutScene.h | 31 | ||||
-rw-r--r-- | tools/MovieSettings.py | 19 |
7 files changed, 246 insertions, 14 deletions
diff --git a/NewerProjectKP.yaml b/NewerProjectKP.yaml index 59c03fd..57fcdc3 100644 --- a/NewerProjectKP.yaml +++ b/NewerProjectKP.yaml @@ -3,6 +3,7 @@ code_address: 0x808D9000 modules: - processed/prolog.yaml - processed/magicplatform.yaml + - processed/cutScene.yaml - processed/bonepiece.yaml - processed/bugfixes.yaml - processed/koopatlas.yaml diff --git a/cutScene.yaml b/cutScene.yaml new file mode 100644 index 0000000..d338c6a --- /dev/null +++ b/cutScene.yaml @@ -0,0 +1,8 @@ +--- +source_files: [.../src/cutScene.cpp] +hooks: + - name: BuildCutScene + type: add_func_pointer + src_addr_pal: 0x8098CD18 + target_func: 'dScCutScene_c::build(void)' + diff --git a/include/game.h b/include/game.h index af235b9..f3b14c3 100755 --- a/include/game.h +++ b/include/game.h @@ -491,6 +491,7 @@ namespace lyt { class AnimResource;
class AnimationLink;
class ResourceAccessor;
+ class Group;
class GroupContainer;
class Layout {
@@ -2546,6 +2547,14 @@ namespace lyt { // class ends at 0xB0
};
+ class AnimResource {
+ public:
+ void *fileHeader;
+ void *info;
+ void *tags;
+ void *share;
+ };
+
}
}
@@ -2557,9 +2566,11 @@ namespace m2d { virtual void initialSetup();
nw4r::lyt::ResourceAccessor *resAccPtr; // 0x04
- u32 unk_08; // 0x08
+ void *arcData; // 0x08
nw4r::lyt::ArcResourceAccessor resAcc; // 0x0C
// class ends at 0xBC
+
+ bool attachArc(void *data, const char *rootDir); // 0x801637A0
};
class ResAccLoader_c : public ResAcc_c {
@@ -2576,6 +2587,57 @@ namespace m2d { void free();
};
+ class AnmResHandler_c {
+ public:
+ AnmResHandler_c();
+ ~AnmResHandler_c();
+
+ struct Thing {
+ nw4r::lyt::Group *group;
+ nw4r::lyt::AnimTransform *animTransform;
+ };
+
+ nw4r::lyt::AnimResource resource; // 0x04
+ Thing *groups; // 0x14
+ u32 groupCount; // 0x18
+
+ bool load(const char *name, ResAcc_c *resAcc, nw4r::lyt::Layout *layout, bool useDiffInit);
+ bool free();
+ Thing *getThingForGroupName(const char *name); // 80164130
+ };
+
+ class FrameCtrl_c {
+ public:
+ virtual ~FrameCtrl_c();
+
+ float frameCount; // 0x04
+ float currentFrame; // 0x08
+ float lastFrame; // 0x0C
+ float speed; // 0x10; default: 1
+ u8 flags; // 0x14
+
+ void processAnim(); // 0x80163800
+ void setup(u8 flags, float frameCount, float speed, float initialFrame); // 0x801638A0
+ void setCurrentFrame(float frame); // 0x80163910
+ void setSpeed(float speed); // 0x80163920
+ bool isDone(); // 0x80163930
+ };
+
+ class Anm_c {
+ public:
+ FrameCtrl_c *frameCtrlPtr;
+
+ AnmResHandler_c *resHandler; // ? 0x04
+ AnmResHandler_c::Thing *thing; // 0x08
+ u8 flags; // 0x0C - |1 = enabled successfully?
+
+ FrameCtrl_c frameCtrl; // 0x10
+
+ // too lazy to list the methods for this atm
+ // after IDA reverted all the changes I made to the DB this
+ // afternoon ...
+ };
+
class EmbedLayoutBase_c : public Base_c {
public:
EmbedLayoutBase_c();
@@ -2597,7 +2659,7 @@ namespace m2d { nw4r::lyt::Layout layout; // 0x10 -- actually m2d::Layout_c but I'll add that later
nw4r::lyt::DrawInfo drawInfo; // 0x30
- void *unk_84; // 0x84 -- a ResAcc? referenced in Build()
+ ResAcc_c *resAccPtr; // 0x84 -- a ResAcc? referenced in Build()
float posX; // 0x88
float posY; // 0x8C
float clipX; // 0x90
@@ -2649,8 +2711,8 @@ namespace m2d { void execAnimations();
ResAccLoader_c loader; // 0xAC
- void *brlanHandlers; // 0x180
- void *grpHandlers; // 0x184
+ AnmResHandler_c *brlanHandlers; // 0x180
+ Anm_c *grpHandlers; // 0x184
bool *animsEnabled; // 0x188
int brlanCount; // 0x18C
int grpCount; // 0x190
diff --git a/kamek_pal.x b/kamek_pal.x index 0afeab8..16325e5 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -742,6 +742,7 @@ SECTIONS { isAnyAnimOn__Q23m2d13EmbedLayout_cFv = 0x800C9730; free__Q23m2d13EmbedLayout_cFv = 0x800C9A20; execAnimations__Q23m2d13EmbedLayout_cFv = 0x800C9650; + attachArc__Q23m2d8ResAcc_cFPvPCc = 0x801637A0; scheduleForDrawing__Q23m2d6Base_cFv = 0x80163990; RenderEffects__Fii = 0x80093F10; diff --git a/src/cutScene.cpp b/src/cutScene.cpp index 27fbafc..f60122f 100644 --- a/src/cutScene.cpp +++ b/src/cutScene.cpp @@ -11,26 +11,152 @@ dScCutScene_c *dScCutScene_c::build() { return c; } -dScCutScene_c::dScCutScene_c() : state(this) { +dScCutScene_c::dScCutScene_c() { + data = 0; + layout = 0; + sceneLoaders = 0; } +dScCutScene_c::~dScCutScene_c() { + if (layout) + delete layout; + + if (sceneLoaders) + delete[] sceneLoaders; +} + + +static const char *CutsceneNames[] = { + "/CS/Opening.cs", + "/CS/Kamek.cs", + "/CS/Ending.cs" +}; int dScCutScene_c::onCreate() { *CurrentDrawFunc = CutSceneDrawFunc; - return true; + currentScene = -1; + + int csNumber = settings >> 28; + if (settingsLoader.load(CutsceneNames[csNumber])) { + // only deal with this once! + if (data) return 1; + + data = (dMovieData_s*)settingsLoader.buffer; + + // fix up the settings + for (int i = 0; i < data->sceneCount; i++) { + data->scenes[i] = + (dMovieScene_s*)((u32)data + (u32)data->scenes[i]); + + data->scenes[i]->sceneName = + (char*)((u32)data + (u32)data->scenes[i]->sceneName); + } + + sceneLoaders = new dDvdLoader_c[data->sceneCount]; + + nextScene = 0; + + return 1; + } + + return 0; } int dScCutScene_c::onDelete() { + if (layout) + return layout->free(); + return true; } int dScCutScene_c::onExecute() { + // deal with loading first + + // what do we want to load? + int loadBegin, loadEnd; + if (nextScene == 0) { + loadBegin = 0; + loadEnd = 1; + } else { + loadBegin = ((currentScene + 1) > nextScene) ? (currentScene + 1) : nextScene; + loadEnd = data->sceneCount; + } + + for (int i = loadBegin; i < loadEnd; i++) { + sceneLoaders[i].load(data->scenes[i]->sceneName); + } + + + + // now, do all other processing + + if (currentScene >= 0) { + if (!layout->isAnyAnimOn()) { + // we're at the end + // what now? + + if ((currentScene + 1) == data->sceneCount) { + // we're TOTALLY done! + OSReport("playback complete\n"); + } else { + nextScene = currentScene + 1; + OSReport("switching to scene %d\n", nextScene); + } + + sceneLoaders[currentScene].unload(); + currentScene = -1; + delete layout; + layout = 0; + return true; + } + + layout->execAnimations(); + layout->update(); + } + + if (nextScene >= 0) { + // is this scene loaded yet? + if (sceneLoaders[nextScene].buffer) { + currentScene = nextScene; + + OSReport("Loading scene %d\n", currentScene); + + layout = new m2d::EmbedLayout_c; + layout->loader.buffer = sceneLoaders[nextScene].buffer; + layout->loader.attachArc(layout->loader.buffer, "arc"); + layout->resAccPtr = &layout->loader; + + bool result = layout->build("cutscene.brlyt"); + OSReport("Result: %d\n", result); + layout->loadAnimations((const char *[1]){"cutscene.brlan"}, 1); + layout->loadGroups((const char *[1]){"cutscene"}, (int[1]){0}, 1); + layout->disableAllAnimations(); + layout->enableNonLoopAnim(0); + + if (IsWideScreen()) { + layout->clippingEnabled = true; + layout->clipX = 66; + layout->clipY = 0; + layout->clipWidth = 508; + layout->clipHeight = 456; + layout->layout.rootPane->scale.x = 0.794f; + } + + OSReport("Loaded scene %d\n", currentScene); + + nextScene = -1; + } + } + return true; } int dScCutScene_c::onDraw() { + if (currentScene >= 0) + layout->scheduleForDrawing(); + return true; } diff --git a/src/cutScene.h b/src/cutScene.h index e875822..5845a86 100644 --- a/src/cutScene.h +++ b/src/cutScene.h @@ -8,18 +8,49 @@ void CutSceneDrawFunc(); +struct dMovieData_s; + class dScCutScene_c : public dScene_c { public: dScCutScene_c(); + ~dScCutScene_c(); int onCreate(); int onDelete(); int onExecute(); int onDraw(); + int currentScene; + int nextScene; + + dMovieData_s *data; + + dDvdLoader_c settingsLoader; + dDvdLoader_c *sceneLoaders; + + m2d::EmbedLayout_c *layout; + static dScCutScene_c *build(); static dScCutScene_c *instance; }; + +struct dMovieSound_s { + u32 delay; + u32 soundID; +}; + +struct dMovieScene_s { + char *sceneName; + u32 soundCount; + dMovieSound_s sounds[1]; +}; + +struct dMovieData_s { + u32 magic; + u32 sceneCount; + dMovieScene_s *scenes[1]; +}; + #endif diff --git a/tools/MovieSettings.py b/tools/MovieSettings.py index b4b1d23..1a6bbaf 100644 --- a/tools/MovieSettings.py +++ b/tools/MovieSettings.py @@ -66,16 +66,19 @@ class Settings(object): s = Settings() -one = s.add_banner('beef') -one.add_sound(0, 200) -one.add_sound(5, 400) -one.add_sound(20, 600) +b = s.add_banner('/CS/Opening1.arc') +b = s.add_banner('/CS/Opening3.arc') +b = s.add_banner('/CS/Opening4.arc') +b = s.add_banner('/CS/Opening5.arc') +b = s.add_banner('/CS/Opening6.arc') +b = s.add_banner('/CS/Opening7.arc') +b = s.add_banner('/CS/Opening8.arc') +b = s.add_banner('/CS/Opening9.arc') +b = s.add_banner('/CS/Opening10.arc') +b = s.add_banner('/CS/Opening11.arc') -two = s.add_banner('cats') -two.add_sound(5, 20) -two.add_sound(10, 40) data = s.export() -open('settings.bin', 'wb').write(data) +open('Opening.cs', 'wb').write(data) |