Scaling sprite groups

From NeoGeo Development Wiki
Jump to: navigation, 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

.dzh:
    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
.novf:
    move.w  d4,VRAM_RW
    add.w   d2,d1      ; Accumulate error
    subq.b  #1,d7      ; Next sprite
    bne     .dzh