-
Notifications
You must be signed in to change notification settings - Fork 601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document Save.cutsceneIndex
and adjacent data / code
#2286
base: main
Are you sure you want to change the base?
Conversation
so that it doesn't clutter previous commit. still, allowing `clangd LSP` to run format-on-save yields inconsistent results for me with the project's tooling, especially for header files
include/z64cutscene.h
Outdated
CS_INDEX_SCRIPTED_D = 0xFFFD, | ||
CS_INDEX_SCRIPTED_E = 0xFFFE, | ||
CS_INDEX_SCRIPTED_F = 0xFFFF, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CS_INDEX_SCRIPTED_D = 0xFFFD, | |
CS_INDEX_SCRIPTED_E = 0xFFFE, | |
CS_INDEX_SCRIPTED_F = 0xFFFF, | |
CS_INDEX_SCRIPTED_D = 0xFFFD, |
Values 0xFFF0-0xFFFC are directly tied to the scene layer system. These values are used to fetch scene layers 4-16, which are intended to contain scene command referencing a cutscene that will play immediately on scene load.
0xFFFD does not have the same behavior and thus should have a different name from the rest. It is intended to be used to trigger a scripted cutscene "manually" after scene load, and has no effect on the scene layer system. You can see this at Play_Init in z_play.c, line 332 or so, where the cutsceneIndex resets to 0 if it's 0xFFFD, before the sceneLayer is computed.
No scene has a layer count greater than 17, so values 0xFFFE/0xFFFF are never used and thus should not be enumerated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, i do see this lines
if (gSaveContext.save.cutsceneIndex == CS_INDEX_SCRIPTED_D) {
gSaveContext.save.cutsceneIndex = CS_INDEX_NONE;
}
and they look to me as
if (gSaveContext.save.cutsceneIndex == CS_INDEX_RESET) {
gSaveContext.save.cutsceneIndex = CS_INDEX_NONE;
}
UPD 8cbdf80: preparing a commit, but did not apply the suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name needs to make sense in all parts of code, not just in the one code block. As I stated before, 0xFFFD triggers cutscenes after the scene has been loaded.
For example, z_bg_toki_sword is the Master Sword, and when you pull or drop the sword it will initiate a scripted cutscene by setting the cutscene script pointer and assigning gSaveContext.cutsceneTrigger
to 1. This causes Cutscene_UpdateScripted
to set the cutsceneIndex to 0xFFFD, which in turn starts the processing of the script.
The purpose of the block in Play_Init is to flush the cutsceneIndex state in the event that the PlayState is destroyed before the cutscene can complete normally. This can happen if e.g. the player falls out of bounds or dies mid-cutscene.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, so CS_INDEX_TRIGGERED
might do
// z_demo.c:2292
void Cutscene_SetupScripted(...)
// if trigger flag set, isn't idling, and not in a cutscene
if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_IDLE) && !Player_InCsMode(play))
// then trigger
gSaveContext.save.cutsceneIndex = CS_INDEX_TRIGGERED;
because it's a "state" not a "request"
UPD 32a2dd0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I like "triggered". Don't values like 0xFFF0 also "trigger" a cutscene?
FWIW I'd prefer calling this CS_INDEX_D, and commenting that values above A do not correspond to any scene layer in the base game (i.e. only used for special cases) instead of trying to encode that in the name. I disagree that values above 0xFFFC are not "directly tied to the scene layer system", there's no check for this in the code, so if some scene did have a layer 19 for example everything would work fine.
This would also reduce the awkwardness with what is currently CS_INDEX_BARRIER
if we call it CS_INDEX_F
instead. Basically, I think all of the scripted cutscenes could be treated uniformly, and we should treat the uses of cutscene D for debug features and the Master Sword as hacks that use the magic value D. This does not seem so different than the fact that z_demo magically knows to use cutscene 1 for CS_DEST_GERUDO_VALLEY_DIN_PART_1
, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i won't however add 0xFFFB
, 0xFFFC
, 0xFFFE
, because no code even mentions them. additionally, i don't want to contradict #2286 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 347 to 381 in 67f0eef
// values `< 0xFFF0` indicate a "manual" cutscene; can be assigned to | |
// - `gSaveContext.save.cutsceneIndex` | |
// - `gSaveContext.nextCutsceneIndex` | |
// using them implies an intention to have `z_play.c` set `gSaveContext.sceneLayer` based on age and day time | |
// see enum values [`SCENE_LAYER_CHILD_DAY` .. `SCENE_LAYER_ADULT_NIGHT`] | |
#define CS_INDEX_DEFAULT 0x0000 | |
#define CS_INDEX_UNK_8000 0x8000 | |
// values `>= 0xFFF0` indicate a "scripted" cutscene; can be assigned to | |
// - `gSaveContext.save.cutsceneIndex` | |
// - `gSaveContext.nextCutsceneIndex` | |
// using them implies an intention to have `z_play.c` set `gSaveContext.sceneLayer` directly by index | |
// see `GET_CUTSCENE_LAYER(index)` | |
#define CS_INDEX_0 0xFFF0 | |
#define CS_INDEX_1 0xFFF1 | |
#define CS_INDEX_2 0xFFF2 | |
#define CS_INDEX_3 0xFFF3 | |
#define CS_INDEX_4 0xFFF4 | |
#define CS_INDEX_5 0xFFF5 | |
#define CS_INDEX_6 0xFFF6 | |
#define CS_INDEX_7 0xFFF7 | |
#define CS_INDEX_8 0xFFF8 | |
#define CS_INDEX_9 0xFFF9 | |
#define CS_INDEX_A 0xFFFA | |
// it's "out of range" even for the largest set of `entrance_table.h` | |
// but `z_demo.c` immediately sets `CS_STATE_STOP` state | |
#define CS_INDEX_UNK_FFFF 0xFFFF | |
// sentinel value used for `cutsceneIndex` to indicate that it should be reset to default | |
#define CS_INDEX_EMPTY 0xFFFD | |
// sentinel value used for `nextCutsceneIndex` to indicate that it is empty | |
// otherwise its value will be copied to `cutsceneIndex` | |
#define CS_INDEX_NEXT_EMPTY 0xFFEF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that is a bit better IMO. I still think that 0xFFFD and 0xFFFF should be named CS_INDEX_D and CS_INDEX_F like the other scripted cutscene indices though, sorry for disagreeing with mzxrules here. Commenting that 0xFFFC and above don't have any corresponding scene layers in the base game is good, but the scene layer bit is only one component of the "cutscene index" system here.
@mzxrules, any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, z_select uses the cutsceneIndex variable differently from the rest of the game, and thus should have separate definitions for values 0x0000 (Night) and 0x8000 (Day) that aren't defined as CS_INDEX values. Otherwise, you will never be able to provide useful names for their values.
0xFFFD is used when executing dozens of cutscenes, the Master Sword is only just one example. Pretty much every time cutsceneTrigger
is set to 1 or 2 it starts such a scripted cutscene. I don't think it makes sense to name this CS_INDEX_EMPTY
0xFFFF seems like an anomaly to me. Idk if it actually represents anything meaningful since in the two instances it appears, the first case should override it with 0xFFFD if I understand the code correctly, and the second should terminate the cutscene.
I think it makes sense for values 0xFFF0-0xFFFA to have a distinction over 0xFFFD and 0xFFFF; values 0xFFF0-0xFFFA actually serve as index offsets for the sceneLayer system in all instances where they appear. 0xFFFD is not and cannot be used for such purposes. 0xFFFF could be, but is not actually being used for such (i.e. you could replace 0xFFFF with any value >= 0xFFF0 that isn't 0xFFFD and achieve the same effect).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
z_select
yeah, it's a special case as by me
I don't think it makes sense to name this CS_INDEX_EMPTY
what does? just CS_INDEX_D
as suggested? looks too "magical", no much better than 0xFFFD
; still, all right, let's
0xFFFF
it does. besides, z_demo.c
sets CS_STATE_STOP
for them right away (Ganon's tower barrier check after each of the beam cutscenes)
Co-authored-by: mzxrules <[email protected]>
and some additional observations reverified with > `check_format.py ...` > `make ...` additionally: - current clang-format lacks a rule for trailing commas - compiler says about them `cfe: Warning 624`
zeldaret#2286 (comment) reverified with > `check_format.py ...` > `make ...`
https://jenkins.deco.mp/job/OOT/job/PR-2286/4/console hmm, i do need this automation locally to
and add a comment chunk from zeldaret#2286 (comment)
it gets assigned to the `nextCutsceneIndex`, so `CS_INDEX_NONE` name was misleading
the purpose of `CS_INDEX_BARRIER` is not quite clear still
`ntsc-1.2` refused to comply though
probably size of enum entries doesn't match well? originally these were just numbers. besides, not like it's a real enumeration from zero to a value or some bit flags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a few comments in the resolved threads, could you un-mark them as resolved? I don't have permission to unresolve them myself
include/z64cutscene.h
Outdated
CS_INDEX_SCRIPTED_D = 0xFFFD, | ||
CS_INDEX_SCRIPTED_E = 0xFFFE, | ||
CS_INDEX_SCRIPTED_F = 0xFFFF, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I like "triggered". Don't values like 0xFFF0 also "trigger" a cutscene?
FWIW I'd prefer calling this CS_INDEX_D, and commenting that values above A do not correspond to any scene layer in the base game (i.e. only used for special cases) instead of trying to encode that in the name. I disagree that values above 0xFFFC are not "directly tied to the scene layer system", there's no check for this in the code, so if some scene did have a layer 19 for example everything would work fine.
This would also reduce the awkwardness with what is currently CS_INDEX_BARRIER
if we call it CS_INDEX_F
instead. Basically, I think all of the scripted cutscenes could be treated uniformly, and we should treat the uses of cutscene D for debug features and the Master Sword as hacks that use the magic value D. This does not seem so different than the fact that z_demo magically knows to use cutscene 1 for CS_DEST_GERUDO_VALLEY_DIN_PART_1
, for example.
(unresolved as needed) |
c91e8c0
to
6efea0a
Compare
@@ -350,7 +350,7 @@ void Scene_DrawConfigTempleOfTime(PlayState* play) { | |||
|
|||
CLOSE_DISPS(play->state.gfxCtx, "../z_scene_table.c", 5145); | |||
|
|||
if (gSaveContext.sceneLayer == 5) { | |||
if (gSaveContext.sceneLayer == GET_CUTSCENE_LAYER(CS_INDEX_1)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (gSaveContext.sceneLayer == GET_CUTSCENE_LAYER(CS_INDEX_1)) { | |
if (gSaveContext.sceneLayer == 5) { |
I'd rather just have layers be defined on a per-scene basis than be a function of CS_INDEX
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, okay, so it was unnecessary for me to do? yeah, probably easier to read and compare with entrance_table.h
when it's indexed the same way, from 0
i was thinking "hey, there's only two instances of gSaveContext.sceneLayer
compared with values [0 .. 3]
"
Line 448 in 67f0eef
if (gSaveContext.sceneLayer != SCENE_LAYER_CHILD_DAY) { Line 457 in 67f0eef
if (gSaveContext.sceneLayer == SCENE_LAYER_ADULT_NIGHT) {
well, if it makes it more difficult, let's revert these line to the original state
while studying the game logic flow, i saw there's a pattern between
Save.entranceIndex
Save.cutsceneIndex
SaveContext.sceneLayer
but values weren't yet described. so, it's time to cleanup my notes and shape them in a proper PR.
(UPD: not anymore) it's a WIP, but i'll start with a draft for visibilityP.S.:
the closest thing i see here is #1300, but
SaveContext.sceneLayer