summaryrefslogtreecommitdiff
path: root/include/z64cutscene_commands.h
blob: 2bcb8f6a489159903bb98204bf2148226dec8f4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
#ifndef Z64CUTSCENE_COMMANDS_H
#define Z64CUTSCENE_COMMANDS_H

#include "command_macros_base.h"
#include "z64cutscene.h"

/**
 * Cutscene scripts are arrays of `CutsceneData` words, including bit-packed integers and floats.
 *
 * Most command macros have unused arguments. This is to account for the vanilla assets setting specific values
 * that don't end up being used by any code. They can safely be set to anything, as they aren't used in the
 * implementation.
 *
 * It is believed the original tool used for cutscenes handled most commands the same way, using similar
 * fields, and the code would have accessed them using common structs. Given this, the unused values observed in vanilla
 * assets may appear to map to a variable that makes sense, even if it doesn't end up being used in the code. It
 * probably isn't garbage data.
 *
 * This codebase goes with specialized structs and macros to make it easier to follow the code.
 * Note this common struct design is still partially reflected in all commands having a `startFrame` and `endFrame`,
 * when sometimes only the `startFrame` matters (as documented).
 */

/**
 * CMD_F expects an (IEEE 754) encoded float (colloquially "in hex", such as `0x42280000`),
 * rather than a C float literal (such as `42.0f`).
 * Float literals cannot be used because cutscenes are arrays of union type CutsceneData, which may contain integers and floats.
 * Regardless of CutsceneData having a float member, initializing with a float will cast the float to s32.
 * Designated initializers (added in C99) would solve this problem but are not supported by IDO (C89 and some extensions).
 */
#ifdef __GNUC__
#define CS_FLOAT(ieee754bin, f) (f)
#else
#define CS_FLOAT(ieee754bin, f) (ieee754bin)
#endif

/**
 * Marks the beginning of a cutscene script.
 * 
 * ARGS
 *   s32 totalEntries (e), s32 frameCount (n)
 * FORMAT
 *   eeeeeeee nnnnnnnn
 *   size = 0x8
 */
#define CS_BEGIN_CUTSCENE(totalEntries, frameCount) { CMD_W(totalEntries) }, { CMD_W(frameCount) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000000A eeeeeeee
 *   size = 0x8
 */
#define CS_TEXT_LIST(entries) { CS_CMD_TEXT }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 textId (i), s16 startFrame (s), s16 endFrame (e), s16 type (o),
 *   s16 topOptionBranch (y), s16 bottomOptionBranch (n)
 * FORMAT
 *   iiiissss eeeeoooo yyyynnnn
 *   size = 0xC
 */
#define CS_TEXT(textId, startFrame, endFrame, type, topOptionBranch, bottomOptionBranch) \
    { CMD_HH(textId, startFrame) }, { CMD_HH(endFrame, type) }, { CMD_HH(topOptionBranch, bottomOptionBranch) }

/**
 * ARGS
 *   s16 textId (i), s16 startFrame (s), s16 endFrame (e),
 *   s16 topOptionBranch (y), s16 bottomOptionBranch (n)
 * FORMAT
 *   iiiissss eeee0000 yyyynnnn
 *   size = 0xC
 */
#define CS_TEXT_DEFAULT(textId, startFrame, endFrame, topOptionBranch, bottomOptionBranch) \
    CS_TEXT(textId, startFrame, endFrame, CS_TEXT_TYPE_DEFAULT, topOptionBranch, bottomOptionBranch)

/**
 * ARGS
 *   s16 textId (i), s16 startFrame (s), s16 endFrame (e),
 *   s16 topOptionBranch (y), s16 bottomOptionBranch (n)
 * FORMAT
 *   iiiissss eeee0001 yyyynnnn
 *   size = 0xC
 */
#define CS_TEXT_TYPE_1(textId, startFrame, endFrame, topOptionBranch, bottomOptionBranch) \
    CS_TEXT(textId, startFrame, endFrame, CS_TEXT_TYPE_1, topOptionBranch, bottomOptionBranch)

/**
 * ARGS
 *   s16 ocarinaSongAction (o), s16 startFrame (s), s16 endFrame (e), s16 textId (i)
 * FORMAT
 *   oooossss eeee0002 iiiiFFFF
 *   size = 0xC
 */
#define CS_TEXT_OCARINA_ACTION(ocarinaSongAction, startFrame, endFrame, textId) \
    CS_TEXT(ocarinaSongAction, startFrame, endFrame, CS_TEXT_OCARINA_ACTION, textId, 0xFFFF)

/**
 * ARGS
 *   s16 textId (i), s16 startFrame (s), s16 endFrame (e),
 *   s16 topOptionBranch (y), s16 bottomOptionBranch (n)
 * FORMAT
 *   iiiissss eeee0003 yyyynnnn
 *   size = 0xC
 */
#define CS_TEXT_TYPE_3(textId, startFrame, endFrame, topOptionBranch, bottomOptionBranch) \
    CS_TEXT(textId, startFrame, endFrame, CS_TEXT_TYPE_3, topOptionBranch, bottomOptionBranch)

/**
 * If Player has all 4 bosses' remains then alternativeTextId is used, otherwise defaultTextId is used
 * ARGS
 *   s16 defaultTextId (d), s16 startFrame (s), s16 endFrame (e), s16 alternativeTextId (a)
 * FORMAT
 *   ddddssss eeee0004 aaaaFFFF
 *   size = 0xC
 */
#define CS_TEXT_BOSSES_REMAINS(defaultTextId, startFrame, endFrame, alternativeTextId) \
    CS_TEXT(defaultTextId, startFrame, endFrame, CS_TEXT_TYPE_BOSSES_REMAINS, alternativeTextId, 0xFFFF)

/**
 * If Player has every non-transformation mask then alternativeTextId is used, otherwise defaultTextId is used
 * ARGS
 *   s16 defaultTextId (d), s16 startFrame (s), s16 endFrame (e), s16 alternativeTextId (a)
 * FORMAT
 *   ddddssss eeee0005 aaaaFFFF
 *   size = 0xC
 */
#define CS_TEXT_ALL_NORMAL_MASKS(defaultTextId, startFrame, endFrame, alternativeTextId) \
    CS_TEXT(defaultTextId, startFrame, endFrame, CS_TEXT_TYPE_ALL_NORMAL_MASKS, alternativeTextId, 0xFFFF)

/**
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   FFFFssss eeeeFFFF FFFFFFFF
 *   size = 0xC
 */
#define CS_TEXT_NONE(startFrame, endFrame) \
    CS_TEXT(0xFFFF, startFrame, endFrame, CS_TEXT_TYPE_NONE, 0xFFFF, 0xFFFF)


/**
 * ARGS
 *   s32 numBytes (b)
 * FORMAT
 *   0000005A bbbbbbbb
 *   size = 0x8
 */
#define CS_CAM_SPLINE_LIST(numBytes) { CS_CMD_CAMERA_SPLINE }, { CMD_W(numBytes) }

/**
 * ARGS
 *   s16 numEntries (e), s16 duration (d)
 * FORMAT
 *   Capital U is Unused
 *   eeeeUUUU UUUUdddd
 *   size = 0x8
 */
#define CS_CAM_SPLINE(numEntries, unused0, unused1, duration) \
    { CMD_HH(numEntries, unused0) }, { CMD_HH(unused1, duration) }

/**
 * ARGS
 *   u8 interpType (i), u8 weight (2), s16 duration (d), Vec3s pos (x/y/z), s16 relativeTo (r)
 * FORMAT
 *   ii22dddd xxxxyyyy zzzzrrrr
 *   size = 0xC
 */
#define CS_CAM_POINT(interpType, weight, duration, posX, posY, posZ, relativeTo) \
    { CMD_BBH(interpType, weight, duration) }, { CMD_HH(posX, posY) }, { CMD_HH(posZ, relativeTo) }

/**
 * ARGS
 *   s16 roll (r), s16 fov (f)
 * FORMAT
 *   Capital U is Unused
 *   UUUUrrrr ffffUUUU
 *   size = 0x8
 */
#define CS_CAM_MISC(unused0, roll, fov, unused1) \
    { CMD_HH(unused0, roll) }, { CMD_HH(fov, unused1) }

// First half-word is read from as `numEntries` in `CS_CAM_SPLINE()`
#define CS_CAM_END() { CMD_HH(0xFFFF, 4) }


/**
 * Declares a list of `CS_MISC` entries.
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000096 eeeeeeee
 *   size = 0x8
 */
#define CS_MISC_LIST(entries) { CS_CMD_MISC }, { CMD_W(entries) }

/**
 * Various miscellaneous commands.
 * @see `CutsceneMiscType` enum for the different types of commands.
 * @note setting `endFrame` to same value as `startFrame` will not behave as expected.
 * For commands that only need to last one frame, set `endFrame` to `startFrame + 1`.
 * 
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_MISC(type, startFrame, endFrame, unused0) \
    { CMD_HH(type, startFrame) }, { CMD_HH(endFrame, unused0) }


/**
 * Declares a list of `CS_LIGHT_SETTING` entries.
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000097 eeeeeeee
 *   size = 0x8
 */
#define CS_LIGHT_SETTING_LIST(entries) { CS_CMD_LIGHT_SETTING }, { CMD_W(entries) }

/**
 * Changes the environment lights to the specified setting.
 * The lighting change will take place immediately with no blending.
 * 
 * ARGS
 *   s16 setting (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_LIGHT_SETTING(lightSetting, startFrame, endFrame) \
    { CMD_BBH(0, (lightSetting + 1), startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000098 eeeeeeee
 *   size = 0x8
 */
#define CS_TRANSITION_LIST(entries) { CS_CMD_TRANSITION }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_TRANSITION(type, startFrame, endFrame) \
    { CMD_HH(type, startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000099 eeeeeeee
 *   size = 0x8
 */
#define CS_MOTION_BLUR_LIST(entries) { CS_CMD_MOTION_BLUR }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_MOTION_BLUR(type, startFrame, endFrame) \
    { CMD_HH(type, startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000009A eeeeeeee
 *   size = 0x8
 */
#define CS_GIVE_TATL_LIST(entries) { CS_CMD_GIVE_TATL }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 giveTatl (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_GIVE_TATL(giveTatl, startFrame, endFrame) \
    { CMD_HH(giveTatl, startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000009B eeeeeeee
 *   size = 0x8
 */
#define CS_TRANSITION_GENERAL_LIST(entries) { CS_CMD_TRANSITION_GENERAL }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e),
 *   u8 red (r), u8 green (g), blue (b)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeerrgg bbUUUUUU
 *   size = 0xC
 */
#define CS_TRANSITION_GENERAL(type, startFrame, endFrame, red, green, blue) \
    { CMD_HH(type, startFrame) }, { CMD_HBB(endFrame, red, green) }, { CMD_BBBB(blue, 0, 0, 0) }


/**
 * Declares a list of `CS_TIME` entries.
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000009D eeeeeeee
 *   size = 0x8
 */
#define CS_TIME_LIST(entries) { CS_CMD_TIME }, { CMD_W(entries) }

/**
 * Sets the time of day.
 * Both the day time and skybox time are set by this command.
 * @note `endFrame` is not used in the implementation of the command, so its value does not matter
 * 
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e), s8 hour (h), s8 min (m)
 * FORMAT
 *   Capital U is Unused
 *   UUUUssss eeeehhmm UUUUUUUU
 *   size = 0xC
 */
#define CS_TIME(unused0, startFrame, endFrame, hour, min) \
    { CMD_HH(unused0, startFrame) }, { CMD_HBB(endFrame, hour, min) }, { CMD_W(0) }


/**
 * Declares a list of `CS_ACTOR_CUE` entries.
 * 
 * ARGS
 *   s32 cmdType (c), s32 entries (e)
 * FORMAT
 *   cccccccc eeeeeeee
 *   size = 0x8
 */
#define CS_ACTOR_CUE_LIST(cmdType, entries) { CMD_W(cmdType) }, { CMD_W(entries) }

/**
 * Defines a cue that an actor can listen for. 
 * The actor can choose whether or not to use the position and rotation data supplied to it.
 * The cue `id` is a number that has an actor-specific meaning.
 * 
 * ARGS
 *   s16 id (a),        s16 startFrame (s), s16 endFrame (e),
 *   s16 rotX (u),      s16 rotY (v),       s16 rotZ (w),
 *   s32 startX (i),    s32 startY (j),     s32 startZ (k),
 *   s32 endX (l),      s32 endY (m),       s32 endZ (n),
 *   f32 normX (x),     f32 normY (y),      f32 normZ (z),
 * FORMAT
 *   aaaassss eeeeuuuu vvvvwwww iiiiiiii jjjjjjjj kkkkkkkk llllllll mmmmmmmm nnnnnnnn xxxxxxxx yyyyyyyy zzzzzzzz
 *   size = 0x30
 */
#define CS_ACTOR_CUE(id, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) \
    { CMD_HH(id, startFrame) }, { CMD_HH(endFrame, rotX) }, { CMD_HH(rotY, rotZ) }, \
    { CMD_W(startX) }, { CMD_W(startY) }, { CMD_W(startZ) }, \
    { CMD_W(endX) }, { CMD_W(endY) }, { CMD_W(endZ) }, \
    { CMD_F(normX) }, { CMD_F(normY) }, { CMD_F(normZ) }


/**
 * Declares a list of `CS_PLAYER_CUE` entries.
 * 
 * ARGS
 *   s32 cmdType (c), s32 entries (e)
 * FORMAT
 *   000000C8 eeeeeeee
 *   size = 0x8
 */
#define CS_PLAYER_CUE_LIST(entries) { CS_CMD_PLAYER_CUE }, { CMD_W(entries) }

/**
 * A player cue is the same as `CS_ACTOR_CUE` but is specifically for player. 
 * 
 * ARGS
 *   s16 id (a),         s16 startFrame (s), s16 endFrame (e),
 *   s16 rotX (u),       s16 rotY (v),       s16 rotZ (w),
 *   s32 startX (i),     s32 startY (j),     s32 startZ (k),
 *   s32 endX (l),       s32 endY (m),       s32 endZ (n),
 *   f32 normX (x),      f32 normY (y),      f32 normZ (z),
 * FORMAT
 *   aaaassss eeeeuuuu vvvvwwww iiiiiiii jjjjjjjj kkkkkkkk llllllll mmmmmmmm nnnnnnnn xxxxxxxx yyyyyyyy zzzzzzzz
 *   size = 0x30
 */
#define CS_PLAYER_CUE(id, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) \
    CS_ACTOR_CUE(id, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ)


/**
 * Declares a list of `CS_START_SEQ` entries.
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000012C eeeeeeee
 *   size = 0x8
 */
#define CS_START_SEQ_LIST(entries) \
    { CS_CMD_START_SEQ }, { CMD_W(entries) }

/**
 * Starts a sequence at the specified time.
 * @note `endFrame` is not used in the implementation of the command, so its value does not matter
 * 
 * ARGS
 *   s16 seqId (i), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   iiiissss eeeeUUUU
 *   size = 0x8
 */
#define CS_START_SEQ(seqId, startFrame, endFrame) \
    { CMD_HH((seqId + 1), startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * Declares a list of `CS_STOP_SEQ` entries.
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000133 eeeeeeee
 *   size = 0x8
 */
#define CS_STOP_SEQ_LIST(entries) { CS_CMD_STOP_SEQ }, { CMD_W(entries) }

/**
 * Stops a sequence at the specified time.
 * 
 * ARGS
 *   s16 seqId (i), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   iiiissss eeeeUUUU
 *   size = 0x8
 */
#define CS_STOP_SEQ(seqId, startFrame, endFrame, unk_06) \
    { CMD_HH((seqId + 1), startFrame) }, { CMD_HH(endFrame, unk_06) }


/**
 *  Stops a sequence at the specified time.
 * @note `endFrame` is not used in the implementation of the command, so its value does not matter
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000009C eeeeeeee
 *   size = 0x8
 */
#define CS_FADE_OUT_SEQ_LIST(entries) { CS_CMD_FADE_OUT_SEQ }, { CMD_W(entries) }

/**
 *  Fade out the sequence that is playing on the specified sequence player, over the specified frame range.
 * @see `CutsceneFadeOutSeqPlayer`
 * 
 * ARGS
 *   s16 seqPlayer (p), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ppppssss eeeeUUUU UUUUUUUU
 *   size = 0xC
 */
#define CS_FADE_OUT_SEQ(seqPlayer, startFrame, endFrame) \
    { CMD_HH(seqPlayer, startFrame) }, { CMD_HH(endFrame, 0) }, { CMD_W(0) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000134 eeeeeeee
 *   size = 0x8
 */
#define CS_START_AMBIENCE_LIST(entries) { CS_CMD_START_AMBIENCE }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   UUUUssss eeeeUUUU
 *   size = 0x8
 */
#define CS_START_AMBIENCE(unused0, startFrame, endFrame) \
    { CMD_HH(unused0, startFrame) }, { CMD_HH(endFrame, 0) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000135 eeeeeeee
 *   size = 0x8
 */
#define CS_FADE_OUT_AMBIENCE_LIST(entries) { CS_CMD_FADE_OUT_AMBIENCE }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   UUUUssss eeeeUUUU
 *   size = 0x8
 */
#define CS_FADE_OUT_AMBIENCE(unused0, startFrame, endFrame) \
    { CMD_HH(unused0, startFrame) }, { CMD_HH(endFrame, 0) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000132 eeeeeeee
 *   size = 0x8
 */
#define CS_MODIFY_SEQ_LIST(entries) { CS_CMD_MODIFY_SEQ }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_MODIFY_SEQ(type, startFrame, endFrame) \
    { CMD_HH(type, startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000130 eeeeeeee
 *   size = 0x8
 */
#define CS_SFX_REVERB_INDEX_2_LIST(entries) { CS_CMD_SFX_REVERB_INDEX_2 }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   UUUUssss eeeeUUUU
 *   size = 0x30
 */
#define CS_SFX_REVERB_INDEX_2(unused0, startFrame, endFrame) \
    { CMD_HH(unused0, startFrame) }, { CMD_HH(endFrame, 0) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000131 eeeeeeee
 *   size = 0x8
 */
#define CS_SFX_REVERB_INDEX_1_LIST(entries) { CS_CMD_SFX_REVERB_INDEX_1 }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   UUUUssss eeeeUUUU
 *   size = 0x8
 */
#define CS_SFX_REVERB_INDEX_1(unused0, startFrame, endFrame) \
    { CMD_HH(unused0, startFrame) }, { CMD_HH(endFrame, 0) }


/**
 * Declares a list of `CS_DESTINATION` entries.
 * 
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000015E eeeeeeee
 *   size = 0x8
 */
#define CS_DESTINATION_LIST(entries) { CS_CMD_DESTINATION }, { CMD_W(entries) }

/**
 *  Sends the player to a new destination using the entry defined in `CutsceneScriptEntry`.
 * 
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_DESTINATION(type, startFrame, endFrame) \
    { CMD_HH(type, startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   0000015F eeeeeeee
 *   size = 0x8
 */
#define CS_CHOOSE_CREDITS_SCENES_LIST(entries) { CS_CMD_CHOOSE_CREDITS_SCENES }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_CHOOSE_CREDITS_SCENES(type, startFrame, endFrame) \
    { CMD_HH(type, startFrame) }, { CMD_HH(endFrame, endFrame) }


/**
 * ARGS
 *   s32 entries (e)
 * FORMAT
 *   00000004 eeeeeeee
 *   size = 0x8
 */
#define CS_RUMBLE_LIST(entries) { CS_CMD_RUMBLE }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 type (t), s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   ttttssss eeeeUUUU
 *   size = 0x8
 */
#define CS_RUMBLE(type, startFrame, endFrame, intensity, decayTimer, decayStep) \
    { CMD_HH(type, startFrame) }, { CMD_HBB(endFrame, intensity, decayTimer) }, { CMD_BBBB(decayStep, 0, 0, 0) }


/**
 * ARGS
 *   s32 cmd (c), s32 entries (e)
 * FORMAT
 *   cccccccc eeeeeeee
 *   size = 0x8
 */
#define CS_UNK_DATA_LIST(cmd, entries) { CMD_W(cmd) }, { CMD_W(entries) }

/**
 * ARGS
 *   s16 startFrame (s), s16 endFrame (e)
 * FORMAT
 *   Capital U is Unused
 *   UUUUssss eeeeUUUU
 *   size = 0x8
 */
#define CS_UNK_DATA(unused0, startFrame, endFrame, unk_06) \
    { CMD_HH(unused0, startFrame) }, { CMD_HH(endFrame, unk_06) }


/**
 * Marks the end of a cutscene
 */
#define CS_END() { CMD_W(0xFFFFFFFF) }

#define CS_PLAYSEQ(seqId, startFrame, endFrame) \
CS_START_SEQ((seqId)-1, startFrame, endFrame)

#define CS_STOPSEQ(seqId, startFrame, endFrame, unk_06) \
CS_STOP_SEQ((seqId)-1, startFrame, endFrame, unk_06)

#define CS_LIGHTING(lightSetting, startFrame, endFrame) \
CS_LIGHT_SETTING((lightSetting)-1, startFrame, endFrame)

#endif