Scaling sprite groups

From NeoGeo Development Wiki
Jump to navigation Jump to search

Horizontal shrinking parameters for sprite groups must be distributed by software to get smooth scaling steps.

If the same parameter is copied to all sprites in a group, the final size will be a multiple of the sprite count. For example, setting all sprites of a group of 5 to a 4-bit value of 13 will give a block 5*(13+1) = 70 pixels wide.

If the parameters are distributed based on a 8-bit value, the steps become smaller. For example, setting a group of 5 sprites to a shrinking value of 183 (scale 72%) will give the following 4-bit values: 10,11,11,10,11, making the group 11+12+12+11+12 = 58 pixels wide, which is 72% of the max width (5*16 = 80 pixels).

Code to distribute horizontal shrinking in sprite groups:

    ; d0.w is the group's overall x shrink value ($00~$FF)
    ; d1.b is the group's y shrink value ($00~$FF)
    ; d2.w is the first sprite's SCB2 VRAM address ($8000+)
    ; d7.b is the group's width in sprites
    move.w  d2,REG_VRAMRW
    move.w  #1,REG_VRAMMOD
    move.w  d0,d2      ; Fast *15
    lsl.w   #4,d0
    sub.w   d2,d0

    move.w  d0,d2
    andi.w  #$0F00,d0  ; d0 = integer part << 8
    or.b    d1,d0      ; Mix in y shrink
    andi.w  #$00FF,d2  ; d2 = fractional part
    move.w  d2,d1      ; d1 = error accumulator

    move.w  d0,d4
    btst.l  #8,d1      ; Enough error to add one pixel ?
    beq     .novf
    addi.w  #$0100,d4
    andi.w  #$00FF,d1  ; Trim error accumulator
    move.w  d4,VRAM_RW
    add.w   d2,d1      ; Accumulate error
    subq.b  #1,d7      ; Next sprite
    bne     .dzh