Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 2/Scripts/Global/TitleCard.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 2
3
// Script Description: Title Card Object
4
// Script Author: Christian Whitehead/Simon Thomley
5
// Unpacked by Rubberduckycooly's script unpacker
6
// ----------------------------------
7
8
// ========================
9
// Aliases
10
// ========================
11
12
private alias object.value0 : object.timer
13
private alias object.value1 : object.actNamePos
14
private alias object.value2 : object.zonePos
15
private alias object.value3 : object.blueRectPos // well yeah it's green with Knuckles in Plus but you know what i mean
16
private alias object.value4 : object.yellowRectPos
17
private alias object.value5 : object.redRectPos
18
private alias object.value6 : object.displayedActNo
19
private alias object.value7 : object.vsReady
20
private alias object.value8 : object.sentReadyFlag
21
22
// States
23
private alias 0 : TITLECARD_SETUP
24
private alias 1 : TITLECARD_DELAY
25
private alias 2 : TITLECARD_ENTERTITLECARD
26
private alias 3 : TITLECARD_SHOWTITLECARD
27
private alias 4 : TITLECARD_EXITREDYELLOWRECT
28
private alias 5 : TITLECARD_EXITBLUERECT
29
private alias 6 : TITLECARD_STARTSTAGE
30
private alias 7 : TITLECARD_CREDITSFADEIN
31
private alias 8 : TITLECARD_FADETOTITLE
32
private alias 9 : TITLECARD_EXITTITLECARD
33
34
// Types
35
private alias 0 : TITLECARD_TYPE_ACTNUM
36
private alias 1 : TITLECARD_TYPE_ACT1
37
private alias 2 : TITLECARD_TYPE_ACT2
38
private alias 3 : TITLECARD_TYPE_ACT3
39
private alias 4 : TITLECARD_TYPE_ZONE
40
private alias 5 : TITLECARD_TYPE_ZONE_MBZ
41
42
// Player Aliases
43
private alias object.propertyValue : player.character
44
private alias object.controlMode : player.controlMode
45
private alias object.jumpPress : player.jumpPress
46
private alias object.jumpHold : player.jumpHold
47
private alias object.up : player.up
48
private alias object.down : player.down
49
private alias object.left : player.left
50
private alias object.right : player.right
51
private alias object.value1 : player.timer
52
53
// Tracks
54
private alias 0 : TRACK_STAGE
55
56
// ========================
57
// Function Declarations
58
// ========================
59
60
reserve function TitleCard_DrawBG
61
62
63
// ========================
64
// Static Values
65
// ========================
66
67
// Determines whether the act results will say got through zone or got through act [num]
68
public value TitleCard_showZoneText = 0
69
70
71
// ========================
72
// Function Definitions
73
// ========================
74
75
private function TitleCard_DrawBG
76
#platform: USE_ORIGINS
77
// Introduced in Plus, draws the BG and determines if it should be blue (regular Sonic 2) or green (Knuckles in Sonic 2)
78
79
if screen.currentID == 0
80
temp0 = player[0].character
81
else
82
temp0 = vs.player2Type
83
end if
84
85
if temp0 == PLAYER_KNUCKLES
86
DrawRect(0, 0, screen.xsize, object.blueRectPos, 0, 135, 1, 0xFF)
87
else
88
DrawRect(0, 0, screen.xsize, object.blueRectPos, 32, 64, 192, 0xFF)
89
end if
90
#endplatform
91
end function
92
93
94
// ========================
95
// Events
96
// ========================
97
98
99
event ObjectUpdate
100
options.touchControls = false
101
102
switch object.state
103
case TITLECARD_SETUP
104
object.alpha = 0xFF
105
object.actNamePos = 720
106
object.zonePos -= 720
107
108
// 510 is the sega forever value (though you should use 512 instead, as it works properly and doesn't cause a bug)
109
// 432 is the original/origins one (the forever one works better on wider screens, the value is basically screen.xsize + 10)
110
object.yellowRectPos = 432
111
112
object.redRectPos = -320
113
114
switch object.propertyValue
115
case TITLECARD_TYPE_ACTNUM
116
object.displayedActNo = stage.actNum
117
TitleCard_showZoneText = false
118
break
119
120
case TITLECARD_TYPE_ACT1
121
object.displayedActNo = 1
122
TitleCard_showZoneText = false
123
break
124
125
case TITLECARD_TYPE_ACT2
126
object.displayedActNo = 2
127
TitleCard_showZoneText = false
128
break
129
130
case TITLECARD_TYPE_ACT3
131
object.displayedActNo = 3
132
TitleCard_showZoneText = false
133
break
134
135
default
136
TitleCard_showZoneText = true
137
break
138
end switch
139
140
if options.vsMode == true
141
object.vsReady = false
142
object.sentReadyFlag = true
143
else
144
object.vsReady = true
145
object.sentReadyFlag = false
146
end if
147
148
#platform: USE_ORIGINS
149
game.missionCondition = false
150
game.missionEnd = false
151
152
if game.playMode == BOOT_PLAYMODE_MISSION
153
PlayMusic(TRACK_STAGE)
154
game.missionCondition = false
155
game.missionEnd = false
156
object.state = TITLECARD_CREDITSFADEIN
157
object.timer = 0
158
stage.timeEnabled = true
159
stage.state = STAGE_RUNNING
160
SetScreenFade(0, 0, 0, 0)
161
else
162
if game.playMode == BOOT_PLAYMODE_BOSSRUSH
163
PlayMusic(TRACK_STAGE)
164
game.missionCondition = false
165
game.missionEnd = false
166
object.state = TITLECARD_CREDITSFADEIN
167
object.timer = 0
168
stage.timeEnabled = true
169
stage.state = STAGE_RUNNING
170
SetScreenFade(0, 0, 0, 0)
171
else
172
#endplatform
173
if credits.screen > 0
174
object.state = TITLECARD_CREDITSFADEIN
175
object.timer = 272
176
stage.state = STAGE_RUNNING
177
SetScreenFade(0, 0, 0, 255)
178
else
179
object.state++
180
end if
181
#platform: USE_ORIGINS
182
end if
183
end if
184
#endplatform
185
break
186
187
case TITLECARD_DELAY
188
if object.timer < 30
189
object.timer++
190
else
191
if options.vsMode == true
192
// Only continue if we're ready
193
CallNativeFunction2(SendEntity, object.entityPos, false)
194
if ReceiveValue == -1 // if we don't have the recieve func, we cant do VS mode, continue.
195
object.vsReady = true
196
else
197
CallNativeFunction2(ReceiveEntity, 0x400, true)
198
// we're ready to start if we got the other entity's 'sendReadyFlag'
199
object.vsReady = object[0x400].sentReadyFlag
200
ResetObjectEntity(0x400, TypeName[Blank Object], 0, 0, 0)
201
end if
202
end if
203
204
if object.vsReady == true
205
object.timer = 0
206
PlayMusic(TRACK_STAGE)
207
object.state++
208
end if
209
end if
210
break
211
212
case TITLECARD_ENTERTITLECARD
213
if options.vsMode == true
214
CallNativeFunction2(SendEntity, object.entityPos, false)
215
end if
216
217
if object.blueRectPos < 240
218
object.blueRectPos += 16
219
end if
220
221
if object.yellowRectPos > 0
222
object.yellowRectPos -= 16
223
object.redRectPos += 16
224
end if
225
226
if object.actNamePos > 0
227
object.actNamePos -= 16
228
object.zonePos += 16
229
else
230
object.state++
231
end if
232
break
233
234
case TITLECARD_SHOWTITLECARD
235
if object.timer < 60
236
if options.vsMode == true
237
CallNativeFunction2(SendEntity, object.entityPos, false)
238
CallNativeFunction2(ReceiveEntity, 0x400, true)
239
ResetObjectEntity(0x400, TypeName[Blank Object], 0, 0, 0)
240
end if
241
object.timer++
242
else
243
object.timer = 0
244
object.state++
245
end if
246
break
247
248
case TITLECARD_EXITREDYELLOWRECT
249
if object.redRectPos > -48
250
object.redRectPos -= 32
251
else
252
if object.yellowRectPos < 424 // 500 is the sega forever value, 424 is the original one (the forever one works better on wider screens, the value is basically just screen.xsize)
253
object.yellowRectPos += 32
254
if options.vsMode == true
255
CallNativeFunction2(ReceiveEntity, 0x400, true)
256
ResetObjectEntity(0x400, TypeName[Blank Object], 0, 0, 0)
257
end if
258
else
259
if options.vsMode == true
260
stage.state = STAGE_2P_MODE
261
else
262
stage.state = STAGE_RUNNING
263
end if
264
265
currentPlayer = 0
266
while currentPlayer < playerCount
267
player[currentPlayer].controlMode = CONTROLMODE_NONE
268
player[currentPlayer].up = false
269
player[currentPlayer].down = false
270
player[currentPlayer].left = false
271
player[currentPlayer].right = false
272
player[currentPlayer].jumpPress = false
273
player[currentPlayer].jumpHold = false
274
player[currentPlayer].timer = 0
275
currentPlayer++
276
loop
277
278
object.state++
279
end if
280
end if
281
break
282
283
case TITLECARD_EXITBLUERECT
284
if object.blueRectPos > 0
285
object.blueRectPos -= 32
286
else
287
currentPlayer = 0
288
while currentPlayer < playerCount
289
#platform: USE_STANDALONE
290
player[currentPlayer].controlMode = CONTROLMODE_P1
291
#endplatform
292
#platform: USE_ORIGINS
293
player[currentPlayer].controlMode = currentPlayer
294
#endplatform
295
currentPlayer++
296
loop
297
object.state++
298
end if
299
break
300
301
case TITLECARD_STARTSTAGE
302
if object.timer < 48
303
object.timer++
304
else
305
object.timer = 0
306
stage.timeEnabled = true
307
object.state = TITLECARD_EXITTITLECARD
308
end if
309
break
310
311
case TITLECARD_CREDITSFADEIN
312
if object.timer > 0
313
object.timer -= 16
314
SetScreenFade(0, 0, 0, object.timer)
315
else
316
currentPlayer = 0
317
while currentPlayer < playerCount
318
#platform: USE_STANDALONE
319
player[currentPlayer].controlMode = CONTROLMODE_P1
320
#endplatform
321
#platform: USE_ORIGINS
322
player[currentPlayer].controlMode = currentPlayer
323
#endplatform
324
currentPlayer++
325
loop
326
ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
327
end if
328
break
329
330
case TITLECARD_FADETOTITLE
331
// This state is set from the Player Object, when a replay is finished
332
// All the credits.screen checks here are just leftovers that don't do much, since S2 doesn't use in-game credits like S1 did
333
334
if object.timer < 300
335
object.timer += 5
336
if credits.screen == 0
337
music.volume -= 2
338
end if
339
else
340
stage.activeList = PRESENTATION_STAGE
341
if credits.screen > 0
342
stage.listPos = 2
343
else
344
stage.listPos = 0
345
StopMusic()
346
end if
347
LoadStage()
348
end if
349
350
SetScreenFade(0, 0, 0, object.timer)
351
break
352
353
case TITLECARD_EXITTITLECARD
354
object.actNamePos += 32
355
object.zonePos -= 32
356
if object.timer < 20
357
object.timer++
358
else
359
object.timer = 0
360
object.type = TypeName[Blank Object]
361
end if
362
break
363
364
end switch
365
end event
366
367
368
event ObjectDraw
369
temp2 = screen.xcenter
370
temp2 -= 160
371
temp2 >>= 1
372
373
switch object.state
374
case TITLECARD_SETUP
375
case TITLECARD_DELAY
376
case TITLECARD_ENTERTITLECARD
377
case TITLECARD_SHOWTITLECARD
378
SetActivePalette(0, 0, screen.ysize)
379
380
#platform: USE_STANDALONE
381
DrawRect(0, 0, screen.xsize, object.blueRectPos, 0x20, 0x40, 0xC0, 0xFF)
382
#endplatform
383
#platform: USE_ORIGINS
384
CallFunction(TitleCard_DrawBG)
385
#endplatform
386
387
DrawRect(0, object.blueRectPos, screen.xsize, screen.ysize, 0x00, 0x00, 0x00, 0xFF)
388
389
#platform: USE_STANDALONE
390
if options.vsMode == true
391
if object.state == TITLECARD_DELAY
392
// Waiting for other player...
393
DrawSpriteScreenXY(32, screen.xsize, screen.ysize)
394
end if
395
end if
396
#endplatform
397
398
// Yellow Rect
399
DrawRect(object.yellowRectPos, 168, screen.xsize, 72, 0xE0, 0xE0, 0x00, 0xFF)
400
401
// "Sonic The Hedgehog" Text
402
temp0 = object.yellowRectPos
403
temp0 += screen.xcenter
404
DrawSpriteScreenXY(31, temp0, 176)
405
406
// Red Rect (& Red Sidebar)
407
DrawRect(0, 0, object.redRectPos, screen.ysize, 0xE0, 0x00, 0x00, 0xFF) // Red Rect
408
DrawSpriteScreenXY(26, object.redRectPos, 0) // Red Sidebar
409
410
temp0 = screen.xcenter
411
temp0 += temp2
412
temp0 += 128
413
temp0 += object.actNamePos
414
DrawActName(0, temp0, 64, 0, 0, 16, 0)
415
416
temp0 = screen.xcenter
417
temp0 += temp2
418
temp0 += 41
419
temp0 += object.zonePos
420
DrawSpriteScreenXY(27, temp0, 88)
421
422
if object.displayedActNo > 0
423
temp1 = 27
424
temp1 += object.displayedActNo
425
if temp1 > 30
426
temp1 = 30
427
end if
428
DrawSpriteScreenXY(temp1, temp0, 88)
429
end if
430
break
431
432
case TITLECARD_EXITREDYELLOWRECT
433
case TITLECARD_EXITBLUERECT
434
SetActivePalette(0, 0, screen.ysize)
435
436
#platform: USE_STANDALONE
437
DrawRect(0, 0, screen.xsize, object.blueRectPos, 0x20, 0x40, 0xC0, 0xFF)
438
#endplatform
439
#platform: USE_ORIGINS
440
CallFunction(TitleCard_DrawBG)
441
#endplatform
442
443
DrawRect(object.yellowRectPos, 168, screen.xsize, 72, 0xE0, 0xE0, 0x00, 0xFF)
444
445
temp0 = object.yellowRectPos
446
temp0 += screen.xcenter
447
DrawSpriteScreenXY(31, temp0, 176)
448
DrawRect(0, 0, object.redRectPos, screen.ysize, 0xE0, 0x00, 0x00, 0xFF)
449
DrawSpriteScreenXY(26, object.redRectPos, 0)
450
451
temp0 = screen.xcenter
452
temp0 += temp2
453
temp0 += 128
454
temp0 += object.actNamePos
455
DrawActName(0, temp0, 64, 0, 0, 16, 0)
456
457
temp0 = screen.xcenter
458
temp0 += temp2
459
temp0 += 41
460
temp0 += object.zonePos
461
DrawSpriteScreenXY(27, temp0, 88)
462
463
if object.displayedActNo > 0
464
temp1 = 27
465
temp1 += object.displayedActNo
466
if temp1 > 30
467
temp1 = 30
468
end if
469
DrawSpriteScreenXY(temp1, temp0, 88)
470
end if
471
break
472
473
case TITLECARD_STARTSTAGE
474
case TITLECARD_EXITTITLECARD
475
SetActivePalette(0, 0, screen.ysize)
476
477
temp0 = screen.xcenter
478
temp0 += temp2
479
temp0 += 128
480
temp0 += object.actNamePos
481
DrawActName(0, temp0, 64, 0, 0, 16, 0)
482
483
temp0 = screen.xcenter
484
temp0 += temp2
485
temp0 += 41
486
temp0 += object.zonePos
487
DrawSpriteScreenXY(27, temp0, 88)
488
489
if object.displayedActNo > 0
490
temp1 = 27
491
temp1 += object.displayedActNo
492
if temp1 > 30
493
temp1 = 30
494
end if
495
DrawSpriteScreenXY(temp1, temp0, 88)
496
end if
497
break
498
end switch
499
end event
500
501
502
event ObjectStartup
503
LoadSpriteSheet("Global/Display.gif")
504
505
// Title card frames
506
507
// Titlecard Letters (0-25)
508
SpriteFrame(0, 0, 15, 16, 37, 79)
509
SpriteFrame(0, 0, 16, 16, 53, 79)
510
SpriteFrame(0, 0, 16, 16, 70, 79)
511
SpriteFrame(0, 0, 16, 16, 87, 79)
512
SpriteFrame(0, 0, 15, 16, 104, 79)
513
SpriteFrame(0, 0, 15, 16, 120, 79)
514
SpriteFrame(0, 0, 16, 16, 136, 79)
515
SpriteFrame(0, 0, 16, 16, 153, 79)
516
SpriteFrame(0, 0, 8, 16, 170, 79)
517
SpriteFrame(0, 0, 16, 16, 179, 79)
518
SpriteFrame(0, 0, 16, 16, 196, 79)
519
SpriteFrame(0, 0, 16, 16, 213, 79)
520
SpriteFrame(0, 0, 23, 16, 43, 96)
521
SpriteFrame(0, 0, 16, 16, 67, 96)
522
SpriteFrame(0, 0, 16, 16, 84, 96)
523
SpriteFrame(0, 0, 16, 16, 101, 96)
524
SpriteFrame(0, 0, 16, 16, 118, 96)
525
SpriteFrame(0, 0, 16, 16, 135, 96)
526
SpriteFrame(0, 0, 16, 16, 152, 96)
527
SpriteFrame(0, 0, 16, 16, 169, 96)
528
SpriteFrame(0, 0, 16, 16, 186, 96)
529
SpriteFrame(0, 0, 16, 16, 203, 96)
530
SpriteFrame(0, 0, 22, 16, 220, 96)
531
SpriteFrame(0, 0, 15, 16, 43, 113)
532
SpriteFrame(0, 0, 16, 16, 59, 113)
533
SpriteFrame(0, 0, 16, 16, 76, 113)
534
535
SpriteFrame(0, 0, 8, 256, 248, 0) // Red Sidebar - #26
536
SpriteFrame(0, 0, 62, 16, 83, 1) // Zone - #27
537
SpriteFrame(63, 0, 16, 29, 42, 1) // Act 1 - #28
538
SpriteFrame(63, 0, 23, 29, 59, 1) // Act 2 - #29
539
SpriteFrame(63, 0, 23, 32, 42, 31) // Act 3 - #30
540
SpriteFrame(0, 0, 140, 5, 37, 73) // "Sonic The Hedgehog" - #31
541
542
if vs.playerID == 0
543
SpriteFrame(-160, -16, 136, 7, 110, 172) // "Waiting for 2P" - #32
544
else
545
SpriteFrame(-160, -16, 136, 7, 110, 164) // "Waiting for 1P" - #32
546
end if
547
548
if options.vsMode == true
549
CallNativeFunction2(ReceiveEntity, 0x400, true)
550
ResetObjectEntity(0x400, TypeName[Blank Object], 0, 0, 0)
551
#platform: USE_ORIGINS
552
SetScreenCount(2)
553
#endplatform
554
end if
555
556
// Cycle through all Title Card objects
557
// (Dunno why a regular foreach isn't used here, but sure...)
558
arrayPos0 = 32
559
while arrayPos0 < 0x420
560
if object[arrayPos0].type == TypeName[Title Card]
561
object[arrayPos0].priority = PRIORITY_ALWAYS
562
object[arrayPos0].alpha = 0xFF
563
object[arrayPos0].drawOrder = 6
564
stage.state = STAGE_PAUSED
565
566
if object[arrayPos0].propertyValue == TITLECARD_TYPE_ZONE_MBZ
567
CheckCurrentStageFolder("ZoneM")
568
if checkResult == false
569
// If the object has a property value of 5 & we're NOT in the Egg Gauntlet folder (somehow), then go back to the title screen
570
// (Purpose unknown, idk why this exists or what it's even supposed to mean)
571
stage.activeList = PRESENTATION_STAGE
572
stage.listPos = 0
573
LoadStage()
574
end if
575
end if
576
end if
577
578
arrayPos0++
579
loop
580
end event
581
582
583
// ========================
584
// Editor Events
585
// ========================
586
587
event RSDKEdit
588
if editor.returnVariable == true
589
switch editor.variableID
590
case EDIT_VAR_PROPVAL // property value
591
checkResult = object.propertyValue
592
break
593
594
case 0 // actType
595
checkResult = object.propertyValue
596
break
597
598
end switch
599
else
600
switch editor.variableID
601
case EDIT_VAR_PROPVAL // property value
602
object.propertyValue = editor.variableValue
603
break
604
605
case 0 // actType
606
object.propertyValue = editor.variableValue
607
break
608
609
end switch
610
end if
611
end event
612
613
614
event RSDKDraw
615
DrawSprite(0)
616
end event
617
618
619
event RSDKLoad
620
LoadSpriteSheet("Global/Display.gif")
621
SpriteFrame(-8, -8, 16, 16, 168, 18)
622
623
AddEditorVariable("actType")
624
SetActiveVariable("actType")
625
AddEnumVariable("Use Act Num", TITLECARD_TYPE_ACTNUM)
626
AddEnumVariable("Show Act 1", TITLECARD_TYPE_ACT1)
627
AddEnumVariable("Show Act 2", TITLECARD_TYPE_ACT2)
628
AddEnumVariable("Show Act 3", TITLECARD_TYPE_ACT3)
629
AddEnumVariable("Show Zone Text", TITLECARD_TYPE_ZONE)
630
AddEnumVariable("Show Zone Text (MBZ)", TITLECARD_TYPE_ZONE_MBZ)
631
end event
632
633