; ---------------------------------------------------------------------------
; Level
; ZONE/SPECIAL STAGE LOOP (MLS values $08, $0C, and $10; bit 7 set indicates
; that the load routine is running)
; ---------------------------------------------------------------------------
; loc_3EC4:
Level:
move.b (Game_Mode).w,(Game_Mode_Copy).w
bset #7,(Game_Mode).w ; add $80 to screen mode (for pre level sequence)
tst.w (Demo_mode_flag).w
bmi.s +
move.b #$79+$80,d0
bsr.w PlaySound_Special ; fade out music
+
bsr.w ClearPLC
bsr.w Pal_FadeFrom
tst.w (Demo_mode_flag).w
bmi.w Level_ClrRam
move #$2700,sr
bsr.w ClearScreen
jsr (LoadTitleCard).l ; load title card patterns
move #$2300,sr
moveq #0,d0
move.w d0,(Timer_frames).w
move.b (Current_Zone).w,d0
cmpi.b #$10,(Game_Mode_Copy).w
bne.w +
moveq #0,d0
move.b (Current_Special_Stage+1).w,d0
+
; multiply d0 by 12, the size of a level art load block
add.w d0,d0
add.w d0,d0
move.w d0,d1
add.w d0,d0
add.w d1,d0
cmpi.b #$10,(Game_Mode_Copy).w ; HOLD UP! Are we in a special stage?
bne.w + ; If we are not, branch. Otherwise...
lea (SpecialStageArtPointers).l,a2 ; ...load the special stage art pointers to a2 instead.
bra.w ++
+
lea (LevelArtPointers).l,a2 ; Load the level art pointers to a2.
+
lea (a2,d0.w),a2
moveq #0,d0
move.b (a2),d0
beq.s +
bsr.w LoadPLC
+
moveq #1,d0
bsr.w LoadPLC
bsr.w sub_4450
moveq #6,d0
tst.w (Two_player_mode).w
bne.s +
cmpi.w #2,(Player_mode).w
bne.s Level_ClrRam
addq.w #1,d0
+
tst.b (Graphics_Flags).w
bpl.s +
addq.w #2,d0
+
bsr.w LoadPLC
; loc_3F48:
Level_ClrRam:
clr.b (Super_Sonic_flag).w
clr.w (Closest_Object_X_Dist).w
clr.w (Closest_Object_Y_Dist).w
clr.w (Closest_Object_Hypotenuse_Dist).w
clr.b (Homing_Attack_Chain_Counter).w
clr.b (Next_Flight_Anim).w
clr.b (Reverse_Gravity_Flag).w
clr.b (Current_Shield).w
clearRAM Sprite_Table_Input,$400
clearRAM Object_RAM,$2400 ; clear object RAM
clearRAM $FFFFF628,$58
clearRAM Misc_Variables,$100
clearRAM $FFFFFE60,$50
clearRAM $FFFFE700,$100
move.b #0,(Camera_System_Selection).w
lea (VDP_control_port).l,a6
move.w #$8B03,(a6)
move.w #$8230,(a6)
move.w #$8407,(a6)
move.w #$857C,(a6)
move.w #$9001,(a6)
move.w #$8004,(a6)
move.w #$8720,(a6)
move.w #$8C81,(a6)
tst.b (Debug_cheat_flag).w
beq.s loc_4012
btst #5,(Ctrl_1_Held).w
beq.s +
move.w #$8C89,(a6)
+
btst #6,(Ctrl_1_Held).w
beq.s loc_4012
move.b #1,(Debug_mode_flag).w
loc_4012:
move.w #$8ADF,(Hint_counter_reserve).w ; H-INT every 223rd scanline
tst.w (Two_player_mode).w
beq.s loc_402C
move.w #$8A6B,(Hint_counter_reserve).w ; H-INT every 108th scanline
move.w #$8014,(a6)
move.w #$8C87,(a6)
loc_402C:
move.w (Hint_counter_reserve).w,(a6)
clr.w (VDP_Command_Buffer).w
move.w #VDP_Command_Buffer,(VDP_Command_Buffer_Slot).w
jsr CheckLevelForWater
; loc_407C:
Level_LoadPal:
moveq #3,d0 ; load Sonic's palette index
cmpi.w #2,(Player_mode).w ; are you playing as Tails?
bne.s + ; if not, branch
moveq #$2C,d0 ; load Tails' palette index
+
cmpi.w #3,(Player_mode).w ; are you playing as Knuckles?
bne.s + ; if not, branch
moveq #$28,d0 ; load Knuckles' palette index
+
cmpi.w #9,(Player_mode).w ; are you playing as Derpy?
bne.s + ; if not, branch
moveq #$33,d0 ; load Derpy's palette index
+
bsr.w PalLoad2 ; load the palette line
tst.b (Last_star_pole_hit).w ; is it the start of the level?
beq.s Level_GetBgm ; if yes, branch
move.b (Saved_Water_move).w,(Water_move).w
; loc_40AE:
Level_GetBgm:
tst.w (Demo_mode_flag).w
bmi.w loc_4114
moveq #0,d0
move.b (Current_Zone).w,d0
lea MusicList1(pc),a1
cmpi.b #0,(Current_Act).w
beq.s Level_BgmChkSS
lea MusicList2(pc),a1
cmpi.b #1,(Current_Act).w
beq.s Level_BgmChkSS
lea MusicList3(pc),a1
cmpi.b #2,(Current_Act).w
beq.s Level_BgmChkSS
lea MusicList4(pc),a1
Level_BgmChkSS:
cmpi.b #$10,(Game_Mode_Copy).w
bne.w Level_PlayBgm
moveq #0,d0
move.b (Current_Special_Stage+1).w,d0
lea MusicListSS(pc),a1
; loc_40C8:
Level_PlayBgm:
move.b (a1,d0.w),d0 ; load from music playlist
move.w d0,(Level_Music).w ; store level music
bsr.w PlayMusic ; play level music
move.b #$34,(Object_RAM+$80).w ; load Obj34 (level title card) at $FFFFB080
; loc_40DA:
Level_TtlCard:
move.b #$C,(Delay_Time).w
bsr.w DelayProgram
jsr (RunObjects).l
jsr (BuildSprites).l
bsr.w RunPLC_RAM
move.w (Object_RAM+$80+x_pos).w,d0
cmp.w (Object_RAM+$80+$30).w,d0 ; has title card sequence finished?
bne.s Level_TtlCard ; if not, branch
tst.l (Plc_Buffer).w ; are there any items in the pattern load cue?
bne.s Level_TtlCard ; if yes, branch
move.b #$C,(Delay_Time).w
bsr.w DelayProgram
jsr (Hud_Base).l
loc_4114:
moveq #3,d0
bsr.w PalLoad1 ; load Sonic's palette line
bsr.w LevelSizeLoad
bsr.w JmpTo_DeformBgLayer
clr.w (Vscroll_Factor).w
move.w #-$E0,($FFFFF61E).w
clearRAM Horiz_Scroll_Buf,$400
bsr.w sub_4E98
bsr.w JmpTo_loadZoneBlockMaps
jsr (loc_402D4).l
bsr.w JmpTo_loc_E300
jsr (FloorLog_Unk).l
bsr.w LoadCollisionIndexes
bsr.w WaterEffects
bsr.w InitPlayers
move.w #0,(Ctrl_1_Logical).w
move.w #0,(Ctrl_2_Logical).w
move.w #0,(Ctrl_1).w
move.w #0,(Ctrl_2).w
move.b #1,(Control_Locked).w
move.b #1,($FFFFF7CF).w
move.b #0,(Level_started_flag).w
; Level_ChkWater:
tst.b (Water_flag).w ; does level have water?
beq.s Level_ClrHUD ; if not, branch
move.b #4,(Object_RAM+$380).w ; load Obj04 (water surface) at $FFFFB380
move.w #$60,(Object_RAM+$380+x_pos).w ; set horizontal offset
move.b #4,(Object_RAM+$3C0).w ; load Obj04 (water surface) at $FFFFB3C0
move.w #$120,(Object_RAM+$3C0+x_pos).w ; set different horizontal offset
; Level_LoadObj: misnomer now
Level_ClrHUD:
moveq #0,d0
tst.b (Last_star_pole_hit).w ; are you starting from a lamppost?
bne.s Level_FromCheckpoint ; if yes, branch
move.w d0,(Ring_count).w ; clear rings
move.l d0,(Timer).w ; clear time
move.b d0,(Extra_life_flags).w ; clear extra lives counter
move.w d0,(Ring_count_2P).w ; ditto for player 2
move.l d0,(Timer_2P).w
move.b d0,(Extra_life_flags_2P).w
; loc_41E4:
Level_FromCheckpoint:
move.b d0,(Time_Over_flag).w
move.b d0,(Time_Over_flag_2P).w
move.b d0,($FFFFFF4E).w
move.w d0,($FFFFFF4C).w
move.w d0,(Debug_placement_mode).w
move.w d0,(Level_Inactive_flag).w
move.b d0,($FFFFF622).w
move.b d0,($FFFFF623).w
move.w d0,($FFFFFEF0).w
move.w d0,($FFFFFEF2).w
move.w d0,($FFFFFEF4).w
move.w d0,($FFFFFEF6).w
move.w d0,(Loser_Time_Left).w
bsr.w OscillateNumInit
move.b #1,(Update_HUD_score).w
move.b #1,(Update_HUD_rings).w
move.b #1,(Update_HUD_timer).w
move.b #1,(Update_HUD_timer_2P).w
jsr (ObjectsManager).l
jsr (RingsManager).l
jsr (SpecialCNZBumpers).l
jsr (RunObjects).l
jsr (BuildSprites).l
bsr.w JmpTo_loc_3FCC4
bsr.w SetLevelEndType
move.w #0,(Demo_button_index).w
move.w #0,(Demo_button_index_2P).w
lea (DemoScriptPointers).l,a1
moveq #0,d0
move.b (Current_Zone).w,d0 ; load zone value
lsl.w #2,d0
movea.l (a1,d0.w),a1
tst.w (Demo_mode_flag).w
bpl.s loc_4290
lea (dword_498C).l,a1
move.w ($FFFFFFF4).w,d0
subq.w #1,d0
lsl.w #2,d0
movea.l (a1,d0.w),a1
loc_4290:
move.b 1(a1),(Demo_press_counter).w
tst.b (Current_Zone).w
bne.s loc_42A8
lea (Demo_EHZ_Tails).l,a1
move.b 1(a1),(Demo_press_counter_2P).w
loc_42A8:
move.w #$668,(Demo_Time_left).w
tst.w (Demo_mode_flag).w
bpl.s loc_42C8
move.w #$21C,(Demo_Time_left).w
cmpi.w #4,($FFFFFFF4).w
bne.s loc_42C8
move.w #$1FE,(Demo_Time_left).w
loc_42C8:
tst.b (Water_flag).w
beq.s loc_42E8
moveq #$15,d0
cmpi.b #8,(Current_Zone).w
beq.s loc_42E4
moveq #$16,d0
cmpi.b #$D,(Current_Zone).w
beq.s loc_42E4
moveq #$17,d0
cmpi.b #$F,(Current_Zone).w
beq.s loc_42E4
moveq #$30,d0
loc_42E4:
bsr.w PalLoad4_Water
loc_42E8:
move.w #-1,(Object_RAM+$80+$3E).w
move.b #$E,(Object_RAM+$1C0+routine).w
move.w #$A,(Object_RAM+$1C0+$34).w
loc_42EA:
move.b #$C,(Delay_Time).w
bsr.w DelayProgram
jsr (RunObjects).l
jsr (BuildSprites).l
bsr.w RunPLC_RAM
tst.b (Object_RAM+$140).w
bne.s loc_42EA ; loop while the object at $FFFFB140 is still loaded
lea (Object_RAM+$80).w,a1
move.b #$16,routine(a1)
move.w #$2D,anim_frame_duration(a1)
move.b #$16,next_object+routine(a1)
move.w #$2D,next_object+anim_frame_duration(a1)
tst.b $80(a1)
beq.s + ; branch if an object has not been loaded at $FFFFB100
move.b #$16,$80+routine(a1)
move.w #$2D,$80+anim_frame_duration(a1)
+ move.b #0,(Control_Locked).w
move.b #0,($FFFFF7CF).w
move.b #1,(Level_started_flag).w
; Level_StartGame: loc_435A:
bclr #7,(Game_Mode).w ; clear $80 from the game mode
; ---------------------------------------------------------------------------
; Main level loop (when all title card and loading sequences are finished)
; ---------------------------------------------------------------------------
; loc_4360:
Level_MainLoop:
bsr.w PauseGame
move.b #8,(Delay_Time).w
bsr.w DelayProgram
addq.w #1,(Timer_frames).w ; add 1 to level timer
bsr.w MoveSonicInDemo
bsr.w WaterEffects
jsr (RunObjects).l
tst.w (Level_Inactive_flag).w
bne.w Level
bsr.w JmpTo_DeformBgLayer
bsr.w UpdateWaterSurface
jsr (RingsManager).l
cmpi.b #$C,(Current_Zone).w ; is it CNZ?
bne.s + ; if not, branch past jsr
jsr (SpecialCNZBumpers).l
+
bsr.w JmpTo_loc_3FCC4
bsr.w PalCycle_Load
bsr.w RunPLC_RAM
bsr.w OscillateNumDo
bsr.w ChangeRingFrame
bsr.w CheckLoadSignpostArt
jsr (BuildSprites).l
jsr (ObjectsManager).l
cmpi.b #8,(Game_Mode).w ; check if in demo mode
beq.s loc_43DC
cmpi.b #$C,(Game_Mode).w ; check if in normal play mode
beq.w Level_MainLoop
cmpi.b #$10,(Game_Mode).w ; check if in special stage play mode
beq.w Level_MainLoop
rts ; Return to whatever code was running before this routine was run.
; ---------------------------------------------------------------------------
loc_43DC:
tst.w (Level_Inactive_flag).w
bne.w loc_43FA
tst.w (Demo_Time_left).w
beq.w loc_43FA
cmpi.b #8,(Game_Mode).w
beq.w Level_MainLoop
move.b #0,(Game_Mode).w ; => SegaScreen
rts ; Return to whatever code was running before this routine was run.
; ---------------------------------------------------------------------------
CheckLevelForWater:
cmpi.b #$0F,(Current_Zone).w ; Are we in Ancient Lake Zone?
beq.w Level_InitWater ; If so, branch.
cmpi.w #$0002,(Current_ZoneAndAct).w ; Are we in Frosty Dusk Zone Act 3?
beq.w Level_InitWater ; If so, branch.
cmpi.w #$0004,(Current_Special_Stage).w ; Are we in the 5th special stage?
beq.w Level_InitWater ; If so, branch.
Level_NoWater:
move.w #$1000,d0
move.w d0,(Water_Level_1).w ; set water heights
move.w d0,(Water_Level_2).w
move.w d0,(Water_Level_3).w
move.b #0,(Water_flag).w
rts
Level_InitWater:
move.b #1,(Water_flag).w
move.w #0,(Two_player_mode).w
tst.b (Water_flag).w ; does level have water?
beq.w Level_LoadPal ; if not, branch
move.w #$8014,(a6)
moveq #0,d0
move.w (Current_ZoneAndAct).w,d0
lsl.b #6,d0
lsr.w #5,d0
andi.w #$FFFE,d0
lea (WaterHeight).l,a1 ; load water height array
move.w (a1,d0.w),d0
move.w d0,(Water_Level_1).w ; set water heights
move.w d0,(Water_Level_2).w
move.w d0,(Water_Level_3).w
clr.b (Water_routine).w ; clear water routine counter
clr.b (Water_move).w ; clear water movement
move.b #1,(Water_on).w ; enable water
Level_LoadWaterPal:
tst.b (Water_flag).w ; does level have water?
beq.w Level_NoWater ; if not, branch
moveq #$15,d0 ; palette number $15
cmpi.b #8,(Current_Zone).w
bne.s Level_PalNotHPZ ; branch if level is not HPZ
cmpi.w #2,(Player_mode).w ; are you playing as Tails?
bne.s + ; if not, branch
moveq #$2F,d0 ; load Tails' palette index
+
cmpi.w #3,(Player_mode).w ; are you playing as Knuckles?
bne.s Level_WaterPal ; if not, branch
moveq #$2B,d0
bra.s Level_WaterPal ; branch
Level_PalNotHPZ:
moveq #$16,d0 ; palette number $16
cmpi.b #$D,(Current_Zone).w
bne.s Level_PalNotCFZ ; branch if level is not CFZ
cmpi.w #2,(Player_mode).w ; are you playing as Tails?
bne.s + ; if not, branch
moveq #$2D,d0 ; load Tails' palette index
+
cmpi.w #3,(Player_mode).w ; are you playing as Knuckles?
bne.s Level_WaterPal ; if not, branch
moveq #$29,d0
bra.s Level_WaterPal ; branch
Level_PalNotCFZ:
moveq #$17,d0 ; palette number $17
cmpi.b #$F,(Current_Zone).w
bne.s Level_PalNotALZ ; branch if level is not ALZ
cmpi.w #2,(Player_mode).w ; are you playing as Tails?
bne.s + ; if not, branch
moveq #$2E,d0 ; load Tails' palette index
+
cmpi.w #3,(Player_mode).w ; are you playing as Knuckles?
bne.s Level_WaterPal ; if not, branch
moveq #$2A,d0
Level_PalNotALZ:
moveq #$30,d0 ; palette number $30
cmpi.w #2,(Player_mode).w ; are you playing as Tails?
bne.s + ; if not, branch
moveq #$31,d0 ; load Tails' palette index
+
cmpi.w #3,(Player_mode).w ; are you playing as Knuckles?
bne.s Level_WaterPal ; if not, branch
moveq #$32,d0
; loc_409E:
Level_WaterPal:
bra.w PalLoad3_Water ; load underwater palette (with d0)
; ---------------------------------------------------------------------------
Comments
0 B
|0 👍
/0 👎
0 B
|👍
/👎