Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-CD-2011-Script-Decompilation
Path: blob/main/Scripts/R7/Spotlights.txt
1319 views
1
//-----------------Sonic CD Spotlights Script-----------------//
2
//--------Scripted by Christian Whitehead 'The Taxman'--------//
3
//-------Unpacked By Rubberduckycooly's Script Unpacker-------//
4
5
// Aliases
6
7
// Position for where the checkpoint should progress to its next version
8
#alias Object.Value1 : Object.Checkpoint
9
10
// The colors the Spotlight should use
11
// Just like everything else, these colors are in RRGGBB
12
#alias Object.Value2 : Object.PrimaryBaseColor
13
#alias Object.Value3 : Object.SecondaryBaseColor
14
#alias Object.Value4 : Object.PrimaryDisplayColor
15
#alias Object.Value5 : Object.SecondaryDisplayColor
16
17
// There are several different types of spotlights that appear in the stage
18
#alias Object.Value0 : Object.SpotlightType
19
// 0 - Pair of two primary ones
20
// - Using SSZ1A's, it's the two big green ones
21
// 1 - Single primary one
22
// - Using SSZ1A's, it's a single green one
23
// 2 - Pair of two secondary ones
24
// - Using SSZ1A's, it's the two yellow ones
25
// 3 - Single small primary one
26
// - Using SSZ1A's, it's a single small green one
27
// 4 - Pair of primary and secondary
28
// - Using SSZ1A's, the pair of a small green one with a big yellow one
29
// Then it loops back
30
31
// HUD Alias
32
#alias Object[24].PropertyValue : HUD.CurrentTimePeriod
33
34
// Time Periods
35
#alias 0 : TIME_PRESENT
36
#alias 2 : TIME_GOOD_FUTURE
37
#alias 3 : TIME_BAD_FUTURE
38
39
// Face Buffer Flags
40
#alias 3 : FACE_FLAG_COLOURED_2D
41
42
// Priority
43
#alias 1 : PRIORITY_ACTIVE
44
45
// Function declarations
46
#function Spotlights_UpdateCorner
47
48
49
function Spotlights_UpdateCorner
50
51
// Called individually for each corner in a spotlight to update it
52
53
// Preconditions:
54
// - ArrayPos0 is the ID of the vertex that should be changes
55
// - TempValue0 is the X multiplier for how much extra this vertex should move
56
// - TempValue1 is the Y multiplier for how much extra this vertex should move
57
// (These last two values are here since spotlights aren't uniform in width - they can be skewed to uneven dimensions as well)
58
59
60
Sin(TempValue2, Object.Rotation)
61
TempValue2 *= TempValue1
62
63
Cos(TempValue3, Object.Rotation)
64
TempValue3 *= TempValue0
65
66
VertexBuffer[ArrayPos0].x = TempValue2
67
VertexBuffer[ArrayPos0].x -= TempValue3
68
VertexBuffer[ArrayPos0].x >>= 9
69
VertexBuffer[ArrayPos0].x += Object.XPos
70
71
Cos(TempValue2, Object.Rotation)
72
TempValue2 *= TempValue1
73
74
Sin(TempValue3, Object.Rotation)
75
TempValue3 *= TempValue0
76
77
VertexBuffer[ArrayPos0].y = TempValue2
78
VertexBuffer[ArrayPos0].y += TempValue3
79
VertexBuffer[ArrayPos0].y >>= 9
80
VertexBuffer[ArrayPos0].y += 256
81
82
end function
83
84
85
sub ObjectMain
86
TempValue0 = Oscillation
87
TempValue0 <<= 2
88
89
// Get some smooth arc movement values
90
91
Sin(TempValue1, TempValue0)
92
TempValue1 >>= 5
93
TempValue1 += 64
94
95
Cos(TempValue2, TempValue0)
96
TempValue2 >>= 5
97
TempValue2 += 64
98
99
// Make the spotlight colors oscillate
100
101
Object.PrimaryDisplayColor = TempValue1
102
Object.PrimaryDisplayColor <<= 24
103
Object.PrimaryDisplayColor += Object.PrimaryBaseColor
104
105
Object.SecondaryDisplayColor = TempValue2
106
Object.SecondaryDisplayColor <<= 24
107
Object.SecondaryDisplayColor += Object.SecondaryBaseColor
108
109
// Check if the current spotlight type should be switched
110
111
TempValue0 = Screen.XOffset
112
TempValue0 += Screen.CenterX
113
if TempValue0 > Object.Checkpoint
114
TempValue0 -= Object.Checkpoint
115
if TempValue0 > 440
116
// Move the next checkpoint ahead
117
Object.Checkpoint += 880
118
119
// Trigger the next spotlight type to start
120
Object.SpotlightType++
121
122
if Object.SpotlightType > 4
123
// Loop back
124
Object.SpotlightType = 0
125
end if
126
end if
127
else
128
TempValue0 -= Object.Checkpoint
129
if TempValue0 < -440
130
// Move the next checkpoint back
131
Object.Checkpoint -= 880
132
133
// Trigger the next spotlight type to start
134
Object.SpotlightType--
135
136
if Object.SpotlightType < 0
137
// Loop ahead
138
Object.SpotlightType = 4
139
end if
140
end if
141
end if
142
143
// Scroll the spotlight
144
Object.XPos = Object.Checkpoint
145
Object.XPos -= Screen.XOffset
146
147
// Different handlings for the different types of spotlights
148
switch Object.SpotlightType
149
case 0
150
// Pair of two primary spotlights
151
152
// Make these spotlights draw above the rest of the stage & its objects
153
Object.DrawOrder = 5
154
155
// 2 rectangles means 8 vertices and 2 faces
156
3DScene.NoVertices = 8
157
3DScene.NoFaces = 2
158
159
// 1st Spotlight offset - move it a bit to the left
160
Object.XPos -= 48
161
162
// Mirror the face color to match the targetted color
163
FaceBuffer[0].Color = Object.PrimaryDisplayColor
164
FaceBuffer[1].Color = Object.PrimaryDisplayColor
165
166
167
// First do spotlight 1 (the left one)
168
169
// Get the base rotation for the spotlight
170
171
TempValue0 = Oscillation
172
TempValue0 <<= 1
173
Sin(Object.Rotation, TempValue0)
174
if Object.Rotation > 0
175
// Enforce that the spotlight never goes towards the left
176
FlipSign(Object.Rotation)
177
end if
178
Object.Rotation /= 10
179
Object.Rotation += 512
180
181
// And now move all the vertexes for it
182
183
// Top right
184
ArrayPos0 = 0
185
TempValue0 = -16
186
TempValue1 = -384
187
CallFunction(Spotlights_UpdateCorner)
188
189
// Top left
190
ArrayPos0++
191
TempValue0 = 16
192
TempValue1 = -384
193
CallFunction(Spotlights_UpdateCorner)
194
195
// Bottom right
196
ArrayPos0++
197
TempValue0 = -8
198
TempValue1 = 0
199
CallFunction(Spotlights_UpdateCorner)
200
201
// Bottom left
202
ArrayPos0++
203
TempValue0 = 8
204
TempValue1 = 0
205
CallFunction(Spotlights_UpdateCorner)
206
207
ArrayPos0++
208
209
// And now update the other spotlight (to the right)
210
211
// Move the sedong spotlight to the right
212
// (48 px from the base spotlight position)
213
Object.XPos += 96
214
215
TempValue0 = Oscillation
216
TempValue0 <<= 1
217
Sin(Object.Rotation, TempValue0)
218
Object.Rotation /= 10
219
Object.Rotation += 512
220
221
// Top right
222
TempValue0 = -16
223
TempValue1 = -384
224
CallFunction(Spotlights_UpdateCorner)
225
226
// Top left
227
ArrayPos0++
228
TempValue0 = 16
229
TempValue1 = -384
230
CallFunction(Spotlights_UpdateCorner)
231
232
// Bottom right
233
ArrayPos0++
234
TempValue0 = -8
235
TempValue1 = 0
236
CallFunction(Spotlights_UpdateCorner)
237
238
// Bottom left
239
ArrayPos0++
240
TempValue0 = 8
241
TempValue1 = 0
242
CallFunction(Spotlights_UpdateCorner)
243
244
ArrayPos0++
245
break
246
247
case 1
248
// Single primary spotlight
249
250
// Make this object draw in the background
251
Object.DrawOrder = 2
252
253
// 1 rectangle means 4 vertices and 1 face
254
3DScene.NoVertices = 4
255
3DScene.NoFaces = 1
256
257
// Set its color to what it should be
258
FaceBuffer[0].Color = Object.PrimaryDisplayColor
259
260
// Handle spotlight movement
261
TempValue0 = Oscillation
262
TempValue0 <<= 1
263
Sin(Object.Rotation, TempValue0)
264
Object.Rotation >>= 3
265
Object.Rotation += 512
266
267
// Top right
268
ArrayPos0 = 0
269
TempValue0 = -16
270
TempValue1 = -384
271
CallFunction(Spotlights_UpdateCorner)
272
273
// Top left
274
ArrayPos0++
275
TempValue0 = 16
276
TempValue1 = -384
277
CallFunction(Spotlights_UpdateCorner)
278
279
// Bottom right
280
ArrayPos0++
281
TempValue0 = -8
282
TempValue1 = 0
283
CallFunction(Spotlights_UpdateCorner)
284
285
// Bottom left
286
ArrayPos0++
287
TempValue0 = 8
288
TempValue1 = 0
289
CallFunction(Spotlights_UpdateCorner)
290
291
ArrayPos0++
292
break
293
294
case 2
295
// Two secondary spotlights
296
297
// Make it draw above everything else again
298
Object.DrawOrder = 5
299
300
// 2 spotlight rectangles means 8 vertices and 2 faces
301
3DScene.NoVertices = 8
302
3DScene.NoFaces = 2
303
304
// Set the display colors...
305
FaceBuffer[0].Color = Object.SecondaryDisplayColor
306
FaceBuffer[1].Color = Object.SecondaryDisplayColor
307
308
// ...and then apply the spotlight offset...
309
Object.XPos -= 48
310
311
// ..but then set the colors again? Why is this done twice?
312
FaceBuffer[0].Color = Object.SecondaryDisplayColor
313
FaceBuffer[1].Color = Object.SecondaryDisplayColor
314
315
// Make the spotlight move
316
TempValue0 = Oscillation
317
TempValue0 <<= 1
318
Sin(Object.Rotation, TempValue0)
319
Object.Rotation >>= 4
320
Object.Rotation += 500
321
322
// Move all the vertexes as needed
323
324
// Top right
325
ArrayPos0 = 0
326
TempValue0 = -20
327
TempValue1 = -384
328
CallFunction(Spotlights_UpdateCorner)
329
330
// Top left
331
ArrayPos0++
332
TempValue0 = 20
333
TempValue1 = -384
334
CallFunction(Spotlights_UpdateCorner)
335
336
// Bottom right
337
ArrayPos0++
338
TempValue0 = -10
339
TempValue1 = 0
340
CallFunction(Spotlights_UpdateCorner)
341
342
// Bottom left
343
ArrayPos0++
344
TempValue0 = 10
345
TempValue1 = 0
346
CallFunction(Spotlights_UpdateCorner)
347
348
ArrayPos0++
349
350
// Do spotlight 2 now, starting with its small X offset
351
Object.XPos += 96
352
353
TempValue0 = Oscillation
354
TempValue0 += 32
355
TempValue0 <<= 1
356
Sin(Object.Rotation, TempValue0)
357
Object.Rotation >>= 3
358
Object.Rotation += 508
359
360
// Top right
361
TempValue0 = -16
362
TempValue1 = -420
363
CallFunction(Spotlights_UpdateCorner)
364
365
// Top left
366
ArrayPos0++
367
TempValue0 = 16
368
TempValue1 = -420
369
CallFunction(Spotlights_UpdateCorner)
370
371
// Bottom right
372
ArrayPos0++
373
TempValue0 = -8
374
TempValue1 = 0
375
CallFunction(Spotlights_UpdateCorner)
376
377
// Bottom left
378
ArrayPos0++
379
TempValue0 = 8
380
TempValue1 = 0
381
CallFunction(Spotlights_UpdateCorner)
382
383
ArrayPos0++
384
break
385
386
case 3
387
// Single small primary spotlight
388
389
// This version should draw above everything else as well
390
Object.DrawOrder = 5
391
392
// 1 spotlight rectangle has four corners and one face
393
3DScene.NoVertices = 4
394
3DScene.NoFaces = 1
395
396
FaceBuffer[0].Color = Object.PrimaryDisplayColor
397
398
// Bounce the spotlight as needed
399
TempValue0 = 512
400
TempValue0 -= Oscillation
401
TempValue0 *= 3
402
Sin(Object.Rotation, TempValue0)
403
Object.Rotation /= 12
404
Object.Rotation += 520
405
406
// Top right
407
ArrayPos0 = 0
408
TempValue0 = -12
409
TempValue1 = -384
410
CallFunction(Spotlights_UpdateCorner)
411
412
// Top left
413
ArrayPos0++
414
TempValue0 = 12
415
TempValue1 = -384
416
CallFunction(Spotlights_UpdateCorner)
417
418
// Bottom right
419
ArrayPos0++
420
TempValue0 = -4
421
TempValue1 = 0
422
CallFunction(Spotlights_UpdateCorner)
423
424
// Bottom left
425
ArrayPos0++
426
TempValue0 = 4
427
TempValue1 = 0
428
CallFunction(Spotlights_UpdateCorner)
429
ArrayPos0++
430
break
431
432
case 4
433
// A pair of primary and secondary spotlights
434
435
// This variant should draw in the BG
436
Object.DrawOrder = 2
437
438
// 2 rectangles means that there should be 8 vertices and 2 faces
439
3DScene.NoVertices = 8
440
3DScene.NoFaces = 2
441
442
Object.XPos -= 48
443
444
FaceBuffer[0].Color = Object.PrimaryDisplayColor
445
FaceBuffer[1].Color = Object.SecondaryDisplayColor
446
447
// First do spotlight 1
448
449
// Update its rotation
450
TempValue0 = Oscillation
451
TempValue0 += 64
452
TempValue0 <<= 2
453
Sin(Object.Rotation, TempValue0)
454
Object.Rotation /= 20
455
Object.Rotation += 496
456
457
// Top right
458
ArrayPos0 = 0
459
TempValue0 = -14
460
TempValue1 = -420
461
CallFunction(Spotlights_UpdateCorner)
462
463
// Top left
464
ArrayPos0++
465
TempValue0 = 14
466
TempValue1 = -420
467
CallFunction(Spotlights_UpdateCorner)
468
469
// Bottom right
470
ArrayPos0++
471
TempValue0 = -4
472
TempValue1 = 0
473
CallFunction(Spotlights_UpdateCorner)
474
475
// Bottom left
476
ArrayPos0++
477
TempValue0 = 4
478
TempValue1 = 0
479
CallFunction(Spotlights_UpdateCorner)
480
481
ArrayPos0++
482
483
// Do spotlight 2 now
484
485
// Total shift of 48 from its starting position, keeping the above subtraction of 48 in mind
486
Object.XPos += 96
487
488
// Rotate the spotlight
489
TempValue0 = Oscillation
490
TempValue0 <<= 1
491
Sin(Object.Rotation, TempValue0)
492
Object.Rotation >>= 4
493
Object.Rotation += 520
494
495
// Top right
496
TempValue0 = -24
497
TempValue1 = -420
498
CallFunction(Spotlights_UpdateCorner)
499
500
// Top left
501
ArrayPos0++
502
TempValue0 = 24
503
TempValue1 = -420
504
CallFunction(Spotlights_UpdateCorner)
505
506
// Bottom right
507
ArrayPos0++
508
TempValue0 = -16
509
TempValue1 = 0
510
CallFunction(Spotlights_UpdateCorner)
511
512
// Bottom left
513
ArrayPos0++
514
TempValue0 = 16
515
TempValue1 = 0
516
CallFunction(Spotlights_UpdateCorner)
517
518
ArrayPos0++
519
break
520
521
end switch
522
523
end sub
524
525
526
sub ObjectDraw
527
// The spotlights are all 3d, so instead of drawing sprites, draw the entire 3d scene instead
528
Draw3DScene()
529
530
end sub
531
532
533
sub ObjectStartup
534
535
// Reset the 3d stuff
536
MatrixTranslateXYZ(MAT_WORLD, 0, 0, 0)
537
MatrixTranslateXYZ(MAT_VIEW, 0, 0, 0)
538
539
// Setup the first spotlight
540
FaceBuffer[0].a = 0
541
FaceBuffer[0].b = 1
542
FaceBuffer[0].c = 2
543
FaceBuffer[0].d = 3
544
FaceBuffer[0].Flag = FACE_FLAG_COLOURED_2D
545
546
// Setup the second spotlight
547
FaceBuffer[1].a = 4
548
FaceBuffer[1].b = 5
549
FaceBuffer[1].c = 6
550
FaceBuffer[1].d = 7
551
FaceBuffer[1].Flag = FACE_FLAG_COLOURED_2D
552
553
// Loop through all obejcts in the stage and setup all Spotlights objects
554
ArrayPos0 = 32
555
while ArrayPos0 < 1056
556
if Object[ArrayPos0].Type == TypeName[Spotlights]
557
558
// Spotlights should always be active
559
Object[ArrayPos0].Priority = PRIORITY_ACTIVE
560
561
// The default draw priority for a spotlight should be above the stage & objects but below the HUD
562
Object[ArrayPos0].DrawOrder = 5
563
564
// And set up the initial starting checkpoint value as well
565
Object[ArrayPos0].Checkpoint = Screen.CenterX
566
567
// Setup the Spotlight's colors based on the current time period
568
switch HUD.CurrentTimePeriod
569
case TIME_PRESENT
570
// Present gets standard colors - set the primary spotlight to green
571
Object[ArrayPos0].PrimaryBaseColor = 128
572
Object[ArrayPos0].PrimaryBaseColor <<= 16
573
TempValue0 = 224
574
TempValue0 <<= 8
575
Object[ArrayPos0].PrimaryBaseColor += TempValue0
576
Object[ArrayPos0].PrimaryBaseColor += 128
577
578
// Set the secondary spotlight to yellow
579
Object[ArrayPos0].SecondaryBaseColor = 224
580
Object[ArrayPos0].SecondaryBaseColor <<= 16
581
TempValue0 = 224
582
TempValue0 <<= 8
583
Object[ArrayPos0].SecondaryBaseColor += TempValue0
584
Object[ArrayPos0].SecondaryBaseColor += 0
585
break
586
587
// No case 1 since spotlights didn't even exist in the Past...
588
589
case TIME_GOOD_FUTURE
590
// The Good Future gets nice and bright colors - primary spotlight is brown
591
Object[ArrayPos0].PrimaryBaseColor = 192
592
Object[ArrayPos0].PrimaryBaseColor <<= 16
593
TempValue0 = 128
594
TempValue0 <<= 8
595
Object[ArrayPos0].PrimaryBaseColor += TempValue0
596
Object[ArrayPos0].PrimaryBaseColor += 0
597
598
// And the secondary spotlight is blue
599
Object[ArrayPos0].SecondaryBaseColor = 0
600
Object[ArrayPos0].SecondaryBaseColor <<= 16
601
TempValue0 = 192
602
TempValue0 <<= 8
603
Object[ArrayPos0].SecondaryBaseColor += TempValue0
604
Object[ArrayPos0].SecondaryBaseColor += 224
605
break
606
607
case TIME_BAD_FUTURE
608
// Bad Future gets cool and fancy colors, primary spotlight is pink
609
Object[ArrayPos0].PrimaryBaseColor = 224
610
Object[ArrayPos0].PrimaryBaseColor <<= 16
611
TempValue0 = 64
612
TempValue0 <<= 8
613
Object[ArrayPos0].PrimaryBaseColor += TempValue0
614
Object[ArrayPos0].PrimaryBaseColor += 128
615
616
// And secondary spotlight is purple
617
Object[ArrayPos0].SecondaryBaseColor = 224
618
Object[ArrayPos0].SecondaryBaseColor <<= 16
619
TempValue0 = 128
620
TempValue0 <<= 8
621
Object[ArrayPos0].SecondaryBaseColor += TempValue0
622
Object[ArrayPos0].SecondaryBaseColor += 192
623
break
624
625
end switch
626
627
end if
628
629
ArrayPos0++
630
loop
631
632
// Set the initial screen offset, this is used in calculations for cycling spotlights
633
Screen.XOffset = Player.XPos
634
Screen.XOffset >>= 16
635
Screen.XOffset -= Screen.CenterX
636
637
end sub
638
639
640
// ========================
641
// Editor Subs
642
// ========================
643
644
645
sub RSDKDraw
646
DrawSprite(0)
647
end sub
648
649
650
sub RSDKLoad
651
LoadSpriteSheet("Global/Display.gif")
652
SpriteFrame(-16, -16, 32, 32, 1, 143) // "Script" Icon
653
654
// This object uses 3d, so there's not really any good way to show it in the editor...
655
// It's normally placed out of bounds though, so it doesn't matter too much anyway
656
657
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
658
end sub
659
660