@@ -4881,7 +4881,7 @@ gfx_RotatedScaledSprite_NoClip:
4881
4881
; arg4 : Scale factor (64 = 100%)
4882
4882
; Returns:
4883
4883
; The size of the sprite after scaling
4884
- ld h , $ 21 ; ld hl , *
4884
+ ld h , $ 11 ; ld de , *
4885
4885
db $ FD ; ld h, * --> ld iyh, *
4886
4886
;-------------------------------------------------------------------------------
4887
4887
gfx_RotatedScaledSprite:
@@ -4910,7 +4910,7 @@ gfx_RotatedScaledTransparentSprite_NoClip:
4910
4910
; arg4 : Scale factor (64 = 100%)
4911
4911
; Returns:
4912
4912
; The size of the sprite after scaling
4913
- ld h , $ 21 ; ld hl , *
4913
+ ld h , $ 11 ; ld de , *
4914
4914
db $ FD ; ld h, * --> ld iyh, *
4915
4915
;-------------------------------------------------------------------------------
4916
4916
gfx_RotatedScaledTransparentSprite:
@@ -4959,8 +4959,7 @@ _RSS_NC:
4959
4959
inc hl
4960
4960
4961
4961
; 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)
4964
4963
4965
4964
ld (iy + (.dsrs_sprptr_0A - .dsrs_base_address)) , hl ; write smc
4966
4965
ld (iy + (.dsrs_sprptr_0B - .dsrs_base_address)) , hl ; write smc
@@ -5031,18 +5030,21 @@ _RSS_NC:
5031
5030
ld b , a ; render height
5032
5031
ld c , a ; render width
5033
5032
5034
- ; changes from call * to ld hl , *
5033
+ ; changes from call * to ld de , *
5035
5034
.dsrs_clip_call := $ + 0
5036
5035
call _RotatedScaled_ClipAdjust
5036
+ ; UHL is zero
5037
5037
5038
5038
ld (iy + (.dsrs_size_1 - .dsrs_base_address)) , c ; write smc
5039
5039
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]
5046
5048
ld (iy + (.line_add - .dsrs_base_address)) , hl
5047
5049
5048
5050
; calculate y-loop offset for IX
@@ -5051,7 +5053,7 @@ _RSS_NC:
5051
5053
call _set_DE_to_HL_mul_C
5052
5054
ld hl , (iy + (.dsrs_sinf_1_plus_offset_ix - .dsrs_base_address))
5053
5055
or a , a
5054
- sbc.s hl , de ; make sure UHL is zero
5056
+ sbc hl , de
5055
5057
ld (iy + (.dsrs_sinf_1_plus_offset_ix - .dsrs_base_address)) , hl
5056
5058
5057
5059
; calculate y-loop offset for HL
@@ -5105,19 +5107,19 @@ _RSS_NC:
5105
5107
jr c , .skip_pixel
5106
5108
.inner_opaque_hijack:
5107
5109
; get pixel and draw to buffer
5108
- push hl ; xs
5110
+ push hl ; preserve ys
5109
5111
ld l , a
5110
5112
inc l
5113
+ ld b , l ; L is a known constant (A + 1) that we can compensate for
5111
5114
mlt hl
5112
- ld b , a ; A is a known constant that we can compensate for
5113
5115
; result is at most 255 * 255 + 255 or 65279. Make sure UBC is zero
5114
5116
add hl , bc ; y * size + x
5115
5117
5116
5118
ld bc , 0
5117
5119
.dsrs_sprptr_0B := $ - 3
5118
5120
add hl , bc
5119
5121
ldi
5120
- pop hl
5122
+ pop hl ; restore ys
5121
5123
5122
5124
ld bc , 0 ; smc = -sinf
5123
5125
.dsrs_sinf_0B := $ - 3
@@ -5161,12 +5163,12 @@ _RSS_NC:
5161
5163
jr c , .skip_pixel
5162
5164
; get pixel and draw to buffer
5163
5165
; SMC: push hl \ ld l, a --> jr inner_opaque_hijack
5164
- push hl ; xs
5166
+ push hl ; preserve ys
5165
5167
ld l , a
5166
5168
.dsrs_jump_2 := $ - 1
5167
5169
inc l
5170
+ ld b , l ; L is a known constant (A + 1) that we can compensate for
5168
5171
mlt hl
5169
- ld b , a ; A is a known constant that we can compensate for
5170
5172
; result is at most 255 * 255 + 255 or 65279. Make sure UBC is zero
5171
5173
add hl , bc ; y * size + x
5172
5174
@@ -5181,7 +5183,7 @@ smcByte _TransparentColor
5181
5183
ld (de) , a
5182
5184
.transparent_pixel:
5183
5185
ld a , b ; restore A
5184
- pop hl ; ys
5186
+ pop hl ; restore ys
5185
5187
.skip_pixel:
5186
5188
inc de ; x++s
5187
5189
ld bc , 0 ; smc = -sinf
@@ -5207,10 +5209,9 @@ smcByte _TransparentColor
5207
5209
;-------------------------------------------------------------------------------
5208
5210
_rss_not_culled:
5209
5211
; offscreen
5210
- ld a , iyl ; sprite out size (iyl/width should remain untouched)
5211
5212
ld sp , ix
5212
- pop ix
5213
- ret
5213
+ jr _RSS_NC.finish
5214
+
5214
5215
_RotatedScaled_ClipAdjust:
5215
5216
; modified version of _ClipCoordinates
5216
5217
push iy
@@ -5346,7 +5347,7 @@ smcWord _XMin
5346
5347
; DE = HL * B(height)
5347
5348
call _set_DE_to_HL_mul_C
5348
5349
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
5350
5351
; ld (iy + (_RSS_NC.dsrs_size128_0_plus_dyc_0 - _RSS_NC.dsrs_base_address)), hl
5351
5352
ld (ix - 12 ) , hl ; dsrs_size128_0_plus_dyc_0
5352
5353
@@ -5401,8 +5402,7 @@ gfx_RotateScaleSprite:
5401
5402
inc hl
5402
5403
5403
5404
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)
5406
5406
5407
5407
ld (iy + (_smc_dsrs_sprptr_0 - _smc_dsrs_base_address)) , hl ; write smc
5408
5408
@@ -5441,7 +5441,7 @@ gfx_RotateScaleSprite:
5441
5441
sbc hl , hl
5442
5442
ld h , b
5443
5443
; BC = size * scale
5444
- mlt bc
5444
+ mlt bc ; UBC cleared
5445
5445
; HL = size / 2
5446
5446
srl h
5447
5447
; rr l
@@ -5517,6 +5517,27 @@ gfx_RotateScaleSprite:
5517
5517
jr drawSpriteRotateScale_Begin
5518
5518
5519
5519
;-------------------------------------------------------------------------------
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
5520
5541
_yloop:
5521
5542
ld bc , $ 000000 ; smc = cosf
5522
5543
_smc_dsrs_cosf_1_plus_offset_hl := $ - 3
@@ -5537,11 +5558,11 @@ _xloop:
5537
5558
cp a , c
5538
5559
jr c , drawSpriteRotateScale_SkipPixel
5539
5560
; get pixel and draw to buffer
5540
- push hl ; xs
5561
+ push hl ; preserve ys
5541
5562
ld l , a
5542
5563
inc l
5564
+ ld b , l ; L is a known constant (A + 1) that we can compensate for
5543
5565
mlt hl
5544
- ld b , a ; A is a known constant that we can compensate for
5545
5566
; result is at most 255 * 255 + 255 or 65279. Make sure UBC is zero
5546
5567
add hl , bc ; y * size + x
5547
5568
@@ -5553,7 +5574,7 @@ _smc_dsrs_sprptr_0 := $-3
5553
5574
; inc de ; x++s
5554
5575
ldi
5555
5576
5556
- pop hl ; ys
5577
+ pop hl ; restore ys
5557
5578
ld bc , $ 000000 ; smc = -sinf
5558
5579
_smc_dsrs_sinf_0A := $ - 3
5559
5580
add hl , bc ; ys += -sinf
@@ -5567,31 +5588,7 @@ _smc_dsrs_cosf_0A := $-3
5567
5588
5568
5589
dec iyh
5569
5590
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:
5595
5592
pop hl ; sprite out ptr
5596
5593
pop ix
5597
5594
ret
@@ -5602,36 +5599,32 @@ calcSinCosSMC_loadCosine:
5602
5599
ld a , 64
5603
5600
add a , (ix + 15 )
5604
5601
calcSinCosSMC:
5605
- ld e , (ix + 18 )
5606
5602
; inputs:
5607
5603
; A = angle
5608
- ; E = scale
5609
5604
; outputs:
5610
5605
; HL = 16bit quotient
5611
5606
; UHL = 0
5612
5607
; getSinCos:
5613
5608
; returns a = sin/cos(a) * 128
5614
- ld bc , $ 80
5609
+ ld bc , $ 107F ; b = 16, c = $7F
5615
5610
ld d , a
5616
- bit 7 , a
5617
- jr z , .bit7
5618
- sub a , c ; sub a, 128
5619
- .bit7:
5620
5611
bit 6 , a
5621
5612
jr z , .bit6
5622
- ; A = 128 - A
5623
- neg
5624
- add a , c ; add a, 128
5613
+ cpl
5614
+ inc a
5625
5615
.bit6:
5616
+ and a , c ; and a, $7F
5617
+ ; A is [0, 64]
5626
5618
ld c , a
5627
- ld hl , _SineTable
5619
+ ld hl , _SineTable - $ 1000 ; since BC is offset by $1000
5628
5620
add hl , bc
5629
5621
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
5632
5625
; H is [0, 127]
5633
5626
; HL <<= 7
5634
- add .s hl , hl
5627
+ add .s hl , hl ; also clears UHL
5635
5628
add hl , hl
5636
5629
add hl , hl
5637
5630
add hl , hl
@@ -5640,10 +5633,10 @@ calcSinCosSMC:
5640
5633
add hl , hl
5641
5634
5642
5635
; _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 :
5647
5640
add hl , hl
5648
5641
rla
5649
5642
jr c , .overflow ; this path is only used when E >= 128
@@ -5653,7 +5646,7 @@ calcSinCosSMC:
5653
5646
sub a , e
5654
5647
inc l
5655
5648
.check:
5656
- djnz . div
5649
+ djnz .div_loop
5657
5650
bit 7 , d
5658
5651
; UHL is zero here
5659
5652
ret z
@@ -5692,6 +5685,7 @@ _CalcDXS:
5692
5685
ld b , a ; -(size * scale / 128)
5693
5686
ld (iy + 0 ) , bc ; smc base address
5694
5687
_16Mul16SignedNeg:
5688
+ ; same as __smulu_fast
5695
5689
; outputs to HL
5696
5690
; UHL = 0
5697
5691
ld d , b
0 commit comments