Sonic CD Extras Menu Script Guide
Sonic CD Extras Menu Script Guide
// Aliases
#alias Object.Value0 : [Link]
#alias Object.Value1 : [Link]
//Object[33] is MenuHeading
#alias Object[33].State : [Link]
#alias Object[33].PropertyValue : [Link]
//Object[-1] is MenuWindow
#alias Object[-1].State : [Link]
#alias Object[1].Value4 : [Link]
// States
#alias 0 : EXTRASMENU_ENTER_MENU
#alias 1 : EXTRASMENU_CONTROLS
#alias 2 : EXTRASMENU_SELECTED_OPTION
#alias 3 : EXTRASMENU_LOAD_EXTRA_STAGE
#alias 4 : EXTRASMENU_LOAD_VISUALMODE
#alias 5 : EXTRASMENU_VISUALMODE_FADEIN
#alias 6 : EXTRASMENU_VISUALMODE
#alias 7 : EXTRASMENU_VISUALMODE_SELECTED
#alias 8 : EXTRASMENU_VISUALMODE_VIDEOPLAY
#alias 9 : EXTRASMENU_VISUALMODE_FADEOUT
#alias 10 : EXTRASMENU_VISUALMODE_RETURN
#alias 11 : EXTRASMENU_EXIT_MENU
#alias 12 : EXTRASMENU_FADEIN
#alias 13 : EXTRASMENU_RETURN_TO_TITLE
// Presentation Stages
#alias 0 : STAGE_P_TITLE
#alias 3 : STAGE_P_STAGESELECT
#alias 4 : STAGE_P_SOUNDTEST
#alias 5 : STAGE_P_DAGARDEN
// Global SFX
#alias 23 : SFX_G_MENUBUTTON
#alias 27 : SFX_G_SELECT
// Stage SFX
#alias 1 : SFX_S_BACKBUTTON
// Languages
#alias 0 : LANG_ENGLISH
#alias 1 : LANG_FRENCH
#alias 2 : LANG_ITALIAN
#alias 3 : LANG_DEUTSCH
#alias 4 : LANG_SPANISH
#alias 5 : LANG_JAPANESE
// Soundtrack
#alias 0 : OST_JP
// Function declarations
#function ExtrasMenu_DrawUnlocks
function ExtrasMenu_DrawUnlocks
switch Helper[+ArrayPos0].FlickerState
case false
if ArrayPos0 == [Link]
DrawSpriteScreenFX(9, FX_INK, [Link], [Link])
TempValue0 = ArrayPos0
TempValue0 += 14
DrawSpriteScreenFX(TempValue0, FX_INK, [Link], [Link])
else
TempValue0 = ArrayPos0
TempValue0 += 10
DrawSpriteScreenFX(TempValue0, FX_INK, [Link], [Link])
end if
break
case true
TempValue0 = [Link]
TempValue0 &= 3
TempValue0 >>= 1
DrawSpriteScreenFX(9, FX_INK, [Link], [Link])
if TempValue0 == 0
TempValue0 = ArrayPos0
TempValue0 += 14
DrawSpriteScreenFX(TempValue0, FX_INK, [Link], [Link])
end if
break
end switch
case 2
if [Link] == true
DrawSpriteScreenFX(0, FX_INK, [Link], [Link])
else
DrawSpriteScreenFX(1, FX_INK, [Link], [Link])
end if
break
case 3
if [Link] == true
DrawSpriteScreenFX(0, FX_INK, [Link], [Link])
else
DrawSpriteScreenFX(1, FX_INK, [Link], [Link])
end if
break
end switch
end function
sub ObjectMain
switch [Link]
case EXTRASMENU_ENTER_MENU
#platform: Use_Origins
if [Link] == false
[Link] = -1
end if
#endplatform
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
[Link] = [Link]
[Link] -= 126
if [Link] < 256
[Link] = [Link]
[Link] += 6
else
[Link] = 0
[Link] = 255
[Link]++
end if
break
case EXTRASMENU_CONTROLS
#platform: Standard
CheckResult = true
#endplatform
#platform: Mobile
CheckEqual([Link], true)
#endplatform
#platform: Use_Origins
CheckEqual([Link], true)
#endplatform
if KeyPress[0].Down == true
[Link]++
if [Link] > 3
[Link] = 0
end if
PlaySfx(SFX_G_MENUBUTTON, false)
end if
TempValue0 = 0
CallFunction(LoadSaveMenu_CheckTouchSave) //D.
A. Garden Touch Press
if CheckResult > -1
[Link] = 0
else
if TempValue3 < 0
if [Link] == 0
KeyPress[0].Start = true
end if
else
if [Link] == 0
[Link] = -1
end if
end if
end if
TempValue0 = 1
CallFunction(LoadSaveMenu_CheckTouchSave)
//Visual Mode Touch Press
if CheckResult > -1
[Link] = 1
else
if TempValue3 < 0
if [Link] == 1
KeyPress[0].Start = true
end if
else
if [Link] == 1
[Link] = -1
end if
end if
end if
TempValue0 = 2
CallFunction(LoadSaveMenu_CheckTouchSave)
//Sound Test Touch Press
if CheckResult > -1
[Link] = 2
else
if TempValue3 < 0
if [Link] == 2
KeyPress[0].Start = true
end if
else
if [Link] == 2
[Link] = -1
end if
end if
end if
TempValue0 = 3
CallFunction(LoadSaveMenu_CheckTouchSave)
//Stage Select Touch Press
if CheckResult > -1
[Link] = 3
else
if TempValue3 < 0
if [Link] == 3
KeyPress[0].Start = true
end if
else
if [Link] == 3
[Link] = -1
end if
end if
end if
CallFunction(MenuHeading_CheckTouchBack) //Back
Button Touch Press
if KeyPress[0].Up == true
[Link] = 3
#platform: Mobile
[Link] = true
#endplatform
#platform: Use_Origins
[Link] = true
#endplatform
end if
if KeyPress[0].Down == true
[Link] = 0
#platform: Mobile
[Link] = true
#endplatform
#platform: Use_Origins
[Link] = true
#endplatform
end if
end if
CheckResult = false
if [Link] > -1
if KeyPress[0].Start == true
CheckResult = true
end if
if KeyPress[0].ButtonA == true
CheckResult = true
end if
end if
if CheckResult == true
if [Link] < 4
switch [Link]
case 0
if [Link] == true
ArrayPos0 = [Link]
Helper[+ArrayPos0].FlickerState = true
[Link]++
StopMusic()
PlaySfx(SFX_G_SELECT, false)
else
#platform: Use_Origins
if [Link] == false
[Link] = -1
end if
#endplatform
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
end if
break
case 1
if [Link] == true
ArrayPos0 = [Link]
Helper[+ArrayPos0].FlickerState = true
[Link]++
PlaySfx(SFX_G_SELECT, false)
else
#platform: Use_Origins
if [Link] == false
[Link] = -1
end if
#endplatform
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
end if
break
case 2
if [Link] == true
ArrayPos0 = [Link]
Helper[+ArrayPos0].FlickerState = true
[Link]++
StopMusic()
PlaySfx(SFX_G_SELECT, false)
else
#platform: Use_Origins
if [Link] == false
[Link] = -1
end if
#endplatform
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
end if
break
case 3
if [Link] == true
ArrayPos0 = [Link]
Helper[+ArrayPos0].FlickerState = true
[Link]++
StopMusic()
PlaySfx(SFX_G_SELECT, false)
else
#platform: Use_Origins
if [Link] == false
[Link] = -1
end if
#endplatform
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
end if
break
end switch
end if
end if
#platform: Use_Origins
if KeyPress[0].ButtonB == true
[Link] = EXTRASMENU_RETURN_TO_TITLE
[Link] = 0
StopMusic()
end if
#endplatform
#platform: Use_Standalone
if KeyPress[0].ButtonB == true
[Link] = 248
[Link] = EXTRASMENU_EXIT_MENU
PlayStageSfx(SFX_S_BACKBUTTON, false)
end if
#endplatform
break
case EXTRASMENU_SELECTED_OPTION
if [Link] < 30
[Link]++
else
[Link] = 0
ArrayPos0 = [Link]
Helper[+ArrayPos0].FlickerState = false
switch [Link]
case 0
[Link] = EXTRASMENU_LOAD_EXTRA_STAGE
break
case 1
[Link] = EXTRASMENU_LOAD_VISUALMODE
[Link] = 40
[Link] *= [Link]
[Link] += [Link]
[Link] -= 87
break
case 2
[Link] = EXTRASMENU_LOAD_EXTRA_STAGE
break
case 3
[Link] = EXTRASMENU_LOAD_EXTRA_STAGE
break
end switch
end if
break
case EXTRASMENU_LOAD_EXTRA_STAGE
if [Link] < 320
[Link] += 8
else
#platform: Use_Origins
game.callbackParam0 = true
EngineCallback(NOTIFY_LEVEL_SELECT_MENU)
game.callbackParam0 = 0
EngineCallback(NOTIFY_PLAYER_SET)
[Link] = PLAYER_SONIC
#endplatform
switch [Link]
case 0
[Link] = STAGE_P_DAGARDEN
LoadStage()
break
case 2
[Link] = STAGE_P_SOUNDTEST
LoadStage()
break
case 3
[Link] = STAGE_P_STAGESELECT
LoadStage()
break
end switch
end if
TempValue0 = [Link]
if TempValue0 > 255
TempValue0 = 255
end if
SetScreenFade(0, 0, 0, TempValue0)
break
case EXTRASMENU_LOAD_VISUALMODE
TempValue0 = [Link]
TempValue0 -= 87
if [Link] > TempValue0
[Link] -= 8
if [Link] < TempValue0
[Link] = TempValue0
end if
else
[Link]++
[Link] = 0
[Link] = 0
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
end if
break
case EXTRASMENU_VISUALMODE_FADEIN
if [Link] < 256
[Link] = [Link]
[Link] += 8
else
[Link] = 0
[Link] = 255
[Link]++
end if
break
case EXTRASMENU_VISUALMODE
ArrayPos0 = [Link]
#platform: Standard
CheckResult = true
#endplatform
#platform: Mobile
CheckEqual([Link],true)
#endplatform
#platform: Use_Origins
CheckEqual([Link],true)
#endplatform
if KeyPress[0].Right == true
[Link]++
PlaySfx(SFX_G_MENUBUTTON, false)
if [Link] > 3
[Link] = 0
end if
end if
if KeyPress[0].Up == true
[Link] -= 2
PlaySfx(SFX_G_MENUBUTTON, false)
if [Link] < 0
[Link] += 4
end if
end if
if KeyPress[0].Down == true
[Link] += 2
PlaySfx(SFX_G_MENUBUTTON, false)
if [Link] > 3
[Link] -= 4
end if
end if
end if
#platform: Mobile
// Just to make it look neat, instead of continuing the code from an
open if on another platform, we ask again for a check in the physical controls
if [Link] == true
CheckTouchRect(0, 0, [Link], [Link])
//Touch Behaviour Check
if CheckResult > -1
[Link] = false
[Link] = -1
end if
else
if [Link] == MESSAGE_LOSTFOCUS
[Link] = -1
end if
CheckTouchRect(0, 0, [Link], [Link])
//Touch Input Reset
TempValue3 = CheckResult
TempValue0 = [Link]
TempValue0 -= 88
TempValue1 = [Link]
TempValue1 -= 40
CheckTouchRect(TempValue0, 72, TempValue1, 120)
//Opening Touch Press
if CheckResult > -1
[Link] = 0
else
if TempValue3 < 0
if [Link] == 0
KeyPress[0].Start = true
end if
else
if [Link] == 0
[Link] = -1
end if
end if
end if
TempValue0 = [Link]
TempValue0 += 40
TempValue1 = [Link]
TempValue1 += 88
CheckTouchRect(TempValue0, 72, TempValue1, 120)
//Pencil Test Touch Press
if CheckResult > -1
[Link] = 1
else
if TempValue3 < 0
if [Link] == 1
KeyPress[0].Start = true
end if
else
if [Link] == 1
[Link] = -1
end if
end if
end if
TempValue0 = [Link]
TempValue0 -= 96
CheckTouchRect(TempValue0, 192, [Link], [Link])
//Back Touch Press
if CheckResult > -1
[Link] = 4
[Link] = true
else
[Link] = false
if TempValue3 < 0
if [Link] == 4
KeyPress[0].ButtonB = true
end if
else
if [Link] == 4
[Link] = -1
end if
end if
end if
//Turn on Physical Controls
if KeyPress[0].Left == true
[Link] = 1
[Link] = true
end if
if KeyPress[0].Right == true
[Link] = 0
[Link] = true
end if
if KeyPress[0].Up == true
[Link] = 3
[Link] = true
end if
if KeyPress[0].Down == true
[Link] = 0
[Link] = true
end if
end if
#endplatform
CheckResult = false
if [Link] > -1
if KeyPress[0].Start == true
CheckResult = true
end if
if KeyPress[0].ButtonA == true
CheckResult = true
end if
end if
if CheckResult == true
PlaySfx(SFX_G_SELECT, false)
StopMusic()
[Link]++
end if
if KeyPress[0].ButtonB == true
[Link] = EXTRASMENU_VISUALMODE_FADEOUT
[Link] = 248
PlayStageSfx(SFX_S_BACKBUTTON, false)
end if
break
case EXTRASMENU_VISUALMODE_SELECTED
if [Link] < 30
[Link]++
else
[Link] = 0
[Link]++
end if
break
case EXTRASMENU_VISUALMODE_VIDEOPLAY
if [Link] < 384
[Link] += 8
else
#platform: Use_Origins
game.callbackParam0 = 1
EngineCallback(NOTIFY_EXTRAS_MODE)
#endplatform
switch [Link]
case 0
LoadVideo("Opening")
break
case 1
LoadVideo("Pencil_Test")
break
case 2
LoadVideo("Good_Ending")
break
case 3
LoadVideo("Bad_Ending")
break
end switch
// Because of the way mobile cd worked (using the phone's native video player)
// it needed to reproduce separated videos depending of the soundtrack option
// for the sake of clarity and simplicity, the mobile code got commented out
//
// switch [Link]
// case 0
// if [Link] == OST_JP
// LoadVideo("Opening")
// else
// LoadVideo("OpeningUS")
// end if
// break
//
// case 1
// LoadVideo("Pencil_Test")
// break
//
// case 2
// if [Link] == OST_JP
// LoadVideo("Good_Ending")
// else
// LoadVideo("Good_EndingUS")
// end if
// break
//
// case 3
// if [Link] == OST_JP
// LoadVideo("Bad_Ending")
// else
// LoadVideo("Bad_EndingUS")
// end if
// break
//
// end switch
#platform: Use_Origins
game.callbackParam0 = 0
EngineCallback(NOTIFY_EXTRAS_MODE)
#endplatform
#platform: Mobile
[Link] = -1
#endplatform
[Link] = EXTRASMENU_FADEIN
end if
TempValue0 = [Link]
if TempValue0 > 255
TempValue0 = 255
end if
SetScreenFade(0, 0, 0, TempValue0)
break
case EXTRASMENU_VISUALMODE_FADEOUT
if [Link] > 0
[Link] = [Link]
[Link] -= 8
else
[Link] = 0
[Link]++
end if
break
case EXTRASMENU_VISUALMODE_RETURN
TempValue0 = [Link]
TempValue0 *= 40
TempValue0 += [Link]
TempValue0 -= 87
if [Link] < TempValue0
[Link] += 8
if [Link] > TempValue0
[Link] = TempValue0
end if
[Link] = 0
else
#platform: Use_Origins
if [Link] == false
[Link] = -1
end if
#endplatform
#platform: Mobile
if [Link] == false
[Link] = -1
end if
#endplatform
[Link] = EXTRASMENU_CONTROLS
[Link] = 255
end if
break
case EXTRASMENU_EXIT_MENU
if [Link] > 0
[Link] = [Link]
[Link] -= 8
else
[Link] = TypeName[Blank Object]
[Link] = MENUWINDOW_SHRINK
//All of this is MenuButton objects
Object[34].State = MENUBUTTON_BUTTONS_IN
Object[35].State = MENUBUTTON_BUTTONS_IN
Object[36].State = MENUBUTTON_BUTTONS_IN
Object[37].State = MENUBUTTON_BUTTONS_IN
Object[38].State = MENUBUTTON_BUTTONS_IN
Object[39].State = MENUBUTTON_BUTTONS_IN
Object[40].State = MENUBUTTON_BUTTONS_IN
Object[41].State = MENUBUTTON_BUTTONS_IN
Object[42].State = MENUBUTTON_BUTTONS_IN
//End
[Link] = MENUHEADING_LEAVE_SCREEN
[Link] = MAINMENU_HEADER
end if
break
case EXTRASMENU_FADEIN
if [Link] > 0
[Link] -= 8
else
[Link] = EXTRASMENU_VISUALMODE
PlayMusic([Link])
end if
TempValue0 = [Link]
if TempValue0 > 255
TempValue0 = 255
end if
SetScreenFade(0, 0, 0, TempValue0)
break
case EXTRASMENU_RETURN_TO_TITLE
[Link] += 4
if [Link] == 384
[Link] = PRESENTATION_STAGE
[Link] = STAGE_P_TITLE
LoadStage()
end if
SetScreenFade(0, 0, 0, [Link])
break
end switch
end sub
sub ObjectDraw
switch [Link]
case EXTRASMENU_ENTER_MENU
case EXTRASMENU_CONTROLS
case EXTRASMENU_SELECTED_OPTION
case EXTRASMENU_LOAD_EXTRA_STAGE
case EXTRASMENU_EXIT_MENU
case EXTRASMENU_RETURN_TO_TITLE
[Link] = [Link]
[Link] -= 87
ArrayPos0 = 0
CallFunction(ExtrasMenu_DrawUnlocks) //Draw DA Garden
[Link] += 40
ArrayPos0++
CallFunction(ExtrasMenu_DrawUnlocks) //Draw Visual Mode
[Link] += 40
ArrayPos0++
CallFunction(ExtrasMenu_DrawUnlocks) //Draw Sound Test
[Link] += 40
ArrayPos0++
CallFunction(ExtrasMenu_DrawUnlocks) //Draw Stage Select
break
case EXTRASMENU_LOAD_VISUALMODE
ArrayPos0 = [Link]
CallFunction(ExtrasMenu_DrawUnlocks)
break
case EXTRASMENU_VISUALMODE_FADEIN
case EXTRASMENU_VISUALMODE
case EXTRASMENU_VISUALMODE_VIDEOPLAY
case EXTRASMENU_VISUALMODE_FADEOUT
case EXTRASMENU_VISUALMODE_RETURN
case EXTRASMENU_FADEIN
TempValue0 = [Link]
TempValue0 -= 64
DrawSpriteScreenFX(4, FX_INK, TempValue0, 96)
if [Link] == 0
DrawSpriteScreenFX(26, FX_INK, TempValue0, 96)
DrawSpriteScreenFX(22, FX_INK, TempValue0, 96)
else
DrawSpriteScreenFX(18, FX_INK, TempValue0, 96)
end if
if [Link] == 2
DrawSpriteScreenFX(26, FX_INK, TempValue0, 153)
DrawSpriteScreenFX(24, FX_INK, TempValue0, 153)
else
DrawSpriteScreenFX(20, FX_INK, TempValue0, 153)
end if
TempValue0 += 128
DrawSpriteScreenFX(5, FX_INK, TempValue0, 96)
if [Link] == 1
DrawSpriteScreenFX(26, FX_INK, TempValue0, 96)
DrawSpriteScreenFX(23, FX_INK, TempValue0, 96)
else
DrawSpriteScreenFX(19, FX_INK, TempValue0, 96)
end if
case EXTRASMENU_VISUALMODE_SELECTED
TempValue1 = [Link]
TempValue1 &= 3
TempValue1 >>= 1
TempValue0 = [Link]
TempValue0 -= 64
if [Link] == 0
if TempValue1 == 0
DrawSpriteScreenFX(4, FX_INK, TempValue0, 96)
DrawSpriteScreenFX(26, FX_INK, TempValue0, 96)
end if
DrawSpriteScreenFX(22, FX_INK, TempValue0, 96)
else
DrawSpriteScreenFX(4, FX_INK, TempValue0, 96)
DrawSpriteScreenFX(18, FX_INK, TempValue0, 96)
end if
if [Link] == 2
if TempValue1 == 0
DrawSpriteScreenFX(6, FX_INK, TempValue0, 153)
DrawSpriteScreenFX(26, FX_INK, TempValue0, 153)
end if
DrawSpriteScreenFX(24, FX_INK, TempValue0, 153)
else
DrawSpriteScreenFX(6, FX_INK, TempValue0, 153)
DrawSpriteScreenFX(20, FX_INK, TempValue0, 153)
end if
TempValue0 += 128
if [Link] == 1
if TempValue1 == 0
DrawSpriteScreenFX(5, FX_INK, TempValue0, 96)
DrawSpriteScreenFX(26, FX_INK, TempValue0, 96)
end if
DrawSpriteScreenFX(23, FX_INK, TempValue0, 96)
else
DrawSpriteScreenFX(5, FX_INK, TempValue0, 96)
DrawSpriteScreenFX(19, FX_INK, TempValue0, 96)
end if
if [Link] == 3
if TempValue1 == 0
DrawSpriteScreenFX(7, FX_INK, TempValue0, 153)
DrawSpriteScreenFX(26, FX_INK, TempValue0, 153)
end if
DrawSpriteScreenFX(25, FX_INK, TempValue0, 153)
else
DrawSpriteScreenFX(7, FX_INK, TempValue0, 153)
DrawSpriteScreenFX(21, FX_INK, TempValue0, 153)
end if
[Link] = 255
CallFunction(ExtrasMenu_DrawUnlocks)
break
end switch
end sub
sub ObjectStartup
switch [Link]
case LANG_ENGLISH
LoadSpriteSheet("Menu/MenuGfx2_EN.gif")
break
case LANG_FRENCH
LoadSpriteSheet("Menu/MenuGfx2_FR.gif")
break
case LANG_ITALIAN
LoadSpriteSheet("Menu/MenuGfx2_IT.gif")
break
case LANG_DEUTSCH
LoadSpriteSheet("Menu/MenuGfx2_DE.gif")
break
case LANG_SPANISH
LoadSpriteSheet("Menu/MenuGfx2_ES.gif")
break
case LANG_JAPANESE
LoadSpriteSheet("Menu/MenuGfx2_JP.gif")
break
end switch
ArrayPos0 = 32
ArrayPos1 = 48
TempValue0 = 0
TempValue1 = 0
while ArrayPos0 < 39
TempValue0 += SaveRAM[ArrayPos1]
ArrayPos1++
TempValue1 += SaveRAM[ArrayPos1]
ArrayPos1 += 5
TempValue0 += SaveRAM[ArrayPos1]
ArrayPos1 += 6
TempValue0 += SaveRAM[ArrayPos1]
ArrayPos1 += 6
ArrayPos0++
loop
// TempValue0 will be used to check regular zones total time in time attack
// TempValue1 checks for special stages total time instead
if TempValue0 == 0
TempValue0 = 400000
TempValue1 = 400000
end if
// ========================
// Editor Subs
// ========================
sub RSDKDraw
DrawSprite(0)
end sub
sub RSDKLoad
LoadSpriteSheet("Menu/MenuGfx2_EN.gif")
SpriteFrame(32, 0, 160, 30, 1, 708) // #8 Extras
SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
end sub