EBLAN_ENGINE/include/engine_math.inc

116 lines
2.9 KiB
PHP

; ==============================================================================
; EBLAN ENGINE - Math, Fixed-Point Trigonometry & RNG
; ==============================================================================
.data
fAngleDiv REAL4 256.0
fFixedScale REAL4 65536.0
.code
; ------------------------------------------------------------------------------
; InitMathTables: Builds 512-entry Sin & Cos tables in 16.16 fixed point
; ------------------------------------------------------------------------------
InitMathTables PROC uses eax ecx edi
LOCAL curAngle:DWORD
mov ecx, 0
init_angle_loop:
mov curAngle, ecx
fldpi
fimul curAngle
fdiv fAngleDiv ; st(0) = (angle * PI) / 256
fsincos ; st(0) = cos, st(1) = sin
; Process Cosine
fmul fFixedScale
fistp DWORD PTR [tableCos + ecx*4]
; Process Sine
fmul fFixedScale
fistp DWORD PTR [tableSin + ecx*4]
inc ecx
cmp ecx, ANGLE_512
jl init_angle_loop
ret
InitMathTables ENDP
; ------------------------------------------------------------------------------
; RandomRange: Generates pseudo-random uint in [0, maxVal-1]
; Input: maxVal (eax)
; Output: eax
; ------------------------------------------------------------------------------
RandomRange PROC uses ecx edx, maxVal:DWORD
cmp maxVal, 1
jle rand_zero
mov eax, rngSeed
imul eax, 1103515245
add eax, 12345
mov rngSeed, eax
shr eax, 16
xor edx, edx
div maxVal
mov eax, edx
ret
rand_zero:
xor eax, eax
ret
RandomRange ENDP
; ------------------------------------------------------------------------------
; FixedMul: Multiplies two 16.16 fixed-point numbers
; Input: a, b
; Output: eax = (a * b) >> 16
; ------------------------------------------------------------------------------
FixedMul PROC uses edx, valA:DWORD, valB:DWORD
mov eax, valA
imul valB
shrd eax, edx, 16
ret
FixedMul ENDP
; ------------------------------------------------------------------------------
; FixedDiv: Divides two 16.16 fixed-point numbers
; Input: a, b
; Output: eax = (a << 16) / b
; ------------------------------------------------------------------------------
FixedDiv PROC uses ebx edx, valA:DWORD, valB:DWORD
mov eax, valA
mov ebx, valB
test ebx, ebx
jz div_zero
cdq
shld edx, eax, 16
shl eax, 16
idiv ebx
ret
div_zero:
mov eax, 7FFFFFFFh ; Return max int on divide-by-zero
ret
FixedDiv ENDP
; ------------------------------------------------------------------------------
; ClampInt: Clamps value between minVal and maxVal
; ------------------------------------------------------------------------------
ClampInt PROC val:DWORD, minVal:DWORD, maxVal:DWORD
mov eax, val
cmp eax, minVal
jge @F
mov eax, minVal
ret
@@:
cmp eax, maxVal
jle @F
mov eax, maxVal
@@:
ret
ClampInt ENDP