[SCM] Lisaac library examples branch, master, updated. 282043cfdef5aaf225a6eb5cf22ecbe890a42213

Damien Bouvarel dams.bouvarel at wanadoo.fr
Wed Aug 26 23:49:07 UTC 2009


The following commit has been merged in the master branch:
commit abe20ae99d4be3de086687bbe77c812d55b95ba6
Author: Damien Bouvarel <dams.bouvarel at wanadoo.fr>
Date:   Mon Aug 24 08:52:22 2009 +0200

    clean opengl examples

diff --git a/chess/bishop.li b/chess/bishop.li
index 2c2968f..f5b5da5 100644
--- a/chess/bishop.li
+++ b/chess/bishop.li
@@ -1,50 +1,50 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := BISHOP;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_piece:Expanded PIECE;
-  
-Section Public
-  
-  - name:STRING_CONSTANT := "bishop";
-  
-  - model:MODEL; // shared model
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
-  // is legal move?
-  ( + result:BOOLEAN;
-    
-    ((dest.piece = NULL) || {player != dest.piece.player}).if {
-      ((dest.x - orig.x).abs = (dest.y - orig.y).abs).if {
-        result := check_path_between orig and dest;
-      };
-    };
-    result
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := BISHOP;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_piece:Expanded PIECE;
+  
+Section Public
+  
+  - name:STRING_CONSTANT := "bishop";
+  
+  - model:MODEL; // shared model
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
+  // is legal move?
+  ( + result:BOOLEAN;
+    
+    ((dest.piece = NULL) || {player != dest.piece.player}).if {
+      ((dest.x - orig.x).abs = (dest.y - orig.y).abs).if {
+        result := check_path_between orig and dest;
+      };
+    };
+    result
   );
\ No newline at end of file
diff --git a/chess/chess.li b/chess/chess.li
index fb0cb90..605f4e0 100644
--- a/chess/chess.li
+++ b/chess/chess.li
@@ -1,863 +1,858 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := CHESS;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_scene:Expanded SCENE;
-  
-  - parent_reshape:RESHAPE := RESHAPE;
-  
-  - parent_key_listener:KEY_LISTENER := KEY_LISTENER;
-  - parent_mouse_listener:MOUSE_LISTENER := MOUSE_LISTENER;
-  
-Section Public  
-  
-  - main <-
-  ( 
-    // pixel format query
-    SETTINGS.use_stencil_buffer;
-    
-    OPENGL.set_reshape Self;
-    
-    OPENGL.make (800,600) title "3D Chess Game" fullscreen FALSE;
-    ENGINE.make OPENGL;
-    
-    ENGINE.attach_scene Self;
-    ENGINE_INPUT.add_key_listener Self;
-    ENGINE_INPUT.add_mouse_listener Self;
-    
-    
-    ENGINE.initialize;
-    
-    ENGINE.main_loop;
-    
-    ENGINE.shutdown;
-    OPENGL.shutdown;
-  );
-  
-Section Public
-  
-  - square_size:INTEGER := 32;
-  
-  // pieces
-  - p1:FAST_ARRAY[PIECE];
-  - p2:FAST_ARRAY[PIECE];
-  
-  - chessboard:FAST_ARRAY[PIECE]; 
-  
-  - gamestate:GAMESTATE := GAMESTATE;
-  
-  - current_square:SQUARE; // for highlighting
-  - current_world:SCENE;
-  
-  
-  - board_texture:TEXTURE;
-  
-  - black_texture:TEXTURE;
-  - white_texture:TEXTURE;
-  
-  - camera:CHESSCAM;
-  
-  - selection_color:COLOR := RGB.create (0,0.7,0);
-  - current_color:COLOR := RGB.create (0.4,0,0.4);
-  
-  - move_ok_color:COLOR := RGB.create (0,0.7,0);
-  - illegal_move_color:COLOR := RGB.create (0.8,0,0);
-  
-  - light:LIGHT;
-  - light_pos:VECTOR3[REAL_32];
-  
-  - light_shader:SHADER;
-  - loc_texture:INTEGER;
-  
-  - sphere:SPHERE;// to represent light source
-  
-  - piece_material:MATERIAL;
-  - board_material:MATERIAL;
-  
-  - shadow_matrix:MATRIX4[REAL_32];
-  - shadow_plane:PLANE;
-  
-  - particle_system:PARTICLE_SYSTEM;// when capture is on
-  - particle_texture:TEXTURE;
-
-  - modelview:MATRIX4[REAL_32];
-  - dx:VECTOR3[REAL_32] := VECTOR3[REAL_32].zero;
-  - dy:VECTOR3[REAL_32] := VECTOR3[REAL_32].zero;
-  
-  - logo:TEXTURE;
-  
-  
-  - initialize <-
-  ( + infolog:STRING;
-    + board:FAST_ARRAY[UINTEGER_8];
-    + dim:INTEGER;
-    + orig,pf_pos:VECTOR3[REAL_32];
-    + ambient,diffuse,specular,emission:RGB;
-    + shine:REAL_32;
-    + constraint:CONSTRAINT;
-    
-    //
-    // load textures
-    //
-    
-    black_texture := renderer.texture2d.create_from (IMAGE.create "textures/black.bmp");
-    white_texture := renderer.texture2d.create_from (IMAGE.create "textures/white.bmp");
-    
-    
-    dim := 256;
-    board := FAST_ARRAY[UINTEGER_8].create (dim*dim);
-    
-    // procedural image
-    0.to (dim-1) do { i:INTEGER;
-      0.to (dim-1) do { j:INTEGER;
-        ((i^j)%64 < 32).if {
-          board.put 0 to (i*dim+j);
-        } else {
-          board.put 255 to (i*dim+j);
-        }
-      };
-    };
-    
-    board_texture := renderer.texture2d.create_from_data board size (dim,dim) type 1;
-    logo := renderer.texture2d.create_from (IMAGE.create "textures/logo.bmp");
-    
-    //
-    // load models
-    //
-    
-    p1 := FAST_ARRAY[PIECE].create_with_capacity 16;
-    p2 := FAST_ARRAY[PIECE].create_with_capacity 16;
-    chessboard := FAST_ARRAY[PIECE].create 64;
-    
-    0.to 7 do { i:INTEGER;
-      load_piece PAWN at (i,6) in p1 player 1;
-      load_piece PAWN at (i,1) in p2 player 2;
-    };
-    
-    load_piece ROOK at (0,7) in p1 player 1;
-    load_piece ROOK at (7,7) in p1 player 1;
-    load_piece ROOK at (0,0) in p2 player 2;
-    load_piece ROOK at (7,0) in p2 player 2;
-    
-    load_piece KNIGHT at (1,7) in p1 player 1;
-    load_piece KNIGHT at (6,7) in p1 player 1;
-    load_piece KNIGHT at (1,0) in p2 player 2;
-    load_piece KNIGHT at (6,0) in p2 player 2;
-    
-    load_piece BISHOP at (2,7) in p1 player 1;
-    load_piece BISHOP at (5,7) in p1 player 1;
-    load_piece BISHOP at (2,0) in p2 player 2;
-    load_piece BISHOP at (5,0) in p2 player 2;
-    
-    load_piece QUEEN at (4,7) in p1 player 1;
-    load_piece QUEEN at (3,0) in p2 player 2;
-    
-    load_piece KING at (3,7) in p1 player 1;
-    load_piece KING at (4,0) in p2 player 2; 
-    
-    
-    set_world WORLD1;
-    
-    camera := CHESSCAM.create;
-    
-    //
-    // intro motion (rotate around chessboard..)
-    //
-    orig := VECTOR3[REAL_32].zero;
-    camera.add_waypoint (VECTOR3[REAL_32].create (0, 100, -800));
-    camera.add_waypoint orig;
-    
-    camera.add_waypoint (VECTOR3[REAL_32].create (0,150,-300));
-    camera.add_waypoint orig;
-    
-    camera.add_waypoint (VECTOR3[REAL_32].create (500, 250, 0));
-    camera.add_waypoint (VECTOR3[REAL_32].create (0, 100, 50));
-    
-    camera.add_waypoint (VECTOR3[REAL_32].create (0,200,300));
-    camera.add_waypoint orig;
-    
-    //
-    // capture effect
-    ///
-    
-    particle_system := PARTICLE_SYSTEM.create orig;
-    particle_system.set_size (2, 0.5);
-    particle_system.set_spawn_rate 4;
-    
-    pf_pos := VECTOR3[REAL_32].create (0, 80, 0); // attraction point
-    
-    constraint := POINT_FORCE.create (pf_pos,0.005,0,0.001);
-    particle_system.add_constraint constraint;
-    
-    constraint := BOUNCE_PLANE.create (VECTOR3[REAL_32].create (0,1,0), 20);
-    particle_system.add_constraint constraint;
-    
-    
-    // load particle texture
-    renderer.texture2d.set_wrapping_mode (renderer.texture2d.clamp);
-    particle_texture := renderer.texture2d.create_from (IMAGE.create "textures/particle.bmp");
-    renderer.texture2d.set_wrapping_mode (renderer.texture2d.repeat);
-    
-    modelview := MATRIX4[REAL_32].create;
-    
-    //
-    //  Board lighting
-    //
-    
-    OPENGL.use_shaders.if_false {
-      engine.log.print "Cannot support GLSL Shaders with ARB extensions";
-    } else {
-      // per-pixel lighting
-      light_shader := renderer.shader.create ("shaders/light.vert","shaders/light.frag");
-      light_shader.enable;
-      
-      light_shader.has_compiled.if_false {
-        // print shader compilation errors - shader is disabled
-        infolog := STRING.create 32;
-        light_shader.get_infolog infolog;
-        
-        engine.log.print "Compilation error(s) in light shader: ";
-        engine.log.print infolog;
-      };
-      loc_texture := light_shader.get_uniform_location "texture";
-      light_shader.disable;
-    };
-    
-    // create OpenGL light (also used in light shader)
-    light_pos := VECTOR3[REAL_32].create (50,300,-30);
-    ambient := RGB.create (0.2, 0.2, 0.2);
-    diffuse := RGB.create (1.0, 1.0, 1.0);
-    specular := RGB.create (1.0, 1.0, 1.0);
-    
-    light := renderer.light.create (ambient,diffuse,specular) at light_pos;
-    
-    // board piece material    
-    ambient := RGB.create (0.2, 0.2, 0.2); 
-    diffuse := RGB.create (1.0, 1.0, 1.0);
-    specular := RGB.create (1.0, 1.0, 1.0);
-    emission := RGB.create (0.0, 0.0, 0.0);// no emission
-    shine := 50.0;
-    
-    piece_material := renderer.material.create (ambient,diffuse,specular,emission,shine);
-    
-    ambient := RGB.create (1.0, 1.0, 1.0); 
-    diffuse := RGB.create (1.0, 1.0, 1.0);
-    specular := RGB.create (1.0, 1.0, 1.0);
-    shine := 8.0;
-    
-    board_material := renderer.material.create (ambient,diffuse,specular,emission,shine);
-    
-    
-    // debug light position
-    sphere := SPHERE.create (light_pos,2,10,10);
-    
-    light.enable;
-    
-    // stencilling is used for reflections
-    renderer.stencil_buffer.set_clear_value 0.0;
-    
-    // for shadow casting
-    shadow_matrix := MATRIX4[REAL_32].create;
-    
-    // cast shadow on board plane
-    shadow_plane := renderer.plane.create (0,1,0,0);
-  );
-  
-  - load_piece type:PIECE at (x,y:INTEGER) in p:FAST_ARRAY[PIECE] player pl:INTEGER <-
-  ( + piece:PIECE;
-    
-    piece := type.create (x,y,pl) index (p.count);
-    p.add_last piece;
-    chessboard.put piece to (y*8+x);
-  );
-  
-  - counter:REAL_32;
-  
-  - render t:UINTEGER_32 <-
-  (         
-    + time:REAL_32;
-    + board_half_size:INTEGER;
-    
-    board_half_size := square_size*4;
-    
-    renderer.begin_frame;
-    //----- begin rendering
-    
-    camera.animate t;
-    camera.look;
-    
-    // update game
-    gamestate.play;
-    
-    // draw world around
-    current_world.render t;
-    
-    // first pass of rendering pieces
-    render_shadows_and_reflections board_half_size;
-    
-    // draw board
-    render_chessboard board_half_size;
-    
-    //
-    // render pieces
-    //
-    
-    time := t.to_real * 0.05;
-    0.to 15 do { i:INTEGER;
-      (p1.item i = gamestate.current_piece).if {
-        p1.item i.update_selected time;
-      } else {
-        p1.item i.update time;
-      };
-      (p2.item i = gamestate.current_piece).if {
-        p2.item i.update_selected time;
-      } else {
-        p2.item i.update time;
-      };
-      
-      // rotate light around
-      counter := counter+time*0.001;
-      light_pos.set_x (100.0 * (0.78*counter).cos);
-      light_pos.set_y (50.0 * (0.3*counter).cos + 100);
-      light_pos.set_z (100.0 * (1.0*counter).sin); 
-      
-      // debug light position
-      renderer.texture2d.disable;
-      renderer.color_buffer.set_color3f (0.9, 1.0, 0.6);
-      sphere.render;
-      renderer.color_buffer.set_color3f (1, 1, 1);
-      renderer.texture2d.enable;
-      
-      
-      renderer.enable_lighting;  
-      ////
-      
-      // if light position is modified 
-      light.set_position light_pos;
-      light.enable;
-      
-      piece_material.apply_front;
-      
-      (light_shader != NULL).if {
-        // per-pixel lighting if shader is supported
-        light_shader.enable;
-        light_shader.bind_sampler black_texture unit 0 location loc_texture;
-      };
-      
-      // draw black pieces
-      p1.item i.render renderer;
-      
-      (light_shader != NULL).if {
-        light_shader.bind_sampler white_texture unit 0 location loc_texture;
-      };
-      
-      // draw white pieces
-      p2.item i.render renderer;
-      
-      (light_shader != NULL).if {
-        light_shader.disable;
-      };
-      
-      /////
-      renderer.disable_lighting;  
-    };
-    
-    //
-    // render particles
-    //
-    
-    gamestate.capture.if {
-      renderer.transform.get_modelview modelview;
-
-      // let particles face the camera (billboard) 
-      dx.make (modelview.item (0,0), modelview.item (1,0), modelview.item (2,0));
-      dy.make (modelview.item (0,1), modelview.item (1,1), modelview.item (2,1));
-      renderer.blending.apply (renderer.blending.src_color,renderer.blending.one);
-      renderer.blending.enable;
-      
-      // update & render
-      particle_system.update (t.to_real);
-    
-      particle_texture.bind;
-      
-      renderer.transform.new_matrix {
-        PIECE.set_renderer renderer at_position (gamestate.move_dest);
-        
-        particle_system.render (dx,dy);
-      };
-      
-      renderer.blending.disable;
-    };
-    
-    // draw logo
-    camera.is_traveling.if_false {
-      renderer.light.push_attrib;
-      renderer.transform.ortho_mode (renderer.width,renderer.height) do {
-        
-        (gamestate.current_player = 1).if {
-          renderer.color_buffer.set_color3f (0.4,0.6,0.8);// blue
-        } else {
-          renderer.color_buffer.set_color3f (0.8,0.6,0.4);// orange
-        };
-        logo.draw_strech (50,50,64,64);
-        renderer.color_buffer.set_color3f (1,1,1);
-      };
-      renderer.light.pop_attrib;
-    };
-    
-    //----- end rendering
-    renderer.end_frame;
-  );
-  
-  - render_chessboard sz:INTEGER <-
-  (
-    + x:INTEGER;
-    
-    //
-    // render board
-    //
-    
-    //renderer.enable_lighting;  
-    /////
-    //  board_material.apply_front;
-    
-    
-    renderer.blending.apply (renderer.blending.src_alpha, renderer.blending.one_minus_src_alpha);
-    renderer.blending.set_alpha_value 0.7;
-    renderer.blending.enable;
-    
-    board_texture.bind;
-    
-    renderer.transform.new_matrix {
-      
-      renderer.vb.new_quads {
-        renderer.vb.add_normal3f (0.0, 1.0, 0.0);
-        
-        renderer.vb.add_texel2f (0.0, 1.0);
-        renderer.vb.add_vertex3f (-sz, 0.0, sz);
-        
-        renderer.vb.add_texel2f (0.0, 0.0);
-        renderer.vb.add_vertex3f (-sz, 0.0, -sz);
-        
-        renderer.vb.add_texel2f (1.0, 0.0);
-        renderer.vb.add_vertex3f (sz, 0.0, -sz);
-        
-        renderer.vb.add_texel2f (1.0, 1.0);
-        renderer.vb.add_vertex3f (sz, 0.0, sz);
-      };
-      
-      renderer.blending.disable;
-      
-      /////
-      //     renderer.disable_lighting;  
-      
-      // render selected squares
-      camera.is_traveling.if_false {
-        gamestate.piece_selected.if {
-          gamestate.current_piece.check_move (gamestate.move_orig) to current_square.if {
-            // move ok
-            current_square.render renderer color move_ok_color;
-          } else {
-            current_square.render renderer color illegal_move_color;
-          };
-        } else {
-          current_square.render renderer color current_color;
-        };
-        gamestate.piece_selected.if {
-          gamestate.move_orig.render renderer color selection_color;
-        };
-      };
-    };
-    
-    x := renderer.width / 2 - 50;
-    renderer.font.print_zone {
-      engine.out.print "3D Chess Game" at (x,50);
-      
-      (gamestate.current_piece != NULL).if {
-        engine.out.print ("this is "+gamestate.current_piece.name+gamestate.current_piece.player.to_string) at (x,500);
-      } else {
-        engine.out.print "Pick up a piece" at (x,500);
-      };
-    };
-  );
-  
-  - render_shadows_and_reflections sz:INTEGER <-
-  (
-    //
-    // First pass: draw an invisible mask of the floor in the stencil buffer
-    //
-    
-    // disable drawing in color buffer
-    renderer.color_buffer.disable;
-    
-    renderer.stencil_buffer.clear;
-    renderer.stencil_buffer.enable;
-    
-    // stencil test always pass and set stencil value to 1 
-    renderer.stencil_buffer.set_function (renderer.stencil_buffer.always) value 1 mask 1;
-    
-    // if test successful replace stencil value else keep the old value
-    renderer.stencil_buffer.when_pass (renderer.stencil_buffer.replace) when_fail (renderer.stencil_buffer.keep) when_zfail (renderer.stencil_buffer.keep);
-    
-    renderer.depth_buffer.disable;
-    
-    // render board in stencil buffer
-    renderer.vb.new_quads {  
-      renderer.vb.add_vertex3f (-sz, 0.0, sz);
-      renderer.vb.add_vertex3f (-sz, 0.0, -sz);
-      renderer.vb.add_vertex3f (sz, 0.0, -sz);
-      renderer.vb.add_vertex3f (sz, 0.0, sz);
-    };
-    
-    // back to color mode
-    renderer.depth_buffer.enable;
-    renderer.color_buffer.enable;
-    
-    //
-    // Second pass: draw reflections & shadows in the masked floor (stencil test enabled)
-    //
-    
-    // only draw pixels masked with 1 in stencil buffer
-    renderer.stencil_buffer.set_function (renderer.stencil_buffer.equal) value 1 mask 1;
-    renderer.stencil_buffer.lock; // read-only
-    
-    ////
-    render_reflections;
-    render_shadows;
-    ///
-    
-    // back to normal mode
-    renderer.stencil_buffer.disable;
-    renderer.depth_buffer.enable;
-  );
-  
-  - render_reflections <-
-  (
-    renderer.transform.new_matrix {
-      
-      // mirror y axis
-      renderer.transform.scalef (1.0, -1.0, 1.0);
-      
-      // draw reflections
-      0.to 15 do { i:INTEGER;
-        p1.item i.render renderer;
-        p2.item i.render renderer;
-      };
-    };
-  );
-  
-  - render_shadows <-
-  (
-    + dot:REAL_32;
-    
-    renderer.depth_buffer.disable;
-    
-    //
-    // build a shadow matrix from light position & shadow plane
-    //
-    
-    // dot product between shadow plane & light_position
-    dot := shadow_plane.a * light_pos.x + shadow_plane.b * light_pos.y + shadow_plane.c * light_pos.z + shadow_plane.d;
-    
-    // first column
-    shadow_matrix.put (dot - light_pos.x * shadow_plane.a) to (0,0);
-    shadow_matrix.put (0.0 - light_pos.x * shadow_plane.b) to (1,0);
-    shadow_matrix.put (0.0 - light_pos.x * shadow_plane.c) to (2,0);
-    shadow_matrix.put (0.0 - light_pos.x * shadow_plane.d) to (3,0);
-    
-    // second column
-    shadow_matrix.put (0.0 - light_pos.y * shadow_plane.a) to (0,1);
-    shadow_matrix.put (dot - light_pos.y * shadow_plane.b) to (1,1);
-    shadow_matrix.put (0.0 - light_pos.y * shadow_plane.c) to (2,1);
-    shadow_matrix.put (0.0 - light_pos.y * shadow_plane.d) to (3,1);
-    
-    // third column
-    shadow_matrix.put (0.0 - light_pos.z * shadow_plane.a) to (0,2);
-    shadow_matrix.put (0.0 - light_pos.z * shadow_plane.b) to (1,2);
-    shadow_matrix.put (dot - light_pos.z * shadow_plane.c) to (2,2);
-    shadow_matrix.put (0.0 - light_pos.z * shadow_plane.d) to (3,2);
-    
-    // fourth column
-    shadow_matrix.put (0.0 - shadow_plane.a) to (0,3);
-    shadow_matrix.put (0.0 - shadow_plane.b) to (1,3);
-    shadow_matrix.put (0.0 - shadow_plane.c) to (2,3);
-    shadow_matrix.put (dot - shadow_plane.d) to (3,3);
-    
-    // shadow color (dark)
-    renderer.color_buffer.set_color3f (0, 0, 0);
-    renderer.texture2d.disable;
-    
-    renderer.transform.new_matrix {
-      
-      // set OpenGL modelview matrix in shadow space
-      renderer.transform.mult_matrix_by shadow_matrix;
-      
-      // draw shadows
-      0.to 15 do { i:INTEGER;
-        p1.item i.render renderer;
-        p2.item i.render renderer;
-      };
-    };
-    renderer.color_buffer.set_color3f (1, 1, 1);
-    renderer.texture2d.enable;
-  );
-  
-  //
-  // Selection.
-  //
-  
-  - hits:FAST_ARRAY[UINTEGER_32] := FAST_ARRAY[UINTEGER_32].create 512;
-  
-  - select_piece (x,y:UINTEGER_32) :PIECE <-
-  // selection from camera view vector
-  (
-    + nb_hits:INTEGER;
-    + choose,depth:UINTEGER_32;
-    + v:VIEWPORT;
-    + result:PIECE;
-    
-    v := renderer.viewport;
-    
-    // start selection mode, hits are recorded in 'hits' array
-    renderer.begin_selection_in hits size 512;
-    
-    // restrict the viewing volume to the mouse click region
-    renderer.transform.new_projection {
-      renderer.transform.push_matrix;
-      renderer.transform.load_identity;
-      
-      // create 5x5 pixel picking region near cursor location 
-      renderer.transform.pickmatrix (x, v.height - y, 5, 5) in v;
-      
-      // multiply it the viewing volume matrix
-      renderer.transform.perspective (renderer.fov, (v.width-v.x0).to_real/(v.height-v.y0).to_real, 0.1, 5000);
-    };
-    
-    // initialize the name stack
-    renderer.name_stack.init;
-    renderer.name_stack.push (-1);// not to have an empty stack
-    
-    // draw pieces in selection buffer
-    0.to 15 do { i:INTEGER;
-      renderer.name_stack.load (p1.item i.id);
-      p1.item i.render renderer;
-      
-      renderer.name_stack.load (p2.item i.id);
-      p2.item i.render renderer;
-    };
-    
-    // go back to previous projection
-    renderer.transform.new_projection {
-      renderer.transform.pop_matrix;
-    };
-    
-    // go back to render mode 
-    nb_hits := renderer.end_selection;
-    
-    //
-    //  Buffer format:
-    //    for each hit:
-    //       0:  number of names for this hit
-    //       1:  z-min value of the hit
-    //       2:  z-max value of the hit
-    //       3:  content of the name stack (bottom of stack)
-    //       ...
-    
-    // choose the closest object hit
-    (nb_hits > 0).if {
-      choose := hits.item 3;
-      depth := hits.item 1;
-      
-      1.to (nb_hits-1) do { i:INTEGER;
-        (hits.item (i*4+1) < depth).if { // here the name stack has 1 elt
-          choose := hits.item (i*4+3);
-          depth := hits.item (i*4+1);
-        };
-      };
-      result := get_piece_from choose;
-    };
-    result
-  );
-  
-  - select_square (x,y:UINTEGER_32) :SQUARE <-
-  // selection from camera view vector
-  ( + result:SQUARE;
-    + target:VECTOR3[REAL_32];
-    + fraction,start_dist,end_dist,start_frac,end_frac,epsilon:REAL_32;
-    + x_col,z_col:REAL_32;
-    + px,py:INTEGER;
-    
-    // create ray from camera eye in world space
-    
-    // camera.view.set_y (camera.view.y + 0.05); // bug fix..
-    target := camera.position + (camera.view * 1000);
-    //   camera.view.set_y (camera.view.y - 0.05); // big fix..
-    
-    epsilon := 0.325;
-    start_frac := -1.0;
-    end_frac := 1.0;
-    
-    // check collision: ray vs board plane (XZ plane, normal=(0,1,0))
-    start_dist := camera.position.y; // a*x+b*y+c*z-d
-    end_dist := target.y;
-    
-    ((start_dist > 0) && {end_dist > 0}).if_false {
-      // else ray is not colliding
-      
-      (start_dist > end_dist).if {
-        fraction := (start_dist - epsilon) / (start_dist - end_dist);
-        (fraction > start_frac).if {
-          start_frac := fraction;
-        };
-      } else {
-        fraction := (start_dist + epsilon) / (start_dist - end_dist);
-        (fraction < end_frac).if {
-          end_frac := fraction;
-        };
-      };
-      (
-        (start_frac < end_frac) && 
-        {start_frac > -1.0} &&
-        {start_frac < 1.0}
-      ).if {
-        // collision
-        
-        fraction := start_frac;
-        (fraction < 0).if {
-          fraction := 0;
-        };
-        x_col := camera.position.x + (target.x-camera.position.x) * fraction;
-        z_col := camera.position.z + (target.z-camera.position.z) * fraction;
-        
-        x_col := (4.0*square_size-x_col) / square_size; // to board space
-        z_col := (z_col+4.0*square_size) / square_size; // to board space
-        
-        px := x_col.to_integer;
-        (px < 0).if {
-          px := 0;
-        };
-        py := z_col.to_integer;
-        (py < 0).if {
-          py := 0;
-        };
-        result := SQUARE.create (px, py);
-      };
-    };
-    
-    result
-  );
-  
-  - get_piece_from id:UINTEGER_32 :PIECE <-
-  ( + result:PIECE;
-    ((id & 01h) = 0).if {
-      // player 1
-      result := p1.item (id >> 1);
-    } else {
-      // player 2     
-      result := p2.item (id >> 1);
-    };
-    result
-  );
-  
-  - release <-
-  (
-    (current_world != NULL).if {
-      current_world.release;
-    };
-    (light_shader != NULL).if {
-      light_shader.delete;
-    };
-  );
-  
-  - set_world w:SCENE <-
-  (
-    (current_world != NULL).if {
-      current_world.release; 
-    };
-    
-    w.set_engine engine;
-    current_world := w;
-    
-    current_world.initialize;
-  );
-  
-  //
-  // Input.
-  //
-  
-  - keydown k:INTEGER <-
-  (
-  );
-  
-  - click button:INTEGER <-
-  ( + x,y:UINTEGER_32;
-    + piece:PIECE;
-    + square:SQUARE;
-    
-    camera.is_traveling.if_false {
-      
-      x := INPUT_SYSTEM.mouse_x;
-      y := INPUT_SYSTEM.mouse_y;
-      
-      piece := select_piece (x,y);
-      (piece != NULL).if {
-        square := piece.square;
-      } else {
-        square := select_square (x,y);
-      };
-      
-      // update game
-      gamestate.update square;
-    };
-  );
-  
-  - move (x,y:INTEGER) <-
-  ( 
-    camera.is_traveling.if_false {
-      current_square := select_square (x,y);
-    };
-  );
-  
-  
-  - on_resize (w,h:INTEGER) <-
-  // world projection
-  (
-    + ratio:REAL_32;
-    
-    ratio := renderer.width / renderer.height;
-    
-    renderer.transform.new_projection {
-      renderer.transform.load_identity;
-      
-      r.transform.perspective (r.fov, w.to_real/h.to_real, 0.1, 5000.0);
-    };
-    // clear modelview matrix
-    r.transform.load_identity;
-  );
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := CHESS;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  - parent_framework:FRAMEWORK := FRAMEWORK;
+
+  + parent_scene:Expanded SCENE;
+  
+  - parent_reshape:RESHAPE := RESHAPE;
+  
+  - parent_event_listener:EVENT_LISTENER := EVENT_LISTENER;
+
+Section Public  
+  
+  - main <-
+  ( 
+    // pixel format query
+    CAPABILITIES.use_stencil_buffer;
+    
+    OPENGL.set_reshape Self;
+   
+    OPENGL.make (800,600) title "3D Chess Game";
+    FRAMEWORK.make OPENGL;
+    
+    attach_scene Self;
+    add_key_listener Self;
+    add_mouse_listener Self;
+    
+    // start game
+    run;
+  );
+  
+Section Public
+  
+  - square_size:INTEGER := 32;
+  
+  // pieces
+  - p1:FAST_ARRAY[PIECE];
+  - p2:FAST_ARRAY[PIECE];
+  
+  - chessboard:FAST_ARRAY[PIECE]; 
+  
+  - gamestate:GAMESTATE := GAMESTATE;
+  
+  - current_square:SQUARE; // for highlighting
+  - current_world:SCENE;
+  
+  
+  - board_texture:TEXTURE;
+  
+  - black_texture:TEXTURE;
+  - white_texture:TEXTURE;
+  
+  - camera:CHESSCAM;
+  
+  - selection_color:COLOR := RGB.create (0,0.7,0);
+  - current_color:COLOR := RGB.create (0.4,0,0.4);
+  
+  - move_ok_color:COLOR := RGB.create (0,0.7,0);
+  - illegal_move_color:COLOR := RGB.create (0.8,0,0);
+  
+  - light:LIGHT;
+  - light_pos:VECTOR3[REAL_32];
+  
+  - light_shader:SHADER;
+  - loc_texture:INTEGER;
+  
+  - sphere:SPHERE;// to represent light source
+  
+  - piece_material:MATERIAL;
+  - board_material:MATERIAL;
+  
+  - shadow_matrix:MATRIX4[REAL_32];
+  - shadow_plane:PLANE;
+  
+  - particle_system:PARTICLE_SYSTEM;// when capture is on
+  - particle_texture:TEXTURE;
+
+  - modelview:MATRIX4[REAL_32];
+  - dx:VECTOR3[REAL_32] := VECTOR3[REAL_32].zero;
+  - dy:VECTOR3[REAL_32] := VECTOR3[REAL_32].zero;
+  
+  - logo:TEXTURE;
+  
+  
+  - initialize:BOOLEAN <-
+  ( + infolog:STRING;
+    + board:FAST_ARRAY[UINTEGER_8];
+    + dim:INTEGER;
+    + orig,pf_pos:VECTOR3[REAL_32];
+    + ambient,diffuse,specular,emission:RGB;
+    + shine:REAL_32;
+    + constraint:CONSTRAINT;
+    
+    //
+    // load textures
+    //
+    
+    black_texture := renderer.texture2d.create_from (IMAGE.create "textures/black.bmp");
+    white_texture := renderer.texture2d.create_from (IMAGE.create "textures/white.bmp");
+    
+    
+    dim := 256;
+    board := FAST_ARRAY[UINTEGER_8].create (dim*dim);
+    
+    // procedural image
+    0.to (dim-1) do { i:INTEGER;
+      0.to (dim-1) do { j:INTEGER;
+        ((i^j)%64 < 32).if {
+          board.put 0 to (i*dim+j);
+        } else {
+          board.put 255 to (i*dim+j);
+        }
+      };
+    };
+    
+    board_texture := renderer.texture2d.create_from_data board size (dim,dim) type 1;
+    logo := renderer.texture2d.create_from (IMAGE.create "textures/logo.bmp");
+    
+    //
+    // load models
+    //
+    
+    p1 := FAST_ARRAY[PIECE].create_with_capacity 16;
+    p2 := FAST_ARRAY[PIECE].create_with_capacity 16;
+    chessboard := FAST_ARRAY[PIECE].create 64;
+    
+    0.to 7 do { i:INTEGER;
+      load_piece PAWN at (i,6) in p1 player 1;
+      load_piece PAWN at (i,1) in p2 player 2;
+    };
+    
+    load_piece ROOK at (0,7) in p1 player 1;
+    load_piece ROOK at (7,7) in p1 player 1;
+    load_piece ROOK at (0,0) in p2 player 2;
+    load_piece ROOK at (7,0) in p2 player 2;
+    
+    load_piece KNIGHT at (1,7) in p1 player 1;
+    load_piece KNIGHT at (6,7) in p1 player 1;
+    load_piece KNIGHT at (1,0) in p2 player 2;
+    load_piece KNIGHT at (6,0) in p2 player 2;
+    
+    load_piece BISHOP at (2,7) in p1 player 1;
+    load_piece BISHOP at (5,7) in p1 player 1;
+    load_piece BISHOP at (2,0) in p2 player 2;
+    load_piece BISHOP at (5,0) in p2 player 2;
+    
+    load_piece QUEEN at (4,7) in p1 player 1;
+    load_piece QUEEN at (3,0) in p2 player 2;
+    
+    load_piece KING at (3,7) in p1 player 1;
+    load_piece KING at (4,0) in p2 player 2; 
+    
+    
+    set_world WORLD1;
+    
+    camera := CHESSCAM.create;
+    
+    //
+    // intro motion (rotate around chessboard..)
+    //
+    orig := VECTOR3[REAL_32].zero;
+    camera.add_waypoint (VECTOR3[REAL_32].create (0, 100, -800));
+    camera.add_waypoint orig;
+    
+    camera.add_waypoint (VECTOR3[REAL_32].create (0,150,-300));
+    camera.add_waypoint orig;
+    
+    camera.add_waypoint (VECTOR3[REAL_32].create (500, 250, 0));
+    camera.add_waypoint (VECTOR3[REAL_32].create (0, 100, 50));
+    
+    camera.add_waypoint (VECTOR3[REAL_32].create (0,200,300));
+    camera.add_waypoint orig;
+    
+    //
+    // capture effect
+    ///
+    
+    particle_system := PARTICLE_SYSTEM.create orig;
+    particle_system.set_size (2, 0.5);
+    particle_system.set_spawn_rate 4;
+    
+    pf_pos := VECTOR3[REAL_32].create (0, 80, 0); // attraction point
+    
+    constraint := POINT_FORCE.create (pf_pos,0.005,0,0.001);
+    particle_system.add_constraint constraint;
+    
+    constraint := BOUNCE_PLANE.create (VECTOR3[REAL_32].create (0,1,0), 20);
+    particle_system.add_constraint constraint;
+    
+    
+    // load particle texture
+    renderer.texture2d.set_wrapping_mode (renderer.texture2d.clamp);
+    particle_texture := renderer.texture2d.create_from (IMAGE.create "textures/particle.bmp");
+    renderer.texture2d.set_wrapping_mode (renderer.texture2d.repeat);
+    
+    modelview := MATRIX4[REAL_32].create;
+    
+    //
+    //  Board lighting
+    //
+    
+    OPENGL.use_shaders.if_false {
+      log.print "Cannot support GLSL Shaders with ARB extensions";
+    } else {
+      // per-pixel lighting
+      light_shader := renderer.shader.create ("shaders/light.vert","shaders/light.frag");
+      light_shader.enable;
+      
+      light_shader.has_compiled.if_false {
+        // print shader compilation errors - shader is disabled
+        infolog := STRING.create 32;
+        light_shader.get_infolog infolog;
+        
+        log.print "Compilation error(s) in light shader: ";
+        log.print infolog;
+      };
+      loc_texture := light_shader.get_uniform_location "texture";
+      light_shader.disable;
+    };
+    
+    // create OpenGL light (also used in light shader)
+    light_pos := VECTOR3[REAL_32].create (50,300,-30);
+    ambient := RGB.create (0.2, 0.2, 0.2);
+    diffuse := RGB.create (1.0, 1.0, 1.0);
+    specular := RGB.create (1.0, 1.0, 1.0);
+    
+    light := renderer.light.create (ambient,diffuse,specular) at light_pos;
+    
+    // board piece material    
+    ambient := RGB.create (0.2, 0.2, 0.2); 
+    diffuse := RGB.create (1.0, 1.0, 1.0);
+    specular := RGB.create (1.0, 1.0, 1.0);
+    emission := RGB.create (0.0, 0.0, 0.0);// no emission
+    shine := 50.0;
+    
+    piece_material := renderer.material.create (ambient,diffuse,specular,emission,shine);
+    
+    ambient := RGB.create (1.0, 1.0, 1.0); 
+    diffuse := RGB.create (1.0, 1.0, 1.0);
+    specular := RGB.create (1.0, 1.0, 1.0);
+    shine := 8.0;
+    
+    board_material := renderer.material.create (ambient,diffuse,specular,emission,shine);
+    
+    
+    // debug light position
+    sphere := SPHERE.create (light_pos,2,10,10);
+    
+    light.enable;
+    
+    // stencilling is used for reflections
+    renderer.stencil_buffer.set_clear_value 0.0;
+    
+    // for shadow casting
+    shadow_matrix := MATRIX4[REAL_32].create;
+    
+    // cast shadow on board plane
+    shadow_plane := renderer.plane.create (0,1,0,0);
+    TRUE
+  );
+  
+  - load_piece type:PIECE at (x,y:INTEGER) in p:FAST_ARRAY[PIECE] player pl:INTEGER <-
+  ( + piece:PIECE;
+    
+    piece := type.create (x,y,pl) index (p.count);
+    p.add_last piece;
+    chessboard.put piece to (y*8+x);
+  );
+  
+  - counter:REAL_32;
+  
+  - render t:REAL_32 <-
+  (         
+    + time:REAL_32;
+    + board_half_size:INTEGER;
+    
+    board_half_size := square_size*4;
+
+    camera.animate t;
+    camera.look;
+    
+    // update game
+    gamestate.play;
+    
+    // draw world around
+    current_world.render t;
+    
+    // first pass of rendering pieces
+    render_shadows_and_reflections board_half_size;
+    
+    // draw board
+    render_chessboard board_half_size;
+    
+    //
+    // render pieces
+    //
+    
+    time := t*50;
+    0.to 15 do { i:INTEGER;
+      (p1.item i = gamestate.current_piece).if {
+        p1.item i.update_selected time;
+      } else {
+        p1.item i.update time;
+      };
+      (p2.item i = gamestate.current_piece).if {
+        p2.item i.update_selected time;
+      } else {
+        p2.item i.update time;
+      };
+      
+      // rotate light around
+      counter := counter+time*0.001;
+      light_pos.set_x (100.0 * (0.78*counter).cos);
+      light_pos.set_y (50.0 * (0.3*counter).cos + 100);
+      light_pos.set_z (100.0 * (1.0*counter).sin); 
+      
+      // debug light position
+      renderer.texture2d.disable;
+      renderer.color_buffer.set_color3f (0.9, 1.0, 0.6);
+      sphere.render;
+      renderer.color_buffer.set_color3f (1, 1, 1);
+      renderer.texture2d.enable;
+      
+      
+      renderer.enable_lighting;  
+      ////
+      
+      // if light position is modified 
+      light.set_position light_pos;
+      light.enable;
+      
+      piece_material.apply_front;
+      
+      (light_shader != NULL).if {
+        // per-pixel lighting if shader is supported
+        light_shader.enable;
+        light_shader.bind_sampler black_texture unit 0 location loc_texture;
+      };
+      
+      // draw black pieces
+      p1.item i.render renderer;
+      
+      (light_shader != NULL).if {
+        light_shader.bind_sampler white_texture unit 0 location loc_texture;
+      };
+      
+      // draw white pieces
+      p2.item i.render renderer;
+      
+      (light_shader != NULL).if {
+        light_shader.disable;
+      };
+      
+      /////
+      renderer.disable_lighting;  
+    };
+    
+    //
+    // render particles
+    //
+    
+    gamestate.capture.if {
+      renderer.transform.get_modelview modelview;
+
+      // let particles face the camera (billboard) 
+      dx.make (modelview.item (0,0), modelview.item (1,0), modelview.item (2,0));
+      dy.make (modelview.item (0,1), modelview.item (1,1), modelview.item (2,1));
+      renderer.blending.apply (renderer.blending.src_color,renderer.blending.one);
+      renderer.blending.enable;
+      
+      // update & render
+      particle_system.update (t.to_real);
+    
+      particle_texture.bind;
+      
+      renderer.transform.new_matrix {
+        PIECE.set_renderer renderer at_position (gamestate.move_dest);
+        
+        particle_system.render (dx,dy);
+      };
+      
+      renderer.blending.disable;
+    };
+    
+    // draw logo
+    camera.is_traveling.if_false {
+      renderer.light.push_attrib;
+      renderer.transform.ortho_mode (renderer.width,renderer.height) do {
+        
+        (gamestate.current_player = 1).if {
+          renderer.color_buffer.set_color3f (0.4,0.6,0.8);// blue
+        } else {
+          renderer.color_buffer.set_color3f (0.8,0.6,0.4);// orange
+        };
+        logo.draw_strech (50,50,64,64);
+        renderer.color_buffer.set_color3f (1,1,1);
+      };
+      renderer.light.pop_attrib;
+    };
+    //----- end rendering
+  );
+  
+  - render_chessboard sz:INTEGER <-
+  (
+    + x:INTEGER;
+    
+    //
+    // render board
+    //
+    
+    //renderer.enable_lighting;  
+    /////
+    //  board_material.apply_front;
+    
+    
+    renderer.blending.apply (renderer.blending.src_alpha, renderer.blending.one_minus_src_alpha);
+    renderer.blending.set_alpha_value 0.7;
+    renderer.blending.enable;
+    
+    board_texture.bind;
+    
+    renderer.transform.new_matrix {
+      
+      renderer.vb.new_quads {
+        renderer.vb.add_normal3f (0.0, 1.0, 0.0);
+        
+        renderer.vb.add_texel2f (0.0, 1.0);
+        renderer.vb.add_vertex3f (-sz, 0.0, sz);
+        
+        renderer.vb.add_texel2f (0.0, 0.0);
+        renderer.vb.add_vertex3f (-sz, 0.0, -sz);
+        
+        renderer.vb.add_texel2f (1.0, 0.0);
+        renderer.vb.add_vertex3f (sz, 0.0, -sz);
+        
+        renderer.vb.add_texel2f (1.0, 1.0);
+        renderer.vb.add_vertex3f (sz, 0.0, sz);
+      };
+      
+      renderer.blending.disable;
+      
+      /////
+      //     renderer.disable_lighting;  
+      
+      // render selected squares
+      camera.is_traveling.if_false {
+        gamestate.piece_selected.if {
+          gamestate.current_piece.check_move (gamestate.move_orig) to current_square.if {
+            // move ok
+            current_square.render renderer color move_ok_color;
+          } else {
+            current_square.render renderer color illegal_move_color;
+          };
+        } else {
+          current_square.render renderer color current_color;
+        };
+        gamestate.piece_selected.if {
+          gamestate.move_orig.render renderer color selection_color;
+        };
+      };
+    };
+    
+    x := renderer.width / 2 - 50;
+    renderer.font.print_zone {
+      out.print "3D Chess Game" at (x,50);
+      
+      (gamestate.current_piece != NULL).if {
+        out.print ("this is "+gamestate.current_piece.name+gamestate.current_piece.player.to_string) at (x,500);
+      } else {
+        out.print "Pick up a piece" at (x,500);
+      };
+    };
+  );
+  
+  - render_shadows_and_reflections sz:INTEGER <-
+  (
+    //
+    // First pass: draw an invisible mask of the floor in the stencil buffer
+    //
+    
+    // disable drawing in color buffer
+    renderer.color_buffer.disable;
+    
+    renderer.stencil_buffer.clear;
+    renderer.stencil_buffer.enable;
+    
+    // stencil test always pass and set stencil value to 1 
+    renderer.stencil_buffer.set_function (renderer.stencil_buffer.always) value 1 mask 1;
+    
+    // if test successful replace stencil value else keep the old value
+    renderer.stencil_buffer.when_pass (renderer.stencil_buffer.replace) when_fail (renderer.stencil_buffer.keep) when_zfail (renderer.stencil_buffer.keep);
+    
+    renderer.depth_buffer.disable;
+    
+    // render board in stencil buffer
+    renderer.vb.new_quads {  
+      renderer.vb.add_vertex3f (-sz, 0.0, sz);
+      renderer.vb.add_vertex3f (-sz, 0.0, -sz);
+      renderer.vb.add_vertex3f (sz, 0.0, -sz);
+      renderer.vb.add_vertex3f (sz, 0.0, sz);
+    };
+    
+    // back to color mode
+    renderer.depth_buffer.enable;
+    renderer.color_buffer.enable;
+    
+    //
+    // Second pass: draw reflections & shadows in the masked floor (stencil test enabled)
+    //
+    
+    // only draw pixels masked with 1 in stencil buffer
+    renderer.stencil_buffer.set_function (renderer.stencil_buffer.equal) value 1 mask 1;
+    renderer.stencil_buffer.lock; // read-only
+    
+    ////
+    render_reflections;
+    render_shadows;
+    ///
+    
+    // back to normal mode
+    renderer.stencil_buffer.disable;
+    renderer.depth_buffer.enable;
+  );
+  
+  - render_reflections <-
+  (
+    renderer.transform.new_matrix {
+      
+      // mirror y axis
+      renderer.transform.scalef (1.0, -1.0, 1.0);
+      
+      // draw reflections
+      0.to 15 do { i:INTEGER;
+        p1.item i.render renderer;
+        p2.item i.render renderer;
+      };
+    };
+  );
+  
+  - render_shadows <-
+  (
+    + dot:REAL_32;
+    
+    renderer.depth_buffer.disable;
+    
+    //
+    // build a shadow matrix from light position & shadow plane
+    //
+    
+    // dot product between shadow plane & light_position
+    dot := shadow_plane.a * light_pos.x + shadow_plane.b * light_pos.y + shadow_plane.c * light_pos.z + shadow_plane.d;
+    
+    // first column
+    shadow_matrix.put (dot - light_pos.x * shadow_plane.a) to (0,0);
+    shadow_matrix.put (0.0 - light_pos.x * shadow_plane.b) to (1,0);
+    shadow_matrix.put (0.0 - light_pos.x * shadow_plane.c) to (2,0);
+    shadow_matrix.put (0.0 - light_pos.x * shadow_plane.d) to (3,0);
+    
+    // second column
+    shadow_matrix.put (0.0 - light_pos.y * shadow_plane.a) to (0,1);
+    shadow_matrix.put (dot - light_pos.y * shadow_plane.b) to (1,1);
+    shadow_matrix.put (0.0 - light_pos.y * shadow_plane.c) to (2,1);
+    shadow_matrix.put (0.0 - light_pos.y * shadow_plane.d) to (3,1);
+    
+    // third column
+    shadow_matrix.put (0.0 - light_pos.z * shadow_plane.a) to (0,2);
+    shadow_matrix.put (0.0 - light_pos.z * shadow_plane.b) to (1,2);
+    shadow_matrix.put (dot - light_pos.z * shadow_plane.c) to (2,2);
+    shadow_matrix.put (0.0 - light_pos.z * shadow_plane.d) to (3,2);
+    
+    // fourth column
+    shadow_matrix.put (0.0 - shadow_plane.a) to (0,3);
+    shadow_matrix.put (0.0 - shadow_plane.b) to (1,3);
+    shadow_matrix.put (0.0 - shadow_plane.c) to (2,3);
+    shadow_matrix.put (dot - shadow_plane.d) to (3,3);
+    
+    // shadow color (dark)
+    renderer.color_buffer.set_color3f (0, 0, 0);
+    renderer.texture2d.disable;
+    
+    renderer.transform.new_matrix {
+      
+      // set OpenGL modelview matrix in shadow space
+      renderer.transform.mult_matrix_by shadow_matrix;
+      
+      // draw shadows
+      0.to 15 do { i:INTEGER;
+        p1.item i.render renderer;
+        p2.item i.render renderer;
+      };
+    };
+    renderer.color_buffer.set_color3f (1, 1, 1);
+    renderer.texture2d.enable;
+  );
+  
+  //
+  // Selection.
+  //
+  
+  - hits:FAST_ARRAY[UINTEGER_32] := FAST_ARRAY[UINTEGER_32].create 512;
+  
+  - select_piece (x,y:UINTEGER_32) :PIECE <-
+  // selection from camera view vector
+  (
+    + nb_hits:INTEGER;
+    + choose,depth:UINTEGER_32;
+    + v:VIEWPORT;
+    + result:PIECE;
+    
+    v := renderer.viewport;
+    
+    // start selection mode, hits are recorded in 'hits' array
+    renderer.begin_selection_in hits size 512;
+    
+    // restrict the viewing volume to the mouse click region
+    renderer.transform.new_projection {
+      renderer.transform.push_matrix;
+      renderer.transform.load_identity;
+      
+      // create 5x5 pixel picking region near cursor location 
+      renderer.transform.pickmatrix (x, v.height - y, 5, 5) in v;
+      
+      // multiply it the viewing volume matrix
+      renderer.transform.perspective (renderer.fov, (v.width-v.x0).to_real/(v.height-v.y0).to_real, 0.1, 5000);
+    };
+    
+    // initialize the name stack
+    renderer.name_stack.init;
+    renderer.name_stack.push (-1);// not to have an empty stack
+    
+    // draw pieces in selection buffer
+    0.to 15 do { i:INTEGER;
+      renderer.name_stack.load (p1.item i.id);
+      p1.item i.render renderer;
+      
+      renderer.name_stack.load (p2.item i.id);
+      p2.item i.render renderer;
+    };
+    
+    // go back to previous projection
+    renderer.transform.new_projection {
+      renderer.transform.pop_matrix;
+    };
+    
+    // go back to render mode 
+    nb_hits := renderer.end_selection;
+    
+    //
+    //  Buffer format:
+    //    for each hit:
+    //       0:  number of names for this hit
+    //       1:  z-min value of the hit
+    //       2:  z-max value of the hit
+    //       3:  content of the name stack (bottom of stack)
+    //       ...
+    
+    // choose the closest object hit
+    (nb_hits > 0).if {
+      choose := hits.item 3;
+      depth := hits.item 1;
+      
+      1.to (nb_hits-1) do { i:INTEGER;
+        (hits.item (i*4+1) < depth).if { // here the name stack has 1 elt
+          choose := hits.item (i*4+3);
+          depth := hits.item (i*4+1);
+        };
+      };
+      result := get_piece_from choose;
+    };
+    result
+  );
+  
+  - select_square (x,y:UINTEGER_32) :SQUARE <-
+  // selection from camera view vector
+  ( + result:SQUARE;
+    + target:VECTOR3[REAL_32];
+    + fraction,start_dist,end_dist,start_frac,end_frac,epsilon:REAL_32;
+    + x_col,z_col:REAL_32;
+    + px,py:INTEGER;
+    
+    // create ray from camera eye in world space
+    
+    // camera.view.set_y (camera.view.y + 0.05); // bug fix..
+    target := camera.position + (camera.view * 1000);
+    //   camera.view.set_y (camera.view.y - 0.05); // big fix..
+    
+    epsilon := 0.325;
+    start_frac := -1.0;
+    end_frac := 1.0;
+    
+    // check collision: ray vs board plane (XZ plane, normal=(0,1,0))
+    start_dist := camera.position.y; // a*x+b*y+c*z-d
+    end_dist := target.y;
+    
+    ((start_dist > 0) && {end_dist > 0}).if_false {
+      // else ray is not colliding
+      
+      (start_dist > end_dist).if {
+        fraction := (start_dist - epsilon) / (start_dist - end_dist);
+        (fraction > start_frac).if {
+          start_frac := fraction;
+        };
+      } else {
+        fraction := (start_dist + epsilon) / (start_dist - end_dist);
+        (fraction < end_frac).if {
+          end_frac := fraction;
+        };
+      };
+      (
+        (start_frac < end_frac) && 
+        {start_frac > -1.0} &&
+        {start_frac < 1.0}
+      ).if {
+        // collision
+        
+        fraction := start_frac;
+        (fraction < 0).if {
+          fraction := 0;
+        };
+        x_col := camera.position.x + (target.x-camera.position.x) * fraction;
+        z_col := camera.position.z + (target.z-camera.position.z) * fraction;
+        
+        x_col := (4.0*square_size-x_col) / square_size; // to board space
+        z_col := (z_col+4.0*square_size) / square_size; // to board space
+        
+        px := x_col.to_integer;
+        (px < 0).if {
+          px := 0;
+        };
+        py := z_col.to_integer;
+        (py < 0).if {
+          py := 0;
+        };
+        result := SQUARE.create (px, py);
+      };
+    };
+    
+    result
+  );
+  
+  - get_piece_from id:UINTEGER_32 :PIECE <-
+  ( + result:PIECE;
+    ((id & 01h) = 0).if {
+      // player 1
+      result := p1.item (id >> 1);
+    } else {
+      // player 2     
+      result := p2.item (id >> 1);
+    };
+    result
+  );
+  
+  - release <-
+  (
+    (current_world != NULL).if {
+      current_world.release;
+    };
+    (light_shader != NULL).if {
+      light_shader.delete;
+    };
+  );
+  
+  - set_world w:SCENE <-
+  (
+    (current_world != NULL).if {
+      current_world.release; 
+    };
+    
+    w.set_renderer renderer;
+    current_world := w;
+    
+    current_world.initialize;
+  );
+  
+  //
+  // Input.
+  //
+  
+  - keydown k:INTEGER <-
+  (
+     (k = KEYCODE.k_escape).if {
+	FRAMEWORK.stop;
+     };
+  );
+  
+  - click b:INTEGER <-
+  ( + x,y:UINTEGER_32;
+    + piece:PIECE;
+    + square:SQUARE;
+    
+    camera.is_traveling.if_false {
+      
+      x := event.mouse_x;
+      y := event.mouse_y;
+      
+      piece := select_piece (x,y);
+      (piece != NULL).if {
+        square := piece.square;
+      } else {
+        square := select_square (x,y);
+      };
+      
+      // update game
+      gamestate.update square;
+    };
+  );
+  
+  - move (x,y:INTEGER) <-
+  ( 
+    camera.is_traveling.if_false {
+      current_square := select_square (x,y);
+    };
+  );
+  
+  
+  - on_resize (w,h:INTEGER) <-
+  // world projection
+  (
+    + ratio:REAL_32;
+    
+    ratio := renderer.width / renderer.height;
+    
+    renderer.transform.new_projection {
+      renderer.transform.load_identity;
+      
+      renderer.transform.perspective (renderer.fov, w.to_real/h.to_real, 0.1, 5000.0);
+    };
+    // clear modelview matrix
+    renderer.transform.load_identity;
+  );
diff --git a/chess/chesscam.li b/chess/chesscam.li
index 2f48b8d..e18d29b 100644
--- a/chess/chesscam.li
+++ b/chess/chesscam.li
@@ -1,96 +1,96 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := CHESSCAM;
-  
-  - comment   := "camera";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_camera:Expanded CAMERA;
-  
-Section Public
-  
-  - waypoints:LINKED_LIST[VECTOR3[REAL_32]] := LINKED_LIST[VECTOR3[REAL_32]].create;
-  - lerp:REAL_32;
-  
-  
-  - is_traveling:BOOLEAN <- waypoints.count > 0;
-  
-  
-  - add_waypoint p:VECTOR3[REAL_32] <-
-  (
-    waypoints.add_last p;
-  );
-  
-  - add_waypoint3f (x,y,z:REAL_32) <-
-  (
-    waypoints.add_last (VECTOR3[REAL_32].create (x, y, z));
-  );
-  
-  - animate t:UINTEGER_32 <-
-  (
-    + u,v:VECTOR3[REAL_32];
-    
-    waypoints.is_empty.if {
-      update_with_mouse;
-      update_with_keys t;
-      
-    }.elseif {waypoints.count < 4} then {
-      waypoints.clear;
-      INPUT_SYSTEM.warp_mouse (screen_width>>1,screen_height>>1);
-      
-      // 'repair' camera after travelling
-      right := (view.cross std_up).normalized;
-      (view.z > 0).if {
-        up.make (view.x, view.z, -view.y); // 90 deg rotation
-      } else {
-        up.make (view.x, -view.z, view.y); // 90 deg rotation
-      };
-      
-    } else {
-      u := waypoints.first;
-      v := waypoints.item (waypoints.lower+2);
-      
-      // linear interpolation
-      position := u + ((v - u) * lerp);
-      
-      u := waypoints.item (waypoints.lower+1);
-      v := waypoints.item (waypoints.lower+3);
-      
-      // linear interpolation
-      view := ((u + ((v - u) * lerp)) - position).normalized;
-      
-      lerp := lerp + t.to_real*0.001;
-      (lerp >= 1.0).if {
-        lerp := 0.0;
-        waypoints.remove_first;
-        waypoints.remove_first;
-      };
-    };
-  );
-  
-  - std_up:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0,1,0);
-  
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := CHESSCAM;
+  
+  - comment   := "camera";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_camera:Expanded CAMERA;
+  
+Section Public
+  
+  - waypoints:LINKED_LIST[VECTOR3[REAL_32]] := LINKED_LIST[VECTOR3[REAL_32]].create;
+  - lerp:REAL_32;
+  
+  
+  - is_traveling:BOOLEAN <- waypoints.count > 0;
+  
+  
+  - add_waypoint p:VECTOR3[REAL_32] <-
+  (
+    waypoints.add_last p;
+  );
+  
+  - add_waypoint3f (x,y,z:REAL_32) <-
+  (
+    waypoints.add_last (VECTOR3[REAL_32].create (x, y, z));
+  );
+  
+  - animate t:REAL_32 <-
+  (
+    + u,v:VECTOR3[REAL_32];
+    
+    waypoints.is_empty.if {
+      update_with_mouse;
+      update_with_keys t;
+      
+    }.elseif {waypoints.count < 4} then {
+      waypoints.clear;
+      FRAMEWORK.event.warp_mouse (screen_width>>1,screen_height>>1);
+      
+      // 'repair' camera after travelling
+      right := (view.cross std_up).normalized;
+      (view.z > 0).if {
+        up.make (view.x, view.z, -view.y); // 90 deg rotation
+      } else {
+        up.make (view.x, -view.z, view.y); // 90 deg rotation
+      };
+      
+    } else {
+      u := waypoints.first;
+      v := waypoints.item (waypoints.lower+2);
+      
+      // linear interpolation
+      position := u + ((v - u) * lerp);
+      
+      u := waypoints.item (waypoints.lower+1);
+      v := waypoints.item (waypoints.lower+3);
+      
+      // linear interpolation
+      view := ((u + ((v - u) * lerp)) - position).normalized;
+      
+      lerp := lerp + t*0.5;
+      (lerp >= 1.0).if {
+        lerp := 0.0;
+        waypoints.remove_first;
+        waypoints.remove_first;
+      };
+    };
+  );
+  
+  - std_up:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0,1,0);
+  
diff --git a/chess/gamestate.li b/chess/gamestate.li
index 4fe7bfb..dff3721 100644
--- a/chess/gamestate.li
+++ b/chess/gamestate.li
@@ -1,201 +1,201 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := GAMESTATE;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  - parent_object:OBJECT := OBJECT;
-  
-Section Public  
-  
-  //
-  // Game states.
-  // 0:  player 1 select a piece
-  // 1:  player 1 select a square destination
-  // 2:  move
-  // 3:  player 2 select a piece
-  // 4:  player 2 select a square destination
-  // 5:  move
-  - state:INTEGER;
-  
-  - move_orig:SQUARE;
-  - move_dest:SQUARE;
-  
-  
-  - current_piece:PIECE <-
-  ( + result:PIECE;
-    
-    piece_selected.if {
-      result := move_orig.piece
-    };
-    result
-  );
-  
-  - current_player:INTEGER <- 
-  ( + result:INTEGER;
-    ((state < 2) || {state = 5}).if {
-      result := 1;
-    } else {
-      result := 2;
-    };
-    result
-  );
-  
-  - piece_selected:BOOLEAN <- (state = 1) || {state = 4};
-  
-  - is_moving:BOOLEAN <- (state = 2) || {state = 5};
-  
-  - capture:BOOLEAN;// true when current piece captures 
-  
-  
-  - play <-
-  ( 
-    + sign:REAL_32;// +1 or -1
-    
-    ((state = 2) || {state = 5}).if {
-      // animate move
-      
-      CHESS.camera.is_traveling.if_false {
-        // not already moving
-        
-        (current_player = 1).if {
-          sign := 1;
-        } else {
-          sign := -1;
-        };
-        
-        // first point
-        CHESS.camera.add_waypoint (CHESS.camera.position);
-        CHESS.camera.add_waypoint (CHESS.camera.view);
-        
-        (ENGINE.random & 11b)
-        .when 0 then {
-          // rotate over the chessboard
-          
-          CHESS.camera.add_waypoint3f (0,250,0);
-          CHESS.camera.add_waypoint3f (0, 0, 0); 
-          
-        }.when 1 then {
-          // turn around the chessboard
-          
-          CHESS.camera.add_waypoint3f (200,200,0);
-          CHESS.camera.add_waypoint3f (0, 0, 0); 
-          
-        }.when 2 then {
-          // jump over the chessboard
-          
-          CHESS.camera.add_waypoint3f (0,500,0);
-          CHESS.camera.add_waypoint3f (0, 50, sign*10);
-          
-        }.when 3 then {
-          // walk on the chessboard
-          
-          CHESS.camera.add_waypoint3f (0,80,0);
-          CHESS.camera.add_waypoint3f (0, 50, sign*100);
-        };      
-        
-        // last point
-        CHESS.camera.add_waypoint3f (0,200,sign*300);
-        CHESS.camera.add_waypoint3f (0, 0, 0);
-      };
-    };
-  );
-  
-  - update square:SQUARE <-
-  (
-    ((state = 0) || {state = 3}).if {
-      // start move
-      
-      ((square.piece != NULL) && {square.piece.player = current_player}).if {
-        move_orig := square; 
-        
-        // go to next state
-        update_state;   
-      };
-    }.elseif {(state = 1) || {state = 4}} then {
-      // finish move
-      
-      move_dest := square;
-      
-      // update game state
-      do_move.if {
-        
-        // go to next state
-        update_state;   
-      } else {
-        state := state - 1; // try again
-      };
-    };
-  );
-  
-  - change_player <-
-  // go to new game cycle
-  (
-    update_state;
-    reset_capture;
-  );
-  
-  - update_state <-
-  (
-    state := (state + 1) % 6;
-  );
-  
-  - reset_capture <-
-  (
-    capture := FALSE;
-  );
-  
-Section Private
-  
-  - do_move:BOOLEAN <-
-  // move orig piece to dest square if allowed
-  ( + piece:PIECE;
-    + result:BOOLEAN;
-    
-    piece := current_piece;
-    
-    piece.check_move move_orig to move_dest.if {
-      // move ok
-      
-      capture := move_dest.piece != NULL; 
-      capture.if {
-        move_dest.piece.capture;
-      };
-      
-      move_orig.clear;
-      move_dest.set_piece piece;
-      
-      piece.set_square move_dest;
-      
-      result := TRUE;
-    };
-    
-    result
-  );
-  
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := GAMESTATE;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  - parent_object:OBJECT := OBJECT;
+  
+Section Public  
+  
+  //
+  // Game states.
+  // 0:  player 1 select a piece
+  // 1:  player 1 select a square destination
+  // 2:  move
+  // 3:  player 2 select a piece
+  // 4:  player 2 select a square destination
+  // 5:  move
+  - state:INTEGER;
+  
+  - move_orig:SQUARE;
+  - move_dest:SQUARE;
+  
+  
+  - current_piece:PIECE <-
+  ( + result:PIECE;
+    
+    piece_selected.if {
+      result := move_orig.piece
+    };
+    result
+  );
+  
+  - current_player:INTEGER <- 
+  ( + result:INTEGER;
+    ((state < 2) || {state = 5}).if {
+      result := 1;
+    } else {
+      result := 2;
+    };
+    result
+  );
+  
+  - piece_selected:BOOLEAN <- (state = 1) || {state = 4};
+  
+  - is_moving:BOOLEAN <- (state = 2) || {state = 5};
+  
+  - capture:BOOLEAN;// true when current piece captures 
+  
+  
+  - play <-
+  ( 
+    + sign:REAL_32;// +1 or -1
+    
+    ((state = 2) || {state = 5}).if {
+      // animate move
+      
+      CHESS.camera.is_traveling.if_false {
+        // not already moving
+        
+        (current_player = 1).if {
+          sign := 1;
+        } else {
+          sign := -1;
+        };
+        
+        // first point
+        CHESS.camera.add_waypoint (CHESS.camera.position);
+        CHESS.camera.add_waypoint (CHESS.camera.view);
+        
+        (FRAMEWORK.random & 11b)
+        .when 0 then {
+          // rotate over the chessboard
+          
+          CHESS.camera.add_waypoint3f (0,250,0);
+          CHESS.camera.add_waypoint3f (0, 0, 0); 
+          
+        }.when 1 then {
+          // turn around the chessboard
+          
+          CHESS.camera.add_waypoint3f (200,200,0);
+          CHESS.camera.add_waypoint3f (0, 0, 0); 
+          
+        }.when 2 then {
+          // jump over the chessboard
+          
+          CHESS.camera.add_waypoint3f (0,500,0);
+          CHESS.camera.add_waypoint3f (0, 50, sign*10);
+          
+        }.when 3 then {
+          // walk on the chessboard
+          
+          CHESS.camera.add_waypoint3f (0,80,0);
+          CHESS.camera.add_waypoint3f (0, 50, sign*100);
+        };      
+        
+        // last point
+        CHESS.camera.add_waypoint3f (0,200,sign*300);
+        CHESS.camera.add_waypoint3f (0, 0, 0);
+      };
+    };
+  );
+  
+  - update square:SQUARE <-
+  (
+    ((state = 0) || {state = 3}).if {
+      // start move
+      
+      ((square.piece != NULL) && {square.piece.player = current_player}).if {
+        move_orig := square; 
+        
+        // go to next state
+        update_state;   
+      };
+    }.elseif {(state = 1) || {state = 4}} then {
+      // finish move
+      
+      move_dest := square;
+      
+      // update game state
+      do_move.if {
+        
+        // go to next state
+        update_state;   
+      } else {
+        state := state - 1; // try again
+      };
+    };
+  );
+  
+  - change_player <-
+  // go to new game cycle
+  (
+    update_state;
+    reset_capture;
+  );
+  
+  - update_state <-
+  (
+    state := (state + 1) % 6;
+  );
+  
+  - reset_capture <-
+  (
+    capture := FALSE;
+  );
+  
+Section Private
+  
+  - do_move:BOOLEAN <-
+  // move orig piece to dest square if allowed
+  ( + piece:PIECE;
+    + result:BOOLEAN;
+    
+    piece := current_piece;
+    
+    piece.check_move move_orig to move_dest.if {
+      // move ok
+      
+      capture := move_dest.piece != NULL; 
+      capture.if {
+        move_dest.piece.capture;
+      };
+      
+      move_orig.clear;
+      move_dest.set_piece piece;
+      
+      piece.set_square move_dest;
+      
+      result := TRUE;
+    };
+    
+    result
+  );
+  
   
\ No newline at end of file
diff --git a/chess/king.li b/chess/king.li
index e1e32f9..30810b2 100644
--- a/chess/king.li
+++ b/chess/king.li
@@ -1,49 +1,49 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := KING;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_piece:Expanded PIECE;
-  
-Section Public
-  
-  - name:STRING_CONSTANT := "king";
-  
-  - model:MODEL; // shared model
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
-  // is legal move?
-  ( + result:BOOLEAN;
-    
-    ((dest.piece = NULL) || {player != dest.piece.player}).if {
-      result := ((dest.x - orig.x).abs <= 1) && {(dest.y - orig.y).abs <= 1};
-    };
-    result
-  );
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := KING;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_piece:Expanded PIECE;
+  
+Section Public
+  
+  - name:STRING_CONSTANT := "king";
+  
+  - model:MODEL; // shared model
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
+  // is legal move?
+  ( + result:BOOLEAN;
+    
+    ((dest.piece = NULL) || {player != dest.piece.player}).if {
+      result := ((dest.x - orig.x).abs <= 1) && {(dest.y - orig.y).abs <= 1};
+    };
+    result
+  );
   
\ No newline at end of file
diff --git a/chess/knight.li b/chess/knight.li
index 956c0ae..1f14e1d 100644
--- a/chess/knight.li
+++ b/chess/knight.li
@@ -1,50 +1,50 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := KNIGHT;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_piece:Expanded PIECE;
-  
-Section Public
-  
-  - name:STRING_CONSTANT := "knight";
-  
-  - model:MODEL; // shared model
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
-  // is legal move?
-  ( + result:BOOLEAN;
-    
-    ((dest.piece = NULL) || {player != dest.piece.player}).if {
-      result := ((orig.x - dest.x).abs - (orig.y - dest.y).abs).abs = 1;
-    };
-    result
-  );
-  
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := KNIGHT;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_piece:Expanded PIECE;
+  
+Section Public
+  
+  - name:STRING_CONSTANT := "knight";
+  
+  - model:MODEL; // shared model
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
+  // is legal move?
+  ( + result:BOOLEAN;
+    
+    ((dest.piece = NULL) || {player != dest.piece.player}).if {
+      result := ((orig.x - dest.x).abs - (orig.y - dest.y).abs).abs = 1;
+    };
+    result
+  );
+  
   
\ No newline at end of file
diff --git a/chess/pawn.li b/chess/pawn.li
index a19c00e..010597e 100644
--- a/chess/pawn.li
+++ b/chess/pawn.li
@@ -1,66 +1,66 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := PAWN;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_piece:Expanded PIECE;
-  
-Section Public
-  
-  - name:STRING_CONSTANT := "pawn";
-  
-  - model:MODEL; // shared model
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
-  // is legal move?
-  ( + result:BOOLEAN;
-    
-    (dest.piece = NULL).if {
-      // no capture
-      
-      (orig.x = dest.x).if {
-        (player = 2).if {
-          result := (dest.y = orig.y+1) || {(orig.y = 1) && {dest.y = 3}};
-        } else {
-          result := (dest.y = orig.y-1) || {(orig.y = 6) && {dest.y = 4}};
-        };
-      };
-    }.elseif {player != dest.piece.player} then {
-      // capture
-      
-      (player = 2).if {
-        result := (dest.y = orig.y+1) && {(orig.x - dest.x).abs = 1};
-      } else {
-        result := (dest.y = orig.y-1) && {(orig.x - dest.x).abs = 1};
-      };
-    };
-    
-    result
-  );
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := PAWN;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_piece:Expanded PIECE;
+  
+Section Public
+  
+  - name:STRING_CONSTANT := "pawn";
+  
+  - model:MODEL; // shared model
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
+  // is legal move?
+  ( + result:BOOLEAN;
+    
+    (dest.piece = NULL).if {
+      // no capture
+      
+      (orig.x = dest.x).if {
+        (player = 2).if {
+          result := (dest.y = orig.y+1) || {(orig.y = 1) && {dest.y = 3}};
+        } else {
+          result := (dest.y = orig.y-1) || {(orig.y = 6) && {dest.y = 4}};
+        };
+      };
+    }.elseif {player != dest.piece.player} then {
+      // capture
+      
+      (player = 2).if {
+        result := (dest.y = orig.y+1) && {(orig.x - dest.x).abs = 1};
+      } else {
+        result := (dest.y = orig.y-1) && {(orig.x - dest.x).abs = 1};
+      };
+    };
+    
+    result
+  );
   
\ No newline at end of file
diff --git a/chess/piece.li b/chess/piece.li
index b7d32ad..a9bcb9d 100644
--- a/chess/piece.li
+++ b/chess/piece.li
@@ -1,208 +1,208 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := PIECE;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  - parent_object:OBJECT := OBJECT;
-  
-Section Public
-  
-  + id:INTEGER; // for selection stack
-  - player:INTEGER <- (id & 01h) + 1; // 1 or 2
-  
-  + square:SQUARE; // position in chessboard
-  
-  + height:REAL_32; // lift position
-  
-  + is_captured:BOOLEAN;
-  
-  
-  
-  - name:STRING_CONSTANT;
-  - model:MODEL <- deferred;
-  
-  - move_lerp:REAL_32;
-  
-  
-  - is_black:BOOLEAN <- player = 1;
-  - is_white:BOOLEAN <- player = 2;
-  
-  //
-  // Creation.
-  //
-  
-  - create (px,py,player:INTEGER) index i:INTEGER :SELF <-
-  ( + result:SELF;
-    result := SELF.clone;
-    result.make (px,py,player,i);
-    result
-  );
-  
-  - make (px,py,pl,i:INTEGER) <- 
-  (  
-    square := SQUARE.create (px,py);
-    id := (i << 1) | (pl-1);
-    
-    // shared model for each type of piece
-    (model = NULL).if {
-      model := MD2_MODEL.create ("models/"+name+".md2");
-    };
-  ); 
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <- deferred;
-  
-  - render r:RENDERER <-
-  (      
-    + texture:TEXTURE;
-    + x,y:REAL_32;
-    + sz:INTEGER;
-    
-    is_captured.if_false {
-      
-      // (x,y) := square.position; // compilo bug
-      x := square.x;
-      y := square.y;
-      
-      sz := CHESS.square_size;
-      
-      r.transform.new_matrix {
-        
-        // translate to origin of board
-        r.transform.translatef (3*CHESS.square_size+CHESS.square_size/2, 0, -3*CHESS.square_size-CHESS.square_size/2);
-        
-        (CHESS.gamestate.is_moving && {CHESS.gamestate.move_dest.piece = Self}).if {
-          // piece is moving
-          
-          x := (x - CHESS.gamestate.move_orig.x).to_real * move_lerp + CHESS.gamestate.move_orig.x;
-          y := (y - CHESS.gamestate.move_orig.y).to_real * move_lerp + CHESS.gamestate.move_orig.y;
-        };
-        // translate to square
-        r.transform.translatef (-x*CHESS.square_size, height, y*CHESS.square_size);       
-        
-        is_black.if {
-          texture := CHESS.black_texture;
-        } else {
-          texture := CHESS.white_texture;
-        };
-        
-        // quake2 z axis is opengl y axis 
-        r.transform.rotatef(-90, 1,0,0);
-        r.transform.rotatef(90, 0,0,1);
-        
-        model.render_with texture;
-      };
-    };
-  );
-  
-  - update_selected t:REAL_32 <-
-  (
-    (height < 10).if {
-      height := height + t;
-    };
-  );
-  
-  - update t:REAL_32 <-
-  (
-    (height != 0).if {
-      height := height - t;
-      (height < 0).if {
-        height := 0;
-      };
-    };
-    (CHESS.gamestate.is_moving && {Self = CHESS.gamestate.move_dest.piece}).if {
-      move_lerp := move_lerp + t*0.05;
-      (move_lerp >= 1.0).if {
-        move_lerp := 0;
-        
-        CHESS.gamestate.change_player; // end of move
-      };
-    };
-  );
-  
-  - capture <-
-  (
-    is_captured := TRUE;
-  );
-  
-  - set_square sq:SQUARE <- square := sq;
-  
-  
-  - set_renderer r:RENDERER at_position sq:SQUARE <-
-  // translate to square
-  ( + x,y:REAL_32;
-    
-    x := sq.x;
-    y := sq.y;
-    r.transform.translatef (3*CHESS.square_size+CHESS.square_size/2, 0, -3*CHESS.square_size-CHESS.square_size/2);
-    
-    r.transform.translatef (-x*CHESS.square_size, 0, y*CHESS.square_size);
-  );
-  
-Section PIECE
-  
-  - check_path_between p1:SQUARE and p2:SQUARE :BOOLEAN <-
-  ( + start,end:SQUARE;
-    + x,y,delta_x,delta_y:INTEGER;
-    + result:BOOLEAN;
-    
-    (p1.x > p2.x).if {
-      start := p2;
-      end := p1;
-    } else {
-      start := p1;
-      end := p2;
-    };
-    (end.x != start.x).if {
-      delta_x := 1;
-    };
-    (end.y != start.y).if {
-      delta_y := (end.y - start.y) / ((end.y - start.y).abs);
-    };
-    
-    x := start.x;
-    y := start.y;
-    result := TRUE;
-    
-    {
-      x := x + delta_x;
-      y := y + delta_y;
-      
-      ((x = end.x) && {y = end.y}).if_false {
-        ((x = start.x) && {y = start.y}).if_false {
-          result := CHESS.chessboard.item (y*8+x) = NULL;
-        };
-      };
-    }.do_while {
-      result &&
-      {(x != end.x) || {y != end.y}} &&
-      {(x != start.x) || {y != start.y}}
-    };
-    result
-  );
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := PIECE;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  - parent_object:OBJECT := OBJECT;
+  
+Section Public
+  
+  + id:INTEGER; // for selection stack
+  - player:INTEGER <- (id & 01h) + 1; // 1 or 2
+  
+  + square:SQUARE; // position in chessboard
+  
+  + height:REAL_32; // lift position
+  
+  + is_captured:BOOLEAN;
+  
+  
+  
+  - name:STRING_CONSTANT;
+  - model:MODEL <- deferred;
+  
+  - move_lerp:REAL_32;
+  
+  
+  - is_black:BOOLEAN <- player = 1;
+  - is_white:BOOLEAN <- player = 2;
+  
+  //
+  // Creation.
+  //
+  
+  - create (px,py,player:INTEGER) index i:INTEGER :SELF <-
+  ( + result:SELF;
+    result := SELF.clone;
+    result.make (px,py,player,i);
+    result
+  );
+  
+  - make (px,py,pl,i:INTEGER) <- 
+  (  
+    square := SQUARE.create (px,py);
+    id := (i << 1) | (pl-1);
+    
+    // shared model for each type of piece
+    (model = NULL).if {
+      model := MD2_MODEL.create ("models/"+name+".md2");
+    };
+  ); 
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <- deferred;
+  
+  - render r:RENDERER <-
+  (      
+    + texture:TEXTURE;
+    + x,y:REAL_32;
+    + sz:INTEGER;
+    
+    is_captured.if_false {
+      
+      // (x,y) := square.position; // compilo bug
+      x := square.x;
+      y := square.y;
+      
+      sz := CHESS.square_size;
+      
+      r.transform.new_matrix {
+        
+        // translate to origin of board
+        r.transform.translatef (3*CHESS.square_size+CHESS.square_size/2, 0, -3*CHESS.square_size-CHESS.square_size/2);
+        
+        (CHESS.gamestate.is_moving && {CHESS.gamestate.move_dest.piece = Self}).if {
+          // piece is moving
+          
+          x := (x - CHESS.gamestate.move_orig.x).to_real * move_lerp + CHESS.gamestate.move_orig.x;
+          y := (y - CHESS.gamestate.move_orig.y).to_real * move_lerp + CHESS.gamestate.move_orig.y;
+        };
+        // translate to square
+        r.transform.translatef (-x*CHESS.square_size, height, y*CHESS.square_size);       
+        
+        is_black.if {
+          texture := CHESS.black_texture;
+        } else {
+          texture := CHESS.white_texture;
+        };
+        
+        // quake2 z axis is opengl y axis 
+        r.transform.rotatef(-90, 1,0,0);
+        r.transform.rotatef(90, 0,0,1);
+        
+        model.render_with texture;
+      };
+    };
+  );
+  
+  - update_selected t:REAL_32 <-
+  (
+    (height < 10).if {
+      height := height + t;
+    };
+  );
+  
+  - update t:REAL_32 <-
+  (
+    (height != 0).if {
+      height := height - t;
+      (height < 0).if {
+        height := 0;
+      };
+    };
+    (CHESS.gamestate.is_moving && {Self = CHESS.gamestate.move_dest.piece}).if {
+      move_lerp := move_lerp + t*0.05;
+      (move_lerp >= 1.0).if {
+        move_lerp := 0;
+        
+        CHESS.gamestate.change_player; // end of move
+      };
+    };
+  );
+  
+  - capture <-
+  (
+    is_captured := TRUE;
+  );
+  
+  - set_square sq:SQUARE <- square := sq;
+  
+  
+  - set_renderer r:RENDERER at_position sq:SQUARE <-
+  // translate to square
+  ( + x,y:REAL_32;
+    
+    x := sq.x;
+    y := sq.y;
+    r.transform.translatef (3*CHESS.square_size+CHESS.square_size/2, 0, -3*CHESS.square_size-CHESS.square_size/2);
+    
+    r.transform.translatef (-x*CHESS.square_size, 0, y*CHESS.square_size);
+  );
+  
+Section PIECE
+  
+  - check_path_between p1:SQUARE and p2:SQUARE :BOOLEAN <-
+  ( + start,end:SQUARE;
+    + x,y,delta_x,delta_y:INTEGER;
+    + result:BOOLEAN;
+    
+    (p1.x > p2.x).if {
+      start := p2;
+      end := p1;
+    } else {
+      start := p1;
+      end := p2;
+    };
+    (end.x != start.x).if {
+      delta_x := 1;
+    };
+    (end.y != start.y).if {
+      delta_y := (end.y - start.y) / ((end.y - start.y).abs);
+    };
+    
+    x := start.x;
+    y := start.y;
+    result := TRUE;
+    
+    {
+      x := x + delta_x;
+      y := y + delta_y;
+      
+      ((x = end.x) && {y = end.y}).if_false {
+        ((x = start.x) && {y = start.y}).if_false {
+          result := CHESS.chessboard.item (y*8+x) = NULL;
+        };
+      };
+    }.do_while {
+      result &&
+      {(x != end.x) || {y != end.y}} &&
+      {(x != start.x) || {y != start.y}}
+    };
+    result
+  );
   
\ No newline at end of file
diff --git a/chess/queen.li b/chess/queen.li
index d966242..fa3b6e6 100644
--- a/chess/queen.li
+++ b/chess/queen.li
@@ -1,51 +1,51 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := QUEEN;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_piece:Expanded PIECE;
-  
-Section Public
-  
-  - name:STRING_CONSTANT := "queen";
-  
-  - model:MODEL; // shared model
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
-  // is legal move?
-  ( + result:BOOLEAN;
-    
-    ((dest.piece = NULL) || {player != dest.piece.player}).if {
-      result := BISHOP.check_move orig to dest;
-      result.if_false {
-        result := ROOK.check_move orig to dest;
-      };
-    };
-    result
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := QUEEN;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_piece:Expanded PIECE;
+  
+Section Public
+  
+  - name:STRING_CONSTANT := "queen";
+  
+  - model:MODEL; // shared model
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
+  // is legal move?
+  ( + result:BOOLEAN;
+    
+    ((dest.piece = NULL) || {player != dest.piece.player}).if {
+      result := BISHOP.check_move orig to dest;
+      result.if_false {
+        result := ROOK.check_move orig to dest;
+      };
+    };
+    result
   );
\ No newline at end of file
diff --git a/chess/rook.li b/chess/rook.li
index dbf5ca4..a1a19fd 100644
--- a/chess/rook.li
+++ b/chess/rook.li
@@ -1,50 +1,50 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := ROOK;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  + parent_piece:Expanded PIECE;
-  
-Section Public
-  
-  - name:STRING_CONSTANT := "rook";
-  
-  - model:MODEL; // shared model
-  
-  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
-  // is legal move?
-  ( + result:BOOLEAN;   
-    
-    ((dest.piece = NULL) || {player != dest.piece.player}).if {
-      ((orig.x = dest.x) || {orig.y = dest.y}).if {
-        result := check_path_between orig and dest;
-      };    
-    };
-    result
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := ROOK;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  + parent_piece:Expanded PIECE;
+  
+Section Public
+  
+  - name:STRING_CONSTANT := "rook";
+  
+  - model:MODEL; // shared model
+  
+  - check_move orig:SQUARE to dest:SQUARE :BOOLEAN <-
+  // is legal move?
+  ( + result:BOOLEAN;   
+    
+    ((dest.piece = NULL) || {player != dest.piece.player}).if {
+      ((orig.x = dest.x) || {orig.y = dest.y}).if {
+        result := check_path_between orig and dest;
+      };    
+    };
+    result
   );
\ No newline at end of file
diff --git a/chess/square.li b/chess/square.li
index 616d609..5b654a3 100644
--- a/chess/square.li
+++ b/chess/square.li
@@ -1,122 +1,122 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := Expanded SQUARE;
-  
-  - comment   := "3D Chess Game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-  - comment     := "square position on chessboard";
-  
-  - type        := `unsigned int`;
-  - default     := ( CONVERT[INTEGER,SQUARE].on 0 );
-  
-Section Insert
-  
-  - parent_object:OBJECT := OBJECT;
-  
-Section Public
-  
-  - value:UINTEGER_32 <- CONVERT[SQUARE,UINTEGER_32].on Self;
-  
-  //
-  // Creation.
-  //
-  
-  - create (x,y:INTEGER) :SQUARE <-
-  ( + cod:UINTEGER_32;
-    ? {x.in_range 0 to 7};
-    ? {y.in_range 0 to 7};
-    
-    cod := y*8 + x;
-    CONVERT[UINTEGER_32,SQUARE].on cod
-  );
-  
-  //
-  // Content
-  //
-  
-  - piece:PIECE <- 
-  (
-    CHESS.chessboard.item value
-  );
-  
-  - set_piece p:PIECE <- 
-  (
-    CHESS.chessboard.put p to value;
-  );
-  
-  - clear <-
-  (
-    set_piece NULL;
-  );
-  
-  
-  - position:(INTEGER,INTEGER) <-
-  (
-    (value % 8, value / 8)
-  );
-  
-  - x:INTEGER <- value % 8;
-  - y:INTEGER <- value / 8;
-  
-  
-  - render r:RENDERER color col:COLOR <-
-  ( + x,y,sz:INTEGER;
-    
-    (x,y) := position;
-    sz := CHESS.square_size/2;
-    
-    ((x < 8) && {y < 8}).if {
-      r.transform.new_matrix {
-        
-        r.transform.translatef (3*CHESS.square_size+CHESS.square_size/2, 0, -3*CHESS.square_size-CHESS.square_size/2);
-        r.transform.translatef (-x*CHESS.square_size, 0, y*CHESS.square_size);
-        
-        r.texture2d.disable;    
-        r.color_buffer.set_color col;
-       
-        r.blending.apply (r.blending.one,r.blending.zero);// erase color
-        r.blending.enable; 
-        
-        r.vb.new_quads {  
-          r.vb.add_texel2f (0.0, 1.0);
-          r.vb.add_vertex3f (-sz, 0.1, sz);
-          
-          r.vb.add_texel2f (0.0, 0.0);
-          r.vb.add_vertex3f (-sz, 0.1, -sz);
-          
-          r.vb.add_texel2f (1.0, 0.0);
-          r.vb.add_vertex3f (sz, 0.1, -sz);
-          
-          r.vb.add_texel2f (1.0, 1.0);
-          r.vb.add_vertex3f (sz, 0.1, sz);
-        };
-        r.blending.disable;
-        r.color_buffer.set_color3f (1,1,1);
-      };
-    };
-  );
-  
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := Expanded SQUARE;
+  
+  - comment   := "3D Chess Game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+  - comment     := "square position on chessboard";
+  
+  - type        := `unsigned int`;
+  - default     := ( CONVERT[INTEGER,SQUARE].on 0 );
+  
+Section Insert
+  
+  - parent_object:OBJECT := OBJECT;
+  
+Section Public
+  
+  - value:UINTEGER_32 <- CONVERT[SQUARE,UINTEGER_32].on Self;
+  
+  //
+  // Creation.
+  //
+  
+  - create (x,y:INTEGER) :SQUARE <-
+  ( + cod:UINTEGER_32;
+    ? {x.in_range 0 to 7};
+    ? {y.in_range 0 to 7};
+    
+    cod := y*8 + x;
+    CONVERT[UINTEGER_32,SQUARE].on cod
+  );
+  
+  //
+  // Content
+  //
+  
+  - piece:PIECE <- 
+  (
+    CHESS.chessboard.item value
+  );
+  
+  - set_piece p:PIECE <- 
+  (
+    CHESS.chessboard.put p to value;
+  );
+  
+  - clear <-
+  (
+    set_piece NULL;
+  );
+  
+  
+  - position:(INTEGER,INTEGER) <-
+  (
+    (value % 8, value / 8)
+  );
+  
+  - x:INTEGER <- value % 8;
+  - y:INTEGER <- value / 8;
+  
+  
+  - render r:RENDERER color col:COLOR <-
+  ( + x,y,sz:INTEGER;
+    
+    (x,y) := position;
+    sz := CHESS.square_size/2;
+    
+    ((x < 8) && {y < 8}).if {
+      r.transform.new_matrix {
+        
+        r.transform.translatef (3*CHESS.square_size+CHESS.square_size/2, 0, -3*CHESS.square_size-CHESS.square_size/2);
+        r.transform.translatef (-x*CHESS.square_size, 0, y*CHESS.square_size);
+        
+        r.texture2d.disable;    
+        r.color_buffer.set_color col;
+       
+        r.blending.apply (r.blending.one,r.blending.zero);// erase color
+        r.blending.enable; 
+        
+        r.vb.new_quads {  
+          r.vb.add_texel2f (0.0, 1.0);
+          r.vb.add_vertex3f (-sz, 0.1, sz);
+          
+          r.vb.add_texel2f (0.0, 0.0);
+          r.vb.add_vertex3f (-sz, 0.1, -sz);
+          
+          r.vb.add_texel2f (1.0, 0.0);
+          r.vb.add_vertex3f (sz, 0.1, -sz);
+          
+          r.vb.add_texel2f (1.0, 1.0);
+          r.vb.add_vertex3f (sz, 0.1, sz);
+        };
+        r.blending.disable;
+        r.color_buffer.set_color3f (1,1,1);
+      };
+    };
+  );
+  
   
\ No newline at end of file
diff --git a/chess/world1.li b/chess/world1.li
index a0039dd..a6e9b59 100644
--- a/chess/world1.li
+++ b/chess/world1.li
@@ -1,352 +1,353 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := WORLD1;
-  
-  - comment   := "world theme for game";
-  
-  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  - parent_world:SCENE := SCENE;
-  
-Section Public
-  
-  - noise:NOISE;
-  
-  - counter:REAL_32;
-  
-  //
-  // non shaded water effect 
-  //
-  
-  - water_resolution:INTEGER := 64;
-  - water_texture:TEXTURE;
-  - water_surface:FAST_ARRAY[REAL_32];
-  
-  //
-  // shaded water effect 
-  //
-  - water_shader:SHADER;
-  
-  - loc_color_map:INTEGER; // variable locations in shader
-  - loc_noise_map:INTEGER;
-  - loc_time:INTEGER;
-  
-  - noise_map:TEXTURE; 
-  
-  
-  - skybox:SKYBOX;
-  - fog:FOG;
-  
-  
-  - initialize <- 
-  (  
-    + pos,dim:VECTOR3[REAL_32];
-    + sky:FAST_ARRAY[TEXTURE];
-    + tex:TEXTURE;
-    + infolog:STRING;
-    
-    //
-    //  Water
-    //
-    
-    OPENGL.use_shaders.if_false {
-      engine.log.print "Cannot support GLSL Shaders with ARB extensions";
-    } else {
-      water_shader := renderer.shader.create ("shaders/water.vert","shaders/water.frag");
-      water_shader.enable;
-      
-      water_shader.has_compiled.if_false {
-        // print shader compilation errors - shader is disabled
-        infolog := STRING.create 32;
-        water_shader.get_infolog infolog;
-        
-        engine.log.print "Compilation error(s) in water shader: ";
-        engine.log.print infolog;
-      };
-      
-      // get glsl uniform variables of shader
-      loc_color_map := water_shader.get_uniform_location "colorMap";
-      loc_noise_map := water_shader.get_uniform_location "noiseMap";
-      loc_time := water_shader.get_uniform_location "timer";
-      
-      water_shader.disable;
-      
-      renderer.texture2d.set_filter (renderer.texture2d.filter_linear);
-      // load noise texture
-      noise_map := renderer.texture2d.create_from (IMAGE.create "textures/perlin_noise.bmp");
-      //
-      renderer.texture2d.set_filter (renderer.texture2d.filter_mipmap);
-      
-      // stencilling is used for reflections
-      renderer.stencil_buffer.set_clear_value 0.0;
-    };
-    
-    //
-    // non-shaded water effect
-    //
-    
-    noise := NOISE.create;
-    water_texture := renderer.texture2d.create_from (IMAGE.create "textures/water.bmp");
-    water_surface := FAST_ARRAY[REAL_32].create (water_resolution*water_resolution);
-    
-    // create noisy surface
-    0.to (water_resolution-1) do { j:INTEGER;      
-      0.to (water_resolution-1) do { i:INTEGER; 
-        water_surface.put ((4.0*noise.get (i,j,0)).to_real) to (j*water_resolution+i);
-      };
-    };
-    
-    //
-    // Sky
-    //
-    
-    pos := VECTOR3[REAL_32].create (0,0,0);
-    dim := VECTOR3[REAL_32].create (1000,500,1000);
-    
-    sky := FAST_ARRAY[TEXTURE].create_with_capacity 5;
-    
-    // clamp sky textures to make invisible edges
-    // not supported on every GL implementation...
-    renderer.texture2d.set_wrapping_mode (renderer.texture2d.clamp_to_edge);
-    //renderer.texture2d.set_wrapping_mode (renderer.texture2d.clamp);
-  
-    1.to 5 do { i:INTEGER;
-      tex := renderer.texture2d.create_from (IMAGE.create ("textures/sky"+i.to_string+".bmp"));
-      sky.add_last tex;
-    };
-    
-    skybox := SKYBOX.create (pos,dim,sky);
-    
-    /*  make the scene too dark..
-      fog := renderer.fog.create (RGB.create (0.8, 0.8, 0.8), 0.02, 800.0, 1500.0);
-    renderer.set_fog fog;
-    fog.enable;
-    */
-  );
-  
-
-  - render t:UINTEGER_32 <-
-  ( 
-    + val,sz:REAL_32;
-    + unit:INTEGER;
-
-    //
-    // draw water surface
-    //
-    
-    (water_shader != NULL).if {
-      
-      // first pass: draw & blend the skybox upside down
-      render_reflection;
-      
-      // now graphic pipeline ends with the shader
-      water_shader.enable;
-      
-      // bind samplers (water texture & noise texture)
-      water_shader.bind_sampler noise_map unit 1 location loc_noise_map; 
-      water_shader.bind_sampler water_texture unit 0 location loc_color_map; 
-      
-      // increase the 'timer' variable in shader
-      counter := counter+ 1.0/engine.fps_max;
-      water_shader.set_uniform1f loc_time to (counter);
-      
-      
-      // draw a single textured polygon
-      sz := 1000;
-      water_texture.bind;      
-    
-      renderer.transform.new_matrix {      
-        renderer.transform.translatef(0, -30, 0);
-  
-        renderer.vb.new_quads {
-          renderer.vb.add_normal3f (0.0, 1.0, 0.0);
-          
-          renderer.vb.add_texel2f (0.0, 1.0);
-          renderer.vb.add_vertex3f (-sz, 0.0, sz);
-          
-          renderer.vb.add_texel2f (0.0, 0.0);
-          renderer.vb.add_vertex3f (-sz, 0.0, -sz);
-          
-          renderer.vb.add_texel2f (1.0, 0.0);
-          renderer.vb.add_vertex3f (sz, 0.0, -sz);
-          
-          renderer.vb.add_texel2f (1.0, 1.0);
-          renderer.vb.add_vertex3f (sz, 0.0, sz);          
-        };
-      };
-      
-      // disable the water shader
-      renderer.blending.disable;
-      water_shader.disable;
-      
-    } else {
-      
-      //
-      // animate non-shaded water surface
-      //
-      
-      counter := counter + t.to_real * 0.01;
-      (counter > 1000h).if {
-        counter := 0;
-      };
-      
-      0.to (water_resolution-2) do { j:INTEGER;      
-        0.to (water_resolution-1) do { i:INTEGER; 
-          
-          val := water_surface.item (j*water_resolution+i);
-          water_surface.put (val+1.5*(counter + 0.2*i).sin) to (j*water_resolution+i);
-        };
-      };
-      
-      //
-      // draw waves 
-      //
-      render_reflection;
-      
-      unit := 30;
-      water_texture.bind;
-      
-      renderer.transform.new_matrix {    
-        
-        renderer.transform.translatef(-15*water_resolution, -30, -15*water_resolution);
-        0.to (water_resolution-2) do { j:INTEGER;
-          renderer.vb.new_triangle_strip {
-            
-            0.to (water_resolution-1) do { i:INTEGER;   
-              
-              // first point (i, j+1)
-              renderer.vb.add_vertex3f (i*unit,water_surface.item ((j+1)*water_resolution+i), (j+1)*unit);
-              renderer.vb.add_texel2f ((i.to_real*256.0)/256.0,((j+1).to_real*256.0)/256.0);
-              
-              // second point (i, j)
-              renderer.vb.add_vertex3f (i*unit,water_surface.item (j*water_resolution+i), j*unit);
-              renderer.vb.add_texel2f ((i.to_real*256.0)/256.0,(j.to_real*256.0)/256.0);
-            };
-          };
-        };      
-      };
-    };
-    renderer.blending.disable;
-    
-    //
-    // draw sky
-    //
-    
-    renderer.transform.new_matrix {  
-      renderer.transform.translatef(0, 400, 0); 
-      skybox.render;
-    };   
-  );
-  
-  - render_reflection <-
-  (
-    //
-    // First pass: draw an invisible mask of the floor in the stencil buffer
-    //
-    
-    // disable drawing in color buffer
-    renderer.color_buffer.disable;
-    
-    renderer.stencil_buffer.enable;
-    
-    // stencil test always pass and set stencil value to 1 
-    renderer.stencil_buffer.set_function (renderer.stencil_buffer.always) value 1 mask 1;
-    
-    // if test successful replace stencil value else keep the old value
-    renderer.stencil_buffer.when_pass (renderer.stencil_buffer.replace) when_fail (renderer.stencil_buffer.keep) when_zfail (renderer.stencil_buffer.keep);
-    
-    renderer.depth_buffer.disable;
-    
-    draw_water_surface;
-    
-    // back to color mode
-    renderer.depth_buffer.enable;
-    renderer.color_buffer.enable;
-    
-    //
-    // Second pass: draw reflections in the masked floor (stencil test enabled)
-    //
-    
-    // only draw pixels masked with 1 in stencil buffer
-    renderer.stencil_buffer.set_function (renderer.stencil_buffer.equal) value 1 mask 1;
-    renderer.stencil_buffer.lock; // read-only
-    
-    renderer.blending.set_alpha_value 0.5;
-    renderer.blending.apply (renderer.blending.dst_alpha,renderer.blending.one_minus_dst_alpha); 
-    renderer.blending.enable;
-    
-    renderer.depth_buffer.disable; 
-    
-    renderer.transform.new_matrix {
-      
-      // mirror y axis
-      renderer.transform.scalef (1.0, -1.0, 1.0);
-      
-      // draw reflection
-      renderer.transform.translatef(0, 400, 0);
-      skybox.render;
-    };
-    
-    // back to normal mode
-    renderer.stencil_buffer.disable;
-    renderer.depth_buffer.enable;
-  );
-  
-  - draw_water_surface <-
-  ( + sz:INTEGER;
-    
-    sz := 1000;
-    renderer.texture2d.disable;
-    
-    renderer.transform.new_matrix {    
-      
-      renderer.transform.translatef(0, -30, 0);
-      
-      renderer.vb.new_quads {
-        renderer.vb.add_normal3f (0.0, 1.0, 0.0);
-        
-        renderer.vb.add_texel2f (0.0, 1.0);
-        renderer.vb.add_vertex3f (-sz, 0.0, sz);
-        
-        renderer.vb.add_texel2f (0.0, 0.0);
-        renderer.vb.add_vertex3f (-sz, 0.0, -sz);
-        
-        renderer.vb.add_texel2f (1.0, 0.0);
-        renderer.vb.add_vertex3f (sz, 0.0, -sz);
-        
-        renderer.vb.add_texel2f (1.0, 1.0);
-        renderer.vb.add_vertex3f (sz, 0.0, sz);          
-      };
-    };
-    renderer.texture2d.enable;
-  );
-  
-  - release <-
-  (
-    (water_shader != NULL).if {
-      water_shader.delete;
-    };
-  );
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := WORLD1;
+  
+  - comment   := "world theme for game";
+  
+  - author    := "Damien Bouvarel (dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  - parent_world:SCENE := SCENE;
+  
+Section Public
+  
+  - noise:NOISE;
+  
+  - counter:REAL_32;
+  
+  //
+  // non shaded water effect 
+  //
+  
+  - water_resolution:INTEGER := 64;
+  - water_texture:TEXTURE;
+  - water_surface:FAST_ARRAY[REAL_32];
+  
+  //
+  // shaded water effect 
+  //
+  - water_shader:SHADER;
+  
+  - loc_color_map:INTEGER; // variable locations in shader
+  - loc_noise_map:INTEGER;
+  - loc_time:INTEGER;
+  
+  - noise_map:TEXTURE; 
+  
+  
+  - skybox:SKYBOX;
+  - fog:FOG;
+  
+  
+  - initialize:BOOLEAN <- 
+  (  
+    + pos,dim:VECTOR3[REAL_32];
+    + sky:FAST_ARRAY[TEXTURE];
+    + tex:TEXTURE;
+    + infolog:STRING;
+    
+    //
+    //  Water
+    //
+    
+    OPENGL.use_shaders.if_false {
+      FRAMEWORK.log.print "Cannot support GLSL Shaders with ARB extensions";
+    } else {
+      water_shader := renderer.shader.create ("shaders/water.vert","shaders/water.frag");
+      water_shader.enable;
+      
+      water_shader.has_compiled.if_false {
+        // print shader compilation errors - shader is disabled
+        infolog := STRING.create 32;
+        water_shader.get_infolog infolog;
+        
+        FRAMEWORK.log.print "Compilation error(s) in water shader: ";
+        FRAMEWORK.log.print infolog;
+      };
+      
+      // get glsl uniform variables of shader
+      loc_color_map := water_shader.get_uniform_location "colorMap";
+      loc_noise_map := water_shader.get_uniform_location "noiseMap";
+      loc_time := water_shader.get_uniform_location "timer";
+      
+      water_shader.disable;
+      
+      renderer.texture2d.set_filter (renderer.texture2d.filter_linear);
+      // load noise texture
+      noise_map := renderer.texture2d.create_from (IMAGE.create "textures/perlin_noise.bmp");
+      //
+      renderer.texture2d.set_filter (renderer.texture2d.filter_mipmap);
+      
+      // stencilling is used for reflections
+      renderer.stencil_buffer.set_clear_value 0.0;
+    };
+    
+    //
+    // non-shaded water effect
+    //
+    
+    noise := NOISE.create;
+    water_texture := renderer.texture2d.create_from (IMAGE.create "textures/water.bmp");
+    water_surface := FAST_ARRAY[REAL_32].create (water_resolution*water_resolution);
+    
+    // create noisy surface
+    0.to (water_resolution-1) do { j:INTEGER;      
+      0.to (water_resolution-1) do { i:INTEGER; 
+        water_surface.put ((4.0*noise.get (i,j,0)).to_real) to (j*water_resolution+i);
+      };
+    };
+    
+    //
+    // Sky
+    //
+    
+    pos := VECTOR3[REAL_32].create (0,0,0);
+    dim := VECTOR3[REAL_32].create (1000,500,1000);
+    
+    sky := FAST_ARRAY[TEXTURE].create_with_capacity 5;
+    
+    // clamp sky textures to make invisible edges
+    // not supported on every GL implementation...
+    renderer.texture2d.set_wrapping_mode (renderer.texture2d.clamp_to_edge);
+    //renderer.texture2d.set_wrapping_mode (renderer.texture2d.clamp);
+  
+    1.to 5 do { i:INTEGER;
+      tex := renderer.texture2d.create_from (IMAGE.create ("textures/sky"+i.to_string+".bmp"));
+      sky.add_last tex;
+    };
+    
+    skybox := SKYBOX.create (pos,dim,sky);
+    
+    /*  make the scene too dark..
+      fog := renderer.fog.create (RGB.create (0.8, 0.8, 0.8), 0.02, 800.0, 1500.0);
+    renderer.set_fog fog;
+    fog.enable;
+    */
+    TRUE
+  );
+  
+
+  - render t:REAL_32 <-
+  ( 
+    + val,sz:REAL_32;
+    + unit:INTEGER;
+
+    //
+    // draw water surface
+    //
+    
+    (water_shader != NULL).if {
+      
+      // first pass: draw & blend the skybox upside down
+      render_reflection;
+      
+      // now graphic pipeline ends with the shader
+      water_shader.enable;
+      
+      // bind samplers (water texture & noise texture)
+      water_shader.bind_sampler noise_map unit 1 location loc_noise_map; 
+      water_shader.bind_sampler water_texture unit 0 location loc_color_map; 
+      
+      // increase the 'timer' variable in shader
+      counter := counter+ 1.0/FRAMEWORK.frame_per_second_max;
+      water_shader.set_uniform1f loc_time to (counter);
+      
+      
+      // draw a single textured polygon
+      sz := 1000;
+      water_texture.bind;      
+    
+      renderer.transform.new_matrix {      
+        renderer.transform.translatef(0, -30, 0);
+  
+        renderer.vb.new_quads {
+          renderer.vb.add_normal3f (0.0, 1.0, 0.0);
+          
+          renderer.vb.add_texel2f (0.0, 1.0);
+          renderer.vb.add_vertex3f (-sz, 0.0, sz);
+          
+          renderer.vb.add_texel2f (0.0, 0.0);
+          renderer.vb.add_vertex3f (-sz, 0.0, -sz);
+          
+          renderer.vb.add_texel2f (1.0, 0.0);
+          renderer.vb.add_vertex3f (sz, 0.0, -sz);
+          
+          renderer.vb.add_texel2f (1.0, 1.0);
+          renderer.vb.add_vertex3f (sz, 0.0, sz);          
+        };
+      };
+      
+      // disable the water shader
+      renderer.blending.disable;
+      water_shader.disable;
+      
+    } else {
+      
+      //
+      // animate non-shaded water surface
+      //
+      
+      counter := counter + t * 10;
+      (counter > 1000h).if {
+        counter := 0;
+      };
+      
+      0.to (water_resolution-2) do { j:INTEGER;      
+        0.to (water_resolution-1) do { i:INTEGER; 
+          
+          val := water_surface.item (j*water_resolution+i);
+          water_surface.put (val+1.5*(counter + 0.2*i).sin) to (j*water_resolution+i);
+        };
+      };
+      
+      //
+      // draw waves 
+      //
+      render_reflection;
+      
+      unit := 30;
+      water_texture.bind;
+      
+      renderer.transform.new_matrix {    
+        
+        renderer.transform.translatef(-15*water_resolution, -30, -15*water_resolution);
+        0.to (water_resolution-2) do { j:INTEGER;
+          renderer.vb.new_triangle_strip {
+            
+            0.to (water_resolution-1) do { i:INTEGER;   
+              
+              // first point (i, j+1)
+              renderer.vb.add_vertex3f (i*unit,water_surface.item ((j+1)*water_resolution+i), (j+1)*unit);
+              renderer.vb.add_texel2f ((i.to_real*256.0)/256.0,((j+1).to_real*256.0)/256.0);
+              
+              // second point (i, j)
+              renderer.vb.add_vertex3f (i*unit,water_surface.item (j*water_resolution+i), j*unit);
+              renderer.vb.add_texel2f ((i.to_real*256.0)/256.0,(j.to_real*256.0)/256.0);
+            };
+          };
+        };      
+      };
+    };
+    renderer.blending.disable;
+    
+    //
+    // draw sky
+    //
+    
+    renderer.transform.new_matrix {  
+      renderer.transform.translatef(0, 400, 0); 
+      skybox.render;
+    };   
+  );
+  
+  - render_reflection <-
+  (
+    //
+    // First pass: draw an invisible mask of the floor in the stencil buffer
+    //
+    
+    // disable drawing in color buffer
+    renderer.color_buffer.disable;
+    
+    renderer.stencil_buffer.enable;
+    
+    // stencil test always pass and set stencil value to 1 
+    renderer.stencil_buffer.set_function (renderer.stencil_buffer.always) value 1 mask 1;
+    
+    // if test successful replace stencil value else keep the old value
+    renderer.stencil_buffer.when_pass (renderer.stencil_buffer.replace) when_fail (renderer.stencil_buffer.keep) when_zfail (renderer.stencil_buffer.keep);
+    
+    renderer.depth_buffer.disable;
+    
+    draw_water_surface;
+    
+    // back to color mode
+    renderer.depth_buffer.enable;
+    renderer.color_buffer.enable;
+    
+    //
+    // Second pass: draw reflections in the masked floor (stencil test enabled)
+    //
+    
+    // only draw pixels masked with 1 in stencil buffer
+    renderer.stencil_buffer.set_function (renderer.stencil_buffer.equal) value 1 mask 1;
+    renderer.stencil_buffer.lock; // read-only
+    
+    renderer.blending.set_alpha_value 0.5;
+    renderer.blending.apply (renderer.blending.dst_alpha,renderer.blending.one_minus_dst_alpha); 
+    renderer.blending.enable;
+    
+    renderer.depth_buffer.disable; 
+    
+    renderer.transform.new_matrix {
+      
+      // mirror y axis
+      renderer.transform.scalef (1.0, -1.0, 1.0);
+      
+      // draw reflection
+      renderer.transform.translatef(0, 400, 0);
+      skybox.render;
+    };
+    
+    // back to normal mode
+    renderer.stencil_buffer.disable;
+    renderer.depth_buffer.enable;
+  );
+  
+  - draw_water_surface <-
+  ( + sz:INTEGER;
+    
+    sz := 1000;
+    renderer.texture2d.disable;
+    
+    renderer.transform.new_matrix {    
+      
+      renderer.transform.translatef(0, -30, 0);
+      
+      renderer.vb.new_quads {
+        renderer.vb.add_normal3f (0.0, 1.0, 0.0);
+        
+        renderer.vb.add_texel2f (0.0, 1.0);
+        renderer.vb.add_vertex3f (-sz, 0.0, sz);
+        
+        renderer.vb.add_texel2f (0.0, 0.0);
+        renderer.vb.add_vertex3f (-sz, 0.0, -sz);
+        
+        renderer.vb.add_texel2f (1.0, 0.0);
+        renderer.vb.add_vertex3f (sz, 0.0, -sz);
+        
+        renderer.vb.add_texel2f (1.0, 1.0);
+        renderer.vb.add_vertex3f (sz, 0.0, sz);          
+      };
+    };
+    renderer.texture2d.enable;
+  );
+  
+  - release <-
+  (
+    (water_shader != NULL).if {
+      water_shader.delete;
+    };
+  );
diff --git a/gl_test/data/test.frag b/gl_test/data/test.frag
index 66d725c..e0a13a5 100644
--- a/gl_test/data/test.frag
+++ b/gl_test/data/test.frag
@@ -1,5 +1,5 @@
-
-void main()
-{
-	gl_FragColor = gl_Color;
-}
+
+void main()
+{
+	gl_FragColor = gl_Color;
+}
diff --git a/gl_test/data/test.vert b/gl_test/data/test.vert
index 524d942..dcb62f1 100644
--- a/gl_test/data/test.vert
+++ b/gl_test/data/test.vert
@@ -1,24 +1,24 @@
-
-uniform float time;
-
-float zfunction (vec4 v) {
-	float  z;
-
-	z = sin(5.0*v.x + time*0.05)*0.25;
-	return(z);
-}
-
-void main()
-{
-	vec4 v = vec4(gl_Vertex);
-
-	float newz = zfunction(v);
-	v.z = newz;	
-
-	// for the fragment shader
-	gl_FrontColor = gl_Color;
-
-
-	gl_Position = gl_ModelViewProjectionMatrix * v;
-}
-
+
+uniform float time;
+
+float zfunction (vec4 v) {
+	float  z;
+
+	z = sin(5.0*v.x + time*0.05)*0.25;
+	return(z);
+}
+
+void main()
+{
+	vec4 v = vec4(gl_Vertex);
+
+	float newz = zfunction(v);
+	v.z = newz;	
+
+	// for the fragment shader
+	gl_FrontColor = gl_Color;
+
+
+	gl_Position = gl_ModelViewProjectionMatrix * v;
+}
+
diff --git a/gl_test/data/toon.frag b/gl_test/data/toon.frag
index 891e097..594ec71 100644
--- a/gl_test/data/toon.frag
+++ b/gl_test/data/toon.frag
@@ -1,29 +1,29 @@
-
-uniform sampler2D Texture;
-
-varying vec3 lVec;
-varying vec3 norm;
-varying vec2 texCoord;
-
-void main(){
-	vec4 tex_color = texture2D(Texture, texCoord);
-
-	vec3 lightVec = normalize(lVec);
-	float intensity = dot(lightVec, normalize(norm));
-
-	//gl_FragColor = texture1D(CelShade, intensity);
-
-	float gris;
-
-  	if (intensity > 0.8)
-		gris = 0.2;
-	else if (intensity > 0.25)
-		gris = 0.4;
-	else if (intensity > 0.10)
-		gris = 0.9;
-	else
-		gris = 1.0;
-
-	//gl_FragColor = vec4(gris);
-	gl_FragColor = clamp(vec4(gris) * tex_color, 0.1, 1.0);
+
+uniform sampler2D Texture;
+
+varying vec3 lVec;
+varying vec3 norm;
+varying vec2 texCoord;
+
+void main(){
+	vec4 tex_color = texture2D(Texture, texCoord);
+
+	vec3 lightVec = normalize(lVec);
+	float intensity = dot(lightVec, normalize(norm));
+
+	//gl_FragColor = texture1D(CelShade, intensity);
+
+	float gris;
+
+  	if (intensity > 0.8)
+		gris = 0.2;
+	else if (intensity > 0.25)
+		gris = 0.4;
+	else if (intensity > 0.10)
+		gris = 0.9;
+	else
+		gris = 1.0;
+
+	//gl_FragColor = vec4(gris);
+	gl_FragColor = clamp(vec4(gris) * tex_color, 0.1, 1.0);
 }
\ No newline at end of file
diff --git a/gl_test/data/toon.vert b/gl_test/data/toon.vert
index fc6bc4c..a595cfb 100644
--- a/gl_test/data/toon.vert
+++ b/gl_test/data/toon.vert
@@ -1,15 +1,15 @@
-uniform vec3 lightPos;
-
-varying vec3 lVec;
-varying vec3 norm;
-varying vec2 texCoord;
-
-void main(){
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-
-	lVec = lightPos; // - gl_Vertex.xyz;
-	norm = gl_Normal;
-
-	texCoord = gl_MultiTexCoord0.xy;	
-}
-
+uniform vec3 lightPos;
+
+varying vec3 lVec;
+varying vec3 norm;
+varying vec2 texCoord;
+
+void main(){
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+	lVec = lightPos; // - gl_Vertex.xyz;
+	norm = gl_Normal;
+
+	texCoord = gl_MultiTexCoord0.xy;	
+}
+
diff --git a/gl_test/my_event_listener.li b/gl_test/framework_test.li
similarity index 65%
copy from gl_test/my_event_listener.li
copy to gl_test/framework_test.li
index 3f920fb..6f376ad 100644
--- a/gl_test/my_event_listener.li
+++ b/gl_test/framework_test.li
@@ -1,72 +1,88 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := MY_EVENT_LISTENER;
-  
-  - comment  := "catch key events";
-  
-Section Inherit
-  
-  - parent_mouse_listener:MOUSE_LISTENER := MOUSE_LISTENER;
-  - parent_key_listener:KEY_LISTENER := KEY_LISTENER;
-  
-Section Public
-  
-  - keydown k:INTEGER <-
-  (
-    + char:CHARACTER;
-    
-    "\n==> ".print; k.print;
-    
-    k
-    .when (KEYCODE.k_f1) then {
-      //ENGINE.screenshot "screenshot.tga";
-    };
-    
-    char := k.to_character.to_upper;
-    char
-    .when 'L' then {
-      ENGINE.toggle_lighting;
-    }.when 'B' then {
-      ENGINE.toggle_blending;    
-    }.when 'F' then {
-      ENGINE.toggle_fog; 
-    }.when 'W' then {
-      ENGINE.toggle_wireframe;  
-    };
-  );
-  
-  - move (x,y:INTEGER) <- 
-  (
-    
-  );
-  
-  - click button:INTEGER <-
-  (
-    ((button & 1) != 0).if {
-      "Right Click\n".print;
-    } else {
-      "Left Click\n".print;
-    };
-  );
-  
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                           Lisaac-OpenGL library                           //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := FRAMEWORK_TEST;
+  
+Section Inherit
+  
+  - parent_framework:FRAMEWORK := FRAMEWORK;
+  
+  - parent_event_listener:EVENT_LISTENER := EVENT_LISTENER;
+  
+Section Public
+  
+  - main <-
+  ( + caps:CAPABILITIES;
+    
+    caps := CAPABILITIES;
+    // caps.use_fullscreen;
+    // caps.set ...
+    OPENGL.set_capabilities caps;
+    
+    // create OpenGL device
+    OPENGL.make (800,600) title "GL Framework test";
+    
+    // set up framework
+    FRAMEWORK.make OPENGL;
+    
+    attach_scene TEST_SCENE;
+    add_key_listener Self;
+    
+    // start it all
+    run;
+  );
+  
+  //
+  // Events.
+  //
+  
+Section Public
+  
+  //
+  // Application events.
+  // 
+  
+  /*- draw_frame <- (
+  // override framework drawing
+  );*/
+  
+  //
+  // Input events.
+  //
+  
+  - keydown k:INTEGER <-
+  (
+    "\n==> ".print; k.print;
+    
+    (k = KEYCODE.k_escape).if {
+      //
+      FRAMEWORK.stop;
+      //
+    };
+  );
+  
+  /* // raw event slot: not to use with listeners
+  - on_keydown k:INTEGER <- (
+  );*/
+ 
+ 
diff --git a/gl_test/my_event_listener.li b/gl_test/gui_test.li
similarity index 60%
copy from gl_test/my_event_listener.li
copy to gl_test/gui_test.li
index 3f920fb..5a1354c 100644
--- a/gl_test/my_event_listener.li
+++ b/gl_test/gui_test.li
@@ -1,72 +1,88 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := MY_EVENT_LISTENER;
-  
-  - comment  := "catch key events";
-  
-Section Inherit
-  
-  - parent_mouse_listener:MOUSE_LISTENER := MOUSE_LISTENER;
-  - parent_key_listener:KEY_LISTENER := KEY_LISTENER;
-  
-Section Public
-  
-  - keydown k:INTEGER <-
-  (
-    + char:CHARACTER;
-    
-    "\n==> ".print; k.print;
-    
-    k
-    .when (KEYCODE.k_f1) then {
-      //ENGINE.screenshot "screenshot.tga";
-    };
-    
-    char := k.to_character.to_upper;
-    char
-    .when 'L' then {
-      ENGINE.toggle_lighting;
-    }.when 'B' then {
-      ENGINE.toggle_blending;    
-    }.when 'F' then {
-      ENGINE.toggle_fog; 
-    }.when 'W' then {
-      ENGINE.toggle_wireframe;  
-    };
-  );
-  
-  - move (x,y:INTEGER) <- 
-  (
-    
-  );
-  
-  - click button:INTEGER <-
-  (
-    ((button & 1) != 0).if {
-      "Right Click\n".print;
-    } else {
-      "Left Click\n".print;
-    };
-  );
-  
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                           Lisaac-OpenGL library                           //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := GUI_TEST;
+  
+Section Inherit
+
+  - parent_inbox:INBOX := INBOX;
+  
+Section Public
+  
+  - test:G_GROUP <-
+  (    
+    G_RAW.create (G_BUTTON.create (G_OUT.create "hello !!!" justify 0) action NULL)
+  );
+  
+  - quit:G_EXPR <- (G_BUTTON.create (G_OUT.create "Close" justify (G_OUT.center)) action { b:G_BUTTON;
+    close;
+  });
+  
+  - gltest:G_GROUP <-
+  (   
+    G_RAW.create (
+      G_OUT.create "OpenGL - GUI demo" /
+      G_RAW.create (G_GLDRAW.create TEST_SCENE) /
+      quit
+    )
+  );
+  
+  - main <-
+  ( 
+    // for escape key
+    KEYBOARD.add_client Self;
+    
+    // Setup opengl. (replace X11 or winGDI)
+    VIDEO.change_driver GL_DRIVER;
+    
+    // Init window.
+    VIDEO.make (640,400);
+
+    GL_DESK.make VIDEO with gltest;
+  );
+  
+  
+  - receive msg:EVENT <-
+  ( + evt_key:EVENT_KEYBOARD;
+    
+    evt_key ?= msg; 
+    (evt_key != NULL).if {
+      
+      // exit
+      (evt_key.key&0FFh = 27).if {
+        
+        close;
+      };
+    };
+  );
+  
+  - close <-
+  (
+    // scene release
+    TEST_SCENE.release;
+    
+    // GL release
+    VIDEO.close;
+    
+    die_with_code exit_success_code;
+  );
diff --git a/gl_test/my_event_listener.li b/gl_test/my_event_listener.li
index 3f920fb..22b3381 100644
--- a/gl_test/my_event_listener.li
+++ b/gl_test/my_event_listener.li
@@ -1,72 +1,73 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := MY_EVENT_LISTENER;
-  
-  - comment  := "catch key events";
-  
-Section Inherit
-  
-  - parent_mouse_listener:MOUSE_LISTENER := MOUSE_LISTENER;
-  - parent_key_listener:KEY_LISTENER := KEY_LISTENER;
-  
-Section Public
-  
-  - keydown k:INTEGER <-
-  (
-    + char:CHARACTER;
-    
-    "\n==> ".print; k.print;
-    
-    k
-    .when (KEYCODE.k_f1) then {
-      //ENGINE.screenshot "screenshot.tga";
-    };
-    
-    char := k.to_character.to_upper;
-    char
-    .when 'L' then {
-      ENGINE.toggle_lighting;
-    }.when 'B' then {
-      ENGINE.toggle_blending;    
-    }.when 'F' then {
-      ENGINE.toggle_fog; 
-    }.when 'W' then {
-      ENGINE.toggle_wireframe;  
-    };
-  );
-  
-  - move (x,y:INTEGER) <- 
-  (
-    
-  );
-  
-  - click button:INTEGER <-
-  (
-    ((button & 1) != 0).if {
-      "Right Click\n".print;
-    } else {
-      "Left Click\n".print;
-    };
-  );
-  
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := MY_EVENT_LISTENER;
+  
+  - comment  := "catch key events";
+  
+Section Inherit
+
+  - parent_event_listener:EVENT_LISTENER := EVENT_LISTENER;
+  
+Section Public
+  
+  - keydown k:INTEGER <-
+  (
+    + char:CHARACTER;
+    
+    "\n==> ".print; k.print;
+    
+    k
+    .when (KEYCODE.k_escape) then {
+       FRAMEWORK.stop;
+    }.when (KEYCODE.k_f1) then {
+      //ENGINE.screenshot "screenshot.tga";
+    };
+    
+    char := k.to_character.to_upper;
+    char
+    .when 'L' then {
+  //    ENGINE.toggle_lighting;
+    }.when 'B' then {
+  //    ENGINE.toggle_blending;    
+    }.when 'F' then {
+  //    ENGINE.toggle_fog; 
+    }.when 'W' then {
+  //    ENGINE.toggle_wireframe;  
+    };
+  );
+  
+  - move (x,y:INTEGER) <- 
+  (
+    
+  );
+  
+  - click b:INTEGER <-
+  (
+    ((b & 1) != 0).if {
+      "Right Click\n".print;
+    } else {
+      "Left Click\n".print;
+    };
+  );
+  
diff --git a/gl_test/my_scene1.li b/gl_test/my_scene1.li
index 7f70dbf..faecabd 100644
--- a/gl_test/my_scene1.li
+++ b/gl_test/my_scene1.li
@@ -34,8 +34,13 @@ Section Inherit
 Section Public  
   
   - main <-
-  (
-    start_test Self;
+  ( + caps:CAPABILITIES;
+    
+    caps := CAPABILITIES;
+    // caps.use_fullscreen;
+    // caps.set ...
+    
+    start_test Self using caps;
   );
   
 Section Public
@@ -45,21 +50,22 @@ Section Public
   + blue:COLOR := RGB.create (0.0, 0.0, 1.0);
   
   + index_buffer:INDEX_BUFFER;
+  + vb:VERTEX_BUFFER;
   
   + shader:SHADER;
   + loc:INTEGER;
   
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   (
     + v1,v2,v3:VERTEX; 
     
     OPENGL.use_arb_vertex_buffer_object.if_false {
-      engine.log.print "ARB_vertex_buffer_object extension not supported";
+      log.print "ARB_vertex_buffer_object extension not supported";
     };
     
     OPENGL.use_shaders.if_false {
-      engine.log.print "Cannot support GLSL Shaders with ARB extensions";
+      log.print "Cannot support GLSL Shaders with ARB extensions";
     } else {
       shader := renderer.shader.create ("data/test.vert","data/test.frag");
       shader.enable;
@@ -76,38 +82,33 @@ Section Public
     };
     
     // create vertex array
-    renderer.active_vertex_array 3;
+    vb := renderer.vertex_array.create 3;
     
     v1 := VERTEX.create (0.0, 2.0, 0.0);
     v2 := VERTEX.create (-1.0, 0.0, 0.0);
     v3 := VERTEX.create (1.0, 0.0, 0.0);
     
     // draw a cool triangle using vertex array
-    renderer.vb.new_triangles {
-      renderer.vb.add_vertex v1 color red;
-      renderer.vb.add_vertex v2 color green;
-      renderer.vb.add_vertex v3 color blue;
+    vb.new_triangles {
+      vb.add_vertex v1 color red;
+      vb.add_vertex v2 color green;
+      vb.add_vertex v3 color blue;
     };
+    TRUE
   );
   
   + time:REAL_32;
   
-  - render t:UINTEGER_32 <-
+  - render t:REAL_32 <-
   (      
-    renderer.new_frame {
-      //----- begin rendering
-      
-      (shader != NULL).if {
-        shader.set_uniform1f loc to time;
-        time := time + 1;
-      };
-      
-      renderer.transform.translatef (0.0, -1.0, -3.0);     
-      renderer.vb.bind;
-      renderer.vb.draw_using index_buffer;
-      
-      //----- end rendering
-    }; 
+    (shader != NULL).if {
+      shader.set_uniform1f loc to time;
+      time := time + 1;
+    };
+    
+    renderer.transform.translatef (0.0, -1.0, -3.0);     
+    vb.bind;
+    vb.draw_using index_buffer;    
   );
   
   - release <-
@@ -115,4 +116,4 @@ Section Public
     (shader != NULL).if {
       shader.delete;
     };
-  );
\ No newline at end of file
+  );
diff --git a/gl_test/my_scene10.li b/gl_test/my_scene10.li
index 429c44a..b271976 100644
--- a/gl_test/my_scene10.li
+++ b/gl_test/my_scene10.li
@@ -38,7 +38,7 @@ Section Public
   - main <-
   (
     OPENGL.set_reshape Self;
-    start_test Self;
+    start_test Self using CAPABILITIES;
   );
   
 Section Public
@@ -57,7 +57,7 @@ Section Public
   + u_res:INTEGER := 8;
   + v_res:INTEGER := 30;
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   ( 
     //
     // Create Bezier Curve
@@ -101,19 +101,19 @@ Section Public
       surface.add_point3f (0.5, -1.5, -1);
       surface.add_point3f (1.5, -1.5, 2);
       
-       // line 2
+      // line 2
       surface.add_point3f (-1.5, -0.5, 1);
       surface.add_point3f (-0.5, -0.5, 3);
       surface.add_point3f (0.5, 0.5, 0);
       surface.add_point3f (1.5, -0.5, -1);
       
-       // line 3
+      // line 3
       surface.add_point3f (-1.5, 0.5, 4);
       surface.add_point3f (-0.5, 0.5, 0);
       surface.add_point3f (0.5, 0.5, 3);
       surface.add_point3f (1.5, 0.5, 0);
       
-       // line 4
+      // line 4
       surface.add_point3f (-1.5, 1.5, -2);
       surface.add_point3f (-0.5, 1.5, -2);
       surface.add_point3f (0.5, 1.5, 0);
@@ -127,101 +127,96 @@ Section Public
     renderer.enable_auto_normal; // generate normals for the surface
     renderer.set_point_size 5.0;
     renderer.light.enable_default_light;
+    TRUE
   );
   
   + rot:REAL_32 := 0.3;
   
   
-  - render t:UINTEGER_32 <-
+  - render t:REAL_32 <-
   (      
-    renderer.new_frame {
-      //----- begin rendering
-      
-      //
-      // 4 control points Bezier Curve
-      //
-      
-      // middle left - in white
-      renderer.transform.set_viewport4i (50,200,200,200);
-      renderer.color_buffer.set_color3f(1,1,1);
-      
-      // draw curve
-      renderer.vb.new_line_strip {
-        0.to resolution do { i:INTEGER;
-          curve.evaluate (i.to_real / resolution.to_real);
-        };
+    //
+    // 4 control points Bezier Curve
+    //
+    
+    // middle left - in white
+    renderer.transform.set_viewport4i (50,200,200,200);
+    renderer.color_buffer.set_color3f(1,1,1);
+    
+    // draw curve
+    renderer.vb.new_line_strip {
+      0.to resolution do { i:INTEGER;
+        curve.evaluate (i.to_real / resolution.to_real);
       };
-      
-      // draw control points
-      renderer.vb.new_points {
-        0.to 3 do { i:INTEGER;
-          renderer.vb.add_vertex (points.item i);
-        };
+    };
+    
+    // draw control points
+    renderer.vb.new_points {
+      0.to 3 do { i:INTEGER;
+        renderer.vb.add_vertex (points.item i);
       };
+    };
+    
+    //
+    // same curve - other way to draw it
+    //
+    
+    // middle right
+    renderer.transform.set_viewport4i (600,200,200,200);
+    renderer.color_buffer.set_color3f(1,1,1);
+    
+    // draw curve
+    curve.generate_grid resolution between (0,1);
+    curve.evaluate_mesh (curve.point) from 0 to resolution;
+    
+    
+    //
+    // Bezier Surface
+    //
+    
+    renderer.transform.set_viewport4i (300,400,200,200);
+    renderer.color_buffer.set_color3f(1,1,1);
+    
+    renderer.transform.new_matrix {
+      renderer.transform.rotatef (rot, 1, 1, 1);
+      rot := rot + 0.7;
       
-      //
-      // same curve - other way to draw it
-      //
-      
-      // middle right
-      renderer.transform.set_viewport4i (600,200,200,200);
-      renderer.color_buffer.set_color3f(1,1,1);
-      
-      // draw curve
-      curve.generate_grid resolution between (0,1);
-      curve.evaluate_mesh (curve.point) from 0 to resolution;
-      
-      
-      //
-      // Bezier Surface
-      //
-      
-      renderer.transform.set_viewport4i (300,400,200,200);
-      renderer.color_buffer.set_color3f(1,1,1);
-      
-      renderer.transform.new_matrix {
-        renderer.transform.rotatef (rot, 1, 1, 1);
-        rot := rot + 0.7;
+      0.to u_res do { u:INTEGER;
         
-        0.to u_res do { u:INTEGER;
-          
-          // horizontal lines
-          renderer.vb.new_line_strip {
-            0.to v_res do { v:INTEGER;
-              surface.evaluate (v.to_real / v_res, u.to_real / u_res);
-            };
+        // horizontal lines
+        renderer.vb.new_line_strip {
+          0.to v_res do { v:INTEGER;
+            surface.evaluate (v.to_real / v_res, u.to_real / u_res);
           };
-          // vertical lines
-          renderer.vb.new_line_strip {
-            0.to v_res do { v:INTEGER;
-              surface.evaluate (u.to_real / u_res, v.to_real / v_res);
-            };
+        };
+        // vertical lines
+        renderer.vb.new_line_strip {
+          0.to v_res do { v:INTEGER;
+            surface.evaluate (u.to_real / u_res, v.to_real / v_res);
           };
         };
       };
+    };
+    
+    //
+    // Filled Bezier surface
+    //
+    
+    renderer.enable_lighting;
+    
+    renderer.transform.set_viewport4i (300,100,300,300);
+    renderer.color_buffer.set_color3f(1,1,1);
+    
+    renderer.transform.new_matrix {
+      renderer.transform.rotatef (rot, 1, 1, 1);
+      rot := rot + 0.2;
+      renderer.transform.scalef (1.5,1.5,1.5);
       
-      //
-      // Filled Bezier surface
-      //
-      
-      renderer.enable_lighting;
-      
-      renderer.transform.set_viewport4i (300,100,300,300);
-      renderer.color_buffer.set_color3f(1,1,1);
-      
-      renderer.transform.new_matrix {
-        renderer.transform.rotatef (rot, 1, 1, 1);
-        rot := rot + 0.2;
-        renderer.transform.scalef (1.5,1.5,1.5);
-        
-        surface.generate_grid (8,8) between (0,1) and (0,1);
-        surface.evaluate_mesh (surface.fill) from (0,0) to (8,8);
-      };
-      
-      renderer.disable_lighting;
-      
-      //----- end rendering
-    }; 
+      surface.generate_grid (8,8) between (0,1) and (0,1);
+      surface.evaluate_mesh (surface.fill) from (0,0) to (8,8);
+    };
+    
+    renderer.disable_lighting;    
   );
   
   - on_resize (w,h:INTEGER) <-
@@ -235,4 +230,4 @@ Section Public
       renderer.transform.load_identity;
       renderer.transform.orthographic (-5.0*ratio,5.0*ratio,-5,5,-5,5);
     };
-  );
\ No newline at end of file
+  );
diff --git a/gl_test/my_scene11.li b/gl_test/my_scene11.li
index 403d8a4..d1e1b33 100644
--- a/gl_test/my_scene11.li
+++ b/gl_test/my_scene11.li
@@ -27,29 +27,28 @@ Section Header
   
 Section Inherit
   
+  - parent_framework:FRAMEWORK := FRAMEWORK;
+  
   + parent_scene:Expanded SCENE;
   
-  - parent_key_listener:KEY_LISTENER := KEY_LISTENER;
+  - parent_key_listener:EVENT_LISTENER := EVENT_LISTENER;
   
 Section Public  
   
   - main <-
   (
-    OPENGL.make (800,600) title "GL Demo test" fullscreen FALSE;
-    ENGINE.make OPENGL;
-    
-    "*** GL Engine ***\n".print;
-    
-    ENGINE.attach_scene Self;
-    ENGINE_INPUT.add_key_listener Self;
-    ENGINE_INPUT.add_mouse_listener MY_EVENT_LISTENER;
+    // create OpenGL device
+    OPENGL.make (800,600) title "GL demo test";
     
-    ENGINE.initialize;
+    // set up framework
+    FRAMEWORK.make OPENGL;
     
-    ENGINE.main_loop;
+    attach_scene Self;
+    add_key_listener Self;
+    add_mouse_listener MY_EVENT_LISTENER;
     
-    ENGINE.shutdown;
-    OPENGL.shutdown;
+    // start it all
+    run;
   );
   
 Section Public
@@ -67,8 +66,8 @@ Section Public
   + material:MATERIAL;
   
   + test:TEXTURE;
-
-  - initialize <-
+  
+  - initialize:BOOLEAN <-
   ( 
     + ambient,diffuse,specular,emission:COLOR;
     + shine:REAL_32;
@@ -105,7 +104,7 @@ Section Public
     renderer.enable_lighting;
     
     renderer.disable_shading; 
-
+    
     renderer.culling.enable;
     renderer.culling.apply_front;
     // renderer.light.set_model_local_viewer TRUE;
@@ -115,38 +114,33 @@ Section Public
     camera.position.make (0,100,50);
     camera.view.make (0,-20,-50);
     camera.view.normalize;
-  
+    TRUE
   );
   + camera:CAMERA;
   
   + xpos:REAL_32;
   + zpos:REAL_32;
-
-  - render t:UINTEGER_32 <-
-  (      
-    renderer.new_frame {
-      //----- begin rendering
-      
-      renderer.font.print_zone {
-        engine.out.print "Height Map test" at (30,40);
-      };
-      
-      camera.look;
-      
-      // render terrain
-      renderer.transform.new_matrix {
-        material.apply_front;
-        terrain.render (renderer.vb) at (xpos, 0, zpos);
-      };
-      
-      // draw height map
-      renderer.light.push_attrib;
-      renderer.transform.ortho_mode (renderer.width,renderer.height) do {
-        test.draw_strech (650,450,100,100);
-      };
-      renderer.light.pop_attrib;
-      //----- end rendering
-    }; 
+  
+  - render t:REAL_32 <-
+  (          
+    renderer.font.print_zone {
+      out.print "Height Map test" at (30,40);
+    };
+    
+    camera.look;
+    
+    // render terrain
+    renderer.transform.new_matrix {
+      material.apply_front;
+      terrain.render (renderer.vb) at (xpos, 0, zpos);
+    };
+    
+    // draw height map
+    renderer.light.push_attrib;
+    renderer.transform.ortho_mode (renderer.width,renderer.height) do {
+      test.draw_strech (650,450,100,100);
+    };
+    renderer.light.pop_attrib;
   );
   
   - keydown k:INTEGER <-
@@ -156,7 +150,9 @@ Section Public
     char := k.to_character.to_upper;
     
     k
-    .when (KEYCODE.k_up) then {
+    .when (KEYCODE.k_escape) then {
+      FRAMEWORK.stop;	 
+    }.when (KEYCODE.k_up) then {
       zpos := zpos + 2;
     }.when (KEYCODE.k_down) then { 
       zpos := zpos - 2; 
@@ -168,8 +164,8 @@ Section Public
     
     char
     .when 'L' then {
-      ENGINE.toggle_lighting; 
+      toggle_lighting; 
     }.when 'W' then {
-      ENGINE.toggle_wireframe;  
+      toggle_wireframe;  
     };
-  );
\ No newline at end of file
+  );
diff --git a/gl_test/my_scene12.li b/gl_test/my_scene12.li
index 41a01d4..100f551 100644
--- a/gl_test/my_scene12.li
+++ b/gl_test/my_scene12.li
@@ -1,162 +1,156 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := MY_SCENE12;
-  
-  - comment   := "first program";
-  
-Section Inherit
-  
-  + parent_scene:Expanded SCENE;
-  
-  - parent_test_any:TEST_ANY := TEST_ANY;
-  
-Section Public  
-  
-  - main <-
-  (
-    start_test Self;
-  );
-  
-Section Public
-  
-  //
-  //  test shaders
-  //
-  
-  + model:MODEL;
-  + texture:TEXTURE;
-  
-  + light:LIGHT;
-  + light_pos:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (5,10,-180);
-  
-  + camera:CAMERA;
-  
-  + shader:SHADER;
-  + lightpos_loc:INTEGER;
-  + sampler_loc:INTEGER;
-  
-  
-  - initialize <-
-  (   
-    + ambient,diffuse,specular:COLOR;
-    + infolog:STRING;
-    
-    camera := CAMERA.create;
-    
-    camera.position.make (0,10,-200);
-    camera.view.make (0,-10,200);
-    camera.view.normalize;
-    
-    // load model
-    texture := renderer.texture2d.create_from (IMAGE.create "data/skin.tga");
-    model := MD2_MODEL.create "data/model.md2" with texture;
-    
-    OPENGL.use_shaders.if_false {
-      engine.log.print "Cannot support GLSL Shaders with ARB extensions";
-    } else {
-      shader := renderer.shader.create ("data/toon.vert","data/toon.frag");
-      shader.enable;
-      
-      shader.has_compiled.if_false {
-        // print error log
-        infolog := STRING.create 32;
-        shader.get_infolog infolog;
-        infolog.print;
-      };
-      
-      lightpos_loc := shader.get_uniform_location "lightPos";
-      sampler_loc := shader.get_uniform_location "Texture";
-    };
-    
-    ambient := RGB.create (0.9, 0.9, 0.9); 
-    diffuse := RGB.create (1.0, 1.0, 1.0);
-    specular := RGB.create (1.0, 1.0, 1.0);
-    
-    // create a light
-    light := renderer.light.create (ambient,diffuse,specular) at light_pos;
-    light.enable;  
-    
-    renderer.enable_lighting;
-    renderer.set_line_width 3;
-    renderer.color_buffer.set_clear_value (0.5,0.5,0.5,0.5);
-    
-    renderer.culling.enable;
-    renderer.culling.apply_front;
-  );
-  
-  - render t:UINTEGER_32 <-
-  (       
-    model.update (t.to_real*0.01);
-    
-    renderer.begin_frame;
-    //----- begin rendering
-    
-    renderer.font.enable;
-    engine.out.print "Toon shading" at (50,100);
-    renderer.font.disable;
-    
-    camera.look;
-    
-    
-    (shader != NULL).if {
-      shader.enable;
-      shader.set_uniform3f lightpos_loc to (light_pos.x,light_pos.y,light_pos.z); 
-      shader.bind_sampler texture unit 0 location sampler_loc;
-    };    
-    
-    // quake2 z axis is opengl y axis
-    renderer.transform.rotatef(-90, 1,0,0);
-    renderer.transform.rotatef(90, 0,0,1);
-    
-    light.enable;
-    
-    //-- render model normally
-    
-    renderer.culling.set_counter_clockwise;
-    model.render;
-    
-    //-- disable shading and change culling order
-    (shader != NULL).if {
-      shader.disable;
-    };    
-    renderer.culling.set_clockwise;
-    
-    // black
-    renderer.color_buffer.set_color4f (0,0,0,0);
-    
-    // render outlines
-    renderer.wireframe_mode TRUE;
-    model.render;
-    renderer.wireframe_mode FALSE;
-    
-    //----- end rendering
-    renderer.end_frame;
-  );
-  
-  - release <-
-  (
-    (shader != NULL).if {
-      shader.delete;
-    };
-  );
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := MY_SCENE12;
+  
+  - comment   := "first program";
+  
+Section Inherit
+  
+  + parent_scene:Expanded SCENE;
+  
+  - parent_test_any:TEST_ANY := TEST_ANY;
+  
+Section Public  
+  
+  - main <-
+  (
+    start_test Self using CAPABILITIES;
+  );
+  
+Section Public
+  
+  //
+  //  test shaders
+  //
+  
+  + model:MODEL;
+  + texture:TEXTURE;
+  
+  + light:LIGHT;
+  + light_pos:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (5,10,-180);
+  
+  + camera:CAMERA;
+  
+  + shader:SHADER;
+  + lightpos_loc:INTEGER;
+  + sampler_loc:INTEGER;
+  
+  
+  - initialize:BOOLEAN <-
+  (   
+    + ambient,diffuse,specular:COLOR;
+    + infolog:STRING;
+    
+    camera := CAMERA.create;
+    
+    camera.position.make (0,10,-200);
+    camera.view.make (0,-10,200);
+    camera.view.normalize;
+    
+    // load model
+    texture := renderer.texture2d.create_from (IMAGE.create "data/skin.tga");
+    model := MD2_MODEL.create "data/model.md2" with texture;
+    
+    OPENGL.use_shaders.if_false {
+      log.print "Cannot support GLSL Shaders with ARB extensions";
+    } else {
+      shader := renderer.shader.create ("data/toon.vert","data/toon.frag");
+      shader.enable;
+      
+      shader.has_compiled.if_false {
+        // print error log
+        infolog := STRING.create 32;
+        shader.get_infolog infolog;
+        infolog.print;
+      };
+      
+      lightpos_loc := shader.get_uniform_location "lightPos";
+      sampler_loc := shader.get_uniform_location "Texture";
+    };
+    
+    ambient := RGB.create (0.9, 0.9, 0.9); 
+    diffuse := RGB.create (1.0, 1.0, 1.0);
+    specular := RGB.create (1.0, 1.0, 1.0);
+    
+    // create a light
+    light := renderer.light.create (ambient,diffuse,specular) at light_pos;
+    light.enable;  
+    
+    renderer.enable_lighting;
+    renderer.set_line_width 3;
+    renderer.color_buffer.set_clear_value (0.5,0.5,0.5,0.5);
+    
+    renderer.culling.enable;
+    renderer.culling.apply_front;
+    TRUE
+  );
+  
+  - render t:REAL_32 <-
+  (       
+    model.update (t*10);
+    
+    renderer.font.enable;
+    out.print "Toon shading" at (50,100);
+    renderer.font.disable;
+    
+    camera.look;
+    
+    (shader != NULL).if {
+      shader.enable;
+      shader.set_uniform3f lightpos_loc to (light_pos.x,light_pos.y,light_pos.z); 
+      shader.bind_sampler texture unit 0 location sampler_loc;
+    };    
+    
+    // quake2 z axis is opengl y axis
+    renderer.transform.rotatef(-90, 1,0,0);
+    renderer.transform.rotatef(90, 0,0,1);
+    
+    light.enable;
+    
+    //-- render model normally
+    
+    renderer.culling.set_counter_clockwise;
+    model.render;
+    
+    //-- disable shading and change culling order
+    (shader != NULL).if {
+      shader.disable;
+    };    
+    renderer.culling.set_clockwise;
+    
+    // black
+    renderer.color_buffer.set_color4f (0,0,0,0);
+    
+    // render outlines
+    renderer.wireframe_mode TRUE;
+    model.render;
+    renderer.wireframe_mode FALSE;
+  );
+  
+  - release <-
+  (
+    (shader != NULL).if {
+      shader.delete;
+    };
+  );
diff --git a/gl_test/my_scene2.li b/gl_test/my_scene2.li
index dd13ed4..d4af916 100644
--- a/gl_test/my_scene2.li
+++ b/gl_test/my_scene2.li
@@ -35,7 +35,7 @@ Section Public
   
   - main <-
   (
-    start_test Self;
+    start_test Self using CAPABILITIES;
   );
   
 Section Public
@@ -48,17 +48,19 @@ Section Public
   
   + sphere:SPHERE := SPHERE.create (VECTOR3[REAL_32].create (0,0,0),2,10,10);
   
-  + vb:VERTEX_BUFFER := GL_VERTEX_BUFFER;
+  + vb:VERTEX_BUFFER;
   
   + green:COLOR := RGB.create (0.0, 1.0, 0.0);
   
-  - render t:UINTEGER_32 <-
+  - initialize:BOOLEAN <-
+  (
+    vb := renderer.vertex_buffer;
+    TRUE
+  );
+
+  - render t:REAL_32 <-
   (      
     camera.animate t;
-    
-    renderer.begin_frame;
-    //----- begin rendering
-    
     camera.look;
     
     //
@@ -86,8 +88,5 @@ Section Public
       
       vb.end;
     };
-    
-    //----- end rendering
-    renderer.end_frame;
   );
-  
\ No newline at end of file
+  
diff --git a/gl_test/my_scene3.li b/gl_test/my_scene3.li
index d2e709a..6536911 100644
--- a/gl_test/my_scene3.li
+++ b/gl_test/my_scene3.li
@@ -35,7 +35,7 @@ Section Public
   
   - main <-
   (
-    start_test Self;
+    start_test Self using CAPABILITIES;
   );
   
 Section Public
@@ -54,7 +54,7 @@ Section Public
   
   + alpha:REAL_32;
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   (    
     + x,y:REAL_32;
     
@@ -64,10 +64,10 @@ Section Public
     bl := renderer.blending;
     
     OPENGL.use_arb_vertex_buffer_object.if_false {
-      engine.log.print "Cannot support ARB_vertex_buffer_object extension";
+      log.print "Cannot support ARB_vertex_buffer_object extension";
     };
     OPENGL.use_arb_multitexture.if_false {
-      engine.log.print "Cannot support ARB_multitexture extension";
+      log.print "Cannot support ARB_multitexture extension";
     };
     
     x := 40;
@@ -93,19 +93,17 @@ Section Public
       texel_array.add_texel2f (0, 1);
       texel_array.add_texel2f (1, 1);
     };
+    TRUE
   );
   
-  - render t:UINTEGER_32 <-
+  - render t:REAL_32 <-
   (       
     + x,y:INTEGER;
-    
-    renderer.begin_frame;
-    //----- begin rendering
-    
+   
     renderer.font.print_zone {
       renderer.color_buffer.set_color3f (1,0,0);
-      engine.out.print "MultiTexture test" at (100, 80);
-      engine.out.print "Blending test" at (400, 80);
+      out.print "MultiTexture test" at (100, 80);
+      out.print "Blending test" at (400, 80);
     };  
     
     // orthographic mode (2d)
@@ -156,8 +154,5 @@ Section Public
       
       bl.disable;
     }; 
-    
-    //----- end rendering
-    renderer.end_frame;
   );
-  
\ No newline at end of file
+  
diff --git a/gl_test/my_scene4.li b/gl_test/my_scene4.li
index 2db0330..5c0f226 100644
--- a/gl_test/my_scene4.li
+++ b/gl_test/my_scene4.li
@@ -1,162 +1,160 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := MY_SCENE4;
-  
-  - comment   := "first program";
-  
-Section Inherit
-  
-  + parent_scene:Expanded SCENE;
-  
-  - parent_key_listener:KEY_LISTENER := KEY_LISTENER;
-  
-Section Public  
-  
-  - main <-
-  ( 
-    OPENGL.make (800,600) title "GL Demo test" fullscreen FALSE;
-    ENGINE.make OPENGL;
-      
-    ENGINE.attach_scene Self;
-    ENGINE_INPUT.add_key_listener Self;
-    ENGINE_INPUT.add_mouse_listener MY_EVENT_LISTENER;
-    
-    ENGINE.initialize;
-    
-    ENGINE.main_loop;
-    
-    ENGINE.shutdown;
-    OPENGL.shutdown;
-  );
-  
-Section Public
-  
-  //
-  //  test particule engine
-  //
-  
-  
-  // origine de l'explosion
-  - orig:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0.0,0,0.0);
-  
-  + camera:CAMERA := CAMERA.create_position (VECTOR3[REAL_32].create (0,20,-300));
-  
-  + particle_system:PARTICLE_SYSTEM;
-  + pf_pos:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (-0.5,1.0,1.0);
-  
-  + constraint:CONSTRAINT;
-  
-  + tex:TEXTURE;
-  
-  + color_scheme:INTEGER;
-  
-  
-  + modelview:MATRIX4[REAL_32];
-  
-  
-  - initialize <-
-  (
-    camera.view.make (0, -20, 300);
-    camera.view.normalize;
-    
-    particle_system := PARTICLE_SYSTEM.create orig;
- 
-    //
-    // constraints test
-    //
-    
-    constraint := POINT_FORCE.create (pf_pos,0.01,0,0.001);
-    particle_system.add_constraint constraint;    
-    
-    constraint := BOUNCE_PLANE.create (VECTOR3[REAL_32].create (0,1,0), 40);
-    particle_system.add_constraint constraint;
-    
-    
-    // load particle texture
-    tex.set_wrapping_mode (tex.clamp);
-    tex := renderer.texture2d.create_from (IMAGE.create "data/flare.bmp");
-    
-    modelview := MATRIX4[REAL_32].create;
-  );
-  
-  + dx:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0,0,0);
-  + dy:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0,0,0);
-  
-  + curtime:REAL_32;
-  
-  + sphere:SPHERE := SPHERE.create (VECTOR3[REAL_32].create (0,0,0),2,10,10);
-  
-  - render t:UINTEGER_32 <-
-  (         
-    renderer.begin_frame;
-    //----- begin rendering
-    
-    camera.look;
-    renderer.transform.get_modelview modelview;
-    
-    curtime := curtime + t.to_real * 0.01;
-    
-    pf_pos.set_x (100.0 * (0.78*curtime).cos);
-    pf_pos.set_y (50.0 * (0.3*curtime).cos);
-    pf_pos.set_z (100.0 * (1.0*curtime).sin);  
-    
-    // let particles face the camera (billboard) 
-    dx.make (modelview.item (0,0), modelview.item (1,0), modelview.item (2,0));
-    dy.make (modelview.item (0,1), modelview.item (1,1), modelview.item (2,1));
-    
-    renderer.blending.apply (renderer.blending.one_minus_dst_color,renderer.blending.one);
-    renderer.blending.enable;//////
-    
-    particle_system.update (t.to_real);
-    
-    // render scene
-    tex.bind;
-    particle_system.render (dx,dy);
-    
-    tex.disable;
-    renderer.transform.new_matrix {
-      sphere.render;
-      renderer.transform.translatef(pf_pos.x,pf_pos.y,pf_pos.z);
-      sphere.render;
-    };
-    
-    //----- end rendering
-    renderer.end_frame;
-  );
-  
-  - keydown k:INTEGER <-
-  (
-    color_scheme := (color_scheme+1) % 4;
-    
-    color_scheme
-    .when 0 then {
-      particle_system.set_color_fire;
-    }.when 1 then {
-      particle_system.set_color_ice;
-    }.when 2 then {
-      particle_system.set_color_smoke;
-    }.when 3 then {
-      particle_system.set_color_rainbow;
-    };
-  );
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := MY_SCENE4;
+  
+  - comment   := "first program";
+  
+Section Inherit
+  
+  - parent_framework:FRAMEWORK := FRAMEWORK;
+
+  + parent_scene:Expanded SCENE;
+
+  - parent_event_listener:EVENT_LISTENER := EVENT_LISTENER;
+  
+Section Public  
+
+  - main <-
+  (    
+    // create OpenGL device
+    OPENGL.make (800,600) title "GL demo test";
+    
+    // set up framework
+    FRAMEWORK.make OPENGL;
+    
+    attach_scene Self;
+    add_key_listener Self;
+ 
+    // start it all
+    run;
+  );
+  
+Section Public
+  
+  //
+  //  test particule engine
+  //
+
+  // origine de l'explosion
+  - orig:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0.0,0,0.0);
+  
+  + camera:CAMERA := CAMERA.create_position (VECTOR3[REAL_32].create (0,20,-300));
+  
+  + particle_system:PARTICLE_SYSTEM;
+  + pf_pos:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (-0.5,1.0,1.0);
+  
+  + constraint:CONSTRAINT;
+  
+  + tex:TEXTURE;
+  
+  + color_scheme:INTEGER;
+  
+  
+  + modelview:MATRIX4[REAL_32];
+  
+  
+  - initialize:BOOLEAN <-
+  (
+    camera.view.make (0, -20, 300);
+    camera.view.normalize;
+    
+    particle_system := PARTICLE_SYSTEM.create orig;
+ 
+    //
+    // constraints test
+    //
+    
+    constraint := POINT_FORCE.create (pf_pos,0.8,0,0.001);
+    particle_system.add_constraint constraint;    
+    
+    constraint := BOUNCE_PLANE.create (VECTOR3[REAL_32].create (0,1,0), 40);
+    particle_system.add_constraint constraint;
+    
+    
+    // load particle texture
+    tex.set_wrapping_mode (tex.clamp);
+    tex := renderer.texture2d.create_from (IMAGE.create "data/flare.bmp");
+    
+    modelview := MATRIX4[REAL_32].create;
+    TRUE
+  );
+  
+  + dx:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0,0,0);
+  + dy:VECTOR3[REAL_32] := VECTOR3[REAL_32].create (0,0,0);
+  
+  + curtime:REAL_32;
+  
+  + sphere:SPHERE := SPHERE.create (VECTOR3[REAL_32].create (0,0,0),2,10,10);
+  
+  - render t:REAL_32 <-
+  (          
+    camera.look;
+    renderer.transform.get_modelview modelview;
+    
+    curtime := curtime + t;
+    
+    pf_pos.set_x (100.0 * (0.78*curtime).cos);
+    pf_pos.set_y (50.0 * (0.3*curtime).cos);
+    pf_pos.set_z (100.0 * (1.0*curtime).sin);  
+    
+    // let particles face the camera (billboard) 
+    dx.make (modelview.item (0,0), modelview.item (1,0), modelview.item (2,0));
+    dy.make (modelview.item (0,1), modelview.item (1,1), modelview.item (2,1));
+    
+    renderer.blending.apply (renderer.blending.one_minus_dst_color,renderer.blending.one);
+    renderer.blending.enable;//////
+    
+    particle_system.update (t);
+    
+    // render scene
+    tex.bind;
+    particle_system.render (dx,dy);
+    
+    tex.disable;
+    renderer.transform.new_matrix {
+      sphere.render;
+      renderer.transform.translatef(pf_pos.x,pf_pos.y,pf_pos.z);
+      sphere.render;
+    };
+  );
+  
+  - keydown k:INTEGER <-
+  (
+    (k = KEYCODE.k_escape).if {
+       FRAMEWORK.stop;
+    };
+
+    color_scheme := (color_scheme+1) % 4;
+    
+    color_scheme
+    .when 0 then {
+      particle_system.set_color_fire;
+    }.when 1 then {
+      particle_system.set_color_ice;
+    }.when 2 then {
+      particle_system.set_color_smoke;
+    }.when 3 then {
+      particle_system.set_color_rainbow;
+    };
+  );
diff --git a/gl_test/my_scene5.li b/gl_test/my_scene5.li
index 8c8defe..2e3c9bd 100644
--- a/gl_test/my_scene5.li
+++ b/gl_test/my_scene5.li
@@ -35,7 +35,7 @@ Section Public
   
   - main <-
   (
-    start_test Self;
+    start_test Self using CAPABILITIES;
   );
   
 Section Public
@@ -53,7 +53,7 @@ Section Public
   
   + light_position:VECTOR3[REAL_32];
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   (
     + ambient,diffuse,specular,emission:COLOR;
     + shine:REAL_32;
@@ -66,7 +66,7 @@ Section Public
     specular := RGB.create (1.0, 1.0, 1.0);
     
     light_position := VECTOR3[REAL_32].create (0,0,1);
-    light := GL_LIGHT.create (ambient,diffuse,specular) at light_position;
+    light := renderer.light.create (ambient,diffuse,specular) at light_position;
     
     ambient := RGB.create (0.7, 0.7, 0.7); 
     diffuse := RGB.create (0.1, 0.5, 0.9);
@@ -74,7 +74,7 @@ Section Public
     emission := RGB.create (0.3, 0.2, 0.2);
     shine := 100.0;
     
-    m1 := GL_MATERIAL.create (ambient,diffuse,specular,emission,shine);
+    m1 := renderer.material.create (ambient,diffuse,specular,emission,shine);
     
     ambient := RGB.create (0.0, 0.0, 0.0); 
     diffuse := RGB.create (0.9, 0.5, 0.0);
@@ -82,25 +82,24 @@ Section Public
     emission := RGB.create (0.3, 0.2, 0.2);
     shine := 3.0;
     
-    m2 := GL_MATERIAL.create (ambient,diffuse,specular,emission,shine);
+    m2 := renderer.material.create (ambient,diffuse,specular,emission,shine);
     
     renderer.enable_lighting;    
+    TRUE
   );
   
   + spin:INTEGER;
   
-  - render t:UINTEGER_32 <-
-  (  
-    
-    renderer.begin_frame;
-    //----- begin rendering
-    
-    spin := (spin + t / 2) % 360;
+  - render t:REAL_32 <-
+  (   
+    spin := (spin + (t*300).to_integer) % 360;
     
     renderer.transform.push_matrix;
     //--
+    renderer.transform.translatef(0.0, 0.0, -1.0);
     renderer.transform.rotatef(spin.to_real, 1.0, 0.0, 0.0);
     renderer.transform.rotatef(0.0, 1.0, 0.0, 0.0);
+
     light.set_position light_position;
     light.enable;
     //--
@@ -111,8 +110,5 @@ Section Public
     
     m2.apply (MATERIAL.mode_front);
     sphere2.render;
-    
-    //----- end rendering
-    renderer.end_frame;
   );
-  
\ No newline at end of file
+  
diff --git a/gl_test/my_scene6.li b/gl_test/my_scene6.li
index 9e8ea3b..2f38164 100644
--- a/gl_test/my_scene6.li
+++ b/gl_test/my_scene6.li
@@ -35,9 +35,9 @@ Section Public
   
   - main <-
   (    
-    SETTINGS.use_accum_buffer;
+    CAPABILITIES.use_accum_buffer;
     
-    start_test Self;
+    start_test Self using CAPABILITIES;
   );
   
 Section Public
@@ -51,7 +51,7 @@ Section Public
   + light:LIGHT;
   + m:MATERIAL;
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   (    
     + ambient,diffuse,specular,emission:COLOR;
     + shine:REAL_32;
@@ -95,10 +95,11 @@ Section Public
     
     m := renderer.material.create (ambient,diffuse,specular,emission,shine); 
     light.enable;
+    TRUE
   );
   
   
-  - render t:UINTEGER_32 <-
+  - render t:REAL_32 <-
   (      
     //
     // accumulation test (motion blur effect)
@@ -142,8 +143,8 @@ Section Public
     
     renderer.font.enable;
     
-    engine.out.print "Test display lists" at (100,50);
-    engine.out.print "Test accumulation buffer" at (100,350);
+    out.print "Test display lists" at (100,50);
+    out.print "Test accumulation buffer" at (100,350);
     
     renderer.font.disable;
  
@@ -156,8 +157,5 @@ Section Public
         renderer.transform.translatef(0.4,0.0,0.0);
       };
     };
-    
-    //----- end rendering
-    renderer.end_frame;
   );
-  
\ No newline at end of file
+  
diff --git a/gl_test/my_scene7.li b/gl_test/my_scene7.li
index 15c07d7..07d26de 100644
--- a/gl_test/my_scene7.li
+++ b/gl_test/my_scene7.li
@@ -35,7 +35,7 @@ Section Public
   
   - main <-
   (
-    start_test Self;
+    start_test Self using CAPABILITIES;
   );
   
 Section Public
@@ -59,7 +59,7 @@ Section Public
   + fog:FOG;
   
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   (
     + ambient,diffuse,specular,emission:COLOR;
     
@@ -91,28 +91,23 @@ Section Public
     camera.position.make (0,5,-1);
     camera.view.make (0,-5,1);
     camera.view.normalize;
+    TRUE
   );  
   
   
-  - render t:UINTEGER_32 <-
+  - render t:REAL_32 <-
   (  
-    renderer.new_frame {
-      //----- begin rendering
-      
-      renderer.font.print_zone {
-        engine.out.print "Texture Mapping" at (100,50);
-      };
-      
-      light.enable;
-      renderer.depth_buffer.enable;
-      
-      camera.look;
-      
-      renderer.transform.new_matrix {
-        draw_cube;
-      };
-      
-      //----- end rendering
+    renderer.font.print_zone {
+      out.print "Texture Mapping" at (100,50);
+    };
+    
+    light.enable;
+    renderer.depth_buffer.enable;
+    
+    camera.look;
+    
+    renderer.transform.new_matrix {
+      draw_cube;
     };
   );
   
@@ -166,4 +161,4 @@ Section Public
     xrot := xrot + 0.3;
     yrot := yrot + 0.2;
     zrot := zrot + 0.4;
-  );
\ No newline at end of file
+  );
diff --git a/gl_test/my_scene8.li b/gl_test/my_scene8.li
index 9949b65..dd22488 100644
--- a/gl_test/my_scene8.li
+++ b/gl_test/my_scene8.li
@@ -1,214 +1,207 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name     := MY_SCENE8;
-  
-  - comment   := "first program";
-  
-Section Inherit
-  
-  + parent_scene:Expanded SCENE;
-    
-  - parent_test_any:TEST_ANY := TEST_ANY;
-  
-Section Public  
-  
-  - main <-
-  (
-    SETTINGS.use_stencil_buffer;
-    
-    start_test Self;
-  );
-  
-Section Public
-  
-  //
-  //  test model
-  //
-  
-  + model:MODEL;
-  + texture:TEXTURE;
-  + material:MATERIAL;
-  
-  + floor:TEXTURE;
-
-  + floor_plane:PLANE;
-  + light:LIGHT;
-  
-  + camera:CAMERA;
-  
-  - initialize <-
-  (   
-    + ambient,diffuse,specular:COLOR;
-    
-    camera := CAMERA.create;
-    
-    camera.position.make (0,10,-200);
-    camera.view.make (0,-10,200);
-    camera.view.normalize;
-    
-    // load textures
-    texture := renderer.texture2d.create_from (IMAGE.create "data/skin.tga");
-    floor := renderer.texture2d.create_from (IMAGE.create "data/floor.tga");
-    
-    // load model
-    model := MD2_MODEL.create "data/model.md2" with texture;
-    
-    ambient := RGB.create (0.9, 0.9, 0.9); 
-    diffuse := RGB.create (1.0, 1.0, 1.0);
-    specular := RGB.create (1.0, 1.0, 1.0);
-    
-    // create a light
-    light := renderer.light.create (ambient,diffuse,specular) at (VECTOR3[REAL_32].create (0,10,-200));
-    light.set_directional;
-    light.enable;  
-    
-    ambient := RGB.create (0.8, 0.8, 1); 
-    diffuse := RGB.create (0, 0, 1);
-    
-    material := renderer.material.create (ambient,diffuse,specular,RGB.zero,50);    
-    model.set_material material;
-    
-    floor_plane := renderer.plane.create (0,0,-1,0);
-    
-    // clear stencil to false
-    renderer.stencil_buffer.set_clear_value 0.0;
-  );
-  
-  - render t:UINTEGER_32 <-
-  (       
-    model.update (t.to_real*0.01);
-    
-    renderer.begin_frame;
-    //----- begin rendering
-    
-    renderer.font.enable;
-    
-    engine.out.print "MD2 test" at (50,100);
-    
-    renderer.font.disable;
-    
-    camera.look;
-    
-    //
-    // First pass: draw an invisible mask of the floor in the stencil buffer
-    //
-    
-    // disable drawing in color buffer
-    renderer.color_buffer.disable;
-    
-    renderer.stencil_buffer.enable;
-    
-    // stencil test always pass and set stencil value to 1 
-    renderer.stencil_buffer.set_function (renderer.stencil_buffer.always) value 1 mask 1;
-    
-    // if test successful replace stencil value else keep the old value
-    renderer.stencil_buffer.when_pass (renderer.stencil_buffer.replace) when_fail (renderer.stencil_buffer.keep) when_zfail (renderer.stencil_buffer.keep);
-    
-    renderer.depth_buffer.disable;
-    
-    draw_floor;
-    
-    // back to color mode
-    renderer.depth_buffer.enable;
-    renderer.color_buffer.enable;
-    
-    //
-    // Second pass: draw reflections in the masked floor (stencil test enabled)
-    //
-    
-    // only draw pixels masked with 1 in stencil buffer
-    renderer.stencil_buffer.set_function (renderer.stencil_buffer.equal) value 1 mask 1;
-    renderer.stencil_buffer.lock; // read-only
-    
-    renderer.blending.set_alpha_value 0.7;
-    renderer.blending.apply (renderer.blending.src_alpha,renderer.blending.one_minus_src_alpha); 
- 
-    renderer.blending.enable;
-    renderer.depth_buffer.disable;
-    
-    // clip upper part of reflected object
-    floor_plane.clip;
-    
-    renderer.transform.new_matrix {
-      
-      // mirror y axis
-      renderer.transform.scalef (1.0, -1.0, 1.0);
-      renderer.transform.translatef (0.0, 130, 0.0);
-      
-      // quake2 z axis is opengl y axis
-      renderer.transform.rotatef(-90, 1,0,0);
-      renderer.transform.rotatef(90, 0,0,1);
-      
-      model.render;
-    };
-    
-    // back to normal mode
-    floor_plane.unclip;
-    renderer.stencil_buffer.disable;
-    renderer.depth_buffer.enable;
-    //
-    // Third pass: draw scene normally
-    //
-
-    draw_floor;
-    
-    // quake2 z axis is opengl y axis
-    renderer.transform.rotatef(-90, 1,0,0);
-    renderer.transform.rotatef(90, 0,0,1);
-    
-    renderer.blending.disable;
-    
-    model.render;
-    
-    renderer.vb.draw;
-    
-    //----- end rendering
-    renderer.end_frame;
-  );
-  
-  - draw_floor <-
-  (        
-    floor.bind;
-    
-    renderer.transform.new_matrix {
-      
-      renderer.transform.translatef (0.0, -80.0, 0);
-      
-      renderer.vb.new_quads {
-        renderer.vb.add_normal3f (0.0, 1.0, 0.0);
-        
-        renderer.vb.add_texel2f (0.0, 1.0);
-        renderer.vb.add_vertex3f (-200.0, 0.0, 200.0);
-        
-        renderer.vb.add_texel2f (0.0, 0.0);
-        renderer.vb.add_vertex3f (-200.0, 0.0, -200.0);
-        
-        renderer.vb.add_texel2f (1.0, 0.0);
-        renderer.vb.add_vertex3f (200.0, 0.0, -200.0);
-        
-        renderer.vb.add_texel2f (1.0, 1.0);
-        renderer.vb.add_vertex3f (200.0, 0.0, 200.0);
-      };
-    };
-  );
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name     := MY_SCENE8;
+  
+  - comment   := "first program";
+  
+Section Inherit
+  
+  + parent_scene:Expanded SCENE;
+    
+  - parent_test_any:TEST_ANY := TEST_ANY;
+  
+Section Public  
+  
+  - main <-
+  (
+    CAPABILITIES.use_stencil_buffer;
+    
+    start_test Self using CAPABILITIES;
+  );
+  
+Section Public
+  
+  //
+  //  test model
+  //
+  
+  + model:MODEL;
+  + texture:TEXTURE;
+  + material:MATERIAL;
+  
+  + floor:TEXTURE;
+
+  + floor_plane:PLANE;
+  + light:LIGHT;
+  
+  + camera:CAMERA;
+  
+  - initialize:BOOLEAN <-
+  (   
+    + ambient,diffuse,specular:COLOR;
+    
+    camera := CAMERA.create;
+    
+    camera.position.make (0,10,-200);
+    camera.view.make (0,-10,200);
+    camera.view.normalize;
+    
+    // load textures
+    texture := renderer.texture2d.create_from (IMAGE.create "data/skin.tga");
+    floor := renderer.texture2d.create_from (IMAGE.create "data/floor.tga");
+    
+    // load model
+    model := MD2_MODEL.create "data/model.md2" with texture;
+    
+    ambient := RGB.create (0.9, 0.9, 0.9); 
+    diffuse := RGB.create (1.0, 1.0, 1.0);
+    specular := RGB.create (1.0, 1.0, 1.0);
+    
+    // create a light
+    light := renderer.light.create (ambient,diffuse,specular) at (VECTOR3[REAL_32].create (0,10,-200));
+    light.set_directional;
+    light.enable;  
+    
+    ambient := RGB.create (0.8, 0.8, 1); 
+    diffuse := RGB.create (0, 0, 1);
+    
+    material := renderer.material.create (ambient,diffuse,specular,RGB.zero,50);    
+    model.set_material material;
+    
+    floor_plane := renderer.plane.create (0,0,-1,0);
+    
+    // clear stencil to false
+    renderer.stencil_buffer.set_clear_value 0.0;
+    TRUE
+  );
+  
+  - render t:REAL_32 <-
+  (       
+    model.update (t*10);
+    
+    renderer.font.enable;
+    out.print "MD2 test" at (50,100);
+    renderer.font.disable;
+    
+    camera.look;
+    
+    //
+    // First pass: draw an invisible mask of the floor in the stencil buffer
+    //
+    
+    // disable drawing in color buffer
+    renderer.color_buffer.disable;
+    
+    renderer.stencil_buffer.enable;
+    
+    // stencil test always pass and set stencil value to 1 
+    renderer.stencil_buffer.set_function (renderer.stencil_buffer.always) value 1 mask 1;
+    
+    // if test successful replace stencil value else keep the old value
+    renderer.stencil_buffer.when_pass (renderer.stencil_buffer.replace) when_fail (renderer.stencil_buffer.keep) when_zfail (renderer.stencil_buffer.keep);
+    
+    renderer.depth_buffer.disable;
+    
+    draw_floor;
+    
+    // back to color mode
+    renderer.depth_buffer.enable;
+    renderer.color_buffer.enable;
+    
+    //
+    // Second pass: draw reflections in the masked floor (stencil test enabled)
+    //
+    
+    // only draw pixels masked with 1 in stencil buffer
+    renderer.stencil_buffer.set_function (renderer.stencil_buffer.equal) value 1 mask 1;
+    renderer.stencil_buffer.lock; // read-only
+    
+    renderer.blending.set_alpha_value 0.7;
+    renderer.blending.apply (renderer.blending.src_alpha,renderer.blending.one_minus_src_alpha); 
+ 
+    renderer.blending.enable;
+    renderer.depth_buffer.disable;
+    
+    // clip upper part of reflected object
+    floor_plane.clip;
+    
+    renderer.transform.new_matrix {
+      
+      // mirror y axis
+      renderer.transform.scalef (1.0, -1.0, 1.0);
+      renderer.transform.translatef (0.0, 130, 0.0);
+      
+      // quake2 z axis is opengl y axis
+      renderer.transform.rotatef(-90, 1,0,0);
+      renderer.transform.rotatef(90, 0,0,1);
+      
+      model.render;
+    };
+    
+    // back to normal mode
+    floor_plane.unclip;
+    renderer.stencil_buffer.disable;
+    renderer.depth_buffer.enable;
+    //
+    // Third pass: draw scene normally
+    //
+
+    draw_floor;
+    
+    // quake2 z axis is opengl y axis
+    renderer.transform.rotatef(-90, 1,0,0);
+    renderer.transform.rotatef(90, 0,0,1);
+    
+    renderer.blending.disable;
+    
+    model.render;
+    
+    renderer.vb.draw;
+  );
+  
+  - draw_floor <-
+  (        
+    floor.bind;
+    
+    renderer.transform.new_matrix {
+      
+      renderer.transform.translatef (0.0, -80.0, 0);
+      
+      renderer.vb.new_quads {
+        renderer.vb.add_normal3f (0.0, 1.0, 0.0);
+        
+        renderer.vb.add_texel2f (0.0, 1.0);
+        renderer.vb.add_vertex3f (-200.0, 0.0, 200.0);
+        
+        renderer.vb.add_texel2f (0.0, 0.0);
+        renderer.vb.add_vertex3f (-200.0, 0.0, -200.0);
+        
+        renderer.vb.add_texel2f (1.0, 0.0);
+        renderer.vb.add_vertex3f (200.0, 0.0, -200.0);
+        
+        renderer.vb.add_texel2f (1.0, 1.0);
+        renderer.vb.add_vertex3f (200.0, 0.0, 200.0);
+      };
+    };
+  );
diff --git a/gl_test/my_scene9.li b/gl_test/my_scene9.li
index c4bc4a2..308929b 100644
--- a/gl_test/my_scene9.li
+++ b/gl_test/my_scene9.li
@@ -27,29 +27,28 @@ Section Header
   
 Section Inherit
   
+  - parent_framework:FRAMEWORK := FRAMEWORK;
+
   + parent_scene:Expanded SCENE;
   
-  - parent_mouse_listener:MOUSE_LISTENER := MOUSE_LISTENER;
+  - parent_mouse_listener:EVENT_LISTENER := EVENT_LISTENER;
   
 Section Public  
   
   - main <-
   (   
-    OPENGL.make (800,600) title "GL Demo test" fullscreen FALSE;
-    ENGINE.make OPENGL;
-    
-    "*** GL Engine ***\n".print;
-    
-    ENGINE.attach_scene Self;
-    ENGINE_INPUT.add_key_listener MY_EVENT_LISTENER;
-    ENGINE_INPUT.add_mouse_listener Self;
-    
-    ENGINE.initialize;
+    // create OpenGL device
+    OPENGL.make (800,600) title "GL Demo test";
     
-    ENGINE.main_loop;
+    // set up framework
+    FRAMEWORK.make OPENGL;
     
-    ENGINE.shutdown;
-    OPENGL.shutdown;
+    attach_scene Self;
+    add_key_listener MY_EVENT_LISTENER;
+    add_mouse_listener Self;
+
+    // start it all
+    run;
   );
   
 Section Public
@@ -62,7 +61,7 @@ Section Public
   
   + camera:CAMERA;
   
-  - initialize <-
+  - initialize:BOOLEAN <-
   (    
     + sphere:SPHERE;
     + cylinder:CYLINDER;
@@ -114,17 +113,15 @@ Section Public
     renderer.enable_lighting;
     renderer.light.enable_default_light;
     renderer.material.enable_color; // enable color & material
+    TRUE
   );
   
   - obj_selected:INTEGER := -1;
   
-  - render t:UINTEGER_32 <-
+  - render t:REAL_32 <-
   (  
     + x:INTEGER;
     
-    renderer.begin_frame;
-    //----- begin rendering
- 
     camera.look;
     
     update_objects;
@@ -132,24 +129,21 @@ Section Public
   
     x := renderer.width / 2 - 50;
     renderer.font.print_zone {
-      engine.out.print "Pick an object" at (x,50);
+      out.print "Pick an object" at (x,50);
       obj_selected
       .when 0 then {
-        engine.out.print "You picked a sphere" at (x,500);
+        out.print "You picked a sphere" at (x,500);
       }
       .when 1 then {
-        engine.out.print "You picked a cylinder" at (x,500)  
+        out.print "You picked a cylinder" at (x,500)  
       }
       .when 2 then {
-        engine.out.print "You picked a cone" at (x,500);         
+        out.print "You picked a cone" at (x,500);         
       }
       .when (-1) then {
-        engine.out.print "No selected object" at (x,500);
+        out.print "No selected object" at (x,500);
       };
     };
-    
-    //----- end rendering
-    renderer.end_frame;
   );
   
   - update_objects <-
@@ -205,17 +199,17 @@ Section Public
     };
   );
   
-  - click button:INTEGER <-
+  - click b:INTEGER <-
   (
     + nb_hits:INTEGER;
     + x,y:UINTEGER_32;
     + v:VIEWPORT;
     
-    ((button & 1) == 0).if {
+    ((b & 1) == 0).if {
       // left click
       
-      x := INPUT_SYSTEM.mouse_x;
-      y := INPUT_SYSTEM.mouse_y;
+      x := event.mouse_x;
+      y := event.mouse_y;
       v := renderer.viewport;
       
       // start selection mode, hits are recorded in 'hits' array
@@ -245,4 +239,4 @@ Section Public
       nb_hits := renderer.end_selection;
       process_hits (nb_hits, hits);
     };
-  );
\ No newline at end of file
+  );
diff --git a/gl_test/test_any.li b/gl_test/test_any.li
index 85558a4..6f1a392 100644
--- a/gl_test/test_any.li
+++ b/gl_test/test_any.li
@@ -1,53 +1,50 @@
-///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
-//                                                                           //
-//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
-//                                                                           //
-//   This program is free software: you can redistribute it and/or modify    //
-//   it under the terms of the GNU General Public License as published by    //
-//   the Free Software Foundation, either version 3 of the License, or       //
-//   (at your option) any later version.                                     //
-//                                                                           //
-//   This program is distributed in the hope that it will be useful,         //
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
-//   GNU General Public License for more details.                            //
-//                                                                           //
-//   You should have received a copy of the GNU General Public License       //
-//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
-//                                                                           //
-//                     http://isaacproject.u-strasbg.fr/                     //
-///////////////////////////////////////////////////////////////////////////////
-
-Section Header
-  
-  + name        := TEST_ANY;
-  
-  - author      := "Damien Bouvarel(dams.bouvarel at wanadoo.fr)";
-  
-Section Inherit
-  
-  - parent_object:OBJECT := OBJECT;
-  
-Section Public  
- 
-  - start_test scene:SCENE <-
-  ( 
-    OPENGL.make (800,600) title "GL Demo test" fullscreen FALSE;
-    ENGINE.make OPENGL;
-    
-    "*** GL Engine ***\n".print;
-    
-    ENGINE.attach_scene scene;
-    ENGINE_INPUT.add_key_listener MY_EVENT_LISTENER;
-    ENGINE_INPUT.add_mouse_listener MY_EVENT_LISTENER;
-    
-    ENGINE.initialize;
-    
-    //ENGINE.track_errors;
-    
-    ENGINE.main_loop;
-    
-    ENGINE.shutdown;
-    OPENGL.shutdown;
-  );
+///////////////////////////////////////////////////////////////////////////////
+//                             Application                                   //
+//                                                                           //
+//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
+//                                                                           //
+//   This program is free software: you can redistribute it and/or modify    //
+//   it under the terms of the GNU General Public License as published by    //
+//   the Free Software Foundation, either version 3 of the License, or       //
+//   (at your option) any later version.                                     //
+//                                                                           //
+//   This program is distributed in the hope that it will be useful,         //
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+//   GNU General Public License for more details.                            //
+//                                                                           //
+//   You should have received a copy of the GNU General Public License       //
+//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
+//                                                                           //
+//                     http://isaacproject.u-strasbg.fr/                     //
+///////////////////////////////////////////////////////////////////////////////
+
+Section Header
+  
+  + name        := TEST_ANY;
+  
+  - author      := "Damien Bouvarel(dams.bouvarel at wanadoo.fr)";
+  
+Section Inherit
+  
+  - parent_framework:FRAMEWORK := FRAMEWORK;
+  
+Section Public  
+ 
+  - start_test scene:SCENE using c:CAPABILITIES <-
+  ( 
+    OPENGL.set_capabilities c;
+    
+    // create OpenGL device
+    OPENGL.make (800,600) title "GL demo test";
+    
+    // set up framework
+    FRAMEWORK.make OPENGL;
+    
+    attach_scene scene;
+    add_key_listener MY_EVENT_LISTENER;
+    add_mouse_listener MY_EVENT_LISTENER;
+    
+    // start it all
+    run;
+  );
diff --git a/sdl_test/my_test1.li b/gl_test/test_scene.li
similarity index 76%
copy from sdl_test/my_test1.li
copy to gl_test/test_scene.li
index d3ceb00..460b1b8 100644
--- a/sdl_test/my_test1.li
+++ b/gl_test/test_scene.li
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-//                             Application                                   //
+//                           Lisaac-OpenGL library                           //
 //                                                                           //
 //                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
 //                                                                           //
@@ -21,24 +21,32 @@
 
 Section Header
   
-  + name     := MY_TEST1;
-  
-  - comment   := "first program";
+  + name     := TEST_SCENE;
   
 Section Inherit
   
-  - parent_object: OBJECT := OBJECT;
-
+  - parent_scene:SCENE := SCENE;
+  
 Section Public  
   
-  - main <-
+  - render t:REAL_32 <-
+  ( 
+    GL.gl_translatef (0.0, -1.0, -3.0);
+    
+    GL.gl_begin (GL.cst_gl_triangles);
+    
+    GL.gl_vertex3f (0.0, 2.0, 0.0);
+    GL.gl_color3f (1, 0, 0);
+    
+    GL.gl_vertex3f (-1.0, 0.0, 0.0);
+    GL.gl_color3f (0, 1, 0);	
+    
+    GL.gl_vertex3f (1.0, 0.0, 0.0);
+    GL.gl_color3f (0, 0, 1);
+    
+    GL.gl_end;	
+  );
+  
+  - release <-
   (
-    //SDL_WM.set_bmp_icon "icon.bmp";
-    SDL.set_video TRUE;
-    SDL.make(800,600) bits 16 title "my first SDL application" fullscreen FALSE video_mode "SDL_SWSURFACE";
-    SDL.set_everything TRUE;
-    SDL_WM.set_caption (SDL.title, SDL.title);
-    KEYCODE.make;
-    `while(1){}`;
-    SDL.quit;
   );

-- 
Lisaac library examples



More information about the Lisaac-commits mailing list