4d5495cfb5
git-svn-id: svn://kolibrios.org@5486 a494cfbc-eb01-0410-851d-a64ba20cac60
815 lines
15 KiB
Plaintext
815 lines
15 KiB
Plaintext
; Files *.asc routines by Maciej Guba
|
|
; Thanks to Reverend for integer/float/ascii conversion examples
|
|
read_asc:
|
|
mov eax,[fptr]
|
|
.find_vert:
|
|
cmp dword[eax],'Vert'
|
|
je @f
|
|
inc eax
|
|
jmp .find_vert
|
|
@@:
|
|
add eax,4
|
|
cmp dword[eax],'ices'
|
|
jne .find_vert
|
|
add eax,3
|
|
@@:
|
|
inc eax
|
|
cmp byte[eax],'0' ; search end of ascii number of vertices string
|
|
jb @b
|
|
cmp byte[eax],'9'
|
|
ja @b
|
|
; eax - start ascii number
|
|
@@:
|
|
inc eax
|
|
cmp byte[eax],'0'
|
|
jb .convert1
|
|
cmp byte[eax],'9'
|
|
ja .convert1
|
|
jmp @b
|
|
.convert1:
|
|
dec eax
|
|
mov ebx,eax
|
|
push eax
|
|
call ascii_to_integer
|
|
mov [points_count_var],dx
|
|
pop eax
|
|
|
|
@@:
|
|
inc eax
|
|
cmp dword[eax],'Face'
|
|
jne @b
|
|
add eax,3
|
|
@@:
|
|
inc eax
|
|
cmp byte[eax],'0'
|
|
jb @b
|
|
cmp byte[eax],'9'
|
|
ja @b
|
|
; eax - start ascii number
|
|
@@:
|
|
inc eax
|
|
cmp byte[eax],'0'
|
|
jb .convert2
|
|
cmp byte[eax],'9'
|
|
ja .convert2
|
|
jmp @b
|
|
; eax - end ascii number
|
|
.convert2:
|
|
dec eax
|
|
mov ebx,eax
|
|
push eax
|
|
call ascii_to_integer
|
|
mov [triangles_count_var],dx
|
|
pop eax
|
|
|
|
@@:
|
|
inc eax
|
|
cmp dword[eax],'Vert'
|
|
jnz @b
|
|
inc eax
|
|
|
|
mov edi,[points_ptr]
|
|
xor ebx,ebx
|
|
.decode_vertices:
|
|
push ebx
|
|
@@:
|
|
inc eax
|
|
cmp dword[eax],'Vert'
|
|
jne @b
|
|
xor ecx,ecx
|
|
|
|
.decode_coord:
|
|
push ecx
|
|
@@:
|
|
inc eax
|
|
mov dl,byte[eax]
|
|
cmp dl,byte[XYZpartices+ecx]
|
|
jne @b
|
|
@@:
|
|
inc eax
|
|
cmp byte[eax],'.'
|
|
je .readF
|
|
cmp byte[eax],'-'
|
|
je .readF
|
|
cmp byte[eax],'0'
|
|
jb @b
|
|
cmp byte[eax],'9'
|
|
ja @b
|
|
.readF: ; read float
|
|
mov esi,eax
|
|
push eax
|
|
push ecx
|
|
|
|
call atof ; st0 - desired dword float
|
|
|
|
pop ecx
|
|
pop eax
|
|
|
|
fstp dword[edi]
|
|
add edi,4
|
|
|
|
pop ecx
|
|
inc ecx
|
|
cmp ecx,3
|
|
jne .decode_coord
|
|
pop ebx
|
|
inc ebx
|
|
cmp bx,[points_count_var]
|
|
jne .decode_vertices
|
|
mov dword[edi],-1
|
|
|
|
|
|
|
|
mov esi,eax
|
|
@@:
|
|
inc esi
|
|
cmp dword[esi],'Face'
|
|
jne @b
|
|
xor edx,edx
|
|
mov edi,[triangles_ptr]
|
|
cld
|
|
.decode_face:
|
|
|
|
push edx
|
|
@@:
|
|
inc esi
|
|
cmp dword[esi],'Face'
|
|
jne @b
|
|
@@:
|
|
inc esi
|
|
cmp byte[esi],'0' ; face number start
|
|
jb @b
|
|
cmp byte[esi],'9'
|
|
ja @b
|
|
@@:
|
|
inc esi
|
|
cmp byte[esi],'0'
|
|
jb @f
|
|
cmp byte[esi],'9' ; face number end
|
|
ja @f
|
|
jmp @b
|
|
@@:
|
|
xor ecx,ecx
|
|
.next_vertex_number:
|
|
|
|
push ecx
|
|
@@:
|
|
inc esi
|
|
cmp byte[esi],'0'
|
|
jb @b
|
|
cmp byte[esi],'9'
|
|
ja @b
|
|
; eax - start ascii number
|
|
@@:
|
|
inc esi
|
|
cmp byte[esi],'0'
|
|
jb @f
|
|
cmp byte[esi],'9'
|
|
ja @f
|
|
jmp @b
|
|
; eax - end ascii number
|
|
@@:
|
|
dec esi
|
|
mov ebx,esi
|
|
push esi
|
|
call ascii_to_integer
|
|
mov eax,edx
|
|
|
|
stosw
|
|
pop esi
|
|
add esi,2
|
|
|
|
pop ecx
|
|
inc ecx
|
|
cmp ecx,3
|
|
jne .next_vertex_number
|
|
pop edx
|
|
inc edx
|
|
cmp dx,[triangles_count_var]
|
|
jne .decode_face
|
|
mov dword[edi],-1 ;dword[triangles+ebx+2],-1 ; end mark
|
|
mov eax,1 ;-> mark if ok
|
|
ret
|
|
|
|
ascii_to_integer:
|
|
; in --- [ebx] -> end of ascii string
|
|
; out -- edx -> desired number
|
|
xor edx,edx
|
|
xor ecx,ecx
|
|
.again:
|
|
movzx eax,byte[ebx]
|
|
sub al,'0'
|
|
cwde
|
|
push edx
|
|
mul dword[convert_muler+ecx]
|
|
pop edx
|
|
add edx,eax
|
|
dec ebx
|
|
cmp byte[ebx],'0'
|
|
jb .end
|
|
cmp byte[ebx],'9'
|
|
ja .end
|
|
add ecx,4
|
|
jmp .again
|
|
@@:
|
|
|
|
.end:
|
|
ret
|
|
|
|
;===============================================================================
|
|
; ASCII to float conversion procedure
|
|
;
|
|
; input:
|
|
; esi - pointer to string
|
|
;
|
|
; output:
|
|
; st0 - number changed into float
|
|
;
|
|
;===============================================================================
|
|
|
|
atof:
|
|
.string equ ebp-4
|
|
|
|
push ebp
|
|
mov ebp,esp
|
|
sub esp,32
|
|
push eax ecx esi
|
|
mov [.string],esi
|
|
fninit
|
|
fldz
|
|
fldz
|
|
|
|
cld
|
|
cmp byte [esi], '-'
|
|
jnz @F
|
|
inc esi
|
|
@@:
|
|
xor eax, eax
|
|
align 4
|
|
.loop.integer_part:
|
|
lodsb
|
|
cmp al, '.'
|
|
jz .mantisa
|
|
cmp al,'0'
|
|
jb .exit
|
|
cmp al,'9'
|
|
ja .exit
|
|
fimul [i10]
|
|
sub al, '0'
|
|
push eax
|
|
fiadd dword [esp]
|
|
add esp, 4
|
|
jmp .loop.integer_part
|
|
|
|
.mantisa:
|
|
xor ecx, ecx
|
|
xor eax, eax
|
|
cld
|
|
fxch st1
|
|
@@:
|
|
|
|
lodsb
|
|
cmp al,'0'
|
|
jb .exit
|
|
cmp al,'9'
|
|
ja .exit
|
|
cmp ecx,7*4
|
|
je .exit ; max 7 digits in mantisa
|
|
sub al,'0'
|
|
push eax
|
|
fild dword[esp]
|
|
fidiv dword[convert_muler+4+ecx]
|
|
faddp
|
|
add esp,4
|
|
add ecx,4
|
|
jmp @b
|
|
.exit:
|
|
faddp
|
|
|
|
mov eax, [.string]
|
|
cmp byte [eax], '-'
|
|
jnz @F
|
|
fchs
|
|
@@:
|
|
cld
|
|
stc ; always returns no error
|
|
pop esi ecx eax
|
|
mov esp,ebp
|
|
pop ebp
|
|
ret
|
|
|
|
|
|
itoa: ; unsigned dword integer to ascii procedure
|
|
; in eax - variable
|
|
; esi - Pointer to ascii string
|
|
; out esi - desired ascii string
|
|
; edi - end of ascii string - ptr to memory
|
|
.temp_string equ dword[ebp-36]
|
|
.ptr equ dword[ebp-40]
|
|
.var equ dword[ebp-44]
|
|
push ecx
|
|
push ebp
|
|
mov ebp,esp
|
|
sub esp,64
|
|
mov .var,eax
|
|
mov eax,-1
|
|
lea edi,.temp_string
|
|
cld
|
|
mov ecx,9
|
|
rep stosd ; make floor
|
|
|
|
|
|
mov .ptr,esi
|
|
lea edi,.temp_string
|
|
add edi,34
|
|
std
|
|
xor eax,eax
|
|
stosb ; mark begin
|
|
mov eax,.var
|
|
mov esi,10
|
|
@@:
|
|
xor edx,edx
|
|
div esi
|
|
xchg eax,edx
|
|
add al,'0'
|
|
stosb
|
|
xchg eax,edx
|
|
or eax,eax
|
|
jnz @b
|
|
stosb ; mark end
|
|
|
|
lea esi,.temp_string
|
|
cld
|
|
@@:
|
|
lodsb
|
|
or al,al
|
|
jnz @b
|
|
|
|
mov edi,.ptr
|
|
@@:
|
|
lodsb
|
|
stosb
|
|
or al,al
|
|
jnz @b
|
|
|
|
mov esp,ebp
|
|
pop ebp
|
|
pop ecx
|
|
ret
|
|
if 1
|
|
ftoa_mac:
|
|
; in : esi - pointer to dword float
|
|
; edi - pointer to ascii string
|
|
.ptr_f equ dword[ebp-4]
|
|
.sign equ dword[ebp-8] ; 0 -> less than zero, 1 - otherwise
|
|
.ptr_ascii equ dword[ebp-12]
|
|
.integer equ dword[ebp-20]
|
|
.fraction equ dword[ebp-28]
|
|
.status_orginal equ word[ebp-32]
|
|
.status_changed equ word[ebp-34]
|
|
push ecx
|
|
push ebp
|
|
mov ebp,esp
|
|
sub esp,64
|
|
fninit
|
|
fnstcw .status_orginal
|
|
mov ax, .status_orginal
|
|
or ax, 0000110000000000b
|
|
mov .status_changed, ax
|
|
fldcw .status_changed
|
|
; --------------------------------
|
|
; check if signed
|
|
xor eax, eax
|
|
fld dword[esi]
|
|
fst .sign
|
|
test .sign, 80000000h
|
|
setz al
|
|
mov .sign, eax
|
|
|
|
mov .ptr_f,esi
|
|
mov .ptr_ascii,edi
|
|
fabs
|
|
fld st0
|
|
frndint
|
|
fist .integer
|
|
fsubp st1, st0
|
|
|
|
mov eax,.integer
|
|
mov esi,.ptr_ascii
|
|
call itoa
|
|
; edi -> ptr to end of ascii string
|
|
dec edi
|
|
mov al,'.'
|
|
stosb
|
|
|
|
mov ecx, 6 ; max 6 digits in fraction part
|
|
.loop:
|
|
fimul [i10]
|
|
fld st0
|
|
frndint
|
|
fist .fraction
|
|
fsubp st1, st0
|
|
mov esi,edi
|
|
mov eax,.fraction
|
|
add al,'0'
|
|
stosb
|
|
ftst
|
|
fnstsw ax
|
|
test ax, 0100000000000000b
|
|
jz @F
|
|
test ax, 0000010100000000b
|
|
jz .finish
|
|
@@:
|
|
loop .loop
|
|
if 0
|
|
fldcw .status_orginal
|
|
fimul [i10]
|
|
fist .fraction
|
|
; mov esi,edi
|
|
mov eax,.fraction
|
|
add al,'0'
|
|
stosb
|
|
; call itoa
|
|
; --------------------------------
|
|
; restore previous values
|
|
.finish:
|
|
; fstp st0
|
|
ffree st
|
|
mov eax,.fraction
|
|
mov esi,edi
|
|
; call itoa
|
|
|
|
add al,'0'
|
|
stosb
|
|
end if
|
|
.finish:
|
|
ffree st
|
|
cmp .sign,0
|
|
jnz @f
|
|
mov esi,.ptr_ascii
|
|
dec esi
|
|
mov byte[esi],'-'
|
|
@@:
|
|
mov esp,ebp
|
|
pop ebp
|
|
pop ecx
|
|
|
|
ret
|
|
end if
|
|
if 0
|
|
;===============================================================================
|
|
; float to ASCII conversion procedure
|
|
;
|
|
; input:
|
|
; buffer - pointer to memory where output will be saved
|
|
; precision - number of digits after dot
|
|
;
|
|
; output:
|
|
; no immediate output
|
|
;
|
|
; notes:
|
|
; separate integer and mantisa part with dot '.'
|
|
; so GOOD 123.456
|
|
; WRONG 123,456
|
|
;
|
|
; coded by Reverend // HTB + RAG
|
|
;===============================================================================
|
|
proc ftoa buffer, precision
|
|
locals
|
|
status_original dw ?
|
|
status_changed dw ?
|
|
integer dd ?
|
|
mantisa dd ?
|
|
signed dd ?
|
|
endl
|
|
push eax ecx;edi ecx
|
|
; --------------------------------
|
|
; set correct precision
|
|
mov eax, [precision]
|
|
cmp eax, 51
|
|
jb @F
|
|
mov eax, 51
|
|
@@:
|
|
mov [precision], eax
|
|
; --------------------------------
|
|
; change control wortd of fpu to prevent rounding
|
|
fnstcw [status_original]
|
|
mov ax, [status_original]
|
|
or ax, 0000110000000000b
|
|
mov [status_changed], ax
|
|
fldcw [status_changed]
|
|
; --------------------------------
|
|
; check if signed
|
|
xor eax, eax
|
|
fst [signed]
|
|
test [signed], 80000000h
|
|
setnz al
|
|
mov [signed], eax
|
|
; --------------------------------
|
|
; cut integer and mantisa separately
|
|
fld st0
|
|
fld st0 ; st0 = x, st1 = x
|
|
frndint
|
|
fist [integer] ; st0 = x, st1 = x
|
|
fabs
|
|
fsubp st1, st0 ; st0 = mantisa(x)
|
|
; --------------------------------
|
|
; save integer part in buffer
|
|
; mov edi, [buffer]
|
|
mov esi,[buffer]
|
|
; push [signed]
|
|
; push edi
|
|
; push 10
|
|
; push [integer]
|
|
mov eax,[integer]
|
|
call itoa
|
|
; add edi, eax
|
|
mov al, '.'
|
|
stosb
|
|
mov esi,edi
|
|
; --------------------------------
|
|
; save mantisa part in buffer
|
|
mov ecx, [precision]
|
|
dec ecx
|
|
.loop:
|
|
fimul [i10]
|
|
fld st0
|
|
frndint
|
|
fist [mantisa]
|
|
fsubp st1, st0
|
|
; push 0
|
|
; push edi
|
|
; push 10
|
|
; push [mantisa]
|
|
mov esi,edi
|
|
mov eax,[mantisa]
|
|
call itoa
|
|
; add edi, eax
|
|
ftst
|
|
fnstsw ax
|
|
test ax, 0100000000000000b
|
|
jz @F
|
|
test ax, 0000010100000000b
|
|
jz .finish
|
|
@@:
|
|
loop .loop
|
|
fldcw [status_original]
|
|
fimul [i10]
|
|
fist [mantisa]
|
|
; push 0
|
|
; push edi
|
|
; push 10
|
|
; push [mantisa]
|
|
mov esi,edi
|
|
mov eax,[mantisa]
|
|
call itoa
|
|
; --------------------------------
|
|
; restore previous values
|
|
.finish:
|
|
fstp st0
|
|
cmp [signed],1
|
|
jnz @f
|
|
mov byte[buffer],'-'
|
|
@@:
|
|
stc
|
|
pop ecx eax ;edi eax
|
|
ret
|
|
endp
|
|
end if
|
|
if 0
|
|
write_asc:
|
|
.counter equ dword[ebp-4]
|
|
push ebp
|
|
mov ebp,esp
|
|
sub esp,64
|
|
fninit
|
|
mov edi,asc_file_buffer
|
|
mov esi,asc_main_header
|
|
cld
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
|
|
mov esi,asc_info_header
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
push esi ; -> position in header info
|
|
movzx eax,[points_count_var]
|
|
mov esi,edi
|
|
call itoa ; unsigned dword integer to ascii procedure
|
|
pop esi
|
|
inc esi
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
push esi
|
|
movzx eax,[triangles_count_var]
|
|
mov esi,edi
|
|
call itoa
|
|
pop esi
|
|
inc esi
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
;=============================================================
|
|
;================vertex list parser===========================
|
|
;=============================================================
|
|
|
|
xor ecx,ecx
|
|
.again_vertex:
|
|
push ecx
|
|
mov esi,asc_one_vertex_formula
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
mov eax,ecx
|
|
; push ecx
|
|
push esi
|
|
mov esi,edi
|
|
call itoa
|
|
pop esi
|
|
; pop ecx
|
|
inc esi
|
|
xor ebx,ebx
|
|
.next_vertex_coef:
|
|
push ebx
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
; int3
|
|
push esi
|
|
lea esi,[ecx*3]
|
|
shl esi,2
|
|
add esi,points_r
|
|
add esi,ebx
|
|
; int3
|
|
call ftoa_mac
|
|
; std
|
|
; fld dword[esi]
|
|
|
|
|
|
; pushad
|
|
; stdcall ftoa, edi, 30
|
|
; popad
|
|
; add edi,20
|
|
|
|
|
|
pop esi
|
|
pop ebx
|
|
add ebx,4
|
|
cmp ebx,12
|
|
jnz .next_vertex_coef
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
pop ecx
|
|
inc ecx
|
|
cmp cx,[points_count_var]
|
|
jnz .again_vertex
|
|
|
|
|
|
; mov edi,[temp_edi]
|
|
|
|
|
|
mov esi,asc_face_list_header
|
|
@@:
|
|
lodsb
|
|
cmp al,1 ; all face header
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
;=====================================
|
|
; ==============face list parser======
|
|
;=====================================
|
|
xor ecx,ecx
|
|
.again_face:
|
|
push ecx
|
|
mov .counter,ecx
|
|
mov esi,asc_one_face_formula
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
mov eax,ecx
|
|
push esi
|
|
mov esi,edi
|
|
call itoa
|
|
pop esi
|
|
inc esi
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
|
|
xor ebx,ebx
|
|
.next_face_index:
|
|
push ebx
|
|
mov ecx,.counter
|
|
lea ecx,[ecx*3]
|
|
add ecx,ecx
|
|
movzx eax,word[triangles+ecx+ebx]
|
|
push esi
|
|
mov esi,edi
|
|
call itoa
|
|
pop esi
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
pop ebx
|
|
add ebx,2
|
|
cmp ebx,6
|
|
jnz .next_face_index
|
|
|
|
; push esi
|
|
mov esi,asc_material
|
|
@@:
|
|
lodsb
|
|
cmp al,1
|
|
jz @f
|
|
stosb
|
|
jmp @b
|
|
@@:
|
|
; pop esi
|
|
|
|
pop ecx
|
|
inc ecx
|
|
cmp cx,[triangles_count_var]
|
|
jnz .again_face
|
|
|
|
; write file
|
|
sub edi,asc_file_buffer
|
|
; mov [file_buffer+2],edi
|
|
mov [FileSize],edi
|
|
|
|
invoke CreateFile,asc_file_name, GENERIC_WRITE, 0, 0,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
|
|
mov [hfile],eax
|
|
invoke WriteFile,eax,asc_file_buffer,[FileSize], byteswritten, 0
|
|
invoke CloseHandle,[hfile]
|
|
|
|
mov esp,ebp
|
|
pop ebp
|
|
ret
|
|
end if
|
|
if 0
|
|
asc_file_buffer:
|
|
rd 65536
|
|
ascii_string rb 50
|
|
ftoa_muler dd 1000000000
|
|
file_size dd ?
|
|
file_handle dd ?
|
|
end if
|
|
|
|
if 0
|
|
convert_muler:
|
|
dd 1, 10, 100, 1000, 10000
|
|
XYZpartices:
|
|
db 'X','Y','Z'
|
|
i10 dw 10
|
|
points_count_var dd ?
|
|
triangles_count_var dd ?
|
|
points rb 100
|
|
triangles rb 100
|
|
asc_file:
|
|
|
|
file "2TORUS.ASC"
|
|
end if |