open Caml_xss let dims = ref (180, 80) let mk_color (r, g, b) = (r * 257, g * 257, b * 257) let _color_bg = mk_color (0, 0, 0) let _color0 = mk_color (255, 255, 255) let _color1 = mk_color (120, 80, 255) let _color2 = mk_color (255, 160, 26) let _color3 = mk_color (20, 250, 62) type shape = | Losange of (int * int * int * int) list (* four lines *) | Square of (int * int) * int (* ((x, y), size) *) | Circle of (int * int) * int (* ((x, y), radius) *) let coords_losange (x, y) = [ (10 + x, 0 + y, 16 + x, 10 + y); (16 + x, 10 + y, 10 + x, 20 + y); (10 + x, 20 + y, 4 + x, 10 + y); ( 4 + x, 10 + y, 10 + x, 0 + y); ] module UserSaver = struct type _state = { colormap: Caml_xss.colormap; color_bg: pixel; color0: pixel; color1: pixel; color2: pixel; color3: pixel; shapes: shape list; } type state = _state ref let update_shapes shapes = List.map (fun shape -> match shape with | Losange (losange_coords) -> Losange (losange_coords) | Square ((x, y), s) -> Square ((x + 1, y), s) | Circle ((x, y), r) -> Circle ((x - 1, y), r) ) shapes let update_state state = { state with shapes = update_shapes state.shapes } type user_calls = { saver_init: x_elems -> state; saver_draw: x_elems -> state -> int; saver_reshape: x_elems -> state -> int -> int -> unit; saver_free: x_elems -> state -> unit; } let user_saver = { saver_init = (fun xelms -> let colormap = X.default_colormap xelms in let color_bg = X.alloc_color xelms colormap _color_bg in let color0 = X.alloc_color xelms colormap _color0 in let color1 = X.alloc_color xelms colormap _color1 in let color2 = X.alloc_color xelms colormap _color2 in let color3 = X.alloc_color xelms colormap _color3 in ref { colormap; color_bg; color0; color1; color2; color3; shapes = [ Losange (coords_losange (20, 30)); Losange (coords_losange (36, 32)); Square ((60, 50), 10); Square ((80, 60), 10); Square ((100, 80), 20); Circle ((100, 80), 20) ]; } ); saver_reshape = (fun xelms state w h -> dims := (w, h); ); saver_free = (fun xelms state -> print_newline ()); saver_draw = (fun xelms _state -> let state = !_state in _state := update_state state; let w, h = !dims in X.set_foreground xelms state.color_bg; X.fill_rectangle xelms (0, 0, w, h); X.set_foreground xelms state.color0; List.iter (X.draw_point xelms) [ (20, 20); (22, 20); (24, 20)]; begin List.iter (fun shape -> match shape with | Losange (losange_coords) -> X.set_foreground xelms state.color1; List.iter (X.draw_line xelms) losange_coords; | Square ((x, y), s) -> X.set_foreground xelms state.color2; List.iter (X.draw_rectangle xelms) [(x, y, s, s)]; List.iter (X.draw_point xelms) [(x + s, y + s)]; | Circle ((x, y), r) -> X.set_foreground xelms state.color3; X.draw_arc xelms (x - r/2, y - r/2, r, r, 0, 360*64); ) state.shapes; end; X.set_foreground xelms state.color3; X.draw_arc xelms (40, 60, 20, 20, 0, 360*64); X.draw_arc xelms (0, 0, 30, 30, 0, 360*64); (80_000) ); } end module SomeSaver = MakeSaver(UserSaver)