rotobjbegin=$
;можно учесть, что уже после первого умножения мы знаем Z и можем грубо клипировать (реальный Z будет после второй пары умножений)

	macro MUL2PRE
;h=флаги для bc инверсно! (уже сдвинуто)
;a=флаги для de инверсно!
;bc,de=+-10.0=%ssssssxx xxxxxxxx
;результат в hl (считаем по одному bc)=+-10.0*32=%srrrrrrr rrr?????
	if 1==1
	xor a ;по идее один раз из 4, но надо CY=0
	ld h,a;ld h,%00000100 ;чтобы без ошибок прибавить или вычесть +-#3ff
	ld l,a
	sbc hl,bc ;/#ed:nop - bug on eZ80!!!
	or a
	sbc hl,de ;/#ed:nop - bug on eZ80!!!
	else
	ld l,0
	jr c,$+2+2 ;>=0
	sbc hl,bc
	rla
	jr c,$+2+2 ;>=0
	sbc hl,de
	endif
	add hl,hl
;+7+9.5+7.5+4+9.5+7.5+11=+56
	endm

	macro MUL2
	dup 5;6 ;знак+5 бит угол
	jr c,$+3
	add hl,bc
	rla
	jr c,$+3
	add hl,de
	add hl,hl
	edup
	org $-1
;5*(9.5+5.5+4+9.5+5.5+11)-11=5*45-11=+214
;результат в hl (считаем по одному bc)=+-10.0*32=%srrrrrrr rrr?????
;ожидается %ssssssXX XXXxxxxx (+-32 полукубика)
	add hl,hl
	ccf ;компенсируем add a,%0000010 в синусе
	sbc a,a
	add hl,hl
	rla
	add hl,hl
	rla
	ld l,h
	ld h,a
;(53t)
	endm

	macro MUL2FAST
	dup 5;6 ;знак+5 бит угол
	add hl,bc ;зависело от h
	add hl,de ;зависело от a
	add hl,hl
	edup
	org $-1
;результат в hl (считаем по одному bc)=+-10.0*32=%srrrrrrr rrr?????
;ожидается %ssssssXX XXXxxxxx (+-32 полукубика)
	add hl,hl
	 ;ccf ;компенсируем add a,%0000010 в синусе
	sbc a,a
	add hl,hl
	rla
	add hl,hl
	rla
	ld l,h
	ld h,a
;(53t)
	endm

mkmul2fast_h
	if 1==1
	;cpl
	ld d,a ;for a
	;ld a,e
	;cpl
	;ld e,a ;for h
	;dec hl
	;dec hl
	;dec hl
	;dec hl
	;dec hl
	rl e ;skip sign (for h)
	sbc a,a
	and #42 ;"sbc hl,bc"
	ld (hl),a ;"sbc hl,bc" (for h) ;/#ed:nop - bug on eZ80!!!
	inc hl
	inc hl
	inc hl
	rl d ;skip sign (for a)
	sbc a,a
	and #52 ;"sbc hl,de"
	ld (hl),a ;"sbc hl,de" (for a) ;/#ed:nop - bug on eZ80!!!
	inc hl
	inc hl
	ld bc,#1909 ;c="add hl,bc" (for h) ;b="add hl,de" (for a)
	dup 5
	rl e
	sbc a,a
	and c ;"add hl,bc" (for h)
	ld (hl),a ;for h
	inc hl
	rl d
	sbc a,a
	and b ;"add hl,de" (for a)
	ld (hl),a ;for a
	inc hl
	inc hl
	edup
	org $-2
	 else
	push af
	push hl
	ld a,c
	cpl
	ld e,a
	ld d,#09 ;"add hl,bc" (for h)
	call mkmul2fast
	pop hl
	pop af
	;ret
;mkmul2fast_a
	cpl
	ld e,a
	inc hl
	ld d,#19 ;"add hl,de" (for a)
mkmul2fast
	rl e ;skip sign
	ld b,5
mkmul2fast0
	rl e
	sbc a,a
	and d
	ld (hl),a
	inc hl
	inc hl
	inc hl
	djnz mkmul2fast0
	endif
	ret
	
	 if FASTROTOBJ
;сейчас быстрый выход 550, всё сложение+вращение 1917
;с патчем первая процедура (быстрый выход) 358, вторая 826, всё сложение+вращение 1184
AddCamRotObj_fastZ
	;macro ADDCAM_ROT
;bc=Y (будет =Z')
;hl=X (будет =X')
;de=Z (будет =Y') ;TODO переставить hl<->de
	ex de,hl
	ld (AddCamZ),hl ;Z (будет =Y')
frame_mcamy=$+1
	ld hl,0
	add hl,de
	ex de,hl
frame_mcamx=$+1
	ld hl,0
	add hl,bc
	ld b,h
	ld c,l
;cosZXpatchN=$+1
;	  ld h,0
;	  sla h
;sinZXpatchN=$+1
;	  ld a,0
	MUL2PRE
mulZX1=$
	MUL2FAST ;hl=rotatex*cos(a) + rotatey*sin(a)
	ret

AddCamRotObj_continue
;bc=rotatex
	push hl ;первый результат
;sinZXpatchnegN=$+1
;	  ld h,0
;	  sla h
;cosZXpatchN2=$+1
;	  ld a,0
	MUL2PRE
mulZX2=$
	MUL2FAST ;hl=rotatey*cos(a) - rotatex*sin(a) ;hl=второй результат
	pop bc ;первый результат
	push hl ;X'
AddCamZ=$+1
	ld hl,0 ;Z (будет =Y')
frame_mcamz=$+1
	ld de,0
	add hl,de
	ex de,hl
;cosZYpatchN=$+1
;	  ld h,0
;	  sla h
;sinZYpatchN=$+1
;	  ld a,0
	MUL2PRE
mulYX1=$
	MUL2FAST ;hl=rotatex*cos(a) + rotatey*sin(a)
	push hl ;первый результат
;sinZYpatchnegN=$+1
;	  ld h,0
;	  sla h
;cosZYpatchN2=$+1
;	  ld a,0
	MUL2PRE
mulYX2=$
	MUL2FAST ;hl=rotatey*cos(a) - rotatex*sin(a) ;hl=второй результат
	pop bc ;первый результат
	pop de ;X'
	;bit 7,b ;Z
	;ret nz;jp nz,skipobj
;bc=Z'
;hl=Y'
;de=X'
       if !TWOAXES
       push bc
        ld (DOOBJXYrotatey),hl
       push de ;X'
        ld b,d
        ld c,e
        ld a,(roll)
       ;neg
        ld (cosXYpatch1),a
        ld (cosXYpatch2),a
        sub 64
       ;neg
        ld (sinXYpatchneg1),a
       ;neg
        ld (sinXYpatch2),a
cosXYpatch1=$+1
	ld a,(tcos)
	call mulabc ;hl=rotatex*sin(a)
	ld bc,(DOOBJXYrotatey)
sinXYpatchneg1=$+1
	ld a,(tcos)
       neg
	call mulabcadd ;hl+=rotatey*cos(a) ;hl=первый результат (X'')
	sra h
	rr l
        ex de,hl
        ;ld b,d
        ;ld c,e
       pop bc ;X'
sinXYpatch2=$+1
	ld a,(tcos)
	call mulabc ;hl=rotatex*sin(a)
DOOBJXYrotatey=$+1
	ld bc,0
cosXYpatch2=$+1
	ld a,(tcos)
	call mulabcadd ;hl+=rotatey*cos(a) ;hl=второй результат (Y'')
	sra h
	rr l
       pop bc
       endif

	ret
	;endm
;------------------------
	 else ;~FASTROTOBJ

AddCamRotObj_fastZ
	;macro ADDCAM_ROT
;bc=Y (будет =Z')
;hl=X (будет =X')
;de=Z (будет =Y')
	ld (AddCamZ),de ;Z (будет =Y')
	;push de
frame_mcamy=$+1
	ld de,0
	add hl,de
	;pop de
	push hl
frame_mcamx=$+1
	ld hl,0
	add hl,bc
	ld b,h
	ld c,l
	pop hl
	ld (DOOBJrotatey),hl
	push bc ;rotatex
cosZXpatch=$+1
	ld a,(tcos)
	call mulabc
DOOBJrotatey=$+1
	ld bc,0
sinZXpatch=$+1
	ld a,(tcos)
	call mulabcadd ;hl+=rotatey*sin(a)
	pop bc ;rotatex
	ret

AddCamRotObj_continue
;bc=rotatex
	push hl ;первый результат
sinZXpatchneg=$+1
	ld a,(tcos)
	call mulabc ;hl=rotatex*sin(a)
	ld bc,(DOOBJrotatey)
cosZXpatch2=$+1
	ld a,(tcos)
	call mulabcadd ;hl+=rotatey*cos(a) ;hl=второй результат
	pop bc ;первый результат
	dup 1
	sra b
	rr c
	sra h
	rr l
	edup
	;bit 7,b ;Z
	;ret nz;jp nz,skipobj
	ex de,hl
	push hl ;X'
AddCamZ=$+1
	ld hl,0 ;Z (будет =Y')
frame_mcamz=$+1
	ld de,0
	add hl,de
	ld (DOOBJrotatey2),hl
	push bc ;rotatex
cosZYpatch=$+1
	ld a,(tcos)
	call mulabc
	ld bc,(DOOBJrotatey2)
sinZYpatch=$+1
	ld a,(tcos)
	call mulabcadd ;hl+=rotatey*sin(a)
	pop bc ;rotatex
	sra h
	rr l
	push hl ;первый результат
sinZYpatchneg=$+1
	ld a,(tcos)
	call mulabc ;hl=rotatex*sin(a)
DOOBJrotatey2=$+1
	ld bc,0
cosZYpatch2=$+1
	ld a,(tcos)
	call mulabcadd ;hl+=rotatey*cos(a) ;hl=второй результат
	pop bc ;первый результат
	pop de ;X'
	sra h
	rr l
	;bit 7,b ;Z
	;ret nz;jp nz,skipobj
;bc=Z'
;hl=Y'
;de=X'
	ret
	;endm
       endif

       ifused mulabc

mulabc
;HL = BC * A
;+-15.0 = +-15.0 * +-.7
	ld hl,0
mulabcadd
	rlca
	jr nc,mulabcmain_
;a<0
;было -1(%11111111) => a=-1(%11111111) => надо (%11111101)
;было -2(%11111110) => a=-3(%11111101) => надо (%11111011)
;было -3(%11111101) => a=-5(%11111011) => надо (%11111001)
;было -4(%11111100) => a=-7(%11111001) => надо (%11110111)
;было -5(%11111011) => a=-9(%11110111) => надо (%11110101)
	sub 2
	;rrca
	;dec a ;neg+cpl = dec a+cpl+cpl
	;rlca
	dup 4;6 ;3 уже слишком прыгает Z
	rlca
	jr c,$+4
	sbc hl,bc
	sra b
	rr c
	edup
	rlca
	ret c
	sbc hl,bc
	ret
mulabcmain_
;a>=0
	dup 4;6 ;3 уже слишком прыгает Z
	rlca
	jr nc,$+3
	add hl,bc
	sra b
	rr c
	edup
	rlca
	ret nc
	add hl,bc
	ret


	 endif

	
	macro ADDCAM_ROT
	call AddCamRotObj_fastZ
MAXTANGAGEFASTCLIPZ=16
	 ld a,(frame_tangage)
	 add a,MAXTANGAGEFASTCLIPZ
	 cp MAXTANGAGEFASTCLIPZ*2
	 jr nc,$+2+2+1 ;обходим быстрый выход, если большой тангаж (иначе объекты под ногами не видно)
	bit 7,h ;Z
	ret nz;jp nz,skipobj ;выход на невидимом (695-7t между невидимыми объектами, включая все вызовы)
	call AddCamRotObj_continue
	bit 7,b ;Z
	ret nz;jp nz,skipobj ;выход на невозможном Z
	endm

       if !TWOAXES
roll
        db 15
       endif


	display "rotobj size=",$-rotobjbegin
