Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-Sonic-2-2013-Script-Decompilation
Path: blob/master/Sonic 1/Scripts/Special/PlayerObject.txt
1480 views
1
// ----------------------------------
2
// RSDK Project: Sonic 1
3
// Script Description: Player Object Object
4
// Script Author: Christian Whitehead/Simon Thomley
5
// Unpacked by Rubberduckycooly's script unpacker
6
// ----------------------------------
7
8
// ========================
9
// Aliases
10
// ========================
11
12
public alias 0x100 : GROUP_PLAYERS
13
public alias 0x101 : GROUP_BLOCKS
14
public alias arrayPos6 : currentPlayer
15
public alias arrayPos7 : playerCount
16
17
// Gravity
18
public alias 0 : GRAVITY_GROUND
19
public alias 1 : GRAVITY_AIR
20
21
// Priority
22
public alias 0 : PRIORITY_BOUNDS
23
public alias 1 : PRIORITY_ACTIVE
24
public alias 2 : PRIORITY_ALWAYS
25
public alias 3 : PRIORITY_XBOUNDS
26
public alias 4 : PRIORITY_XBOUNDS_DESTROY
27
public alias 5 : PRIORITY_INACTIVE
28
public alias 6 : PRIORITY_BOUNDS_SMALL
29
public alias 7 : PRIORITY_ACTIVE_SMALL
30
31
// Control Modes
32
public alias -1 : CONTROLMODE_NONE
33
public alias 0 : CONTROLMODE_P1
34
public alias 1 : CONTROLMODE_P2
35
public alias 2 : CONTROLMODE_P3
36
public alias 3 : CONTROLMODE_P4
37
38
// Camera Styles
39
public alias 0 : CAMERASTYLE_FOLLOW
40
public alias 1 : CAMERASTYLE_EXTENDED
41
public alias 2 : CAMERASTYLE_EXTENDED_OFFSET_L
42
public alias 3 : CAMERASTYLE_EXTENDED_OFFSET_R
43
public alias 4 : CAMERASTYLE_HLOCKED
44
45
// Ink Effects
46
public alias 0 : INK_NONE
47
public alias 1 : INK_BLEND
48
public alias 2 : INK_ALPHA
49
public alias 3 : INK_ADD
50
public alias 4 : INK_SUB
51
52
// Flip Directions
53
public alias 0 : FLIP_NONE
54
public alias 1 : FLIP_X
55
public alias 2 : FLIP_Y
56
public alias 3 : FLIP_XY
57
58
// Collision Sides
59
public alias 0 : CSIDE_FLOOR
60
public alias 1 : CSIDE_LWALL
61
public alias 2 : CSIDE_RWALL
62
public alias 3 : CSIDE_ROOF
63
64
// Collision Modes
65
public alias 0 : CMODE_FLOOR
66
public alias 1 : CMODE_LWALL
67
public alias 2 : CMODE_ROOF
68
public alias 3 : CMODE_RWALL
69
70
// Collision Directions
71
public alias 0 : COL_NONE
72
public alias 1 : COL_TOP
73
public alias 2 : COL_LEFT
74
public alias 3 : COL_RIGHT
75
public alias 4 : COL_BOTTOM
76
77
// Variables
78
private alias object.type : player.type
79
private alias object.groupID : player.groupID // Normally GROUP_PLAYERS, unless in Debug Mode
80
private alias object.entityPos : player.entityPos // Where the player is on the object list - P1 should be 0, P2 should be 1
81
private alias object.state : player.state
82
private alias object.priority : player.priority
83
private alias object.xpos : player.xpos // In total world-space position (0x10000 == 1.0)
84
private alias object.ypos : player.ypos
85
private alias object.ixpos : player.ixpos // In screen space position (1 == 1)
86
private alias object.iypos : player.iypos
87
private alias object.xvel : player.xvel // Based on world-space
88
private alias object.yvel : player.yvel
89
private alias object.speed : player.speed // Also based on world-space
90
private alias object.rotation : player.rotation
91
private alias object.direction : player.direction
92
private alias object.gravity : player.gravity
93
private alias object.frame : player.frame
94
private alias object.animation : player.animation
95
private alias object.animationSpeed : player.animationSpeed
96
private alias object.drawOrder : player.drawOrder
97
private alias object.controlMode : player.controlMode // See control mode aliases
98
private alias object.interaction : player.interaction // Will the object interact with other objects?
99
private alias object.tileCollisions : player.tileCollisions
100
101
// *Object-wise* input, not to be confused with keyPress and keyDown
102
private alias object.jumpPress : player.jumpPress
103
private alias object.jumpHold : player.jumpHold
104
private alias object.up : player.up
105
private alias object.down : player.down
106
private alias object.left : player.left
107
private alias object.right : player.right
108
109
private alias object.value0 : player.rings
110
private alias object.value1 : player.timer
111
private alias object.value2 : player.moveSpeed
112
private alias object.value3 : player.acceleration
113
private alias object.value5 : player.rollSpeed
114
// value6 is unused
115
private alias object.value7 : player.jumpStrength
116
private alias object.value8 : player.moveVelocity.x
117
private alias object.value9 : player.moveVelocity.y
118
private alias object.value10 : debugMode.currentSelection
119
private alias object.value11 : player.collisionFlags
120
private alias object.value12 : player.worldVelocity.x
121
private alias object.value13 : player.worldVelocity.y
122
private alias object.value14 : player.rotateBlockTimer
123
private alias object.value15 : player.upDownBlockTimer
124
125
private alias 0 : SLOT_PLAYER1
126
127
// Player List Pos Aliases
128
public alias 0 : PLAYER_SONIC_A
129
public alias 1 : PLAYER_TAILS_A
130
public alias 2 : PLAYER_KNUCKLES_A
131
public alias 3 : PLAYER_SONIC_TAILS_A
132
public alias 4 : PLAYER_KNUCKLES_TAILS_A
133
public alias 5 : PLAYER_AMY_A
134
public alias 6 : PLAYER_AMY_TAILS_A
135
136
// TitleCard aliases
137
private alias 8 : TITLECARD_FADETOTITLE
138
139
140
// ========================
141
// Function Declarations
142
// ========================
143
144
reserve function Player_ProcessUpdate
145
reserve function Player_State_Static
146
reserve function Player_HandleRollAnimSpeed
147
reserve function Player_State_SS_Roll
148
reserve function Player_SetupAttractDemo
149
reserve function Player_HandleGroundCollision
150
reserve function Player_HandleAirCollision
151
152
153
// ========================
154
// Static Values
155
// ========================
156
157
public value Player_stageRotation = 0
158
public value Player_rotateSpeed = 0
159
public value Player_rotateDir = 0
160
public value Player_isWinner = 0
161
public value Player_attractTable = 0
162
public value Player_attractTablePos = 0
163
public value Player_attractTableSize = 0
164
public value Player_attractFrameCount = 0
165
public value Player_attractDuration = 0
166
public value Player_playerSlot = 0
167
168
// All these below are unused
169
private value Player_unusedValue1 = 0
170
private value Player_unusedValue2 = 0
171
private value Player_unusedValue3 = 0
172
private value Player_unusedValue4 = 0
173
private value Player_unusedValue5 = 0
174
private value Player_unusedValue6 = 0
175
private value Player_unusedValue7 = 0
176
177
178
// ========================
179
// Function Definitions
180
// ========================
181
182
public function Player_SetupAttractDemo
183
Player_attractTablePos = 2
184
Player_attractFrameCount = 1
185
186
currentPlayer = 0
187
while currentPlayer < playerCount
188
GetTableValue(player[currentPlayer].xpos, 0, Player_attractTable)
189
GetTableValue(player[currentPlayer].ypos, 1, Player_attractTable)
190
player[currentPlayer].controlMode = CONTROLMODE_NONE
191
player[currentPlayer].up = false
192
player[currentPlayer].down = false
193
player[currentPlayer].left = false
194
player[currentPlayer].right = false
195
player[currentPlayer].jumpPress = false
196
player[currentPlayer].jumpHold = false
197
player[currentPlayer].timer = 0
198
currentPlayer++
199
loop
200
201
// 0 = SLOT_PLAYER1
202
camera[0].xpos = player[0].ixpos
203
camera[0].ypos = player[0].iypos
204
end function
205
206
207
public function Player_ProcessUpdate
208
if options.attractMode == false
209
#platform: USE_STANDALONE
210
if options.touchControls == true
211
if player.controlMode == CONTROLMODE_P1
212
// Update virtual stick inputs
213
CheckTouchRect(0, 96, screen.xcenter, screen.ysize)
214
if checkResult > -1
215
arrayPos0 = checkResult
216
217
temp0 = touchscreen[arrayPos0].xpos
218
temp0 -= saveRAM[39]
219
220
temp1 = touchscreen[arrayPos0].ypos
221
temp1 -= saveRAM[40]
222
223
ATan2(temp2, temp0, temp1)
224
225
temp2 += 32
226
temp2 &= 255
227
temp2 >>= 6
228
229
switch temp2
230
case 0
231
keyDown[1].right = true
232
break
233
234
case 1
235
keyDown[1].down = true
236
break
237
238
case 2
239
keyDown[1].left = true
240
break
241
242
case 3
243
keyDown[1].up = true
244
break
245
end switch
246
end if
247
248
// Check if the jump button is touched
249
CheckTouchRect(screen.xcenter, 96, screen.xsize, 240)
250
if checkResult > -1
251
keyDown[1].buttonA = true
252
end if
253
254
if touchJump == false
255
// If the jump button only started being touched this frame, then update the press variable accordingly
256
keyPress[1].buttonA |= keyDown[1].buttonA
257
end if
258
259
// And now store the current held state for next frame
260
touchJump = keyDown[1].buttonA
261
262
if stage.debugMode == true
263
// And now to the same process for the B button (debug mode buttom)
264
CheckTouchRect(0, 0, 112, 56)
265
if checkResult > -1
266
keyDown[1].buttonB = true
267
end if
268
269
if touchDebug == false
270
keyPress[1].buttonB |= keyDown[1].buttonB
271
end if
272
273
touchDebug = keyDown[1].buttonB
274
end if
275
276
CheckTouchRect(240, 0, screen.xsize, 40)
277
if checkResult > -1
278
PlaySfx(SfxName[Menu Back], false)
279
engine.state = 5
280
end if
281
282
if keyPress[0].start == true
283
PlaySfx(SfxName[Menu Back], false)
284
engine.state = 5
285
end if
286
end if
287
end if
288
#endplatform
289
290
#platform: USE_ORIGINS
291
if object.controlMode == CONTROLMODE_P1
292
if keyPress[0].start == true
293
// These are left over from the standalone versions, as evident by the fact you can't fly in special stages
294
StopSfx(SfxName[Flying])
295
StopSfx(SfxName[Jump])
296
297
engine.state = 5
298
end if
299
end if
300
#endplatform
301
302
ProcessObjectControl()
303
else
304
#platform: USE_STANDALONE
305
CheckTouchRect(0, 0, screen.xsize, screen.ysize)
306
if keyPress[0].start == true
307
checkResult = false
308
end if
309
310
if checkResult > -1
311
if Player_attractDuration > 1
312
Player_attractDuration = 1
313
end if
314
end if
315
#endplatform
316
317
if keyPress[0].start == true
318
Player_attractDuration = 1
319
end if
320
321
Player_attractFrameCount--
322
if Player_attractFrameCount < 1
323
if Player_attractTablePos < Player_attractTableSize
324
GetTableValue(temp0, Player_attractTablePos, Player_attractTable)
325
GetBit(player.up, temp0, 0)
326
GetBit(player.down, temp0, 1)
327
GetBit(player.left, temp0, 2)
328
GetBit(player.right, temp0, 3)
329
GetBit(player.jumpPress, temp0, 4)
330
GetBit(player.jumpHold, temp0, 5)
331
Player_attractTablePos++
332
GetTableValue(Player_attractFrameCount, Player_attractTablePos, Player_attractTable)
333
Player_attractTablePos++
334
end if
335
else
336
if player.jumpPress == true
337
player.jumpPress = false
338
end if
339
end if
340
341
if Player_attractDuration > 0
342
Player_attractDuration--
343
if Player_attractDuration < 1
344
arrayPos0 = Player_playerSlot
345
player[arrayPos0].type = TypeName[Title Card]
346
player[arrayPos0].state = TITLECARD_FADETOTITLE
347
player[arrayPos0].priority = PRIORITY_ACTIVE
348
player[arrayPos0].drawOrder = 6
349
end if
350
end if
351
end if
352
end function
353
354
public function Player_State_Static
355
checkResult = false
356
end function
357
358
359
public function Player_HandleRollAnimSpeed
360
#platform: USE_STANDALONE
361
if stage.playerListPos == PLAYER_TAILS_A
362
#endplatform
363
#platform: USE_ORIGINS
364
// Bug Details:
365
// pretty sure this should be PLAYER_TAILS, this would be giving sonic a constant animation speed of 120 like Tails would.
366
if stage.playerListPos == PLAYER_SONIC
367
#endplatform
368
369
player.animationSpeed = 120
370
else
371
player.animationSpeed = player.moveSpeed
372
Abs(player.animationSpeed)
373
player.animationSpeed *= 240
374
player.animationSpeed /= 0x60000
375
player.animationSpeed += 48
376
end if
377
end function
378
379
380
public function Player_HandleGroundCollision
381
if player.worldVelocity.x > 0
382
GetBit(temp0, player.collisionFlags, 2)
383
else
384
GetBit(temp0, player.collisionFlags, 3)
385
end if
386
387
if temp0 != 0
388
player.worldVelocity.x = 0
389
player.gravity = GRAVITY_GROUND
390
end if
391
392
if player.worldVelocity.y > 0
393
GetBit(temp0, player.collisionFlags, 1)
394
else
395
GetBit(temp0, player.collisionFlags, 4)
396
end if
397
398
if temp0 != 0
399
player.worldVelocity.y = 0
400
player.gravity = GRAVITY_GROUND
401
end if
402
end function
403
404
405
public function Player_HandleAirCollision
406
// Get the nearest rotation quarter
407
temp0 = Player_stageRotation
408
temp0 >>= 1
409
temp0 -= 0xE0
410
temp0 &= 0xC0
411
switch temp0
412
case 0x00
413
if player.moveSpeed > 0
414
GetBit(temp0, player.collisionFlags, 2)
415
else
416
GetBit(temp0, player.collisionFlags, 3)
417
end if
418
break
419
420
case 0x40
421
if player.moveSpeed > 0
422
GetBit(temp0, player.collisionFlags, 1)
423
else
424
GetBit(temp0, player.collisionFlags, 4)
425
end if
426
break
427
428
case 0x80
429
if player.moveSpeed > 0
430
GetBit(temp0, player.collisionFlags, 3)
431
else
432
GetBit(temp0, player.collisionFlags, 2)
433
end if
434
break
435
436
case 0xC0
437
if player.moveSpeed > 0
438
GetBit(temp0, player.collisionFlags, 4)
439
else
440
GetBit(temp0, player.collisionFlags, 1)
441
end if
442
break
443
444
end switch
445
446
if temp0 == true
447
player.moveSpeed = 0
448
end if
449
450
player.collisionFlags = 0
451
end function
452
453
454
public function Player_State_SS_Roll
455
CallFunction(Player_HandleGroundCollision)
456
if player.gravity == GRAVITY_AIR
457
if player.rotateBlockTimer != 0
458
player.rotateBlockTimer--
459
end if
460
461
if player.upDownBlockTimer != 0
462
player.upDownBlockTimer--
463
end if
464
end if
465
466
temp2 = Player_stageRotation
467
temp2 &= 504
468
if player.gravity == GRAVITY_GROUND
469
if player.jumpPress == true
470
checkResult = true
471
else
472
checkResult = false
473
end if
474
else
475
checkResult = false
476
end if
477
478
if checkResult == true
479
Sin(temp0, temp2)
480
temp0 *= player.jumpStrength
481
temp0 >>= 9
482
483
Cos(temp1, temp2)
484
temp1 *= player.jumpStrength
485
temp1 >>= 9
486
487
player.worldVelocity.x = 0
488
player.worldVelocity.x += temp0
489
player.worldVelocity.y = 0
490
player.worldVelocity.y -= temp1
491
PlaySfx(SfxName[Jump], false)
492
else
493
Sin(temp0, temp2)
494
temp0 *= player.rollSpeed
495
temp0 >>= 9
496
497
Cos(temp1, temp2)
498
temp1 *= player.rollSpeed
499
temp1 >>= 9
500
501
player.worldVelocity.x -= temp0
502
player.worldVelocity.y += temp1
503
end if
504
505
CallFunction(Player_HandleAirCollision)
506
507
temp0 = 0
508
if player.left == true
509
player.moveSpeed -= player.acceleration
510
if player.moveSpeed < -0x80000
511
player.moveSpeed = -0x80000
512
end if
513
514
player.direction = FACING_LEFT
515
temp0 = true
516
end if
517
518
if player.right == true
519
player.moveSpeed += player.acceleration
520
if player.moveSpeed > 0x80000
521
player.moveSpeed = 0x80000
522
end if
523
524
player.direction = FACING_RIGHT
525
temp0 = true
526
end if
527
528
if temp0 == false
529
if player.moveSpeed != 0
530
if player.moveSpeed > 0
531
player.moveSpeed -= player.acceleration
532
if player.moveSpeed < 0
533
player.moveSpeed = 0
534
end if
535
else
536
player.moveSpeed += player.acceleration
537
if player.moveSpeed > 0
538
player.moveSpeed = 0
539
end if
540
end if
541
end if
542
end if
543
544
temp0 = Player_stageRotation
545
temp0 += 0x40
546
temp0 &= 0x180
547
548
Cos(player.moveVelocity.x, temp0)
549
player.moveVelocity.x *= player.moveSpeed
550
player.moveVelocity.x >>= 9
551
552
Sin(player.moveVelocity.y, temp0)
553
player.moveVelocity.y *= player.moveSpeed
554
player.moveVelocity.y >>= 9
555
556
player.xvel = player.worldVelocity.x
557
player.xvel += player.moveVelocity.x
558
player.yvel = player.worldVelocity.y
559
player.yvel += player.moveVelocity.y
560
CallFunction(Player_HandleRollAnimSpeed)
561
end function
562
563
564
// ========================
565
// Events
566
// ========================
567
568
event ObjectUpdate
569
if stage.debugMode == true
570
CallFunction(Player_ProcessUpdate)
571
if keyPress[0].buttonB == true
572
player.type = TypeName[Debug Mode]
573
574
#platform: USE_STANDALONE
575
if stage.playerListPos == PLAYER_TAILS_A
576
#endplatform
577
#platform: USE_ORIGINS
578
// Bug Details:
579
// pretty sure this should be PLAYER_TAILS...?
580
if stage.playerListPos == PLAYER_SONIC
581
#endplatform
582
// Clear the following Tails Object if needed too
583
object[+1].type = TypeName[Blank Object]
584
end if
585
586
player.moveSpeed = 0
587
player.rotation = 0
588
player.frame = 0
589
Player_stageRotation = 0
590
Player_rotateSpeed = 2
591
player.frame = debugMode.currentSelection
592
player.interaction = false
593
else
594
CallFunction(player.state)
595
ProcessAnimation()
596
597
if player.state != Player_State_Static
598
ProcessObjectMovement()
599
end if
600
601
player.gravity = GRAVITY_AIR
602
end if
603
else
604
CallFunction(Player_ProcessUpdate)
605
CallFunction(player.state)
606
ProcessAnimation()
607
608
if player.state != Player_State_Static
609
ProcessObjectMovement()
610
end if
611
612
player.gravity = GRAVITY_AIR
613
end if
614
end event
615
616
617
event ObjectDraw
618
DrawObjectAnimation()
619
end event
620
621
622
event ObjectStartup
623
LoadSpriteSheet("Global/Display.gif") // We don't even use any SpriteFrames, but go ahead and load the sheet anyway..?
624
625
foreach (TypeName[Player Object], arrayPos0, ALL_ENTITIES)
626
#platform: USE_STANDALONE
627
if stage.playerListPos >= PLAYER_SONIC_TAILS_A
628
stage.playerListPos = PLAYER_SONIC_A
629
stage.player2Enabled = true
630
end if
631
#endplatform
632
633
#platform: USE_ORIGINS
634
switch stage.playerListPos
635
case PLAYER_SONIC_TAILS_A
636
stage.playerListPos = PLAYER_SONIC
637
stage.player2Enabled = true
638
break
639
640
case PLAYER_AMY_TAILS_A
641
stage.playerListPos = PLAYER_AMY
642
stage.player2Enabled = true
643
break
644
end switch
645
#endplatform
646
647
648
// 0 = SLOT_PLAYER1
649
ResetObjectEntity(SLOT_PLAYER1, TypeName[Player Object], 0, player[arrayPos0].xpos, player[arrayPos0].ypos)
650
camera[0].xpos = player[0].ixpos
651
camera[0].ypos = player[0].iypos
652
player[0].groupID = GROUP_PLAYERS
653
player[0].xvel = 0
654
player[0].yvel = 0
655
player[0].speed = 0
656
Player_playerSlot = player.entityPos
657
658
switch stage.playerListPos
659
case PLAYER_SONIC_A
660
LoadAnimation("SonicSS.ani")
661
player[0].animationSpeed = 48
662
break
663
664
case PLAYER_TAILS_A
665
LoadAnimation("TailsSS.ani")
666
player[0].animationSpeed = 120
667
break
668
669
case PLAYER_KNUCKLES_A
670
LoadAnimation("KnucklesSS.ani")
671
player[0].animationSpeed = 48
672
break
673
674
#platform: USE_ORIGINS
675
case PLAYER_AMY_A
676
LoadAnimation("AmySS.ani")
677
player[0].animationSpeed = 48
678
break
679
#endplatform
680
end switch
681
682
// Note - player.animation never needs to be set since the desired animation is animation ID 0 in the file
683
684
player[0].state = Player_State_SS_Roll
685
player[0].priority = PRIORITY_ACTIVE
686
player[0].drawOrder = 4
687
player[0].acceleration = 0xC00
688
player[0].jumpStrength = 0x68000
689
player[0].rollSpeed = 0x2A00
690
ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
691
player[0].tileCollisions = false
692
player[0].gravity = GRAVITY_AIR
693
Player_stageRotation = 0
694
Player_rotateSpeed = 0
695
Player_rotateDir = 0
696
Player_isWinner = false
697
next
698
699
options.touchControls = true
700
end event
701
702
703
// ========================
704
// Editor Events
705
// ========================
706
707
event RSDKDraw
708
DrawSprite(0)
709
end event
710
711
712
event RSDKLoad
713
LoadSpriteSheet("Players/Sonic1.gif")
714
SpriteFrame(-16, -16, 32, 32, 42, 118)
715
716
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
717
end event
718
719