0,0 → 1,111 |
|
align 4 |
proc calc_buf uses ebx ecx, buf:dword, shininess:dword |
locals |
val dd ? ;float |
f_inc dd ? ;float |
endl |
mov dword[val],0.0f |
mov dword[f_inc],SPECULAR_BUFFER_SIZE |
fld1 |
fidiv dword[f_inc] |
fstp dword[f_inc] ;f_inc = 1.0f/SPECULAR_BUFFER_SIZE |
xor ecx,ecx |
align 4 |
.cycle_0: ;for (i = 0; i <= SPECULAR_BUFFER_SIZE; i++) |
cmp ecx,SPECULAR_BUFFER_SIZE |
jg @f |
;Вычисляем x^y |
fld dword[shininess] |
fld dword[val] |
fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x): |
;Теперь считаем 2**z: |
fld st0 ;Создаем еще одну копию z |
frndint ;Округляем |
fsubr st0,st1 ;st1=z, st0=z-trunc(z) |
f2xm1 ;st1=z, st0=2**(z-trunc(z))-1 |
fld1 |
faddp ;st1=z, st0=2**(z-trunc(z)) |
fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t |
fxch st1 |
fstp st ;Результат остается на вершине стека st0 |
|
mov ebx,ecx |
shl ebx,2 |
add ebx,offs_spec_buf |
add ebx,[buf] |
fstp dword[ebx] ;buf.buf[i] = pow(val, shininess) |
|
fld dword[val] |
fadd dword[f_inc] |
fstp dword[val] ;val += f_inc |
inc ecx |
jmp .cycle_0 |
@@: |
ret |
endp |
|
align 4 |
proc specbuf_get_buffer uses ebx ecx edx, context:dword, shininess_i:dword, shininess:dword |
locals |
found dd ? ;GLSpecBuf * |
oldest dd ? ;GLSpecBuf * |
endl |
mov edx,[context] |
mov eax,[edx+offs_cont_specbuf_first] |
mov [found],eax |
mov [oldest],eax |
mov ebx,[shininess_i] |
.cycle_0: |
or eax,eax ;while (found) |
jz @f |
cmp [eax+offs_spec_shininess_i],ebx ;while (found.shininess_i != shininess_i) |
je @f |
mov ecx,[oldest] |
mov ecx,[ecx+offs_spec_last_used] |
cmp [eax+offs_spec_last_used],ecx ;if (found.last_used < oldest.last_used) |
jge .end_0 |
mov [oldest],eax ;oldest = found |
.end_0: |
mov eax,[eax+offs_spec_next] ;found = found.next |
jmp .cycle_0 |
@@: |
cmp dword[found],0 ;if (found) /* hey, found one! */ |
je @f |
mov eax,[found] |
mov ecx,[edx+offs_cont_specbuf_used_counter] |
mov [eax+offs_spec_last_used],ecx ;found.last_used = context.specbuf_used_counter |
inc dword[edx+offs_cont_specbuf_used_counter] |
jmp .end_f ;return found |
@@: |
cmp dword[oldest],0 ;if (oldest == NULL || context.specbuf_num_buffers < MAX_SPECULAR_BUFFERS) |
je @f |
cmp dword[edx+offs_cont_specbuf_num_buffers],MAX_SPECULAR_BUFFERS |
jl @f |
jmp .end_1 |
@@: |
; create new buffer |
stdcall gl_malloc, sizeof.GLSpecBuf |
;if (!eax) gl_fatal_error("could not allocate specular buffer") |
inc dword[edx+offs_cont_specbuf_num_buffers] |
mov ecx,[edx+offs_cont_specbuf_first] |
mov [eax+offs_spec_next],ecx |
mov [edx+offs_cont_specbuf_first],eax |
mov ecx,[edx+offs_cont_specbuf_used_counter] |
mov [eax+offs_spec_last_used],ecx |
inc dword[edx+offs_cont_specbuf_used_counter] |
mov [eax+offs_spec_shininess_i],ebx |
stdcall calc_buf, eax,dword[shininess] |
jmp .end_f |
.end_1: |
; overwrite the lru buffer |
;tgl_trace("overwriting spec buffer :(\n"); |
mov eax,[oldest] |
mov [eax+offs_spec_shininess_i],ebx |
mov ecx,[edx+offs_cont_specbuf_used_counter] |
mov [eax+offs_spec_last_used],ecx |
inc dword[edx+offs_cont_specbuf_used_counter] |
stdcall calc_buf, eax,dword[shininess] |
.end_f: |
ret |
endp |