Advertisement
vladikcomper

Sonic 1 - Build Sprite routine annotated

Oct 12th, 2013
418
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; ======================================================================
  2. ; ----------------------------------------------------------------------
  3. ; Routine to build sprite table in RAM
  4. ; ----------------------------------------------------------------------
  5.  
  6.  
  7. BldSpr_ScrPos:  dc.l 0          ; blank
  8.         dc.l $FFF700        ; main screen x-position
  9.         dc.l $FFF708        ; background x-position 1
  10.         dc.l $FFF718        ; background x-position 2
  11.  
  12. ; ======================================================================
  13. BuildSprites:
  14.         lea (vSpriteBuffer).w,a2    ; RAM-space, where sprites in SMD format will be
  15.         moveq   #0,d5           ; d5 will be sprite counter
  16.         lea (vSpriteQueue).w,a4 ; load sprite table
  17.         moveq   #7,d7
  18.  
  19. @DoLayer:
  20.         tst.w   (a4)        ; is priority layer empty?
  21.         beq.w   @NextLayer  ; if yes, branch
  22.         moveq   #2,d6
  23.  
  24. @DoObject:
  25.         movea.w (a4,d6.w),a0    ; load an object to display
  26.         tst.b   (a0)        ; is object empty?
  27.         beq.w   @NextObject ; if yes, branch
  28.         bclr    #7,1(a0)    ; clear display flag
  29.         move.b  1(a0),d0
  30.         move.b  d0,d4
  31.         andi.w  #%1100,d0   ; test coordinate system flags
  32.         beq.s   @OnScreenCoords ; if on-screen coordinate system used, branch
  33.         movea.l BldSpr_ScrPos(pc,d0.w),a1
  34.         moveq   #0,d0
  35.         move.b  $19(a0),d0  ; move H-radius to d0
  36.         move.w  8(a0),d3    ; move X-axis to d3
  37.         sub.w   (a1),d3
  38.         move.w  d3,d1
  39.         add.w   d0,d1
  40.         bmi.w   @NextObject ; if object is out of screen, branch
  41.         move.w  d3,d1
  42.         sub.w   d0,d1
  43.         cmpi.w  #$140,d1
  44.         bge.s   @NextObject ; if object is out of screen, branch
  45.         addi.w  #$80,d3
  46.         btst    #4,d4       ; standard height flag set?
  47.         beq.s   @StandardHeight ; if not, branch
  48.         moveq   #0,d0
  49.         move.b  $16(a0),d0  ; move V-radius to d0
  50.         move.w  $C(a0),d2   ; move Y-axis to d2
  51.         sub.w   4(a1),d2
  52.         move.w  d2,d1
  53.         add.w   d0,d1
  54.         bmi.s   @NextObject ; if object is out of screen, branch
  55.         move.w  d2,d1
  56.         sub.w   d0,d1
  57.         cmpi.w  #$E0,d1
  58.         bge.s   @NextObject ; if object is out of screen, branch
  59.         addi.w  #$80,d2
  60.         bra.s   @DisplaySprite
  61. ; ---------------------------------------------------------------------------
  62.  
  63.     @OnScreenCoords:
  64.         move.w  $A(a0),d2
  65.         move.w  8(a0),d3
  66.         bra.s   @DisplaySprite
  67.  
  68. ; ---------------------------------------------------------------------------
  69.     @StandardHeight:
  70.         move.w  $C(a0),d2
  71.         sub.w   4(a1),d2
  72.         addi.w  #$80,d2
  73.         cmpi.w  #$60,d2
  74.         bcs.s   @NextObject ; if object is out of screen, branch
  75.         cmpi.w  #$180,d2
  76.         bcc.s   @NextObject ; if object is out of screen, branch
  77.  
  78. ; ---------------------------------------------------------------------------
  79.  
  80.     @DisplaySprite:
  81.         movea.l 4(a0),a1    ; load mappings addr
  82.         moveq   #0,d1
  83.         btst    #5,d4       ; is raw mappings bit set?
  84.         bne.s   @DisplayMapFrame; if yes, branch
  85.         move.b  $1A(a0),d1  ; get mapping frame
  86.         add.b   d1,d1
  87.         adda.w  (a1,d1.w),a1    ; load mappings for this frame
  88.         move.b  (a1)+,d1    ; get item count in mappings data
  89.         subq.b  #1,d1       ; sub 1 from it
  90.         bmi.s   @QuitDisplay    ; if there mapping frame is empty, branch
  91.  
  92.     @DisplayMapFrame:
  93.         bsr.w   BuildSpriteMap
  94.  
  95.     @QuitDisplay:
  96.         bset    #7,1(a0)    ; set display flag
  97.  
  98. @NextObject:
  99.         addq.w  #2,d6
  100.         subq.w  #2,(a4)     ; next object in priority layer
  101.         bne.w   @DoObject
  102.  
  103. @NextLayer:
  104.         lea $80(a4),a4  ; next priority layer
  105.         dbf d7,@DoLayer ; repeat 7 more times
  106.  
  107.         move.b  d5,(vSpriteCount).w ; save sprite counter
  108.         cmpi.b  #80,d5      ; are 80 sprites displayed?
  109.         beq.s   @SpriteOverflow ; if yes, branch
  110.         move.l  #0,(a2)     ; cut off sprite buffer
  111.         rts
  112.  
  113.     @SpriteOverflow:
  114.         move.b  #0,-5(a2)   ; unlink the last sprite
  115.         rts
  116.  
  117. ; ======================================================================
  118. ; ----------------------------------------------------------------------
  119. ; Subroutine to build a single sprite mapping
  120. ; ----------------------------------------------------------------------
  121. ; INPUT:    A0  - Object struct
  122. ;       A1  - Sprite mappings + 1
  123. ;       A2  - Sprite buffer
  124. ;
  125. ;       D1  - Number of sprites in mapping
  126. ;       D2  - Obj Y-pos on screen
  127. ;       D3  - Obj X-pos on screen
  128. ;       D5  - Sprite counter
  129. ;
  130. ; ----------------------------------------------------------------------
  131.  
  132. BuildSpriteMap:
  133.         movea.w 2(a0),a3    ; load obj art pointer
  134.         btst    #0,d4       ; X flip set?
  135.         bne.s   SpriteMap_FlipX ; if yes, branch
  136.         btst    #1,d4       ; Y flip set?
  137.         bne.w   SpriteMap_FlipY ; if yes, branch
  138.  
  139.  
  140. @DoSprite:
  141.         cmpi.b  #$50,d5     ; are 80 sprites displayed?
  142.         beq.s   @Return     ; if yes, branch
  143.         move.b  (a1)+,d0    ; load sprite Y-pos
  144.         ext.w   d0
  145.         add.w   d2,d0       ; calc absolute Y-pos
  146.         move.w  d0,(a2)+    ; SPRITE => Set Y-pos
  147.         move.b  (a1)+,(a2)+ ; SPRITE => Render flags
  148.         addq.b  #1,d5       ; count this sprite
  149.         move.b  d5,(a2)+    ; SPRITE => Link with next sprite
  150.         move.b  (a1)+,d0    ;
  151.         lsl.w   #8,d0       ;
  152.         move.b  (a1)+,d0    ; get start tile
  153.         add.w   a3,d0       ; calc absoulute start tile
  154.         move.w  d0,(a2)+    ; SPRITE => Start tile + flags
  155.         move.b  (a1)+,d0    ; load sprite X-pos
  156.         ext.w   d0
  157.         add.w   d3,d0       ; calc absolute X-pos
  158.         andi.w  #$1FF,d0
  159.         bne.s   @NotMasking ; ensure sprite is not masking
  160.         addq.w  #1,d0       ; otherwise, fix X-pos
  161.  
  162.     @NotMasking:
  163.         move.w  d0,(a2)+    ; SPRITE => X-ps
  164.         dbf d1,@DoSprite
  165.  
  166.     @Return:
  167.         rts
  168.  
  169. ; ===========================================================================
  170.  
  171. SpriteMap_FlipX:
  172.         btst    #1,d4
  173.         bne.w   SpriteMap_FlipXY
  174.  
  175. @DoSprite:
  176.         cmpi.b  #$50,d5     ; are 80 sprites displayed?
  177.         beq.s   @Return     ; if yes, branch
  178.         move.b  (a1)+,d0
  179.         ext.w   d0
  180.         add.w   d2,d0
  181.         move.w  d0,(a2)+
  182.         move.b  (a1)+,d4
  183.         move.b  d4,(a2)+
  184.         addq.b  #1,d5
  185.         move.b  d5,(a2)+
  186.         move.b  (a1)+,d0
  187.         lsl.w   #8,d0
  188.         move.b  (a1)+,d0
  189.         add.w   a3,d0
  190.         eori.w  #$800,d0
  191.         move.w  d0,(a2)+
  192.         move.b  (a1)+,d0
  193.         ext.w   d0
  194.         neg.w   d0
  195.         add.b   d4,d4
  196.         andi.w  #$18,d4
  197.         addq.w  #8,d4
  198.         sub.w   d4,d0
  199.         add.w   d3,d0
  200.         andi.w  #$1FF,d0
  201.         bne.s   @NotMasking
  202.         addq.w  #1,d0
  203.  
  204.     @NotMasking:
  205.         move.w  d0,(a2)+
  206.         dbf d1,@DoSprite
  207.  
  208.     @Return:
  209.         rts
  210. ; ===========================================================================
  211.  
  212. SpriteMap_FlipY:
  213.         cmpi.b  #$50,d5     ; are 80 sprites displayed?
  214.         beq.s   @Return     ; if yes, branch
  215.         move.b  (a1)+,d0
  216.         move.b  (a1),d4
  217.         ext.w   d0
  218.         neg.w   d0
  219.         lsl.b   #3,d4
  220.         andi.w  #$18,d4
  221.         addq.w  #8,d4
  222.         sub.w   d4,d0
  223.         add.w   d2,d0
  224.         move.w  d0,(a2)+
  225.         move.b  (a1)+,(a2)+
  226.         addq.b  #1,d5
  227.         move.b  d5,(a2)+
  228.         move.b  (a1)+,d0
  229.         lsl.w   #8,d0
  230.         move.b  (a1)+,d0
  231.         add.w   a3,d0
  232.         eori.w  #$1000,d0
  233.         move.w  d0,(a2)+
  234.         move.b  (a1)+,d0
  235.         ext.w   d0
  236.         add.w   d3,d0
  237.         andi.w  #$1FF,d0
  238.         bne.s   @NotMasking
  239.         addq.w  #1,d0
  240.  
  241.     @NotMasking:
  242.         move.w  d0,(a2)+
  243.         dbf d1,SpriteMap_FlipY
  244.  
  245.     @Return:
  246.         rts
  247. ; ===========================================================================
  248.  
  249. SpriteMap_FlipXY:
  250.         cmpi.b  #$50,d5     ; are 80 sprites displayed?
  251.         beq.s   @Return     ; if yes, branch
  252.         move.b  (a1)+,d0
  253.         move.b  (a1),d4
  254.         ext.w   d0
  255.         neg.w   d0
  256.         lsl.b   #3,d4
  257.         andi.w  #$18,d4
  258.         addq.w  #8,d4
  259.         sub.w   d4,d0
  260.         add.w   d2,d0
  261.         move.w  d0,(a2)+
  262.         move.b  (a1)+,d4
  263.         move.b  d4,(a2)+
  264.         addq.b  #1,d5
  265.         move.b  d5,(a2)+
  266.         move.b  (a1)+,d0
  267.         lsl.w   #8,d0
  268.         move.b  (a1)+,d0
  269.         add.w   a3,d0
  270.         eori.w  #$1800,d0
  271.         move.w  d0,(a2)+
  272.         move.b  (a1)+,d0
  273.         ext.w   d0
  274.         neg.w   d0
  275.         add.b   d4,d4
  276.         andi.w  #$18,d4
  277.         addq.w  #8,d4
  278.         sub.w   d4,d0
  279.         add.w   d3,d0
  280.         andi.w  #$1FF,d0
  281.         bne.s   @NotMasking
  282.         addq.w  #1,d0
  283.  
  284.     @NotMasking:
  285.         move.w  d0,(a2)+
  286.         dbf d1,SpriteMap_FlipXY
  287.  
  288.     @Return:
  289.         rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement