0,0 → 1,815 |
; 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 |