+++ /dev/null
-{$E-,N+}\r
-uses Crt, Modex;\r
-\r
-const\r
- DEFVERT = 12; (* Vertex count *)\r
- DEFREPL = 3; (* Repetition count *)\r
- DEFQIXS = 2; (* Qixs *)\r
- FADESPEED = 48;\r
-type\r
- TPoint = record\r
- X, Y : integer;\r
- end;\r
- TRGB = record\r
- R, G, B: byte;\r
- end;\r
- TQix = record\r
- Color: integer;\r
- Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint;\r
- Delta: array[ 0..DEFVERT-1 ] of TPoint;\r
- end;\r
-var\r
- Page : integer;\r
- MaxX,\r
- MaxY : word;\r
- Qix : array[ 0..DEFQIXS-1 ] of TQix;\r
- Pal : array[ byte ] of TRGB;\r
-\r
-type\r
- TReal = double;\r
- TRPoint = record\r
- X, Y: TReal;\r
- end;\r
- TMatrix = array[ 0..3, 0..3 ] of TReal;\r
-var\r
- M: TMatrix;\r
- G: array[ 0..DEFVERT-1 ] of TRPoint;\r
- C: array[ 0..DEFVERT-1 ] of TRPoint;\r
-\r
-procedure BumpPal( Idx, DR, DG, DB, Steps: integer );\r
-var\r
- I: integer;\r
-begin\r
- for I:=1 to Steps do begin\r
- Pal[Idx+1].R := Pal[Idx].R + DR;\r
- Pal[Idx+1].G := Pal[Idx].G + DG;\r
- Pal[Idx+1].B := Pal[Idx].B + DB;\r
- Inc( Idx );\r
- end;\r
-end;\r
-\r
-procedure InitPalette;\r
-begin\r
- with Pal[0] do begin R:=0; G:=0; B:=0; end;\r
- with Pal[1] do begin R:=0; G:=0; B:=62; end;\r
- BumpPal( 1, 0, 2, -2, 31 );\r
- BumpPal( 32, 2, -2, 0, 31 );\r
- BumpPal( 63, -2, 2, 2, 31 );\r
- BumpPal( 94, 2, 0, -2, 31 );\r
- BumpPal( 125, -2, -2, 2, 31 );\r
-end;\r
-\r
-procedure Init( var Qix: TQix; Color: integer );\r
-var\r
- I: integer;\r
-begin\r
- FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 );\r
- for I:=0 to DEFVERT-1 do begin\r
- Qix.Vert[I, DEFREPL-1].X := Random( MaxX );\r
- Qix.Vert[I, DEFREPL-1].Y := Random( MaxY );\r
- Qix.Delta[I].X := Random(5)+1;\r
- Qix.Delta[I].Y := Random(5)+1;\r
- end;\r
- Qix.Color := Color;\r
-\r
- (* Initialize matrix (Catmull-Rom) *)\r
- M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2;\r
- M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2;\r
- M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0;\r
- M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0;\r
-end;\r
-\r
-procedure mxBezier( var Qix: TQix; I0, Idx, N: integer );\r
-var\r
- I, J: integer;\r
- T, T2, T3: TReal;\r
- X0, Y0, X, Y: TReal;\r
- Delta: TReal;\r
-begin\r
- (* Compute coefficients *)\r
- for I:=0 to 3 do begin\r
- C[I].X := 0;\r
- for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X;\r
- C[I].Y := 0;\r
- for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y;\r
- end;\r
- X0 := C[3].X;\r
- Y0 := C[3].Y;\r
- Delta := 1 / N;\r
- T := 0;\r
- for I:=1 to N do begin\r
- T := T + Delta;\r
- T2 := T*T;\r
- T3 := T*T2;\r
- X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X;\r
- Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y;\r
- mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET );\r
- X0 := X;\r
- Y0 := Y;\r
- end;\r
-end;\r
-\r
-procedure Plot( var Qix: TQix; Idx: integer );\r
-var\r
- I, J: integer;\r
-begin\r
- for I:=0 to DEFVERT-1 do begin\r
- mxBezier( Qix, I, Idx, 12 );\r
- end;\r
-end;\r
-\r
-procedure Update( var Qix: TQix; Idx: integer );\r
-var\r
- I: integer;\r
-begin\r
- for I:=0 to DEFVERT-1 do with Qix do begin\r
- Inc( Vert[I,Idx].X, Delta[I].X );\r
- if( Vert[I,Idx].X < 0 ) then begin\r
- Vert[I,Idx].X := 0;\r
- Delta[I].X := Random( 5 )+1;\r
- end;\r
- if( Vert[I,Idx].X > MaxX ) then begin\r
- Vert[I,Idx].X := MaxX;\r
- Delta[I].X := -Random( 5 )-1;\r
- end;\r
- Inc( Vert[I,Idx].Y, Delta[I].Y );\r
- if( Vert[I,Idx].Y < 0 ) then begin\r
- Vert[I,Idx].Y := 0;\r
- Delta[I].Y := Random( 5 )+1;\r
- end;\r
- if( Vert[I,Idx].Y > MaxY ) then begin\r
- Vert[I,Idx].Y := MaxY;\r
- Delta[I].Y := -Random( 5 )-1;\r
- end;\r
- end;\r
-end;\r
-\r
-procedure Copy( var Qix: TQix; Dest, Src: integer );\r
-var\r
- I: integer;\r
-begin\r
- for I:=0 to DEFVERT-1 do with Qix do begin\r
- Vert[I,Dest].X := Vert[I,Src].X;\r
- Vert[I,Dest].Y := Vert[I,Src].Y;\r
- end;\r
-end;\r
-\r
-procedure AnimateQix;\r
-var\r
- Q, Idx, I, J, P, Count: integer;\r
-begin\r
- Count := 0;\r
- P := DEFREPL-1;\r
- I := 0;\r
- J := 1;\r
- repeat\r
- mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 );\r
- mxSetClip( TRUE );\r
- mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET );\r
- for Q:=0 to DEFQIXS-1 do begin\r
- Copy( Qix[Q], I, P );\r
- Update( Qix[Q], I );\r
- for Idx:=0 to DEFREPL-1 do begin\r
- Plot( Qix[Q], Idx );\r
- end;\r
- end;\r
- I := (I+1) mod DEFREPL;\r
- J := (J+1) mod DEFREPL;\r
- P := (P+1) mod DEFREPL;\r
- Inc( Count );\r
- mxStartLine( Page );\r
- if( Count >= FADESPEED ) then begin\r
- for Q:=0 to DEFQIXS-1 do begin\r
- Inc( Qix[Q].Color );\r
- if( Qix[Q].Color > 156 ) then\r
- Qix[Q].Color := 1;\r
- end;\r
- Count := 0;\r
- end;\r
- Page := 240-Page;\r
- until( KeyPressed );\r
-end;\r
-\r
-var\r
- I: integer;\r
-begin\r
- Randomize;\r
- mxInit;\r
- mxSetMode( MX_320x240 );\r
- mxGetScreenSize( MaxX, MaxY );\r
- for I:=0 to DEFQIXS-1 do\r
- Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 );\r
- InitPalette;\r
- mxSetPalette( @Pal, 0, 157 );\r
- Page := 240;\r
- Dec( MaxX );\r
- Dec( MaxY );\r
- AnimateQix;\r
- mxSetMode( MX_TEXT );\r
- mxTerm;\r
-end.\r