indexing description: "[ Main scene of this example ]" date: "$Date$" revision: "$Revision$" class TUNNEL_SCENE inherit EM_DRAWABLE_SCENE redefine initialize_scene, redraw end EM_SHARED_BITMAP_FACTORY export {NONE} all end MATH_CONST export {NONE} all end DOUBLE_MATH export {NONE} all end create make_scene feature {NONE} -- Initialization initialize_scene is -- Set the scene ready local file: RAW_FILE i: INTEGER do set_frame_counter_visibility (true) turn := 0 w_times_h := width * height create angle.make (1, w_times_h) create depth.make (1, w_times_h) create texture.make (1, 16384) create file.make_open_read ("texture.data") initialize_tab from i := 1 until i > 16384 loop file.read_integer texture.put (file.last_integer.bit_and (65535).to_integer_16, i) texture.put (file.last_integer.bit_shift_right (16).to_integer_16, i+1) i := i + 2 end -- create bitmap Bitmap_factory.create_empty_surface (width, height) surface := bitmap_factory.last_surface end initialize_tab is -- Initializes the angle and the depth arrays local a, i, j: INTEGER x, y: DOUBLE do a := 1 from j := 0 until j = height loop from i := 0 until i = width loop y := j - height / 2 x := i - width / 2 angle.put ((128 + atan2 (x, y) * 255 / 6.24).truncated_to_integer.to_natural_8, a) if x = 0.0 and y = 0.0 then depth.put ((0).to_natural_8, a) else depth.put (((radius*distance) / sqrt ((x)*(x)+(y)*(y))).truncated_to_integer.to_natural_8, a) end a := a + 1 i := i + 1 end j := j + 1 end end feature -- Drawing redraw is -- Redraw `Current' scene. -- Causes to clear `screen' and redraw `main_container' onto it. do refresh screen.blit_surface (surface, 0, 0) frame_counter.draw (screen) screen.redraw end refresh is -- Does strange things local i,j: INTEGER a, x, y, depX, depY: INTEGER color_org, color_r, color_g, color_b, color: INTEGER do a := 1 depX := (w_half * (1 + sine (turn))).truncated_to_integer.abs \\ 256 depY := (w_half * (1 + cosine (turn))).truncated_to_integer.abs \\ 256 turn := turn + 0.0314 from j := 0 until j = height loop from i := 0 until i = width loop x := (((angle @ (a) + depX) \\ 256) |>> 1).abs y := (((depth @ (a) + depY) \\ 256) |>> 1).abs color_org := (texture @ ((y |<< 7).abs + x + 1)) color_r := (color_org |>> 8).bit_and(248) color_g := (color_org |>> 3).bit_and(255) color_b := (color_org |<< 3).bit_and(56) color := 255 color := color.bit_or(color_b |<< 8) color := color.bit_or(color_g |<< 16) color := color.bit_or(color_r |<< 24) surface.put_pixel_value (i, j, color) a := a + 1 i := i + 1 end j := j + 1 end end atan2 (y, x: DOUBLE): DOUBLE is -- Compute the principal value of the arc tangent of (`y'/`x') -- in the range [-pi, +pi] -- Same as atan2 in standart c/c++ lib do if y < 0.0 then if x < 0.0 then Result := arc_tangent (y / x) - Pi elseif x = 0.0 then Result := - Pi / 2 else Result := arc_tangent (y / x) end elseif y = 0.0 then if x < 0 then Result := Pi else Result := 0.0 end else if x < 0.0 then Result := arc_tangent (y / x) + Pi elseif x = 0.0 then Result := Pi / 2 else Result := arc_tangent (y / x) end end end feature {NONE} -- Implementation surface: EM_SURFACE -- on this we draw everything angle: ARRAY [NATURAL_8] -- Angle depth: ARRAY [NATURAL_8] -- Angle texture: ARRAY [INTEGER_16] -- Textur image: ARRAY [INTEGER_16] -- Textur width: INTEGER is 256 -- The width of the surface height: INTEGER is 256 -- The height of the surface w_half: INTEGER is 128 -- Half ot the width of the surface w_times_h: INTEGER -- result for width * height radius: INTEGER is 64 -- The radius distance: INTEGER is 256 -- The distance turn: DOUBLE -- The turn end