		.386p
		ASSUME	CS:CODE,DS:DATA

		PUBLIC	Rot2,Rot2Fast,Rot2Hq

DATA		SEGMENT
		EXTRN	FX_sintbl:DWORD,FX_costbl:DWORD,FX_tantbl:DWORD
		EXTRN	FX_asintbl:DWORD,FX_acostbl:DWORD,FX_atantbl:DWORD
DATA		ENDS


CODE		SEGMENT
		ALIGN	4
Rot2		PROC
#ANG		EQU	ESP+36
#YPTR		EQU	ESP+32
#XPTR		EQU	ESP+28
#RETADR		EQU	ESP+24
#ESI		EQU	ESP+20
#EDI		EQU	ESP+16
#EBX		EQU	ESP+12
#ESPOFS		EQU	12
#SIN		EQU	ESP+8
#COS		EQU	ESP+4
#RESULTX	EQU	ESP

		PUSH	ESI
		PUSH	EDI
		PUSH	EBX
		SUB	ESP,#ESPOFS

		MOV	EAX,[#ANG]
		AND	EAX,0FFFFH
		SHR	EAX,6
		MOV	EDX,[FX_sintbl+EAX*4]
		MOV	[#SIN],EDX
		MOV	EDX,[FX_costbl+EAX*4]
		MOV	[#COS],EDX

		MOV	ESI,[#XPTR]
		MOV	EDI,[#YPTR]
		MOV	EAX,[ESI]
		MOV	EDX,[#COS]
		IMUL	EDX
		MOV	EBX,EAX
		MOV	ECX,EDX
		MOV	EAX,[EDI]
		MOV	EDX,[#SIN]
		IMUL	EDX
		SUB	EBX,EAX
		SBB	ECX,EDX
		SHRD	EBX,ECX,16
		MOV	[#RESULTX],EBX

		MOV	EAX,[ESI]
		MOV	EDX,[#SIN]
		IMUL	EDX
		MOV	EBX,EAX
		MOV	ECX,EDX
		MOV	EAX,[EDI]
		MOV	EDX,[#COS]
		IMUL	EDX
		ADD	EBX,EAX
		ADC	ECX,EDX
		SHRD	EBX,ECX,16

		MOV	EAX,[#RESULTX]
		MOV	[ESI],EAX
		MOV	[EDI],EBX

		ADD	ESP,#ESPOFS
		POP	EBX
		POP	EDI
		POP	ESI
		RET
Rot2		ENDP



		ALIGN	4
Rot2Fast	PROC
#ANGPTR		EQU	ESP+36
#YPTR		EQU	ESP+32
#XPTR		EQU	ESP+28
#RETADR		EQU	ESP+24
#ESI		EQU	ESP+20
#EDI		EQU	ESP+16
#EBX		EQU	ESP+12
#ESPOFS		EQU	12
#SIN		EQU	ESP+8
#COS		EQU	ESP+4
#RESULTX	EQU	ESP

		PUSH	ESI
		PUSH	EDI
		PUSH	EBX
		SUB	ESP,#ESPOFS

		MOV	ESI,[#ANGPTR]
		MOV	EAX,[ESI]
		MOV	[#SIN],EAX
		MOV	EAX,[ESI+4]
		MOV	[#COS],EAX

		MOV	ESI,[#XPTR]
		MOV	EDI,[#YPTR]
		MOV	EAX,[ESI]
		MOV	EDX,[#COS]
		IMUL	EDX
		MOV	EBX,EAX
		MOV	ECX,EDX
		MOV	EAX,[EDI]
		MOV	EDX,[#SIN]
		IMUL	EDX
		SUB	EBX,EAX
		SBB	ECX,EDX
		SHRD	EBX,ECX,16
		MOV	[#RESULTX],EBX

		MOV	EAX,[ESI]
		MOV	EDX,[#SIN]
		IMUL	EDX
		MOV	EBX,EAX
		MOV	ECX,EDX
		MOV	EAX,[EDI]
		MOV	EDX,[#COS]
		IMUL	EDX
		ADD	EBX,EAX
		ADC	ECX,EDX
		SHRD	EBX,ECX,16

		MOV	EAX,[#RESULTX]
		MOV	[ESI],EAX
		MOV	[EDI],EBX

		ADD	ESP,#ESPOFS
		POP	EBX
		POP	EDI
		POP	ESI
		RET
Rot2Fast	ENDP



;EAX:angle    result  All Registers except ESI will be destroyed.
GETHQ		MACRO	TBL
		AND	EAX,0FFFFH
		MOV	EDI,EAX
		SHR	EAX,6
		MOV	ECX,[TBL+EAX*4]
		MOV	EDX,[TBL+EAX*4+4]
		SHL	EAX,6

		;X2-X1=64  (Y2-Y1)*(X-X1)/64 +Y1
		SUB	EDX,ECX		;EDX=Y2-Y1
		SUB	EAX,EDI		;EAX=(X1-X)*-1
		NEG	EAX		;   = X-X1
		IMUL	EDX		;EAX:EDX=(X-X1)(Y2-Y1)
		SHRD	EAX,EDX,6	;EAX=(X-X1)(Y2-Y1)/64
		ADD	EAX,ECX		;EAX=(X-X1)(Y2-Y1)/64+Y1
		ENDM

		ALIGN	4
Rot2Hq		PROC
#ANG		EQU	ESP+36
#YPTR		EQU	ESP+32
#XPTR		EQU	ESP+28
#RETADR		EQU	ESP+24
#ESI		EQU	ESP+20
#EDI		EQU	ESP+16
#EBX		EQU	ESP+12
#ESPOFS		EQU	12
#SIN		EQU	ESP+8
#COS		EQU	ESP+4
#RESULTX	EQU	ESP

		PUSH	ESI
		PUSH	EDI
		PUSH	EBX
		SUB	ESP,#ESPOFS

		MOV	EAX,[#ANG]
		GETHQ	FX_sintbl
		MOV	[#SIN],EAX
		MOV	EAX,[#ANG]
		GETHQ	FX_costbl
		MOV	[#COS],EAX

		MOV	ESI,[#XPTR]
		MOV	EDI,[#YPTR]
		MOV	EAX,[ESI]
		MOV	EDX,[#COS]
		IMUL	EDX
		MOV	EBX,EAX
		MOV	ECX,EDX
		MOV	EAX,[EDI]
		MOV	EDX,[#SIN]
		IMUL	EDX
		SUB	EBX,EAX
		SBB	ECX,EDX
		SHRD	EBX,ECX,16
		MOV	[#RESULTX],EBX

		MOV	EAX,[ESI]
		MOV	EDX,[#SIN]
		IMUL	EDX
		MOV	EBX,EAX
		MOV	ECX,EDX
		MOV	EAX,[EDI]
		MOV	EDX,[#COS]
		IMUL	EDX
		ADD	EBX,EAX
		ADC	ECX,EDX
		SHRD	EBX,ECX,16

		MOV	EAX,[#RESULTX]
		MOV	[ESI],EAX
		MOV	[EDI],EBX

		ADD	ESP,#ESPOFS
		POP	EBX
		POP	EDI
		POP	ESI
		RET
Rot2Hq		ENDP

CODE		ENDS
		END
