; ============================================================================== ; 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