116 lines
2.9 KiB
PHP
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
|