Alright, some more plumbing to wrap up the week. Aside from the
dynamic resize routines, every level has a set of four additional functions: screen init, screen event, background init and background event. The "init" functions, as the name implies, run once at level load. Meanwhile, the "event" functions, much like the resize routines, run once every frame.
Offs_ScreenInit: dc.l AIZ1_ScreenInit
Offs_BackgroundInit: dc.l AIZ1_BackgroundInit
dc.l AIZ2_ScreenInit
dc.l AIZ2_BackgroundInit
Offs_ScreenEvent: dc.l AIZ1_ScreenEvent
Offs_BackgroundEvent: dc.l AIZ1_BackgroundEvent
dc.l AIZ2_ScreenEvent
dc.l AIZ2_BackgroundEvent
dc.l HCZ1_ScreenInit
dc.l HCZ1_BackgroundInit
dc.l HCZ2_ScreenInit
dc.l HCZ2_BackgroundInit
dc.l HCZ1_ScreenEvent
dc.l HCZ1_BackgroundEvent
dc.l HCZ2_ScreenEvent
dc.l HCZ2_BackgroundEvent
...
The main job of these functions is actually to render the background layers, applying all the stage-specific scroll effects such as distortions and parallax. The "screen" functions are responsible for drawing the foreground plane, whereas the "background" functions draw, well, the background plane. Much like the dynamic resize routines, they're often split into several states, indexed by a value stored in RAM.
AIZ2_ScreenEvent:
move.w ($FFFFEECE).w,d0
add.w d0,(Camera_Y_pos_copy).w
move.w ($FFFFEEC0).w,d0
jmp loc_4FF26(pc,d0.w)
; ---------------------------------------------------------------------------
loc_4FF26:
bra.w AIZ2SE_Normal
; ---------------------------------------------------------------------------
bra.w AIZ2SE_ShipRefresh
; ---------------------------------------------------------------------------
bra.w AIZ2SE_ShipDraw
; ---------------------------------------------------------------------------
bra.w AIZ2SE_EndRefresh
; ---------------------------------------------------------------------------
bra.w AIZ2SE_End
; ---------------------------------------------------------------------------
Moreover, these functions frequently perform the kind of tasks a resize routine would, in levels that don't use them. For instance, Mushroom Hill Zone 1's screen event function is responsible for vertically locking the camera at the end of the level and
spawning the act 1 boss object.
MHZ1_ScreenEvent:
tst.b ($FFFFEED2).w
bne.s loc_54B7C
tst.w ($FFFFEEE8).w
bne.s loc_54B7C
jsr sub_54B80(pc)
move.w #$AA0,d0
cmpi.w #$4100,($FFFFB010).w
blo.s loc_54B40
move.w #$710,d0
loc_54B40:
cmp.w (Camera_max_Y_pos).w,d0
beq.s loc_54B4E
move.w d0,(Camera_max_Y_pos).w
move.w d0,(Camera_target_max_Y_pos).w
loc_54B4E:
cmpi.w #$710,(Camera_Y_pos).w
blo.s loc_54B7C
cmpi.w #$4298,(Camera_X_pos).w
blo.s loc_54B7C
move.w #$710,(Camera_min_Y_pos).w
move.w #8,($FFFFEEB2).w
st ($FFFFEED2).w
jsr (Create_New_Sprite).l
bne.s loc_54B7C
move.l #Obj_MHZ_Miniboss,(a1)
loc_54B7C:
jmp DrawTilesAsYouMove(pc)
This kind of stuff can just as easily go on the background event function though, particularly when it involves using the
solid background flag. Generally speaking, either function is suitable for executing arbitrary logic throughout the whole stage. There's one thing in particular that the act 1 background event functions are responsible for, though.
HCZ1_BackgroundEvent:
move.w ($FFFFEEC2).w,d0
jmp loc_50BC6(pc,d0.w)
; ---------------------------------------------------------------------------
loc_50BC6:
bra.w HCZ1BGE_Normal
; ---------------------------------------------------------------------------
bra.w HCZ1BGE_DoTransition
; ---------------------------------------------------------------------------
That's right, we're finally taking a look at act transitions next. You know, those things that crash Sonic Mania unless you stay perfectly still.
No comments:
Post a Comment