; anrieff's fractal ; init stuff IDEAL MODEL tiny P486N P487 NOSMART ; equates vseg equ 0a000h vbuf equ 09000h zbuf equ 08000h table_seg equ 0f000h table_offset equ 0fa6eh test_time equ 10 tire_en equ 04e2dh ; "-N" ; *** this is important: reclevel equ 4 ;--------------------------------------------------------------------------- ; reclevels controls the maximum depth of the recursion, that creates the ; balls. The actual number of balls is 6^(reclevel-1). Examples: ; ------------------------------------ ; | reclevel | Description | ; |----------|-----------------------| ; | 1 | Just one huge ball. | ; | | | ; | 2 | Six big balls, weird | ; | | ordered. | ; | 3 | Many small balls plus | ; | | 1 big one. | ; | 4 | So many balls, as to | ; | | slow down the engine. | ; |----------|-----------------------| ;------------------------------------------------------------------------------ DataSeg msg1 db "Wesko's Melodyes",0 msg2 db " presents ",0 msg3 db "anrieff's fractal",0 istring1 db " Frames for ",0 istring2 db " timer ticks.",13,10,0 rdtscm db "This program uses RDTSC for timing.",13,10,"If it crashes on your computer, invoke the program with the -n option...$" useTSC db 1 fadedly dw 15 ; 22 i256 dw 256 pcnt dw 0 hscale dw 160 rseed dw 6543h i6666 dw 6666 i10 dw 10 i100 dw 100 i2 dw 2 i5 dw 5 i127 dw 127 ballz dw 0 reclev dw 0 i320 dw 320 i200 dw 200 i160 dw 160 i63 DW 63 p90 dd 4F41Ch ; bench cycles on my p-90 MHz frames dd 0 lx dq 90.0 ly dq 35.0 lz dq -75.0 density dq 19.5 height dq 150.0 rq160 dq 160.0 rhgt dq 35.0 spf dq 0.25 ; seconds per frame on the p-90. r63_5 dq 63.5 r_0_3 dq 0.3 r_0_4 dq 0.4 r_0_5 dq 0.5 r_0_6 dq 0.6 r_0_7 dq 0.7 r1000 dq 1000.0 r_blahlimit dq 0.05 lightuptime dq 3.55 edgeconst dq 0.92 ambient dq 0.2 diffuse dq 0.6 specular dq 0.4 ;rfogness dq 23211.6; sqrt(3.95) time dq 0.0 tickss dq 18.2 rcol dq 0.666 gcol dq 0.768 bcol dq 1.0 ; SPHERE CONFIGURATION: BASE OF FRACTAL basex dq 0.0 basey dq -40.0 basez dq 12.0 baser dq 100.0 ; EXACT: M_PI_2 dq 1.570796326795 ; 'pi/2 M_2_PI dq 6.283185307181 ; '2*pi M1_5_PI dq 4.712388980385 ; '1.5*pi startx dq 0.707106781187 ; 'sqrt(2)/2 starty dq 0.441941738242 ; '{[sqrt(2)/2]/320} * 200 r_wCircConst dq 0.0000390625 ; 1/[Circle constant] (1/25600) eps dq 0.00001 ;------------------------------------------------------------------------- ; some explanation on the frame-dropping used here: ; ; as the standard 18.2 Hz clock isn't accurate enough (especially on fast ; PCs), I've precalculated how many bench (see the actual proc below...) ; cycles can my Pentium-90 do. Also I know the average time it does one ; frame (it is on the spf var). So if the intro is ran on a faster (or ; slower :) processor it will fix the "spf" accordingly. The formula ; itself is: ; ; SecondsPerFrame = SPF_on_p90 * Bench_cycles_on_p90 / Bench_cycles_on_current_cpu ; ; (the FPS rate on an arbitrary CPU can be calculated as 1 / spf, after the ; bench adjustment of course :-) ;------------------------------------------------------------------------- ; udataseg infi dw ? cbx dw ? i dw ? j dw ? ballz5 dw ? mscrx dw ? mscry dw ? wsteps dw ? mips dd ? timesave dd ? timeall dd ? itx dd ? ity dd ? ecbx dd ? rmul dq ? rstep dq ? xd dq ? yd dq ? alfa dq ? beta dq ? xtime dq ? ttysq dq ? pydsq dq ? jgmul dq ? camx dq ? camy dq ? camz dq ? ttx dq ? tty dq ? ttz dq ? X dq ? Y dq ? Z dq ? tx dq ? ty dq ? tz dq ? ttxi dq ? ttyi dq ? ttzi dq ? txi dq ? tyi dq ? tzi dq ? wx1 dq ? wy1 dq ? wz1 dq ? wx2 dq ? wy2 dq ? wz2 dq ? wx3 dq ? wy3 dq ? wz3 dq ? lpydsq dq ? hpydsq dq ? cy_h dq ? h_cy dq ? ma dq ? mb dq ? mc dq ? md dq ? me dq ? mf dq ? mg dq ? mh dq ? mr1 dq ? mr2 dq ? mr3 dq ? mx dq ? my dq ? mz dq ? mdisc dq ? critangle dq ? critstr dq ? mx1 dq ? my1 dq ? mz1 dq ? mx2 dq ? my2 dq ? mz2 dq ? mx3 dq ? my3 dq ? mz3 dq ? mrh dq ? mr dw ? wradmul dq ? wangle dq ? wai dq ? wxd dw ? wyd dw ? carh dq ? sarh dq ? bcs dq ? mult dq ? ix dq ? iy dq ? iz dq ? DIL dq ? DOI dq ? DLC dq ? DCI dq ? mm dq ? mk dq ? mn dq ? fx dq ? fy dq ? fz dq ? gx dq ? gy dq ? gz dq ? pvx dq ? pvy dq ? pvz dq ? opx dq ? opy dq ? opz dq ? dpi dq ? dpc dq ? dpx dq ? cosgamma dq ? sintheta dq ? costheta dq ? sindelta dq ? cosdelta dq ? l2x dq ? l2y dq ? x2 dq ? y2 dq ? cosOIL dq ? cosOIC dq ? OIL dq ? OIC dq ? la dq ? va dq ? lbeta dq ? betalim dq ? CPU_HZ dt ? CP_st dt ? nbuff db 12 dup (?) s db 100 dup (?) t1 db 768 dup (?) t2 db 768 dup (?) d db 5 dup (?) recs db 7*32 dup (?) asp db 256*32 dup (?) ; DON'T PUT ANYTHING BETWEEN THE FOLLOWING TWO!!!: predist db 256*8 dup (?) prersqr db 256*8 dup (?) ;------------------------------------------------- (see initframe, ;44blah-1) pregii db 256*8 dup (?) preDLO db 256*8 dup (?) sorta db 256*5 dup (?) sortb db 256*5 dup (?) ord db 256 dup (?) tex db 16384 dup (?) CodeSeg org 100h Start: finit cmp [word ds:5dh], tire_en je short @nonrdtsc mov dx, offset rdtscm mov ax, 0900h int 21h mov ax, 2000 call delay jmp short @goIntro @nonrdtsc: mov [useTSC],0 @goIntro: mov ax, 13h int 10h call intro call FullBench call maineffect mov ax, 3 int 10h call showfps mov ax, 4c00h int 21h ; --- structural ende ------ Proc bench ;----------------------------------------------------------------------- ; ; Proc Bench - equalize the running time of the intro on all machines. ; ;----------------------------------------------------------------------- push es xor eax, eax push 0 pop es mov si, 046Ch mov dx, [es:si] @w8_1: cmp dx, [es:si] je @w8_1 mov dx, [es:si] @bench_cycle: fldpi fld1 fadd fld st fmul fldz fld st fmul fld1 fldpi fdiv fld st fmul fadd fadd fsqrt fistp [cbx] inc eax mov bx, [es:si] sub bx, dx cmp bx, test_time jb @bench_cycle mov [mips], eax fild [p90] fild [mips] fdiv fmul [spf] fstp [spf] pop es ret ENDP bench ;------------------------------------------ ; Proc RDTSC - issues the RDTSC instrucion ; and converts the EDX:EAX ; to ST(0) ;------------------------------------------ PROC RDTSC db 0fh db 31h mov [cbx], 32 fild [cbx] mov [ecbx], edx fild [ecbx] fscale fadd mov [ecbx], eax fild [ecbx] test eax, 80000000h jz short @reaxpos fild [cbx] fld1 fscale fadd fadd @reaxpos: fadd ret ENDP RDTSC PROC RDBench mov di, 46ch push es xor ax, ax mov es, ax mov bx, [es:di] @t1ckwait: cmp [es:di],bx je @t1ckwait mov bx, [es:di] call rdtsc @t1ckcyc: mov cx, [es:di] sub cx, bx cmp cx, test_time jb @t1ckcyc call rdtsc fsub fabs mov [word cbx], test_time fild [cbx] fdiv [tickss] fdiv fstp [CPU_HZ] pop es ret ENDP RDBench PROC FullBench cmp [useTSC],1 je short @fb01 call Bench ret @fb01: call RDBench ret ENDP FullBench ;----------------------------------------- ; ; PROC INiTTexTURe - creates the texture ; ;----------------------------------------- ProC InitTexture mov si, offset tex xor bx, bx @itLineLoop: xor ax, ax mov [cbx], bx fild [cbx] fdiv [r63_5] fld1 fsub fabs fstp [yd] @itPLoop: push ax mov [cbx], ax fild [cbx] fdiv [r63_5] fld1 fsub fabs fstp [xd] mov ax, 666 call random mov [cbx], ax fild [cbx] fidiv [i6666] fld1 fld1 fadd fld [xd] fld st fmul fsub fld [yd] fld st fmul fsub fld [xd] fsqrt fld [yd] fsqrt fadd fld1 fsub fabs fld [r_blahlimit] fsub ftst fstsw ax sahf ja short @nolim fimul [i10] fsub fdecstp @nolim: ffree st fincstp fadd fidiv [i2] fld st fld1 fsub ftst ffree st fincstp fstsw ax sahf jbe short @nolim1 ffree st fld1 @nolim1: fimul [i127] fistp [cbx] mov ax, 128 add ax, [cbx] mov [ds:si],al inc si pop ax inc ax cmp al, 128 jb @itPloop inc bx cmp bl, 128 jb @itLineLoop ret EndP InitTexture Proc Recu add si, 32 inc [reclev] cmp [reclev], reclevel jb short @r_normal mov cx, 8 mov di, [ballz] shl di, 5 add di, offset asp rep movsd sub si, 32 inc [ballz] jmp @r_exit @r_normal: fld [qword si ] fstp [qword si+32] fld [qword si+ 8] fstp [qword si+40] fld [qword si+16] fld [qword si+24] fmul [r_0_4] fsub fstp [qword si+48] fld [qword si+24] fmul [r_0_6] fstp [qword si+56] call recu fld [qword si ] fstp [qword si+32] fld [qword si+ 8] fstp [qword si+40] fld [qword si+16] fstp [qword si+48] fld [qword si+24] fmul [r_0_3] fstp [qword si+56] fld [qword si+24] fmul [r_0_7] fadd [qword si+48] fstp [qword si+48] call recu fld [qword si+24] fmul [r_0_7] fchs fadd [qword si+48] fstp [qword si+48] fld [qword si+24] fmul [r_0_7] fadd [qword si+40] fstp [qword si+40] call recu fld [qword si+24] fmul [r_0_7] fchs fimul [i2] fadd [qword si+40] fstp [qword si+40] call recu fld [qword si+24] fmul [r_0_7] fadd [qword si+40] fstp [qword si+40] fld [qword si+24] fmul [r_0_7] fadd [qword si+32] fstp [qword si+32] call recu fld [qword si+24] fmul [r_0_7] fchs fimul [i2] fadd [qword si+32] fstp [qword si+32] call recu @r_exit: sub si, 32 dec [reclev] ret EndP recu ;------------------------------------------------------ ; ; Proc InitSpheres - uses recursive fractal formula to ; create the spheres. ; ;------------------------------------------------------ ProC InitSpheres fld [basex] fstp [qword recs] fld [basey] fstp [qword recs+8] fld [basez] fstp [qword recs+16] fld [baser] fstp [qword recs+24] mov si, offset recs - 32 call Recu mov ax, [ballz] mov bx, ax shl ax, 2 add ax, bx mov [ballz5], ax ret EnDp InitSpheres proc blah_it lodsb mov [cbx], ax fild [cbx] fmul fistp [cbx] mov ax, [cbx] stosb ret endp blah_it Proc InitPalette ;---------------------------------------- ; the palette is: ; ; 0 -> 63 black -> white ; 64 -> 127 black -> dark blue ; 128 -> 255 dark blue -> light blue + green -> bright blue, almost white ; ;---------------------------------------- mov di, offset t1 xor ax, ax mov cx, 64 push ds pop es @cl64: stosb stosb stosb inc ax loop @cl64 xor cx, cx @cl128: mov ax, cx shl ax, 1 mov bx, 5 xor dx, dx div bx stosb mov ax, cx shr ax, 1 stosb mov ax, cx shl ax, 1 mov bx, 3 xor dx, dx div bx stosb inc cx cmp cx, 64 jb @cl128 xor cx, cx @cl192: mov ax, cx shr ax, 2 add ax, 24 stosb mov ax, cx mov bx, 5 xor dx, dx div bx add ax, 32 stosb mov ax, cx mov bx, 3 xor dx, dx div bx add ax, 42 stosb inc cx cmp cx, 64 jb @cl192 xor cx, cx @cl256: mov ax, cx mov bx, 3 xor dx, dx div bx add ax, 40 stosb mov ax, cx shr ax, 2 add ax, 45 stosb mov ax, 63 stosb inc cx cmp cx, 64 jb @cl256 mov si, offset t1 + 192 mov di, si mov cx, 192 xor ax, ax @ffmull: fld [rcol] call blah_it fld [gcol] call blah_it fld [bcol] call blah_it loop @ffmull ret ENDP InitPalette Proc SAddString ; adds string at [ds:si] to end of string at [ds:di] @addloop: mov al, [ds:si] mov [ds:di],al inc si inc di or al, al jnz @addloop dec di ret Endp SAddString Proc SAddInteger ; converts ax to string and adds it to the end of [ds:di] mov si, offset nbuff + 10 mov [byte ds:si], 0 mov bx, 10 @saloop: xor dx, dx div bx add dl, 48 dec si mov [ds:si],dl or ax, ax jnz @Saloop call SAddString ret Endp SAddInteger Proc showfps mov di, offset s mov [byte ds:di], 0 mov eax, [frames] call SaddInteger mov si, offset istring1 call SAddString mov eax, [timeall] call SaddInteger mov si, offset istring2 call SAddString mov [byte ds:di], '$' mov dx, offset s mov ax, 0900h int 21h ret EndP showfps ProC DoPalette ;---------------------------------------- ; Proc DOPalette - ; input: real value in st(0) [0..1] ; output: multiplies all t1 colors and ; stores the results at t2; ; then initialises the palette ; with the t2 table ;----------------------------------------- mov si, offset t1 mov cx, 768 xor ax, ax @mmxLoop: fld st mov al, [ds:si] mov [cbx], ax fimul [cbx] fistp [cbx] mov ax, [cbx] mov [ds:si+768], al inc si loop @mmxLoop mov cx, 768 mov dx, 3c8h xor ax, ax out dx, al inc dx rep outsb ret ENDP DoPalette Proc fillscr0 ;------------------------------------- ; fills the back-buffer with zeros. ;------------------------------------- push es mov ax, vbuf mov es, ax xor di, di xor eax, eax mov cx, 16000 cld rep stosd pop es ret ENDP fillscr0 Proc blurscr0 ;-------------------------------------- ; blurs the back-buffer ;-------------------------------------- push es mov ax, vbuf mov es, ax xor ax, ax xor di, di mov cx, 321 rep stosb mov cx, 198 @bLineLoop: mov dx, 1 @bPixelLoop: xor ax, ax mov al, [es:di] shl ax, 2 xor bx, bx mov bl, [es:di-321] add ax, bx mov bl, [es:di-319] add ax, bx mov bl, [es:di+321] add ax, bx mov bl, [es:di+319] add ax, bx mov bl, [es:di-320] shl bl, 1 add ax, bx shr bl, 1 mov bl, [es:di-1] shl bl, 1 add ax, bx shr bl, 1 mov bl, [es:di+1] shl bl, 1 add ax, bx shr bl, 1 mov bl, [es:di+320] shl bl, 1 add ax, bx shr ax, 4 stosb inc dx cmp dx, 319 jb @bPixelLoop xor ax, ax stosw loop @bLineLoop mov cx, 319 rep stosb pop es ret EndP blurscr0 PROC flip ;--------------------------------------------- ; copies 64000 bytes from es:0 to 0a000h:0 ;--------------------------------------------- push ds push es push es pop ds push vseg pop es xor di, di xor si, si mov cx, 16000 cld rep movsd pop es pop ds ret ENDP flip Proc WriteString ;------------------------------------------------------------------------ ; (routine for 13h videomode): ; renders a string (ASCIIZ-type) from [ds:si] to videoseg at [es:], ; at column dl, row dh, with a color of 1. Char spacing is 1 pixel. ;------------------------------------------------------------------------ xor ax, ax xchg al, dh mov bx, 320 mov di, dx xor dx, dx mul bx add di, ax mov ax, table_seg mov fs, ax @w_charloop: xor bx, bx mov bl, [ds:si] shl bx, 3 mov cx, 8 @w_lineloop: mov al, [fs:bx+table_offset] push cx mov cx, 8 @w_pixelloop: test ax, 128 jz short @w_blh mov [byte es:di], 1 @w_blh: inc di shl ax, 1 loop @w_pixelloop pop cx inc bx add di, 312 loop @w_lineloop sub di, 8*320-9 inc si cmp [byte ds:si], 0 jnz @w_charloop ret Endp WriteString Proc delay ;----------------------------------------------- ; expects: milliseconds in ax to delay. ; NOTE: uses int15h ;----------------------------------------------- push dx push cx push bx xor dx, dx mov bx, 1000 mul bx mov cx, dx mov dx, ax mov ax, 8600h int 15h pop bx pop cx pop dx ret Endp delay ;--------------------------------- ;PROC Random ;-gets the value in ax and returns ;-(in ax) number between 1 and ax ;-example: ;-mov ax,200 ;-call random ;-...ax will contain a number 1ö200 ; ;INPUT: ;AX=max output ; ;OUTPUT: ;AX=random number ; ;NOTE: rseed (word) should be in ;the dataseg. ;---------------------------------- PROC RANDOM push dx push bx ;save some registers push ax in al, 40h ;get the timer in ax mov ah, al mov bx, ax ;and in bx also mov ax, [rseed] ;rseed contains the previous random number add ax, 5543 ;this is not kind a special number-i just put it for accurancy and true randomisation imul bx ;for example ax=A63C,bx=1C1C. Ax will become BE90h rcl ax, 3 ;now ax is F485h mov [rseed],ax ;this random number is stored in rseed for next random pop bx ;bx=max output (see above) xor dx, dx div bx mov ax, dx inc ax pop bx ;random number 1ömaxoutput stored in ax pop dx ret ;work done ENDP Random Proc GetPalette push es push ds pop es mov di, offset t1 mov cx, 768 mov dx, 3c7h xor ax, ax out dx, al inc dx inc dx rep insb pop es ret Endp GetPalette Proc GenFade call GetPalette mov cx, 64 mov [cbx], 0 @fadeloop: mov si, offset t1 push cx mov cx, 768 @fcolorloop: mov al, [ds:si] mov [byte cbx], al fild [cbx] fmul [rmul] fistp [cbx] mov al, [byte cbx] mov [ds:si+768], al inc si loop @fcolorloop xor ax, ax mov dx, 3c8h out dx, al inc dx mov cx, 768 rep outsb fld [rmul] fadd [rstep] fstp [rmul] mov ax, [fadedly] call delay pop cx loop @fadeloop ret Endp GenFade Proc FadeIN fldz fstp [rmul] fld1 mov [cbx], 64 fidiv [cbx] fstp [rstep] call GenFade ret ENDP FadeIN Proc FadeOUT fld1 fstp [rmul] fld1 mov [cbx], 64 fidiv [cbx] fchs fstp [rstep] ret ENDP FadeOUT proc fadeoutc call fadeout push es push di push cx push eax push 0a000h pop es xor di, di mov cx, 16000 xor eax, eax cld rep stosd pop eax pop cx pop di pop es ret endp fadeoutc PROC outcol ;------------------------------------------------------ ; what this does: ; splits eax to its four bytes, like this: a.b.c.d ; color d becomes (r,g,b) = (c,b,a) ; :-)) ;------------------------------------------------------ mov dx, 3c8h out dx, al shr eax, 8 inc dx out dx, al shr eax, 8 out dx, al shr eax, 8 out dx, al ret ENDP outcol Proc Effect mov dx, 3c8h xor ax, ax out dx, al inc dx mov cx, 768 @blackloop: out dx, al loop @blackloop mov ax, vbuf mov fs, ax mov ax, vseg mov es, ax xor di, di xor si, si xor bh, bh @eLineLoop: xor bl, bl @ePixLoop: cmp [byte fs:si],0 je short @noneed mov al, 127 cmp [byte fs:si-1],0 jne short @nz1 mov al, 63 @nz1: mov [es:di], al mov [es:di+320], al mov al, 127 cmp [byte fs:si+1],0 jne short @nz2 mov al, 191 @nz2: mov [es:di+1], al mov [es:di+321], al @noneed: inc si inc di inc di inc bl cmp bl, 160 jb @ePixLoop add di, 320 add si, 160 inc bh cmp bh, 100 jb @eLineLoop mov eax, 03f3f3f3fh call outcol mov eax, 0143f147fh call outcol mov eax, 000003fbfh call outcol call fadein ret EndP Effect Proc Init_BGR ; ; initialises the following palette: ; 0- 63 black-white ; 64-127 black-green ;128-191 black-red ; mov cx, 64 xor eax, eax @bgr_loop: mov ax, cx dec ax mov ah, al push eax add al, 128 call outcol pop eax push eax shl eax, 8 xchg ah, al add al, 64 call outcol pop eax push ax shl eax, 16 pop ax call outcol loop @bgr_loop ret ENDP Init_BGR ProC Intro call fillscr0 mov ax, vbuf mov es, ax mov si, offset msg1 mov dx, 2a04h call WriteString mov si, offset msg2 mov dx, 3304h call writestring call Effect mov ax, 2000 call delay call FadeOutC call fillscr0 mov si, offset msg3 mov dx, 2e04h mov ax, vbuf mov es, ax call Writestring call Effect mov ax, 2000 call delay ; ---- post effect push vseg pop es xor bx, bx xor ax, ax xor si, si mov di, offset d @lloop00: mov dl, [byte es:si] or dl, dl jz short @nblh ; type TPoint = record ; x, y : Integer; ; z, zi: double; ; color: byte; ; end; ; {sizeof(TPoint)=21} mov [di], ax sub [word di], 160 mov [di+2], bx sub [word di+2], 100 add di, 4 fld [rq160] fstp [qword di] push ax mov ax, 1000 call random add ax, 800 mov [cbx], ax fild [cbx] mov [cbx], 500 fidiv [cbx] fstp [qword di+8] pop ax mov [di+16], dl add di, 17 inc [pcnt] @nblh: inc ax cmp ax, 320 jb short @xbxib xor ax, ax inc bx @xbxib: inc si cmp si, 64000 jb @lloop00 push vbuf pop es call init_BGR mov cx, 200 @fr_loop: push cx call blurscr0 mov si, offset d mov cx, [pcnt] @point_loop: ; vis_point fld [qword si+4] ftst fstsw ax ffree st(0) sahf jbe short @ndispl fild [word si] fdiv [qword si+4] fimul [hscale] fistp [cbx] mov di, 160 add di, [cbx] cmp di, 319 ja short @ndispl fild [word si+2] fdiv [qword si+4] fimul [hscale] fistp [cbx] mov ax, 100 add ax, [cbx] cmp ax, 199 ja short @ndispl mov bx, 320 mul bx add di, ax mov al, [si+20] stosb @ndispl: fld [qword si+4] fsub [qword si+12] fstp [qword si+4] ;//vis_point add si, 21 loop @point_loop call flip pop cx loop @fr_loop ret EndP Intro ProC Gettime ;-------------------------------------- ; mov eax, [0:046CH] ;-------------------------------------- push ds push 0 pop ds mov eax, [ds:046Ch] pop ds ret ENDP GetTime Proc r0tate2d ;-------------------------------------------------------- ; proc r0tate2d: ; ; INPUT: . real value in st(0) - angle to rotate to ; . x coord in ds:si ; . y coord in ds:di ; OUTPUT: rotates point (x,y) to angle st(0), pops ; the fpu stack, and writes new (x,y) to ; ds:si and ds:di ;-------------------------------------------------------- fld [qword ds:si] fld [qword ds:di] fpatan fadd fsincos fld [qword ds:si] fmul [qword ds:si] fld [qword ds:di] fmul [qword ds:di] fadd fsqrt fst st(3) fmul fstp [qword ds:di] fmul fstp [qword ds:si] ret Endp r0tate2d Proc r0tate ;-------------------------------------------- ; rotates a 3dpoint at ds:dx to alfa & beta. ;-------------------------------------------- fld [alfa] mov si, dx mov di, dx add di, 16 call r0tate2d add si, 8 fld [alfa] fcos fmul [beta] call r0tate2d sub si, 8 sub di, 8 fld [alfa] fsin fchs fmul [beta] call r0tate2d ret Endp r0tate Proc CalcGrid ;------------------------------------------------------- ; calcgrid: ; -input: correct alfa & beta. (beta e [-pi/2..pi..2]) ; -output: calculates w?? arrays and prepares ; tx, ty, tz (= wx1, wy1, wz1) and calculates ; txi,tyi,tzi,ttxi,ttyi,ttzi ;------------------------------------------------------- fld [startx] fst [wx2] fst [wz1] fst [wz2] fst [wz3] fchs fst [wx1] fstp [wx3] fld [starty] fst [wy3] fchs fst [wy1] fstp [wy2] ;perform the rotations... mov dx, offset wx1 mov cx, 3 @r0tloop: call r0tate add dx, 24 loop @r0tloop mov [cbx], 320 fld [wx2] fsub [wx1] fidiv [cbx] fstp [ttxi] fld [wy2] fsub [wy1] fidiv [cbx] fstp [ttyi] fld [wz2] fsub [wz1] fidiv [cbx] fstp [ttzi] mov [cbx], 200 fld [wx3] fsub [wx1] fidiv [cbx] fstp [txi] fld [wy3] fsub [wy1] fidiv [cbx] fstp [tyi] fld [wz3] fsub [wz1] fidiv [cbx] fstp [tzi] fld [wx1] fstp [tx] fld [wy1] fstp [ty] fld [wz1] fstp [tz] ret EndP CalcGrid ProC wCircle ;---------------------------------------------------------- ; - draws "false" circle, mapping the about right region ; a ball is expected to render in. ; ; Input: ; mscrx, mscry - centre of the "circle" ; mrh - minimal radius (achieved on screen center) ; dl - color to fill with ; critangle - angle of distortion ; critstr - distortion strength ; ; Note: the formula is unaccurate, but works fine. :-)) ;---------------------------------------------------------- fld [density] fmul [mrh] fld1 fadd [critstr] fmul fistp [wsteps] add [wsteps], 2 fldz fstp [wangle] fld [M_2_PI] fidiv [wsteps] fstp [wai] mov cx, [wsteps] @wOutLoop: fld [wangle] fsub [critangle] fcos fabs fst [wradmul] fsub [R_0_5] ftst fstsw ax ffree st sahf ja short @rmabhalf fld [r_0_5] fstp [wradmul] @rmabhalf: fld [wangle] fsincos fst [carh] fincstp fst [sarh] fdecstp fmul [mrh] fistp [wyd] fmul [mrh] fist [wxd] fild [mscrx] fadd fild [i160] fsub fld st fmul fmul [r_wCircConst] fstp [critstr] fild [wyd] fild [mscry] fadd fild [i100] fsub fld st fmul fmul [r_wCircConst] fadd [critstr] fmul [wradmul] fld1 fadd fmul [mrh] fistp [mr] inc [mr] @cwhile: dec [mr] fld [sarh] fimul [mr] fistp [cbx] mov ax, [cbx] add ax, [mscrx] cmp ax, 320 jnb short @skippixel fld [carh] fimul [mr] fistp [cbx] mov bx, [cbx] add bx, [mscry] cmp bx, 200 jnb short @skippixel mov di, bx shl bx, 2 add di, bx shl di, 6 add di, ax mov [es:di],dl @skippixel: cmp [mr], 0 jne @cwhile fld [wangle] fadd [wai] fstp [wangle] dec cx jnz @wOutLoop ret EndP wCircle Proc ldNormMatrix ;------------------------------------------ ; initialises the following matrix: ; ; | a b -c | ; | 0 d -e | ; | f g -h | ; ;------------------------------------------ fld [ma] fstp [mx1] fld [mb] fstp [my1] fld [mc] fchs fstp [mz1] fldz fstp [mx2] fld [md] fstp [my2] fld [me] fchs fstp [mz2] fld [mf] fstp [mx3] fld [mg] fstp [my3] fld [mh] fchs fstp [mz3] ret EndP ldNormMatrix Proc MatriXRoot ;---------------------------------------- ; takes the following matrix: ; ; | mx1 my1 mz1 | ; | mx2 my2 mz2 | ; | mx3 my3 mz3 | ; ; and calculates its determinant in st(0) ;----------------------------------------- fld [mx1] fmul [my2] fmul [mz3] fld [mx2] fmul [my3] fmul [mz1] fadd fld [mx3] fmul [my1] fmul [mz2] fadd fld [mx3] fmul [my2] fmul [mz1] fsub fld [mx2] fmul [my1] fmul [mz3] fsub fld [mx1] fmul [my3] fmul [mz2] fsub ret EndP MatriXRoot ;============================================================ ; ; Function Dist: ; ; calculates the pithagorean distance: ; dist = sqrt [ (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2 ] ; ; INPUT: ; st(0) : z2 ; st(1) : z1 ; st(2) : y2 ; st(3) : y1 ; st(4) : x2 ; st(5) : x1 ; OUTPUT: result in st(0) ; ; NOTE: 1. not useful for speed-critical calculations... ; 2. the contents of st(6) and st(7) are overwritten ;========================================================== ProC Dist fsub fld st fmul fst st(5) ffree st fincstp fsub fld st fmul fst st(4) ffree st fincstp fsub fld st fmul fadd fadd fsqrt ret EndP Dist ;-------------------------------- ; *** Procedure InitFrame *** : ; what it does: : ; : ; 1. calculates the distancies : ; between camera and balls. : ; 2. sorts them in descending : ; order in the "ord" array. : ; (uses bit-sorting method) : ; 3. Fills the back-buffer with : ; "colors", describing : ; projected ball locations. : ; If a pixel is coloured 5, : ; it is expected that pixel : ; belongs to ball Nr. 5. : ; pixels being left 0s do not: ; belong to any ball and can : ; be filled by the floor : ; engine : ;-------------------------------: Proc InitFrame ;new stuff: fld [camx] fld [lx] fld [camy] fld [ly] fld [camz] fld [lz] call Dist fstp [DLC] mov cx, [ballz] mov si, offset asp mov di, offset predlo mov bx, offset pregii @init1loop: fld [qword ds:si ] fld [lx] fld [qword ds:si+8 ] fld [ly] fld [qword ds:si+16] fld [lz] call dist fstp [qword ds:di] fld [qword ds:si ] fsub [camx] fld st fmul fld [qword ds:si+8 ] fsub [camy] fld st fmul fld [qword ds:si+16] fsub [camz] fld st fmul fadd fadd fld [qword ds:si+24] fld st fmul fsub fstp [qword ds:bx] add si, 32 add di, 8 add bx, 8 loop @init1loop ; mov cx, [ballz] mov si, offset asp mov di, offset predist mov bx, offset sorta xor ax, ax @cdistloop: inc ax fld [qword si ] fsub [camx] fld st fmul fld [qword si+8 ] fsub [camy] fld st fmul fld [qword si+16] fsub [camz] fld st fmul fadd fadd fsqrt fst [qword ds:di] fimul [i256] fistp [dword ds:bx] fld [qword si+24] fld st fmul ;44blah-1 fstp [qword ds:di+2048] mov [bx+4], al add bx, 5 add si, 32 add di, 8 loop @cdistloop ;distances are precalculated :)) ;let's sort ! :> xor edx, edx mov dl, 1 mov si, offset sorta mov di, offset sortb @sorrrt: push si push di mov bp, [ballz5] sub bp, 5 add bp, di mov cx, [ballz] @makeithappen: mov eax, [si] mov bl, [si+4] add si, 5 test eax, edx jz short @xzero mov [ds:di],eax mov [ds:di+4],bl add di, 5 jmp short @rloop12 @xzero: mov [ds:bp],eax mov [ds:bp+4],bl sub bp, 5 @rloop12: loop @makeithappen add bp, 5 ;; NEW CODE pusha popa pop di push di add di, [ballz5] sub di, 5 @while1: cmp bp, di jg short @whileexit mov eax, [ds:bp] mov bl, [ds:bp+4] xchg eax, [ds:di] xchg bl, [ds:di+4] mov [ds:bp],eax mov [ds:bp+4], bl add bp, 5 sub di, 5 jmp @while1 @whileexit: ; NEW CODE endz. pop si pop di shl edx, 1 cmp edx, 80000000h jne @sorrrt mov cx, [ballz] mov di, offset ord @ordloop: mov al, [si+4] mov [ds:di],al add si, 5 inc di loop @ordLoop fld [ttxi] fimul [i320] fstp [ma] fld [txi] fimul [i200] fstp [mb] fld [wx1] fchs fstp [mr1] fld [tyi] fimul [i200] fstp [md] fld [wy1] fchs fstp [mr2] fld [ttzi] fimul [i320] fstp [mf] fld [tzi] fimul [i200] fstp [mg] fld [wz1] fchs fstp [mr3] mov cx, [ballz] mov si, offset ord @project_ball: push si xor ax, ax mov al, [si] dec ax mov si, offset asp shl ax, 5 add si, ax fld [qword si ] fsub [camx] fstp [mc] fld [qword si+8 ] fsub [camy] fstp [me] fld [qword si+16] fsub [camz] fstp [mh] call ldNormMatrix call MatrixRoot fst [mdisc] fabs fsub [eps] ftst fstsw ax ffree st sahf jbe @skipsphere call ldNormMatrix fld [mr1] fstp [mx1] fld [mr2] fstp [mx2] fld [mr3] fstp [mx3] call MatrixRoot fdiv [mdisc] fstp [mx] call ldNormMatrix fld [mr1] fstp [my1] fld [mr2] fstp [my2] fld [mr3] fstp [my3] call MatrixRoot fdiv [mdisc] fstp [my] call ldNormMatrix fld [mr1] fstp [mz1] fld [mr2] fstp [mz2] fld [mr3] fstp [mz3] call MatrixRoot fdiv [mdisc] ftst fstsw ax fstp [mz] sahf jb @skipsphere fld [mx] fld1 fadd ftst fstsw ax ffree st sahf jb @skipsphere fld [my] fld1 fadd ftst fstsw ax ffree st sahf jb @skipsphere fld [mx] fild [i2] fsub ftst fstsw ax ffree st sahf ja @skipsphere fld [my] fild [i2] fsub ftst fstsw ax ffree st sahf ja @skipsphere fld [mx] fimul [i320] fist [mscrx] fild [i160] fsub fld [my] fimul [i200] fist [mscry] fild [i100] fsub fpatan fstp [critangle] fld [mx] fsub [r_0_5] fld st fmul fld [my] fsub [r_0_5] fld st fmul fadd fsqrt fstp [critstr] fld [qword si+24] fimul [hscale] pop si push si mov dl, [si] xor dh, dh mov si, dx dec si shl si, 3 add si, offset predist fdiv [qword si] fstp [mrh] push cx call wcircle pop cx @skipsphere: pop si inc si dec cx jnz @project_ball ret EndP InitFrame ;====================================================================== ;\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ ; Procedure Solve3d. -- calculates the phong illumination and stores ; a color [0..63] in al. ; INPUT: ; es:di -- pixel to render. ; ds:si -- pointer to the sphere ; ds:bp -- pointer to the predist value for the same sphere ; dl -- sphere no. [0..ballz-1] ; x,y,z -- visual vector ; camx,camy,camz -- camera coordinates ; lx,ly,lz -- light source coordinates ; ! st -- is the same as bcs, just not removed from the fpu stack ; ;/____________________________________________________________________\ ;====================================================================== ProC Solve3d fsqrt fdiv [qword si+24] fld st fsub [edgeconst] ftst fstsw ax ffree st fincstp sahf jb short @multeq1 fchs fld1 fadd fld1 fsub [edgeconst] fdiv fstp [mult] jmp short @multrdy @multeq1: ffree st fld1 fstp [mult] @multrdy: ; PAS [srchexactdist] fld [camx] fsub [qword ds:si ] fmul [x] fld [camy] fsub [qword ds:si+8 ] fmul [y] fld [camz] fsub [qword ds:si+16] fmul [z] fadd fadd fst [mk] mov bx, dx shl bx, 3 add bx, offset pregii fmul [mk] fsub [qword ds:bx] fsqrt fadd [mk] fabs ; should be fchs, but as the result must (should?) never be negative, ; I use fabs :)) ; PAS { ; ix := CX + X * Dsurface; ; iy := CY + Y * Dsurface; ; iz := CZ + Z * Dsurface; ; } fst [mm] fst [DCI] fld st fmul [x] fadd [camx] fstp [ix] fld st fmul [y] fadd [camy] fstp [iy] fmul [z] fadd [camz] fstp [iz] ; PAS [function solve3d(cx3,cy3,cz3,ox3,oy3,oz3,ix3,iy3,iz3,lx3,ly3,lz3 : real): real;] ; PAS dOI := dist(ox3,oy3,oz3,ix3,iy3,iz3); fld [qword ds:si ] fsub [ix] fld st fmul fld [qword ds:si+8 ] fsub [iy] fld st fmul fld [qword ds:si+16] fsub [iz] fld st fmul fadd fadd fsqrt fstp [DOI] ; PAS dIL := dist(ix3,iy3,iz3,lx3,ly3,lz3); fld [ix] fsub [lx] fld st fmul fld [iy] fsub [ly] fld st fmul fld [iz] fsub [lz] fld st fmul fadd fadd fsqrt fstp [DIL] ; PAS FindPlaneVector(cx3,cy3,cz3,ix3,iy3,iz3,lx3,ly3,lz3, tx, ty, tz); fld [ix] fsub [camx] fstp [fx] fld [iy] fsub [camy] fstp [fy] fld [iz] fsub [camz] fstp [fz] fld [lx] fsub [camx] fstp [gx] fld [ly] fsub [camy] fstp [gy] fld [lz] fsub [camz] fstp [gz] fld [fy] fmul [gz] fld [fz] fmul [gy] fsub fstp [pvx] fld [fz] fmul [gx] fld [fx] fmul [gz] fsub fstp [pvy] fld [fx] fmul [gy] fld [fy] fmul [gx] fsub fstp [pvz] fld1 fld [pvz] fmul [pvz] fld [pvy] fmul [pvy] fld [pvx] fmul [pvx] fadd fadd fsqrt fdiv fld st fmul [pvx] fstp [pvx] fld st fmul [pvy] fstp [pvy] fmul [pvz] fstp [pvz] ; PAS { ; r1 := ox3 - lx3; r2 := oy3 - ly3; r3 := oz3 - lz3; ; n := -(r1*tx + r2*ty + r3*tz); ; } fld [lx] fsub [qword ds:si ] fmul [pvx] fld [ly] fsub [qword ds:si+8 ] fmul [pvy] fld [lz] fsub [qword ds:si+16] fmul [pvz] fadd fadd fstp [mn] ; PAS opx := ox3 + n*tx; opy := oy3 + n*ty; opz := oz3 + n*tz; fld [qword ds:si ] fld [pvx] fmul [mn] fadd fstp [opx] fld [qword ds:si+8 ] fld [pvy] fmul [mn] fadd fstp [opy] fld [qword ds:si+16] fld [pvz] fmul [mn] fadd fst [opz] ; PAS dpi := dist(opx,opy,opz, ix3, iy3, iz3); fsub [iz] fld st fmul fld [opx] fsub [ix] fld st fmul fld [opy] fsub [iy] fld st fmul fadd fadd fsqrt fstp [dpi] ; PAS dpc := dist(opx,opy,opz, cx3, cy3, cz3); fld [opx] fsub [camx] fld st fmul fld [opy] fsub [camy] fld st fmul fld [opz] fsub [camz] fld st fmul fadd fadd fsqrt fstp [dpc] ; PAS cosgamma := dpi / dOI; fld [dpi] fdiv [DOI] fstp [cosgamma] ; PAS costheta := limit1(( sqr(dil) + sqr(DCI) - sqr(dcl) ) / ( 2 * dil * DCI )); fld [DIL] fmul [DIL] fld [DCI] fmul [DCI] fadd fld [DLC] fmul [DLC] fsub fild [i2] fmul [DIL] fmul [DCI] fdiv ;limit1: fld1 fsub ftst fstsw ax sahf jbe short @cos1OK ffree st fldz @cos1OK: fld1 fadd fst [costheta] ; PAS sintheta := sqrt(1 - sqr(costheta) ); fld st fmul fchs fld1 fadd fsqrt fstp [sintheta] ; PAS { ; Lx := CosTheta * DIL; ; lY := SinTheta * DIL; ; } fld [costheta] fmul [DIL] fstp [l2x] fld [sintheta] fmul [DIL] fstp [l2y] ; PAS cosdelta := limit1(( sqr(dpi) + sqr(DCI) - sqr(dpc) ) / ( 2 * dpi * DCI )); fld [dpi] fmul [dpi] fld [dci] fmul [dci] fadd fld [dpc] fmul [dpc] fsub fild [i2] fmul [dpi] fmul [dci] fdiv ;limit1: fld1 fsub ftst fstsw ax sahf jbe short @cos2OK ffree st fldz @cos2OK: fld1 fadd fst [cosdelta] ; PAS sindelta := sqrt(1 - sqr(cosdelta) ); fld st fmul fchs fld1 fadd fsqrt fstp [sindelta] ; PAS { ; X := CosDelta * dpi; ; Y := SinDelta * dpi; ; } fld [cosdelta] fmul [dpi] fstp [x2] fld [sindelta] fmul [dpi] fstp [y2] ; PAS { ; if abs(sqr(x-lx)+sqr(y-ly)+(n*n) - dol*dol)>0.0001 then ; y := -y; ; } mov bx, dx shl bx, 3 add bx, offset preDLO fld [x2] fsub [l2x] fld st fmul fld [y2] fsub [l2y] fld st fmul fld [mn] fmul [mn] fadd fadd fld [qword ds:bx] fld st fmul fsub fabs fsub [eps] ftst fstsw ax ffree st sahf jb short @y2OK fld [y2] fchs fstp [y2] @y2OK: ; PAS dpx := sqr(x-lx) + sqr(y-ly); fld [x2] fsub [l2x] fld st fmul fld [y2] fsub [l2y] fld st fmul fadd fstp [dpx] ; PAS cosOIL := limit1(( sqr(dpi) + sqr(Dil) - dpx ) / (2*dpi*dil)); fld [dpi] fmul [dpi] fld [DIL] fmul [DIL] fadd fsub [dpx] fild [i2] fmul [dpi] fmul [dil] fdiv ;limit1: fld1 fsub ftst fstsw ax sahf jbe short @cos3OK ffree st fldz @cos3OK: fld1 fadd fstp [cosOIL] ; PAS cosOIC := limit1(( sqr(dpi) + sqr(cx) - dpx ) / (2*dpi*cx)); fld [dpi] fmul [dpi] fld [DCI] fmul [DCI] fadd fsub [dpx] fild [i2] fmul [dpi] fmul [DCI] fdiv ;limit1: fld1 fsub ftst fstsw ax sahf jbe short @cos4OK ffree st fldz @cos4OK: fld1 fadd fst [cosOIC] ; PAS OIL := arccos(CosOIL); OIC := arccos(CosOIC); fmul [cosOic] fchs fld1 fadd fsqrt fld [cosOIC] fpatan fstp [OIC] fld [cosOIL] fmul [cosOIL] fchs fld1 fadd fsqrt fld [cosOIL] fpatan fstp [OIL] xor bx, bx fld [cosOIL] ftst fstsw ax ffree st sahf jb short @sskip1 mov bl, 2 @sskip1: fld [x2] fmul [l2y] fld [y2] fmul [l2x] fsub ftst fstsw ax ffree st sahf jb short @sskip2 add bl, 1 @sskip2: ; PAS { ; case byte(lpr)*2 + byte(lord) of ; 0 : la := oil - pi/2; ; 1 : la := pi/2 + (pi-oil); ; 2 : la := -pi/2 + oil; ; 3 : la := -pi/2 - oil; ; end; ; } or bx, bx jne short @case11 fld [oil] fsub [M_PI_2] jmp short @case1end @case11: cmp bl, 1 jne short @case12 fldpi fsub [oil] fadd [M_PI_2] jmp short @case1end @case12: cmp bl, 2 jne short @case13 fld [oil] fsub [M_PI_2] jmp short @case1end @case13: fld [oil] fadd [M_PI_2] fchs @case1end: fstp [la] xor bx, bx fld [cosOIC] ftst fstsw ax ffree st sahf jb short @sskip3 mov bl, 2 @sskip3: fld [y2] fmul [l2x] fchs ftst fstsw ax ffree st sahf jb short @sskip4 add bl, 1 @sskip4: ; PAS { ; case byte(cpr)*2 + byte(cord) of ; 0 : va := 1.5*pi - oic; ; 1 : va := oic - pi/2; ; 2 : va := -pi/2 - oic; ; 3 : va := -pi/2 + oic; ; end; ; } or bx, bx jne short @case21 fld [M1_5_PI] fsub [oic] jmp short @case2end @case21: cmp bl, 1 jne short @case22 fld [oic] fsub [M_PI_2] jmp short @case2end @case22: cmp bl, 2 jne short @case23 fld [oic] fadd [M_PI_2] fchs jmp short @case2end @case23: fld [oic] fsub [M_PI_2] @case2end: fst [va] ; PAS beta := abs(va-la); fsub [la] fabs fst [lbeta] ; PAS if beta > pi then beta := 2*pi-beta; fldpi fsub ftst fstsw ax ffree st sahf jbe short @lbetaok fld [M_2_PI] fsub [lbeta] fstp [lbeta] @lbetaok: ; PAS if betalim > pi/2 then betalim := pi/2; fld [lbeta] fst [betalim] fsub [M_PI_2] ftst fstsw ax ffree st sahf jb short @lbetanolim fld [M_PI_2] fstp [betalim] @lbetanolim: ; PAS solve3d := limit1(ambient + lift(cosgamma * cos(beta/2)) * specular + cos(betalim) * diffuse); fld [lbeta] fild [i2] fdiv fcos fmul [cosgamma] fld st fmul fmul [specular] fld [betalim] fcos fmul [diffuse] fadd [ambient] fadd ;limit1: fld1 fsub ftst fstsw ax sahf jbe short @resultNoLim ffree st fldz @ResultNoLim: fld1 fadd ; solution in st(0) !!! :)))) we did it ! fmul [mult] fimul [i63] fistp [cbx] mov ax, [cbx] and ax, 63 ret EndP Solve3d ;****************************************** ;****************************************** ;*** procedure FRAME ::: *** ;*** does the actual renderering. *** ;****************************************** ;****************************************** PROC Frame fld [height] fsub [camy] fstp [h_cy] fld [height] fadd [camy] fstp [cy_h] fld [height] fsub [ly] fld st fmul fstp [hpydsq] fld [ly] fadd [height] fld st fmul fstp [lpydsq] call fillscr0 call calcgrid call initframe xor di, di mov [j], 0 @LineLoop: fld [tx] fstp [ttx] fld [ty] fstp [tty] fld [tz] fstp [ttz] mov [i], 0 mov [infi], 0 fld [tty] fmul [tty] fstp [ttysq] fld [ty] ftst fstsw ax sahf jb short @lowplane ja short @highplane mov [infi], 1 ffree st jmp short @Pixelloop @lowplane: fabs fld [cy_h] fdivr fstp [jgmul] fld [lpydsq] fstp [pydsq] jmp short @PixelLoop @HighPlane: fld [h_cy] fdivr fstp [jgmul] fld [hpydsq] fstp [pydsq] @PixelLoop: xor dx, dx cmp [byte es:di], 0 jz dropped ; floor engine mov dl, [es:di] fld1 ; normalize a vector fld [ttx] fmul [ttx] fld [ttysq] fld [ttz] fmul [ttz] fadd fadd fsqrt fdiv fld st fmul [ttx] fstp [x] fld st fmul [tty] fstp [y] fmul [ttz] fstp [z] dec dx mov bp, dx shl bp, 3 add bp, offset predist mov si, dx shl si, 5 add si, offset asp fld [camx] fld [x] fmul [qword bp] fadd fsub [qword si] fld st fmul fld [camy] fld [y] fmul [qword bp] fadd fsub [qword si+8] fld st fmul fld [camz] fld [z] fmul [qword bp] fadd fsub [qword si+16] fld st fmul fadd fadd fst [bcs] fsub [qword bp+2048] ftst fstsw ax sahf ja short @fullsearch fadd [qword bp+2048] call solve3d jmp @AxOkPut @fullsearch: ffree st mov bx, [ballz] @srchc: dec bx mov dl, [ord + bx] dec dx mov bp, dx shl bp, 3 add bp, offset predist mov si, dx shl si, 5 add si, offset asp fld [camx] fld [x] fmul [qword bp] fadd fsub [qword si] fld st fmul fld [camy] fld [y] fmul [qword bp] fadd fsub [qword si+8] fld st fmul fld [camz] fld [z] fmul [qword bp] fadd fsub [qword si+16] fld st fmul fadd fadd fst [bcs] fsub [qword bp+2048] ftst fstsw ax sahf ja short @consearch fadd [qword bp+2048] call solve3d jmp @axOKPut @consearch: ffree st or bx, bx jnz @srchc dropped: cmp [infi], 0 je short @ynorm xor ax, ax jmp @axOKPut @ynorm: fld [jgmul] fld st fmul [ttx] fadd [camx] fist [itx] mov ax, [word itx] fld st fmul fst st(2) ffree st fincstp fmul [ttz] fadd [camz] fist [ity] mov bx, [word ity] fld st fmul fadd fadd [pydsq] fsqrt ; fsqrt @fmakepixcalc: and ax, 127 and bx, 127 shl bx, 7 add bx, ax mov al, [byte ds:bx+tex] shl ax, 6 mov [cbx], ax fild [cbx] fdivr ; fmul [rfogness] fistp [cbx] mov ax, [cbx] add ax, 64 cmp ax, 100h jb short @axOKPut mov ax, 0ffh @axOKPut: stosb @fcontinue: fld [ttx] fadd [ttxi] fstp [ttx] ; fld [tty] ; fadd [ttyi] ; fstp [tty] fld [ttz] fadd [ttzi] fstp [ttz] inc [i] cmp [i], 320 jb @PixelLoop fld [tx] fadd [txi] fstp [tx] fld [ty] fadd [tyi] fstp [ty] fld [tz] fadd [tzi] fstp [tz] inc [j] cmp [j], 200 jb @LineLoop call flip ret ENDP Frame ;------------------------------------------------------------------------- ; **********************************************************************/ ; MathCalc && Maineffect ; ; (i've seperated these this way, coz they drive the engine, so ; the intro behaviour depends on them ... :] ) ; ; * MathCalc: * ; ; one biiig "case", examines the "time" variable and determines ; where the objects are, the camera position and direction and some ; other things like palette, etc. ; ; ; * MainEffect: * ; ; Just a nasty caller. Only calls calls calls and does some simple work ; sometimes ;) ; ; ***********************************************************************\ ;-------------------------------------------------------------------------- ProC MathCalc fld [time] mov [cbx], 2 fidiv [cbx] fstp [xtime] fld [xtime] fsin mov [cbx], 250 fimul [cbx] fstp [camx] fld [xtime] fcos fimul [cbx] fstp [camz] fld [time] fsincos fidiv [i2] fstp [beta] mov [cbx], 80 fimul [cbx] fstp [camy] mov [cbx], 4 fld [time] fidiv [cbx] fstp [alfa] fld [time] fld [lightuptime] fld1 fadd fsub ftst fstsw ax sahf jnb @mathbye fld1 fadd ftst fstsw ax sahf jb @cccoll ffree st fld1 jmp @dopal @cccoll: fadd [lightuptime] fdiv [lightuptime] @dopal: call dopalette @mathbye: ffree st ret EndP MathCalc ProC MainEffect call inittexture call initpalette call initspheres call GetTime mov [timesave], eax cmp [useTSC], 1 jne short @gskip call rdtsc fstp [CP_st] @gskip: push vbuf pop es ; do main effect @FrameLoop: inc [frames] call MathCalc call frame cmp [useTSC],1 jne short @n0nTSC call rdtsc fld [CP_st] fsub fld [CPU_HZ] fdiv fstp [time] jmp short @aftertime @n0nTSC: fld [time] fadd [spf] fstp [time] @aftertime: mov ah, 11 int 21h or al, al jz @FrameLoop call GetTime sub eax, [timesave] mov [timeall], eax ret EndP MainEffect END Start