{ MATRiX #1 DEMO (x) 2000 Z0MBiE } { compiler: TMT Pascal 2.11 } {$OPTFRM+,OPT+,OPTREG+,A+,R-,I-,P-,T-,X+,B-,CC+,Q-,V-,S-,W+,D-,L-} {$DEFINE USEGRAPH} { use pascal graphics and /pas option } {$DEFINE USEPOINTS} { draw points } {$DEFINE USELINES} { draw lines } {$DEFINE USEPLANES} { draw planes } {$DEFINE USETEXT} { draw text } {$DEFINE USEBMP} { draw background bitmap } {$DEFINE USEFLAME} { draw flame as background } uses crt, {$IFDEF USEGRAPH} graph, {$ENDIF} zentimer; {$IFDEF USETEXT} {$I FONT.INC} {$ENDIF} {$IFDEF USEBMP} {$I BKGR.INC} {$ENDIF} const C_STACKSIZE = 8192; C_MAXANGLE = 2048; C_SHRSC = 8; C_MAXSC = 1 shl C_SHRSC; C_SHRZ = 18; C_MAXX = 320; C_MAXY = 200; C_CENTERX = C_MAXX div 2; C_CENTERY = C_MAXY div 2; C_FPS = 30; C_VIDEOPTR = $A0000; C_PAL0 = 0; C_PAL1 = 128; C_PAL2 = 128+64; C_point_max = 8192; C_line_max = 8192; C_plane_max = 8192; const dd_C_MAXANGLE_div2 : longint = C_MAXANGLE div 2; dd_C_MAXSC : longint = C_MAXSC; OPT_NOFIXFPS : longint = 0; OPT_CONT : longint = 0; OPT_VGA : longint = 1; look_z : longint = 0; angle_x : longint = 0; angle_y : longint = 0; angle_z : longint = 0; var cos_x, cos_y, cos_z, sin_x, sin_y, sin_z : longint; draw_type, bkgr_type, flame_type : longint; point_max, plane_max, line_max : longint; point3_x, point2_x : array[0..C_point_max-1] of longint; point3_y, point2_y : array[0..C_point_max-1] of longint; point3_z, point2_z : array[0..C_point_max-1] of longint; plane_p1, plane_p2, plane_p3, plane_z, index : array[0..C_plane_max-1] of longint; line_p1, line_p2 : array[0..C_line_max-1] of longint; buf,bmp : array[0..C_MAXY-1+8,0..C_MAXX-1] of byte; procedure initgraph; begin {$IFDEF USEGRAPH} if OPT_VGA=1 then begin {$ENDIF} asm mov ax, 0013h int 10h end; {$IFDEF USEGRAPH} end else begin setsvgamode(640,480,8,LFBOrBanked); end; {$ENDIF} end; procedure donegraph; begin {$IFDEF USEGRAPH} if OPT_VGA=1 then begin {$ENDIF} asm mov ax, 0003h int 10h end; {$IFDEF USEGRAPH} end else begin closegraph; end; {$ENDIF} end; const page:longint=0; procedure clearscreen; begin {$IFDEF USEGRAPH} if OPT_VGA=0 then begin page:=1-page; setactivepage(page); clearpage; end else begin {$ENDIF} asm mov edi, offset buf mov ecx, C_MAXX*C_MAXY/4 {$IFDEF USEBMP} mov esi, offset bmp rep movsd {$ELSE} xor eax, eax rep stosd {$ENDIF} end; {$IFDEF USEGRAPH} end; {$ENDIF} end; procedure onscreen; begin {$IFDEF USEGRAPH} if OPT_VGA=1 then begin {$ENDIF} asm mov esi, offset buf mov edi, C_VIDEOPTR mov ecx, C_MAXX*C_MAXY/4 rep movsd end; {$IFDEF USEGRAPH} end else begin setvisualpage(page,true); end; {$ENDIF} end; procedure calc_angle; assembler; asm xor ebx, ebx @@1:and angle_x[ebx], C_MAXANGLE-1 fild angle_x[ebx] fldpi fmul fild dd_C_MAXANGLE_div2 fdiv fsincos fild dd_C_MAXSC fmul fistp cos_x[ebx] fild dd_C_MAXSC fmul fistp sin_x[ebx] add ebx, 4 cmp ebx, 3*4 jb @@1 end; procedure calc_points; assembler; asm mov ebx, point_max shl ebx, 2 @@1:sub ebx, 4 mov eax, dword ptr point3_x[ebx] mov ecx, dword ptr point3_y[ebx] mov edx, dword ptr point3_z[ebx] mov esi, ecx imul esi, cos_x mov edi, edx imul edi, sin_x add esi, edi sar esi, C_SHRSC imul ecx, sin_x imul edx, cos_x sub edx, ecx sar edx, C_SHRSC mov ecx, esi mov esi, eax imul esi, cos_y mov edi, edx imul edi, sin_y add esi, edi sar esi, C_SHRSC imul eax, sin_y imul edx, cos_y sub edx, eax sar edx, C_SHRSC mov eax, esi mov esi, eax imul esi, cos_z mov edi, ecx imul edi, sin_z add esi, edi sar esi, C_SHRSC imul eax, sin_z imul ecx, cos_z sub ecx, eax sar ecx, C_SHRSC mov eax, esi mov dword ptr point2_z[ebx], edx add edx, look_z imul eax, edx imul ecx, edx sar eax, C_SHRZ sar ecx, C_SHRZ add eax, C_CENTERX add ecx, C_CENTERY mov dword ptr point2_x[ebx], eax mov dword ptr point2_y[ebx], ecx or ebx, ebx jnz @@1 end; procedure draw_line(x1,y1,x2,y2,color : longint); assembler; asm mov eax, x1 mov ebx, y1 mov ecx, x2 mov edx, y2 cmp eax, C_MAXX jae @@o cmp ebx, C_MAXY jae @@o cmp ecx, C_MAXX jae @@o cmp edx, C_MAXY jae @@o mov ecx, 1 mov eax, x2 sub eax, x1 jl @@1 jg @@2 dec ecx @@1:neg eax neg ecx @@2:mov dword ptr @@q - 4, eax mov dword ptr @@i - 4, ecx mov ecx, 1 mov ebx, y2 sub ebx, y1 jl @@3 jg @@4 dec ecx @@3:neg ebx neg ecx @@4:mov dword ptr @@w - 4, ebx imul ecx, C_MAXX mov dword ptr @@j - 4, ecx sub ebx, eax sbb ecx, ecx xor ecx, -1 and ecx, ebx add ecx, eax mov edx, ecx mov esi, x1 mov edi, y1 imul edi, C_MAXX mov eax, color mov byte ptr @@k - 1, al {-$DEFINE X1} {$IFDEF X1} mov dword ptr @@u-4, esp mov dword ptr @@y-4, ebp {$ENDIF} xor eax, eax xor ebx, ebx @@cycle: mov byte ptr buf[esi+edi], 12h @@k: {$IFDEF X1} add eax, 12345678h @@q:cmp ecx, eax sbb ebp, ebp mov esp, ebp and ebp, ecx and esp, 12345678h @@i:sub eax, ebp add esi, esp add ebx, 12345678h @@w:cmp ecx, ebx sbb ebp, ebp mov esp, ebp and ebp, ecx and esp, 12345678h @@j:sub ebx, ebp add edi, esp {$ELSE} add eax, 12345678h @@q:cmp eax, ecx jb @@i sub eax, ecx add esi, 12345678h @@i: add ebx, 12345678h @@w:cmp ebx, ecx jb @@j sub ebx, ecx add edi, 12345678h @@j: {$ENDIF} dec edx jge @@cycle {$IFDEF X1} mov esp, 12345678h @@u:mov ebp, 12345678h @@y: {$ENDIF} @@o: end; procedure draw_point(x,y,color : longint); assembler; asm mov eax, y cmp eax, C_MAXY jae @@exit mov ebx, x mov ecx, C_MAXX cmp ebx, ecx jae @@exit imul eax, ecx add ebx, eax mov eax, color mov ah, al mov ecx, eax shl ecx, 16 or eax, ecx mov dword ptr buf[ebx], eax mov dword ptr buf[ebx+320], eax mov dword ptr buf[ebx+2*320], eax mov byte ptr bmp[ebx], 110 @@exit: end; procedure draw_plane3(x1,y1,x2,y2,x3,y3,color:longint); var rv1, rv2 : longint; asm mov eax, x1 mov ebx, y1 mov ecx, x2 mov edx, y2 mov esi, x3 mov edi, y3 cmp eax, C_MAXX jae @@exit cmp ebx, C_MAXY jae @@exit cmp ecx, C_MAXX jae @@exit cmp edx, C_MAXY jae @@exit cmp esi, C_MAXX jae @@exit cmp edi, C_MAXY jae @@exit cmp edx, edi jle @@1 xchg ecx, esi xchg edx, edi @@1: cmp ebx, edx jle @@2 xchg eax, ecx xchg ebx, edx @@2: cmp edx, edi jle @@3 xchg ecx, esi xchg edx, edi @@3: mov x1, eax mov y1, ebx mov x2, ecx mov y2, edx mov x3, esi mov y3, edi mov esi, y1 imul esi, C_MAXX add esi, x1 mov edx, esi mov eax, y3 sub eax, y1 inc eax mov dword ptr @@dey1-4, eax mov rv1, eax mov eax, y2 sub eax, y1 inc eax mov dword ptr @@dey2-4, eax mov rv2, eax mov ebx, 1 mov eax, x3 sub eax, x1 jge @@skipdxneg1 neg eax neg ebx @@skipdxneg1: inc eax mov dword ptr @@dex1-4, eax mov dword ptr @@if1-4, ebx mov ebx, 1 mov eax, x2 sub eax, x1 jge @@skipdxneg2 neg eax neg ebx @@skipdxneg2: inc eax mov dword ptr @@dex2-4, eax mov dword ptr @@if2-4, ebx call @@drawloop mov eax, y3 sub eax, y2 inc eax mov dword ptr @@dey2-4, eax mov rv2, eax mov ebx, 1 mov eax, x3 sub eax, x2 jnc @@dx2pos neg eax neg ebx @@dx2pos: inc eax mov dword ptr @@dex2-4, eax mov dword ptr @@if2-4, ebx call @@drawloop jmp @@exit @@drawloop: mov eax, color mov ah, al mov ebx, eax shl ebx, 16 or eax, ebx mov ebx, dword ptr @@dey2-4 mov dword ptr @@esp0-4, esp mov dword ptr @@ebp0-4, ebp mov esp, rv1 mov ebp, rv2 @@drawloop1: mov edi, edx mov ecx, esi cmp ecx, edi ja @@dontswap1 xchg ecx, edi @@dontswap1: sub ecx, edi {inc ecx} add edi, offset buf shr ecx, 1 jnc @@q1 stosb @@q1: shr ecx, 1 jnc @@q2 stosw @@q2: rep stosd sub esp, 12345678h @@dex1: jg @@donothing1 @@dosomething1: add edx, 12345678h @@if1: add esp, 12345678h @@dey1: jle @@dosomething1 @@donothing1: add edx, C_MAXX sub ebp, 12345678h @@dex2: jg @@donothing2 @@dosomething2: add esi, 12345678h @@if2: add ebp, 12345678h @@dey2: jle @@dosomething2 @@donothing2: add esi, C_MAXX dec ebx jnz @@drawloop1 mov esp, 12345678h @@esp0: mov ebp, 12345678h @@ebp0: db 0C3h {retn} @@exit: end; const min_z : longint = $7FFFFFFF; max_z : longint = $80000000; var delt_z : longint; procedure calc_minmax; var i,z:longint; begin for i := 0 to point_max-1 do begin z := point2_z[i]; if min_z>z then min_z:=z; if max_zj; if l0 then begin for y := 0 to my-1 do for x := 0 to mx-1 do if a[y,x]<>0 then begin rx:=(x-mx div 2)*200; ry:=(y-my div 2)*200; rz:=0; if x>7 then if x<=17 then begin rz:=rx+11*200; rx:=-11*200; end; if x>26 then if x<=32 then begin rz:=ry; ry:=0; end; addcube(rx,ry,rz,100); end; end; if n and 2 <>0 then begin for z := -3 to 3 do for y := -3 to 3 do for x := -3 to 3 do if byte(abs(x)=3) + byte(abs(y)=3) + byte(abs(z)=3) = 2 then addcube(x*500,y*500,z*500,200); end; end; procedure setrgb(c,r,g,b:longint); begin port[$3c8]:=c; port[$3c9]:=r; port[$3c9]:=g; port[$3c9]:=b; end; procedure setrgbpal(a,b,r1,g1,b1,r2,g2,b2:longint); var i:longint; begin for i:=a to b do setrgb(i, r1+(r2-r1)*(i-a) div (b-a), g1+(g2-g1)*(i-a) div (b-a), b1+(b2-b1)*(i-a) div (b-a)); end; var timer:longint absolute $40:$6C; dx,dy,dz,totalframes,totaltime:longint; procedure quit; begin donegraph; writeln('MATRiX #1 Demo (x) 2000 Z0MBiE, http://z0mbie.cjb.net'); writeln; writeln(point_max:6,' points ',totalframes:7,' frames'); writeln(line_max :6,' lines ',totaltime/1000000.0:7:2,' seconds'); writeln(plane_max:6,' planes ',totalframes*1000000.0/(totaltime+1):7:2,' fps'); halt; end; {$IFDEF USETEXT} const s_text:string=' '+ ' ULTRAS mort NBK Henkey Del_Armg0 '+ ' '+ ' greetz to VX scene '+ ' '; x_ptr:longint=0; s_ptr:longint=0; procedure puttext; var rx,ry,i,x,y,tx,c:longint; s:string; begin if s_ptr=-1 then exit; tx:=1; for i:=0+1 to 19-1 do for x:=0 to 7 do begin if s_text[s_ptr+i]<>#32 then begin c:=C_PAL2+63; if tx<=63 then c:=C_PAL2+tx; if C_MAXX shr 1-tx<=63 then c:=C_PAL2+C_MAXX shr 1-tx; for y:=0 to 15 do if font[ ord(s_text[s_ptr+i]) shl 4+y] shl x and $80 <> 0 then begin rx:=(i shl 3+x) shl 1-x_ptr; ry:=C_MAXY-32+y shl 1; {$IFDEF USEGRAPH} if OPT_VGA=1 then begin {$ENDIF} asm mov esi, ry imul esi,320 add esi, rx mov eax,c mov ah,al mov word ptr buf[esi], ax mov word ptr buf[esi+320], ax end; if bkgr_type=1 then if flame_type=2 then bmp[ry,rx]:=random(2)*160; {$IFDEF USEGRAPH} end else begin putpixel(rx shl 1, ry shl 1+40, c); end; {$ENDIF} end; end; inc(tx); end; x_ptr:=(x_ptr+1) and 15; if x_ptr=0 then inc(s_ptr); if s_ptr>=length(s_text)-20 then s_ptr:= -1; end; {$ENDIF} {$IFDEF USEBMP} procedure setbmppal(scale:longint); var c:longint; begin for c:=0 to 127 do setrgb(C_PAL0+c, bkgr[1+54+c shl 2+2]*scale div 255, bkgr[1+54+c shl 2+1]*scale div 255, bkgr[1+54+c shl 2+0]*scale div 255); end; procedure processbmp; var c,x,y:longint; begin fillchar(bmp,sizeof(bmp),0); for y:=0 to 199 do for x:=0 to 319 do bmp[y,x]:= bkgr[1+54+1024+(199-y)*320+x]+C_PAL0; setbmppal(0); end; {$ENDIF} {$IFDEF USEFLAME} procedure setflamepal(scale:longint); var x,y:longint; begin for x := 0 to 31 do begin y:=x*scale div 31; setrgb(C_PAL0+x, y, 0, 0); setrgb(C_PAL0+x+32, scale, y, 0); setrgb(C_PAL0+x+64, scale, scale, y); setrgb(C_PAL0+x+96, scale, scale, scale); end; end; procedure updateflame; var x:longint; begin x:=random(65536); asm mov ecx, x xor esi, esi @@cycle1: mov edi, 0*320 @@cycle2: xor eax, eax mov al, byte ptr bmp[edi+esi] xor ebx, ebx mov bl, byte ptr bmp[edi+esi+2] add eax, ebx mov bl, byte ptr bmp[edi+esi-2] add eax, ebx mov bl, byte ptr bmp[edi+esi+2*320+2] add eax, ebx shr eax, 2 jz @@1 dec al @@1:mov ah, al mov word ptr bmp[esi+edi-2*320], ax mov word ptr bmp[esi+edi-1*320], ax add edi, 2*320 cmp edi, 204*320 jbe @@cycle2 cmp flame_type,2 je @@3 imul ecx, 214013 add ecx, 2531011 xor al, al test ecx, 10000h jz @@2 mov al, 160 @@2:mov byte ptr bmp[edi+esi-2*320], al @@3: add esi, 2 cmp esi, 320 jb @@cycle1 end; end; {$ENDIF} function cycle : boolean; var time1,time2:longint; begin cycle:=true; time1 := LZTimerLap; angle_x := angle_x + dx; angle_y := angle_y + dy; angle_z := angle_z + dz; {$IFDEF USEFLAME} if bkgr_type=1 then updateflame; {$ENDIF} clearscreen; calc_angle; calc_points; calc_minmax; if draw_type=3 then sortplanes; draw; {$IFDEF USETEXT} puttext; {$ENDIF} onscreen; inc(totalframes); repeat time2:=LZTimerLap-time1; until (OPT_NOFIXFPS=1) or (time2 > 1000000 div C_FPS); inc(totaltime,time2); if keypressed then case readkey of #32: OPT_NOFIXFPS:=OPT_NOFIXFPS xor 1; #27: quit; 'x': cycle := false; end; end; procedure showhelp; begin writeln('options:'); writeln(' /maxfps -- allow max avail fps rate (SPACE within the demo)'); writeln(' /cont -- execute demo continously'); {$IFDEF USEGRAPH} writeln(' /pas -- use pascal''s graph (sucks)'); {$ENDIF} halt; end; procedure initbkgr; begin if bkgr_type=1 then begin {$IFDEF USEFLAME} fillchar(bmp, sizeof(bmp), 0); {$ENDIF} end else begin {$IFDEF USEBMP} if OPT_VGA=1 then processbmp; {$ENDIF} end; end; var i,j:longint; begin for i:=1 to paramcount do begin if paramstr(i)='/maxfps' then OPT_NOFIXFPS:=1 else if paramstr(i)='/cont' then OPT_CONT:=1 else {$IFDEF USEGRAPH} if paramstr(i)='/pas' then OPT_VGA:=0 else {$ENDIF} showhelp; end; initgraph; { look_z:=7000; angle_x:=128; angle_y:=128; angle_z:=0; draw_type := 2; bkgr_type := 2; initbkgr; gen_data(1); setrgbpal(C_PAL1,C_PAL1+63, 63,0,0, 0,0,63); clearscreen; calc_angle; calc_points; calc_minmax; sortplanes; draw; onscreen; readkey; quit; } for i:=0 to 63 do setrgb(C_PAL2+i, i,i,i); fillchar(buf, sizeof(buf), 0); totalframes:=0; totaltime:=0; ZTimerInit; LZTimerOn; j:=0; repeat {$IFDEF USETEXT} if s_ptr=-1 then s_ptr:=0; {$ENDIF} angle_x:=0; angle_y:=0; angle_z:=0; case j mod 3 of 0: {$IFDEF USEPOINTS} gen_data(1); {$ELSE} gen_data(3); {$ENDIF} 1: gen_data(1); 2: gen_data(2); end; {$IFDEF USEPOINTS} if j<>2 then begin look_z := 5000; setrgbpal(C_PAL1,C_PAL1+63, 63,0,0, 63,63,42); draw_type := 1; bkgr_type := 1; flame_type := 2; initbkgr; dx:=8; dy:=0; dz:=8; for i:=0 to 63 do begin {$IFDEF USEFLAME} setflamepal(i); {$ENDIF} if not cycle then break; end; for i:=1+64 to C_MAXANGLE div 2-64 do if not cycle then break; for i:=0 to 63 do begin {$IFDEF USEFLAME} setflamepal(63-i); {$ENDIF} setrgbpal(C_PAL1,C_PAL1+63, 63-i,0,0, 63-i,63,42-i*2 div 3); if not cycle then break; end; end; case j mod 3 of 0: gen_data(3); end; {$ENDIF} {$IFDEF USELINES} look_z := 5000; setrgbpal(C_PAL1,C_PAL1+63, 0,0,0, 0,63,0); draw_type := 2; bkgr_type := 2; initbkgr; dx:=16; dy:=8; dz:=0; for i:=0 to 99 do begin {$IFDEF USEBMP} if i<=63 then setbmppal(i); {$ENDIF} inc(look_z,50); if not cycle then break; end; for i:=100 to C_MAXANGLE div 4 do if not cycle then break; dy:=-dy; for i:=100 to C_MAXANGLE div 4-64 do if not cycle then break; for i:=0 to 63 do begin {$IFDEF USEBMP} setbmppal(63-i); {$ENDIF} setrgbpal(C_PAL1,C_PAL1+63, i,0,0, i,63,i*2 div 3); if not cycle then break; end; {$ENDIF} {$IFDEF USEPLANES} look_z := 10000; setrgbpal(C_PAL1,C_PAL1+63, 63,0,0, 63,63,42); draw_type:=3; bkgr_type := 1; flame_type := 1; initbkgr; dx:=4; dy:=-16; dz:=4; for i:=0 to 63 do begin {$IFDEF USEFLAME} setflamepal(i); {$ENDIF} if not cycle then break; end; for i:=64 to C_MAXANGLE div 4-64 do if not cycle then break; for i:=0 to 63 do begin {$IFDEF USEFLAME} setflamepal(63-i); {$ENDIF} setrgbpal(C_PAL1,C_PAL1+63, 63,i,i, 63-i,63-i,42+i div 3); if not cycle then break; end; bkgr_type := 3; for i:=1 to C_MAXANGLE div 4-200 do if not cycle then break; for i:=0 to 199 do begin dec(look_z,25); if not cycle then break; end; {$ENDIF} inc(j); if (OPT_CONT=0) and (j>=3) then quit; until false; end.