Skip to content

Commit 4021275

Browse files
committed
optimized OOB-pixels in _RotateScaleSprite, calcSinCosSMC, and sprite-pointer rotation offsets
1 parent bad34de commit 4021275

File tree

1 file changed

+66
-72
lines changed

1 file changed

+66
-72
lines changed

src/graphx/graphx.asm

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4881,7 +4881,7 @@ gfx_RotatedScaledSprite_NoClip:
48814881
; arg4 : Scale factor (64 = 100%)
48824882
; Returns:
48834883
; The size of the sprite after scaling
4884-
ld h, $21 ; ld hl, *
4884+
ld h, $11 ; ld de, *
48854885
db $FD ; ld h, * --> ld iyh, *
48864886
;-------------------------------------------------------------------------------
48874887
gfx_RotatedScaledSprite:
@@ -4910,7 +4910,7 @@ gfx_RotatedScaledTransparentSprite_NoClip:
49104910
; arg4 : Scale factor (64 = 100%)
49114911
; Returns:
49124912
; The size of the sprite after scaling
4913-
ld h, $21 ; ld hl, *
4913+
ld h, $11 ; ld de, *
49144914
db $FD ; ld h, * --> ld iyh, *
49154915
;-------------------------------------------------------------------------------
49164916
gfx_RotatedScaledTransparentSprite:
@@ -4959,8 +4959,7 @@ _RSS_NC:
49594959
inc hl
49604960

49614961
; or a, a ; carry already cleared
4962-
dec b
4963-
sbc hl, bc ; offset the sprite pointer by (size - 1) * 256
4962+
sbc hl, bc ; offset the sprite pointer by (size * 256)
49644963

49654964
ld (iy + (.dsrs_sprptr_0A - .dsrs_base_address)), hl ; write smc
49664965
ld (iy + (.dsrs_sprptr_0B - .dsrs_base_address)), hl ; write smc
@@ -5031,18 +5030,21 @@ _RSS_NC:
50315030
ld b, a ; render height
50325031
ld c, a ; render width
50335032

5034-
; changes from call * to ld hl, *
5033+
; changes from call * to ld de, *
50355034
.dsrs_clip_call := $+0
50365035
call _RotatedScaled_ClipAdjust
5036+
; UHL is zero
50375037

50385038
ld (iy + (.dsrs_size_1 - .dsrs_base_address)), c ; write smc
50395039

5040-
or a, a
5041-
sbc hl, hl
5042-
ld l, c
5043-
ld de, ti.lcdWidth
5044-
ex de, hl
5045-
sbc hl, de
5040+
; HL = ti.lcdWidth - C
5041+
ld a, $40 ; 320 % 256
5042+
sub a, c
5043+
ld l, a ; low 8 bits
5044+
sbc a, a
5045+
inc a
5046+
ld h, a
5047+
; HL is [65, 319] since C is [1, 255]
50465048
ld (iy + (.line_add - .dsrs_base_address)), hl
50475049

50485050
; calculate y-loop offset for IX
@@ -5051,7 +5053,7 @@ _RSS_NC:
50515053
call _set_DE_to_HL_mul_C
50525054
ld hl, (iy + (.dsrs_sinf_1_plus_offset_ix - .dsrs_base_address))
50535055
or a, a
5054-
sbc.s hl, de ; make sure UHL is zero
5056+
sbc hl, de
50555057
ld (iy + (.dsrs_sinf_1_plus_offset_ix - .dsrs_base_address)), hl
50565058

50575059
; calculate y-loop offset for HL
@@ -5105,19 +5107,19 @@ _RSS_NC:
51055107
jr c, .skip_pixel
51065108
.inner_opaque_hijack:
51075109
; get pixel and draw to buffer
5108-
push hl ; xs
5110+
push hl ; preserve ys
51095111
ld l, a
51105112
inc l
5113+
ld b, l ; L is a known constant (A + 1) that we can compensate for
51115114
mlt hl
5112-
ld b, a ; A is a known constant that we can compensate for
51135115
; result is at most 255 * 255 + 255 or 65279. Make sure UBC is zero
51145116
add hl, bc ; y * size + x
51155117

51165118
ld bc, 0
51175119
.dsrs_sprptr_0B := $-3
51185120
add hl, bc
51195121
ldi
5120-
pop hl
5122+
pop hl ; restore ys
51215123

51225124
ld bc, 0 ; smc = -sinf
51235125
.dsrs_sinf_0B := $-3
@@ -5161,12 +5163,12 @@ _RSS_NC:
51615163
jr c, .skip_pixel
51625164
; get pixel and draw to buffer
51635165
; SMC: push hl \ ld l, a --> jr inner_opaque_hijack
5164-
push hl ; xs
5166+
push hl ; preserve ys
51655167
ld l, a
51665168
.dsrs_jump_2 := $-1
51675169
inc l
5170+
ld b, l ; L is a known constant (A + 1) that we can compensate for
51685171
mlt hl
5169-
ld b, a ; A is a known constant that we can compensate for
51705172
; result is at most 255 * 255 + 255 or 65279. Make sure UBC is zero
51715173
add hl, bc ; y * size + x
51725174

@@ -5181,7 +5183,7 @@ smcByte _TransparentColor
51815183
ld (de), a
51825184
.transparent_pixel:
51835185
ld a, b ; restore A
5184-
pop hl ; ys
5186+
pop hl ; restore ys
51855187
.skip_pixel:
51865188
inc de ; x++s
51875189
ld bc, 0 ; smc = -sinf
@@ -5207,10 +5209,9 @@ smcByte _TransparentColor
52075209
;-------------------------------------------------------------------------------
52085210
_rss_not_culled:
52095211
; offscreen
5210-
ld a, iyl ; sprite out size (iyl/width should remain untouched)
52115212
ld sp, ix
5212-
pop ix
5213-
ret
5213+
jr _RSS_NC.finish
5214+
52145215
_RotatedScaled_ClipAdjust:
52155216
; modified version of _ClipCoordinates
52165217
push iy
@@ -5346,7 +5347,7 @@ smcWord _XMin
53465347
; DE = HL * B(height)
53475348
call _set_DE_to_HL_mul_C
53485349
pop hl
5349-
add.s hl, de ; make sure UHL is zero
5350+
add.s hl, de ; make sure UHL is zero when returning from this function
53505351
; ld (iy + (_RSS_NC.dsrs_size128_0_plus_dyc_0 - _RSS_NC.dsrs_base_address)), hl
53515352
ld (ix - 12), hl ; dsrs_size128_0_plus_dyc_0
53525353

@@ -5401,8 +5402,7 @@ gfx_RotateScaleSprite:
54015402
inc hl
54025403

54035404
or a, a
5404-
dec b
5405-
sbc hl, bc ; offset the sprite pointer by (size - 1) * 256
5405+
sbc hl, bc ; offset the sprite pointer by (size * 256)
54065406

54075407
ld (iy + (_smc_dsrs_sprptr_0 - _smc_dsrs_base_address)), hl ; write smc
54085408

@@ -5441,7 +5441,7 @@ gfx_RotateScaleSprite:
54415441
sbc hl, hl
54425442
ld h, b
54435443
; BC = size * scale
5444-
mlt bc
5444+
mlt bc ; UBC cleared
54455445
; HL = size / 2
54465446
srl h
54475447
; rr l
@@ -5517,6 +5517,27 @@ gfx_RotateScaleSprite:
55175517
jr drawSpriteRotateScale_Begin
55185518

55195519
;-------------------------------------------------------------------------------
5520+
5521+
drawSpriteRotateScale_SkipPixel:
5522+
ex de, hl
5523+
ld (hl), TRASPARENT_COLOR ; write pixel
5524+
smcByte _TransparentColor
5525+
ex de, hl
5526+
inc de ; x++s
5527+
5528+
ld bc, 0 ; smc = -sinf
5529+
_smc_dsrs_sinf_0B := $-3
5530+
add hl, bc ; ys += -sinf
5531+
5532+
ld bc, 0 ; smc = cosf
5533+
_smc_dsrs_cosf_0B := $-3
5534+
add ix, bc ; xs += cosf
5535+
5536+
dec iyl
5537+
jr nz, _xloop ; x loop
5538+
; We are here because the right edge of the sprite was transparent.
5539+
dec iyh
5540+
jr z, drawSpriteRotateScale_Finish
55205541
_yloop:
55215542
ld bc, $000000 ; smc = cosf
55225543
_smc_dsrs_cosf_1_plus_offset_hl := $-3
@@ -5537,11 +5558,11 @@ _xloop:
55375558
cp a, c
55385559
jr c, drawSpriteRotateScale_SkipPixel
55395560
; get pixel and draw to buffer
5540-
push hl ; xs
5561+
push hl ; preserve ys
55415562
ld l, a
55425563
inc l
5564+
ld b, l ; L is a known constant (A + 1) that we can compensate for
55435565
mlt hl
5544-
ld b, a ; A is a known constant that we can compensate for
55455566
; result is at most 255 * 255 + 255 or 65279. Make sure UBC is zero
55465567
add hl, bc ; y * size + x
55475568

@@ -5553,7 +5574,7 @@ _smc_dsrs_sprptr_0 := $-3
55535574
; inc de ; x++s
55545575
ldi
55555576

5556-
pop hl ; ys
5577+
pop hl ; restore ys
55575578
ld bc, $000000 ; smc = -sinf
55585579
_smc_dsrs_sinf_0A := $-3
55595580
add hl, bc ; ys += -sinf
@@ -5567,31 +5588,7 @@ _smc_dsrs_cosf_0A := $-3
55675588

55685589
dec iyh
55695590
jr nz, _yloop ; y loop
5570-
pop hl ; sprite out ptr
5571-
pop ix
5572-
ret
5573-
5574-
drawSpriteRotateScale_SkipPixel:
5575-
ld b, a ; preserve A
5576-
ld a,TRASPARENT_COLOR
5577-
smcByte _TransparentColor
5578-
ld (de), a ; write pixel
5579-
inc de ; x++s
5580-
ld a, b ; restore A
5581-
5582-
ld bc, 0 ; smc = -sinf
5583-
_smc_dsrs_sinf_0B := $-3
5584-
add hl, bc ; ys += -sinf
5585-
5586-
ld bc, 0 ; smc = cosf
5587-
_smc_dsrs_cosf_0B := $-3
5588-
add ix, bc ; xs += cosf
5589-
5590-
dec iyl
5591-
jr nz, _xloop ; x loop
5592-
; We are here because the right edge of the sprite was transparent.
5593-
dec iyh
5594-
jr nz, _yloop ; y loop
5591+
drawSpriteRotateScale_Finish:
55955592
pop hl ; sprite out ptr
55965593
pop ix
55975594
ret
@@ -5602,36 +5599,32 @@ calcSinCosSMC_loadCosine:
56025599
ld a, 64
56035600
add a, (ix + 15)
56045601
calcSinCosSMC:
5605-
ld e, (ix + 18)
56065602
; inputs:
56075603
; A = angle
5608-
; E = scale
56095604
; outputs:
56105605
; HL = 16bit quotient
56115606
; UHL = 0
56125607
; getSinCos:
56135608
; returns a = sin/cos(a) * 128
5614-
ld bc, $80
5609+
ld bc, $107F ; b = 16, c = $7F
56155610
ld d, a
5616-
bit 7, a
5617-
jr z, .bit7
5618-
sub a, c ; sub a, 128
5619-
.bit7:
56205611
bit 6, a
56215612
jr z, .bit6
5622-
; A = 128 - A
5623-
neg
5624-
add a, c ; add a, 128
5613+
cpl
5614+
inc a
56255615
.bit6:
5616+
and a, c ; and a, $7F
5617+
; A is [0, 64]
56265618
ld c, a
5627-
ld hl, _SineTable
5619+
ld hl, _SineTable - $1000 ; since BC is offset by $1000
56285620
add hl, bc
56295621
ld h, (hl)
5630-
ld l, b ; ld l, 0
5631-
; hl = _SineTable[angle + 64] * 128
5622+
xor a, a
5623+
ld l, a ; ld l, 0
5624+
; hl = _SineTable[angle] * 128
56325625
; H is [0, 127]
56335626
; HL <<= 7
5634-
add.s hl, hl
5627+
add.s hl, hl ; also clears UHL
56355628
add hl, hl
56365629
add hl, hl
56375630
add hl, hl
@@ -5640,10 +5633,10 @@ calcSinCosSMC:
56405633
add hl, hl
56415634

56425635
; _16Div8Signed:
5643-
; hl = _SineTable[angle + 64] * 128 / scale (cos)
5644-
ld b, 16
5645-
xor a, a
5646-
.div:
5636+
; hl = _SineTable[angle] * 128 / scale (sin)
5637+
ld e, (ix + 18) ; scale
5638+
; 16 iterations
5639+
.div_loop:
56475640
add hl, hl
56485641
rla
56495642
jr c, .overflow ; this path is only used when E >= 128
@@ -5653,7 +5646,7 @@ calcSinCosSMC:
56535646
sub a, e
56545647
inc l
56555648
.check:
5656-
djnz .div
5649+
djnz .div_loop
56575650
bit 7, d
56585651
; UHL is zero here
56595652
ret z
@@ -5692,6 +5685,7 @@ _CalcDXS:
56925685
ld b, a ; -(size * scale / 128)
56935686
ld (iy + 0), bc ; smc base address
56945687
_16Mul16SignedNeg:
5688+
; same as __smulu_fast
56955689
; outputs to HL
56965690
; UHL = 0
56975691
ld d, b

0 commit comments

Comments
 (0)