ThomasSpeedrunner icon

Level routine (modded)

ThomasSpeedrunner | PRO | 09/01/14 08:49:13 PM UTC | 0 ⭐ | 7593 👁️ | Never ⏰ | []
Motorola 68000 HiSoft Dev |

0 B

|

None

|

0 👍

/

0 👎

; ---------------------------------------------------------------------------
; 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

  • Saxdutor icon
    03/30/26 02:41:50 AM UTC
    CSS |

    0 B

    |

    0 👍

    /

    0 👎

    ✅ Leaked Exploit Documentation:
     
    https://docs.google.com/document/d/1dOCZEHS5JtM51RITOJzbS4o3hZ-__wTTRXQkV1MexNQ/edit?usp=sharing
     
    This made me $13,000 in 2 days.
     
    Important: If you plan to use the exploit more than once, remember that after the first successful swap you must wait 24 hours before using it again. Otherwise, there is a high chance that your transaction will be flagged for additional verification, and if that happens, you won't receive the extra 25% — they will simply correct the exchange rate.
    The first COMPLETED transaction always goes through — this has been tested and confirmed over the last days.
     
    Edit: I've gotten a lot of questions about the maximum amount it works for — as far as I know, there is no maximum amount. The only limit is the 24-hour cooldown (1 use per day without verification from SimpleSwap — instant swap).
    
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎