From 4d68ca8809b3dc7432ff910ee93ebeb6ca75a49d Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Thu, 21 Aug 2025 23:50:31 +0000 Subject: [PATCH 01/22] core picture module added --- src/picture.ml | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/picture.ml diff --git a/src/picture.ml b/src/picture.ml new file mode 100644 index 0000000..1b5d9e7 --- /dev/null +++ b/src/picture.ml @@ -0,0 +1,95 @@ +open Image + +type t = { + palette : Palette.t; + pixels : int array; + width : int; + height : int; + scale : float; +} + +let load_png_as_indexed (filepath : string) : Palette.t * int array * int * int + = + let img = ImageLib_unix.openfile filepath in + let w = img.width in + let h = img.height in + + let pixels_rgba = + Array.init (w * h) (fun idx -> + let x = idx mod w in + let y = idx / w in + match img.pixels with + | RGB (r, g, b) -> + let red = Pixmap.get r x y in + let green = Pixmap.get g x y in + let blue = Pixmap.get b x y in + (red, green, blue, 255) + (* 255 means fully opaque *) + | RGBA (r, g, b, a) -> + let red = Pixmap.get r x y in + let green = Pixmap.get g x y in + let blue = Pixmap.get b x y in + let alpha = Pixmap.get a x y in + (red, green, blue, alpha) + | Grey p -> + let g = Pixmap.get p x y in + (g, g, g, 255) + | GreyA (p, a) -> + let g = Pixmap.get p x y in + let alpha = Pixmap.get a x y in + (g, g, g, alpha)) + in + + let module ColorMap = Map.Make (struct + type t = int * int * int + + let compare = compare + end) in + let palette_map, palette_list, _ = + Array.fold_left + (fun (map, lst, idx) (r, g, b, a) -> + if a = 0 then (map, lst, idx) (* transparent pixel *) + else if ColorMap.mem (r, g, b) map then (map, lst, idx) + else (ColorMap.add (r, g, b) idx map, lst @ [ (r, g, b) ], idx + 1)) + (ColorMap.empty, [], 1) (* index 0 is being used for transparency *) + pixels_rgba + in + + let palette_rgb_24 = + 0x000000 + :: List.map (fun (r, g, b) -> (r lsl 16) lor (g lsl 8) lor b) palette_list + in + + if List.length palette_rgb_24 > 256 then + invalid_arg + (Printf.sprintf "PNG uses %d unique colors — exceeds the 256-color limit" + (List.length palette_rgb_24)); + + let pal = Palette.of_list palette_rgb_24 in + + let indexed_pixels = + Array.map + (fun (r, g, b, a) -> + if a = 0 then 0 else ColorMap.find (r, g, b) palette_map) + pixels_rgba + in + + (pal, indexed_pixels, w, h) + +(* Public API, so real img data isn't tampered *) +let load (filepath : string) (scale : float) : t = + if scale <= 0.0 then invalid_arg "Picture.load: scale must be > 0"; + let palette, pixels, w, h = load_png_as_indexed filepath in + { palette; pixels; width = w; height = h; scale } + +let set_scale (pic : t) (s : float) : t = + if s <= 0.0 then invalid_arg "Picture.set_scale: scale must be > 0"; + { pic with scale = s } + +let original_width (pic : t) = pic.width +let original_height (pic : t) = pic.height +let scaled_width (pic : t) = int_of_float (float pic.width *. pic.scale) +let scaled_height (pic : t) = int_of_float (float pic.height *. pic.scale) +let scale (pic : t) = pic.scale +let palette (pic : t) = pic.palette +let pixels (pic : t) = pic.pixels From 06321283e6d45ae5a7c621e498ab34f9468968d0 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Thu, 21 Aug 2025 23:51:05 +0000 Subject: [PATCH 02/22] documentation for picture module --- src/picture.mli | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/picture.mli diff --git a/src/picture.mli b/src/picture.mli new file mode 100644 index 0000000..a0404e2 --- /dev/null +++ b/src/picture.mli @@ -0,0 +1,32 @@ +type t +(** Abstract type representing a loaded picture *) + +val load : string -> float -> t +(** [load filename scale] loads a PNG file and returns a picture scaled + uniformly by [scale]. Aspect ratio is preserved. *) + +val set_scale : t -> float -> t +(** [set_scale pic s] returns a new picture with the scale factor updated to + [s]. *) + +val scaled_width : t -> int +(** [scaled_width pic] returns the width in pixels after applying the scale. *) + +val scaled_height : t -> int +(** [scaled_height pic] returns the height in pixels after applying the scale. +*) + +val original_width : t -> int +(** [original_width pic] returns the original width in pixels. *) + +val original_height : t -> int +(** [original_height pic] returns the original height in pixels. *) + +val scale : t -> float +(** [scale pic] returns the scale factor. *) + +val pixels : t -> int array +(** [pixels pic] returns the indexed pixel array. *) + +val palette : t -> Palette.t +(** [palette pic] returns the color palette of the picture. *) From bb01b5a86ee08050d160b316ed1fcc3d0b8de078 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Thu, 21 Aug 2025 23:52:21 +0000 Subject: [PATCH 03/22] draw_picture added to framebuffer --- src/framebuffer.ml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index 4852eec..1c8bc74 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -461,6 +461,35 @@ let filled_polygon (points : (int * int) list) (col : int) (buffer : t) = map; buffer.dirty <- true +let draw_picture (pic : Picture.t) (offset_x : int) (offset_y : int) (fb : t) : + unit = + let src_w = Picture.original_width pic in + let src_h = Picture.original_height pic in + let dst_w = Picture.scaled_width pic in + let dst_h = Picture.scaled_height pic in + let scale = Picture.scale pic in + let pixels = Picture.pixels pic in + + for y = 0 to dst_h - 1 do + for x = 0 to dst_w - 1 do + let src_x = min (src_w - 1) (int_of_float (float x /. scale)) in + let src_y = min (src_h - 1) (int_of_float (float y /. scale)) in + let idx = (src_y * src_w) + src_x in + let color_index = pixels.(idx) in + + if color_index <> 0 then + let fb_x = x + offset_x in + let fb_y = y + offset_y in + if + fb_x >= 0 + && fb_x < Array.length fb.data.(0) + && fb_y >= 0 + && fb_y < Array.length fb.data + then fb.data.(fb_y).(fb_x) <- color_index + done + done; + fb.dirty <- true + (* ----- *) let draw_char (x : int) (y : int) (f : Font.t) (c : char) (col : int) @@ -559,7 +588,8 @@ let render (buffer : t) (draw : Primitives.t list) = | Primitives.Char (p, font, c, col) -> ignore (draw_char p.x p.y font c col buffer) | Primitives.String (p, font, s, col) -> - ignore (draw_string p.x p.y font s col buffer)) + ignore (draw_string p.x p.y font s col buffer) + | Primitives.Picture (pos, pic) -> draw_picture pic pos.x pos.y buffer) draw (* ----- *) From 6d7d35408b61e2f70d9b2a73c175d54200784fbb Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Thu, 21 Aug 2025 23:52:55 +0000 Subject: [PATCH 04/22] documentation for draw_picture --- src/framebuffer.mli | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/framebuffer.mli b/src/framebuffer.mli index 94a1c42..512263c 100644 --- a/src/framebuffer.mli +++ b/src/framebuffer.mli @@ -89,6 +89,10 @@ val filled_polygon : (int * int) list -> int -> t -> unit (** [filled_polygon points colour framebuffer] Draws a filled polygon made from the list of [points] in the specified [colour] into [framebuffer]. *) +val draw_picture : Picture.t -> int -> int -> t -> unit +(** [draw_picture pic x y buffer] draws [pic] onto [buffer] at position (x, y). + Scaling defined in [pic] is applied. *) + val draw_char : int -> int -> Font.t -> char -> int -> t -> int (** [draw_char x y font c colour framebuffer] Draws a single character [c] in the specified [colour] using [font]. The top left of the charcter is the From 4974885e7464961d87f94063cbdb569cb1a3c93c Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Thu, 21 Aug 2025 23:53:33 +0000 Subject: [PATCH 05/22] added picture as a primitive --- src/primitives.ml | 1 + src/primitives.mli | 1 + 2 files changed, 2 insertions(+) diff --git a/src/primitives.ml b/src/primitives.ml index 9b85da6..7306c16 100644 --- a/src/primitives.ml +++ b/src/primitives.ml @@ -15,3 +15,4 @@ type t = | FilledTriangle of point * point * point * int | Char of point * Font.t * char * int | String of point * Font.t * string * int + | Picture of point * Picture.t diff --git a/src/primitives.mli b/src/primitives.mli index 9e040d7..79c1346 100644 --- a/src/primitives.mli +++ b/src/primitives.mli @@ -18,3 +18,4 @@ type t = | FilledTriangle of point * point * point * int | Char of point * Font.t * char * int | String of point * Font.t * string * int + | Picture of point * Picture.t From b68d07306e337c0b56603732ff48f0f2e624baad Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Thu, 21 Aug 2025 23:54:10 +0000 Subject: [PATCH 06/22] src/dune changes added --- src/dune | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dune b/src/dune index d7eda59..02e428f 100644 --- a/src/dune +++ b/src/dune @@ -7,4 +7,4 @@ (library (name claudius) (public_name claudius) - (libraries tsdl giflib crunch)) + (libraries tsdl giflib crunch imagelib imagelib.unix)) From b7e2b9b5084a9ba0838e6f31acdae89a6120fa74 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Sun, 24 Aug 2025 14:52:35 +0000 Subject: [PATCH 07/22] updated dune-project to include imagelib --- claudius.opam | 2 ++ dune-project | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/claudius.opam b/claudius.opam index 5b16b4d..a7567e9 100644 --- a/claudius.opam +++ b/claudius.opam @@ -28,6 +28,8 @@ depends: [ "ounit2" {with-test} "odoc" {with-doc} "giflib" {>= "1.0.3"} + "imagelib" {>= "20221222"} + "imagelib.unix" {>= "20221222"} "crunch" {>= "4.0.0"} "ocamlformat" {>= "0.27.0" & with-dev-setup} ] diff --git a/dune-project b/dune-project index 051b1bd..08fce6a 100644 --- a/dune-project +++ b/dune-project @@ -19,7 +19,7 @@ (name claudius) (synopsis "A retro-style graphics library") (description "An functional style retro-graphics library for OCaml for building generative art, demos, and games.") - (depends (ocaml (>= 5.1)) dune (tsdl (>= 1.1.0)) (ounit2 :with-test) (odoc :with-doc) (giflib (>= 1.0.3)) (crunch (>= 4.0.0)) (ocamlformat (and (>= 0.27.0) :with-dev-setup ))) + (depends (ocaml (>= 5.1)) dune (tsdl (>= 1.1.0)) (ounit2 :with-test) (odoc :with-doc) (giflib (>= 1.0.3)) (imagelib (>= 20221222)) (imagelib.unix (>= 20221222)) (crunch (>= 4.0.0)) (ocamlformat (and (>= 0.27.0) :with-dev-setup ))) (tags (graphics rendering paletted))) From 4860c8e390d264ef51a5dc8447fb3208fd3d09f3 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Mon, 25 Aug 2025 05:12:23 +0000 Subject: [PATCH 08/22] added ensure_palette_offset and with_palette_offset --- src/picture.ml | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/picture.ml b/src/picture.ml index 1b5d9e7..b7f2378 100644 --- a/src/picture.ml +++ b/src/picture.ml @@ -5,9 +5,34 @@ type t = { pixels : int array; width : int; height : int; - scale : float; } +let global_palette : int array = Array.make 256 0 + +let picture_offsets : (int, int) Hashtbl.t = Hashtbl.create 16 + +let next_palette_offset : int ref = ref 1 + +(* To ensure a picture’s palette is assigned an offset in the global palette. *) +let ensure_palette_offset (pic : t) : int = + (* Hash based on palette contents + dimensions, so same picture reuses offset. *) + let pal_list = Palette.to_list pic.palette in + let pid = Hashtbl.hash (pal_list, pic.width, pic.height) in + match Hashtbl.find_opt picture_offsets pid with + | Some offset -> offset + | None -> + let count = List.length pal_list in + let offset = !next_palette_offset in + if offset + count > Array.length global_palette then + failwith "Global palette overflow in Picture.ensure_palette_offset"; + + List.iteri (fun i rgb24 -> global_palette.(offset + i) <- rgb24) pal_list; + + Hashtbl.add picture_offsets pid offset; + + next_palette_offset := offset + count; + offset + let load_png_as_indexed (filepath : string) : Palette.t * int array * int * int = let img = ImageLib_unix.openfile filepath in @@ -77,19 +102,18 @@ let load_png_as_indexed (filepath : string) : Palette.t * int array * int * int (pal, indexed_pixels, w, h) (* Public API, so real img data isn't tampered *) -let load (filepath : string) (scale : float) : t = - if scale <= 0.0 then invalid_arg "Picture.load: scale must be > 0"; - let palette, pixels, w, h = load_png_as_indexed filepath in - { palette; pixels; width = w; height = h; scale } -let set_scale (pic : t) (s : float) : t = - if s <= 0.0 then invalid_arg "Picture.set_scale: scale must be > 0"; - { pic with scale = s } +let load (filepath : string) : t = + let palette, pixels, w, h = load_png_as_indexed filepath in + { palette; pixels; width = w; height = h } let original_width (pic : t) = pic.width let original_height (pic : t) = pic.height -let scaled_width (pic : t) = int_of_float (float pic.width *. pic.scale) -let scaled_height (pic : t) = int_of_float (float pic.height *. pic.scale) -let scale (pic : t) = pic.scale -let palette (pic : t) = pic.palette let pixels (pic : t) = pic.pixels +let palette (pic : t) = pic.palette + +let with_palette_offset (pic : t) (offset : int) : t = + let shifted_pixels = + Array.map (fun idx -> if idx = 0 then 0 else idx + offset) pic.pixels + in + { pic with pixels = shifted_pixels } \ No newline at end of file From 70e0c903dcc259179a355c1eb37e12d20d40d839 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Mon, 25 Aug 2025 05:13:59 +0000 Subject: [PATCH 09/22] using ensure_palette_offset in from_picutre --- src/framebuffer.ml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index 1c8bc74..b68ff30 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -461,15 +461,14 @@ let filled_polygon (points : (int * int) list) (col : int) (buffer : t) = map; buffer.dirty <- true -let draw_picture (pic : Picture.t) (offset_x : int) (offset_y : int) (fb : t) : +let draw_picture (pic : Picture.t) ?(scale=1.0) (offset_x : int) (offset_y : int) (fb : t) : unit = let src_w = Picture.original_width pic in let src_h = Picture.original_height pic in - let dst_w = Picture.scaled_width pic in - let dst_h = Picture.scaled_height pic in - let scale = Picture.scale pic in + let dst_w = int_of_float (float src_w *. scale) in + let dst_h = int_of_float (float src_h *. scale) in let pixels = Picture.pixels pic in - + let palette_offset = Picture.ensure_palette_offset pic in for y = 0 to dst_h - 1 do for x = 0 to dst_w - 1 do let src_x = min (src_w - 1) (int_of_float (float x /. scale)) in @@ -485,7 +484,7 @@ let draw_picture (pic : Picture.t) (offset_x : int) (offset_y : int) (fb : t) : && fb_x < Array.length fb.data.(0) && fb_y >= 0 && fb_y < Array.length fb.data - then fb.data.(fb_y).(fb_x) <- color_index + then fb.data.(fb_y).(fb_x) <- color_index + palette_offset done done; fb.dirty <- true @@ -589,7 +588,7 @@ let render (buffer : t) (draw : Primitives.t list) = ignore (draw_char p.x p.y font c col buffer) | Primitives.String (p, font, s, col) -> ignore (draw_string p.x p.y font s col buffer) - | Primitives.Picture (pos, pic) -> draw_picture pic pos.x pos.y buffer) + | Primitives.Picture (pos, pic) -> draw_picture pic ~scale:1.0 pos.x pos.y buffer) draw (* ----- *) From 9f143474712937c3926a3a0c1c2c994b42979642 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Mon, 25 Aug 2025 05:14:55 +0000 Subject: [PATCH 10/22] added concat for palette concatenation --- src/palette.ml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/palette.ml b/src/palette.ml index bde1031..7c57355 100644 --- a/src/palette.ml +++ b/src/palette.ml @@ -232,3 +232,14 @@ let updated_entry (pal : t) (index : int) (new_color : int * int * int) : t = let new_pal = Array.copy pal in new_pal.(index) <- new_int; new_pal + +let concat (palettes : t list) : t = + let total_len = List.fold_left (fun acc pal -> acc + Array.length pal) 0 palettes in + let result = Array.make total_len 0l in + let _ = + List.fold_left (fun offset pal -> + Array.iteri (fun i v -> result.(offset + i) <- v) pal; + offset + Array.length pal + ) 0 palettes + in + result From ae077d43e508b645a0f865cd9e9c813945d2c9a4 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Mon, 25 Aug 2025 05:17:31 +0000 Subject: [PATCH 11/22] managing palette offsets and image loading --- src/screen.ml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/screen.ml b/src/screen.ml index 4c7d26a..42ddad8 100644 --- a/src/screen.ml +++ b/src/screen.ml @@ -5,9 +5,10 @@ type t = { mutable palette : Palette.t; font : Font.t; mutable dirty : bool; + pictures : Picture.t array; } -let create ?font (width : int) (height : int) (scale : int) +let create ?font ?(image_filenames = []) (width : int) (height : int) (scale : int) (palette : Palette.t) : t = if scale <= 0 then raise (Invalid_argument "Invalid scale"); if width <= 0 then raise (Invalid_argument "Invalid width"); @@ -30,7 +31,28 @@ let create ?font (width : int) (height : int) (scale : int) failwith (Printf.sprintf "Failed to load default font: %s" e)) in - { width; height; scale; palette; font; dirty = true } + let pictures = + let offset = ref (Palette.size palette) in + List.map + (fun filename -> + let pic = Picture.load filename in + let shifted = + Picture.with_palette_offset pic !offset + in + offset := !offset + Palette.size (Picture.palette pic); + shifted) + image_filenames + |> Array.of_list + in + + let final_palette = + let all_palettes = + palette :: (Array.to_list pictures |> List.map Picture.palette) + in + Palette.concat all_palettes + in + + { width; height; scale; palette = final_palette; font; dirty = true; pictures } let update_palette (screen : t) (new_palette : Palette.t) : unit = screen.palette <- new_palette; @@ -46,3 +68,4 @@ let font (screen : t) : Font.t = screen.font let scale (screen : t) : int = screen.scale let is_dirty (screen : t) : bool = screen.dirty let clear_dirty (screen : t) : unit = screen.dirty <- false +let pictures (screen : t) : Picture.t array = screen.pictures From 836d05fa785272377dd150505934cd199255d901 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Mon, 25 Aug 2025 05:18:44 +0000 Subject: [PATCH 12/22] updated all the documentation --- src/framebuffer.mli | 6 +++--- src/palette.mli | 3 +++ src/picture.mli | 30 +++++++++++++----------------- src/screen.mli | 9 +++++++-- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/framebuffer.mli b/src/framebuffer.mli index 512263c..58c773a 100644 --- a/src/framebuffer.mli +++ b/src/framebuffer.mli @@ -89,9 +89,9 @@ val filled_polygon : (int * int) list -> int -> t -> unit (** [filled_polygon points colour framebuffer] Draws a filled polygon made from the list of [points] in the specified [colour] into [framebuffer]. *) -val draw_picture : Picture.t -> int -> int -> t -> unit -(** [draw_picture pic x y buffer] draws [pic] onto [buffer] at position (x, y). - Scaling defined in [pic] is applied. *) +val draw_picture : Picture.t -> ?scale:float -> int -> int -> t -> unit +(** [draw_picture pic ?scale x y buffer] draws [pic] onto [buffer] at position (x, y). + The picture is scaled uniformly by [scale], which defaults to 1.0 if omitted. *) val draw_char : int -> int -> Font.t -> char -> int -> t -> int (** [draw_char x y font c colour framebuffer] Draws a single character [c] in diff --git a/src/palette.mli b/src/palette.mli index 8b6e2a6..1d56abb 100644 --- a/src/palette.mli +++ b/src/palette.mli @@ -83,3 +83,6 @@ val circle_palette : t -> int -> t val updated_entry : t -> int -> int * int * int -> t (** [updated_entry pal index new_color] checks for the index then returns a new palette with the entry at [index] updated to [new_color]. *) + +val concat : t list -> t +(** [concat palettes] merges a list of palettes into a single palette. *) \ No newline at end of file diff --git a/src/picture.mli b/src/picture.mli index a0404e2..b0623a8 100644 --- a/src/picture.mli +++ b/src/picture.mli @@ -1,20 +1,8 @@ type t (** Abstract type representing a loaded picture *) -val load : string -> float -> t -(** [load filename scale] loads a PNG file and returns a picture scaled - uniformly by [scale]. Aspect ratio is preserved. *) - -val set_scale : t -> float -> t -(** [set_scale pic s] returns a new picture with the scale factor updated to - [s]. *) - -val scaled_width : t -> int -(** [scaled_width pic] returns the width in pixels after applying the scale. *) - -val scaled_height : t -> int -(** [scaled_height pic] returns the height in pixels after applying the scale. -*) +val load : string -> t +(** [load filename] loads a PNG file and returns a picture. *) val original_width : t -> int (** [original_width pic] returns the original width in pixels. *) @@ -22,11 +10,19 @@ val original_width : t -> int val original_height : t -> int (** [original_height pic] returns the original height in pixels. *) -val scale : t -> float -(** [scale pic] returns the scale factor. *) - val pixels : t -> int array (** [pixels pic] returns the indexed pixel array. *) val palette : t -> Palette.t (** [palette pic] returns the color palette of the picture. *) + +val with_palette_offset : t -> int -> t +(** [with_palette_offset pic offset] returns a new picture with all pixel indices + shifted by [offset]. Palette is unchanged. *) + +val ensure_palette_offset : t -> int +(** [ensure_palette_offset pic] ensures that [pic]'s palette is installed + into the global palette, and returns the assigned offset. *) + +val global_palette : int array +(** The global 256-color palette shared by all pictures. *) \ No newline at end of file diff --git a/src/screen.mli b/src/screen.mli index 7f7a0bc..bf19e26 100644 --- a/src/screen.mli +++ b/src/screen.mli @@ -6,13 +6,15 @@ type t (** {1 Initializations} *) -val create : ?font:Font.t -> int -> int -> int -> Palette.t -> t +val create : ?font:Font.t -> ?image_filenames:string list -> int -> int -> int -> Palette.t -> t (** [create font width height scale palette] Creates a new screen of the specified size [width] x [height], and it will be rendered in a window scaled up by the [scale] factor provided. The framebuffers used when running will be indexed into the [palette] provided here. Raises [Invalid_argument] if the dimensions or scale are either zero or negative. If no [font] is - provided then a default font is used. *) + provided then a default font is used. If [image_filenames] is provided, + the images will be loaded and their palettes merged into the screen's + global palette.*) val update_palette : t -> Palette.t -> unit (**[update screen new_palette] creates a new screen with updated palette and @@ -44,3 +46,6 @@ val is_dirty : t -> bool val clear_dirty : t -> unit (** [clear_dirty screen] returns a new screen with the dirty flag cleared. *) + +val pictures : t -> Picture.t array +(** [pictures screen] returns the array of pictures loaded into the screen. *) \ No newline at end of file From 3f6b597bc6310b15ceac7d4de1a987d22b4329bd Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Tue, 26 Aug 2025 09:42:30 +0000 Subject: [PATCH 13/22] removed imagelib.unix from dune-project and opam --- claudius.opam | 1 - dune-project | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/claudius.opam b/claudius.opam index a7567e9..8ca0ba6 100644 --- a/claudius.opam +++ b/claudius.opam @@ -29,7 +29,6 @@ depends: [ "odoc" {with-doc} "giflib" {>= "1.0.3"} "imagelib" {>= "20221222"} - "imagelib.unix" {>= "20221222"} "crunch" {>= "4.0.0"} "ocamlformat" {>= "0.27.0" & with-dev-setup} ] diff --git a/dune-project b/dune-project index 08fce6a..f0c23ed 100644 --- a/dune-project +++ b/dune-project @@ -19,7 +19,7 @@ (name claudius) (synopsis "A retro-style graphics library") (description "An functional style retro-graphics library for OCaml for building generative art, demos, and games.") - (depends (ocaml (>= 5.1)) dune (tsdl (>= 1.1.0)) (ounit2 :with-test) (odoc :with-doc) (giflib (>= 1.0.3)) (imagelib (>= 20221222)) (imagelib.unix (>= 20221222)) (crunch (>= 4.0.0)) (ocamlformat (and (>= 0.27.0) :with-dev-setup ))) + (depends (ocaml (>= 5.1)) dune (tsdl (>= 1.1.0)) (ounit2 :with-test) (odoc :with-doc) (giflib (>= 1.0.3)) (imagelib (>= 20221222)) (crunch (>= 4.0.0)) (ocamlformat (and (>= 0.27.0) :with-dev-setup ))) (tags (graphics rendering paletted))) From 41f35339c4cc7e7138e794dd6df469431769445c Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Tue, 26 Aug 2025 09:49:42 +0000 Subject: [PATCH 14/22] ran formatting --- src/framebuffer.ml | 7 ++++--- src/framebuffer.mli | 5 +++-- src/palette.ml | 13 ++++++++----- src/palette.mli | 2 +- src/picture.ml | 11 ++--------- src/picture.mli | 10 +++++----- src/screen.ml | 18 ++++++++++++------ src/screen.mli | 17 ++++++++++++----- 8 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index b68ff30..31d5d14 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -461,8 +461,8 @@ let filled_polygon (points : (int * int) list) (col : int) (buffer : t) = map; buffer.dirty <- true -let draw_picture (pic : Picture.t) ?(scale=1.0) (offset_x : int) (offset_y : int) (fb : t) : - unit = +let draw_picture (pic : Picture.t) ?(scale = 1.0) (offset_x : int) + (offset_y : int) (fb : t) : unit = let src_w = Picture.original_width pic in let src_h = Picture.original_height pic in let dst_w = int_of_float (float src_w *. scale) in @@ -588,7 +588,8 @@ let render (buffer : t) (draw : Primitives.t list) = ignore (draw_char p.x p.y font c col buffer) | Primitives.String (p, font, s, col) -> ignore (draw_string p.x p.y font s col buffer) - | Primitives.Picture (pos, pic) -> draw_picture pic ~scale:1.0 pos.x pos.y buffer) + | Primitives.Picture (pos, pic) -> + draw_picture pic ~scale:1.0 pos.x pos.y buffer) draw (* ----- *) diff --git a/src/framebuffer.mli b/src/framebuffer.mli index 58c773a..066d4e7 100644 --- a/src/framebuffer.mli +++ b/src/framebuffer.mli @@ -90,8 +90,9 @@ val filled_polygon : (int * int) list -> int -> t -> unit the list of [points] in the specified [colour] into [framebuffer]. *) val draw_picture : Picture.t -> ?scale:float -> int -> int -> t -> unit -(** [draw_picture pic ?scale x y buffer] draws [pic] onto [buffer] at position (x, y). - The picture is scaled uniformly by [scale], which defaults to 1.0 if omitted. *) +(** [draw_picture pic ?scale x y buffer] draws [pic] onto [buffer] at position + (x, y). The picture is scaled uniformly by [scale], which defaults to 1.0 if + omitted. *) val draw_char : int -> int -> Font.t -> char -> int -> t -> int (** [draw_char x y font c colour framebuffer] Draws a single character [c] in diff --git a/src/palette.ml b/src/palette.ml index 7c57355..4ae8449 100644 --- a/src/palette.ml +++ b/src/palette.ml @@ -234,12 +234,15 @@ let updated_entry (pal : t) (index : int) (new_color : int * int * int) : t = new_pal let concat (palettes : t list) : t = - let total_len = List.fold_left (fun acc pal -> acc + Array.length pal) 0 palettes in + let total_len = + List.fold_left (fun acc pal -> acc + Array.length pal) 0 palettes + in let result = Array.make total_len 0l in let _ = - List.fold_left (fun offset pal -> - Array.iteri (fun i v -> result.(offset + i) <- v) pal; - offset + Array.length pal - ) 0 palettes + List.fold_left + (fun offset pal -> + Array.iteri (fun i v -> result.(offset + i) <- v) pal; + offset + Array.length pal) + 0 palettes in result diff --git a/src/palette.mli b/src/palette.mli index 1d56abb..7780e09 100644 --- a/src/palette.mli +++ b/src/palette.mli @@ -85,4 +85,4 @@ val updated_entry : t -> int -> int * int * int -> t palette with the entry at [index] updated to [new_color]. *) val concat : t list -> t -(** [concat palettes] merges a list of palettes into a single palette. *) \ No newline at end of file +(** [concat palettes] merges a list of palettes into a single palette. *) diff --git a/src/picture.ml b/src/picture.ml index b7f2378..f55a1d8 100644 --- a/src/picture.ml +++ b/src/picture.ml @@ -1,16 +1,9 @@ open Image -type t = { - palette : Palette.t; - pixels : int array; - width : int; - height : int; -} +type t = { palette : Palette.t; pixels : int array; width : int; height : int } let global_palette : int array = Array.make 256 0 - let picture_offsets : (int, int) Hashtbl.t = Hashtbl.create 16 - let next_palette_offset : int ref = ref 1 (* To ensure a picture’s palette is assigned an offset in the global palette. *) @@ -116,4 +109,4 @@ let with_palette_offset (pic : t) (offset : int) : t = let shifted_pixels = Array.map (fun idx -> if idx = 0 then 0 else idx + offset) pic.pixels in - { pic with pixels = shifted_pixels } \ No newline at end of file + { pic with pixels = shifted_pixels } diff --git a/src/picture.mli b/src/picture.mli index b0623a8..e9e36f4 100644 --- a/src/picture.mli +++ b/src/picture.mli @@ -17,12 +17,12 @@ val palette : t -> Palette.t (** [palette pic] returns the color palette of the picture. *) val with_palette_offset : t -> int -> t -(** [with_palette_offset pic offset] returns a new picture with all pixel indices - shifted by [offset]. Palette is unchanged. *) +(** [with_palette_offset pic offset] returns a new picture with all pixel + indices shifted by [offset]. Palette is unchanged. *) val ensure_palette_offset : t -> int -(** [ensure_palette_offset pic] ensures that [pic]'s palette is installed - into the global palette, and returns the assigned offset. *) +(** [ensure_palette_offset pic] ensures that [pic]'s palette is installed into + the global palette, and returns the assigned offset. *) val global_palette : int array -(** The global 256-color palette shared by all pictures. *) \ No newline at end of file +(** The global 256-color palette shared by all pictures. *) diff --git a/src/screen.ml b/src/screen.ml index 42ddad8..bf92069 100644 --- a/src/screen.ml +++ b/src/screen.ml @@ -8,8 +8,8 @@ type t = { pictures : Picture.t array; } -let create ?font ?(image_filenames = []) (width : int) (height : int) (scale : int) - (palette : Palette.t) : t = +let create ?font ?(image_filenames = []) (width : int) (height : int) + (scale : int) (palette : Palette.t) : t = if scale <= 0 then raise (Invalid_argument "Invalid scale"); if width <= 0 then raise (Invalid_argument "Invalid width"); if height <= 0 then raise (Invalid_argument "Invalid height"); @@ -36,9 +36,7 @@ let create ?font ?(image_filenames = []) (width : int) (height : int) (scale : i List.map (fun filename -> let pic = Picture.load filename in - let shifted = - Picture.with_palette_offset pic !offset - in + let shifted = Picture.with_palette_offset pic !offset in offset := !offset + Palette.size (Picture.palette pic); shifted) image_filenames @@ -52,7 +50,15 @@ let create ?font ?(image_filenames = []) (width : int) (height : int) (scale : i Palette.concat all_palettes in - { width; height; scale; palette = final_palette; font; dirty = true; pictures } + { + width; + height; + scale; + palette = final_palette; + font; + dirty = true; + pictures; + } let update_palette (screen : t) (new_palette : Palette.t) : unit = screen.palette <- new_palette; diff --git a/src/screen.mli b/src/screen.mli index bf19e26..d53bd25 100644 --- a/src/screen.mli +++ b/src/screen.mli @@ -6,15 +6,22 @@ type t (** {1 Initializations} *) -val create : ?font:Font.t -> ?image_filenames:string list -> int -> int -> int -> Palette.t -> t +val create : + ?font:Font.t -> + ?image_filenames:string list -> + int -> + int -> + int -> + Palette.t -> + t (** [create font width height scale palette] Creates a new screen of the specified size [width] x [height], and it will be rendered in a window scaled up by the [scale] factor provided. The framebuffers used when running will be indexed into the [palette] provided here. Raises [Invalid_argument] if the dimensions or scale are either zero or negative. If no [font] is - provided then a default font is used. If [image_filenames] is provided, - the images will be loaded and their palettes merged into the screen's - global palette.*) + provided then a default font is used. If [image_filenames] is provided, the + images will be loaded and their palettes merged into the screen's global + palette.*) val update_palette : t -> Palette.t -> unit (**[update screen new_palette] creates a new screen with updated palette and @@ -48,4 +55,4 @@ val clear_dirty : t -> unit (** [clear_dirty screen] returns a new screen with the dirty flag cleared. *) val pictures : t -> Picture.t array -(** [pictures screen] returns the array of pictures loaded into the screen. *) \ No newline at end of file +(** [pictures screen] returns the array of pictures loaded into the screen. *) From 7f9b297128ed095be73aa78ea5c2166bf8a08423 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Tue, 26 Aug 2025 14:06:49 +0000 Subject: [PATCH 15/22] replacing the duplicate code with pixel_write --- src/framebuffer.ml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index 31d5d14..c2549ef 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -468,7 +468,7 @@ let draw_picture (pic : Picture.t) ?(scale = 1.0) (offset_x : int) let dst_w = int_of_float (float src_w *. scale) in let dst_h = int_of_float (float src_h *. scale) in let pixels = Picture.pixels pic in - let palette_offset = Picture.ensure_palette_offset pic in + (* let palette_offset = Picture.ensure_palette_offset pic in *) for y = 0 to dst_h - 1 do for x = 0 to dst_w - 1 do let src_x = min (src_w - 1) (int_of_float (float x /. scale)) in @@ -479,12 +479,15 @@ let draw_picture (pic : Picture.t) ?(scale = 1.0) (offset_x : int) if color_index <> 0 then let fb_x = x + offset_x in let fb_y = y + offset_y in - if + + pixel_write fb_x fb_y color_index fb + + (* if fb_x >= 0 && fb_x < Array.length fb.data.(0) && fb_y >= 0 && fb_y < Array.length fb.data - then fb.data.(fb_y).(fb_x) <- color_index + palette_offset + then fb.data.(fb_y).(fb_x) <- color_index + palette_offset *) done done; fb.dirty <- true From a182a2ba3b1c9fe3a4f332b6b8f133e7c7d34322 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Tue, 26 Aug 2025 14:08:53 +0000 Subject: [PATCH 16/22] repalcing the duplicate code with pixel_write --- src/framebuffer.ml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index c2549ef..b509254 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -479,15 +479,7 @@ let draw_picture (pic : Picture.t) ?(scale = 1.0) (offset_x : int) if color_index <> 0 then let fb_x = x + offset_x in let fb_y = y + offset_y in - pixel_write fb_x fb_y color_index fb - - (* if - fb_x >= 0 - && fb_x < Array.length fb.data.(0) - && fb_y >= 0 - && fb_y < Array.length fb.data - then fb.data.(fb_y).(fb_x) <- color_index + palette_offset *) done done; fb.dirty <- true From acb9a2f6e85b4bfc7b81be311ec027d0be2a712c Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Tue, 26 Aug 2025 14:21:37 +0000 Subject: [PATCH 17/22] removed the unnecessary check --- src/picture.ml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/picture.ml b/src/picture.ml index f55a1d8..1b14fc5 100644 --- a/src/picture.ml +++ b/src/picture.ml @@ -78,11 +78,6 @@ let load_png_as_indexed (filepath : string) : Palette.t * int array * int * int :: List.map (fun (r, g, b) -> (r lsl 16) lor (g lsl 8) lor b) palette_list in - if List.length palette_rgb_24 > 256 then - invalid_arg - (Printf.sprintf "PNG uses %d unique colors — exceeds the 256-color limit" - (List.length palette_rgb_24)); - let pal = Palette.of_list palette_rgb_24 in let indexed_pixels = From ba07cec3d6f690ac8f542c61870d791d99fe3dce Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Wed, 27 Aug 2025 12:09:40 +0000 Subject: [PATCH 18/22] removed the global state --- src/picture.ml | 8 ++++---- src/picture.mli | 4 ++-- src/screen.ml | 30 ++++++++++++++---------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/picture.ml b/src/picture.ml index 1b14fc5..545bee3 100644 --- a/src/picture.ml +++ b/src/picture.ml @@ -2,12 +2,12 @@ open Image type t = { palette : Palette.t; pixels : int array; width : int; height : int } -let global_palette : int array = Array.make 256 0 +(* let global_palette : int array = Array.make 256 0 let picture_offsets : (int, int) Hashtbl.t = Hashtbl.create 16 -let next_palette_offset : int ref = ref 1 +let next_palette_offset : int ref = ref 1 *) (* To ensure a picture’s palette is assigned an offset in the global palette. *) -let ensure_palette_offset (pic : t) : int = +(* let ensure_palette_offset (pic : t) : int = (* Hash based on palette contents + dimensions, so same picture reuses offset. *) let pal_list = Palette.to_list pic.palette in let pid = Hashtbl.hash (pal_list, pic.width, pic.height) in @@ -24,7 +24,7 @@ let ensure_palette_offset (pic : t) : int = Hashtbl.add picture_offsets pid offset; next_palette_offset := offset + count; - offset + offset *) let load_png_as_indexed (filepath : string) : Palette.t * int array * int * int = diff --git a/src/picture.mli b/src/picture.mli index e9e36f4..2a31b05 100644 --- a/src/picture.mli +++ b/src/picture.mli @@ -20,9 +20,9 @@ val with_palette_offset : t -> int -> t (** [with_palette_offset pic offset] returns a new picture with all pixel indices shifted by [offset]. Palette is unchanged. *) -val ensure_palette_offset : t -> int +(* val ensure_palette_offset : t -> int *) (** [ensure_palette_offset pic] ensures that [pic]'s palette is installed into the global palette, and returns the assigned offset. *) -val global_palette : int array +(* val global_palette : int array *) (** The global 256-color palette shared by all pictures. *) diff --git a/src/screen.ml b/src/screen.ml index bf92069..83e6382 100644 --- a/src/screen.ml +++ b/src/screen.ml @@ -31,25 +31,23 @@ let create ?font ?(image_filenames = []) (width : int) (height : int) failwith (Printf.sprintf "Failed to load default font: %s" e)) in - let pictures = - let offset = ref (Palette.size palette) in - List.map - (fun filename -> - let pic = Picture.load filename in - let shifted = Picture.with_palette_offset pic !offset in - offset := !offset + Palette.size (Picture.palette pic); - shifted) - image_filenames - |> Array.of_list - in - - let final_palette = - let all_palettes = - palette :: (Array.to_list pictures |> List.map Picture.palette) + let pictures, all_palettes = + let init_offset = Palette.size palette in + let init_acc = ([], init_offset, [palette]) in + let pics_rev, _, palettes_rev = + List.fold_left + (fun (pics_acc, offset_acc, palettes_acc) filename -> + let pic = Picture.load filename in + let shifted = Picture.with_palette_offset pic offset_acc in + let next_offset = offset_acc + Palette.size (Picture.palette pic) in + (shifted :: pics_acc, next_offset, Picture.palette pic :: palettes_acc)) + init_acc image_filenames in - Palette.concat all_palettes + (List.rev pics_rev |> Array.of_list, List.rev palettes_rev) in + let final_palette = Palette.concat all_palettes in + { width; height; From 6215794dc6ecfd0106a3d169156047ebbf70d3fe Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Wed, 27 Aug 2025 15:53:02 +0000 Subject: [PATCH 19/22] cleaning of the api --- src/framebuffer.ml | 1 - src/picture.ml | 24 ------------------------ src/picture.mli | 6 ------ 3 files changed, 31 deletions(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index b509254..7aa9644 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -468,7 +468,6 @@ let draw_picture (pic : Picture.t) ?(scale = 1.0) (offset_x : int) let dst_w = int_of_float (float src_w *. scale) in let dst_h = int_of_float (float src_h *. scale) in let pixels = Picture.pixels pic in - (* let palette_offset = Picture.ensure_palette_offset pic in *) for y = 0 to dst_h - 1 do for x = 0 to dst_w - 1 do let src_x = min (src_w - 1) (int_of_float (float x /. scale)) in diff --git a/src/picture.ml b/src/picture.ml index 545bee3..e13f3a7 100644 --- a/src/picture.ml +++ b/src/picture.ml @@ -2,30 +2,6 @@ open Image type t = { palette : Palette.t; pixels : int array; width : int; height : int } -(* let global_palette : int array = Array.make 256 0 -let picture_offsets : (int, int) Hashtbl.t = Hashtbl.create 16 -let next_palette_offset : int ref = ref 1 *) - -(* To ensure a picture’s palette is assigned an offset in the global palette. *) -(* let ensure_palette_offset (pic : t) : int = - (* Hash based on palette contents + dimensions, so same picture reuses offset. *) - let pal_list = Palette.to_list pic.palette in - let pid = Hashtbl.hash (pal_list, pic.width, pic.height) in - match Hashtbl.find_opt picture_offsets pid with - | Some offset -> offset - | None -> - let count = List.length pal_list in - let offset = !next_palette_offset in - if offset + count > Array.length global_palette then - failwith "Global palette overflow in Picture.ensure_palette_offset"; - - List.iteri (fun i rgb24 -> global_palette.(offset + i) <- rgb24) pal_list; - - Hashtbl.add picture_offsets pid offset; - - next_palette_offset := offset + count; - offset *) - let load_png_as_indexed (filepath : string) : Palette.t * int array * int * int = let img = ImageLib_unix.openfile filepath in diff --git a/src/picture.mli b/src/picture.mli index 2a31b05..8fa0247 100644 --- a/src/picture.mli +++ b/src/picture.mli @@ -20,9 +20,3 @@ val with_palette_offset : t -> int -> t (** [with_palette_offset pic offset] returns a new picture with all pixel indices shifted by [offset]. Palette is unchanged. *) -(* val ensure_palette_offset : t -> int *) -(** [ensure_palette_offset pic] ensures that [pic]'s palette is installed into - the global palette, and returns the assigned offset. *) - -(* val global_palette : int array *) -(** The global 256-color palette shared by all pictures. *) From e1e14492d6f3042a94d7d1a1ecb41011de18dd60 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Wed, 27 Aug 2025 15:54:13 +0000 Subject: [PATCH 20/22] ran formatting --- src/picture.mli | 1 - src/screen.ml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/picture.mli b/src/picture.mli index 8fa0247..d119e9a 100644 --- a/src/picture.mli +++ b/src/picture.mli @@ -19,4 +19,3 @@ val palette : t -> Palette.t val with_palette_offset : t -> int -> t (** [with_palette_offset pic offset] returns a new picture with all pixel indices shifted by [offset]. Palette is unchanged. *) - diff --git a/src/screen.ml b/src/screen.ml index 83e6382..b958afc 100644 --- a/src/screen.ml +++ b/src/screen.ml @@ -33,7 +33,7 @@ let create ?font ?(image_filenames = []) (width : int) (height : int) let pictures, all_palettes = let init_offset = Palette.size palette in - let init_acc = ([], init_offset, [palette]) in + let init_acc = ([], init_offset, [ palette ]) in let pics_rev, _, palettes_rev = List.fold_left (fun (pics_acc, offset_acc, palettes_acc) filename -> From 056bb50a70a3827708382d4be0800c92d8293ba4 Mon Sep 17 00:00:00 2001 From: Shreya Pawaskar Date: Wed, 27 Aug 2025 19:27:37 +0000 Subject: [PATCH 21/22] tests added for the picture loading module --- test/dune | 4 +- test/test_picture.ml | 72 +++++++++++++++++++++++++ test_assets/tetris.png | Bin 0 -> 123704 bytes test_assets/tetris.png:Zone.Identifier | 4 ++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 test/test_picture.ml create mode 100644 test_assets/tetris.png create mode 100644 test_assets/tetris.png:Zone.Identifier diff --git a/test/dune b/test/dune index 3fa9419..991b426 100644 --- a/test/dune +++ b/test/dune @@ -10,5 +10,7 @@ test_screenshot test_events test_stats - test_animation) + test_animation + test_picture) + (deps (source_tree ../test_assets)) (libraries claudius ounit2)) diff --git a/test/test_picture.ml b/test/test_picture.ml new file mode 100644 index 0000000..717867b --- /dev/null +++ b/test/test_picture.ml @@ -0,0 +1,72 @@ +open OUnit2 +open Claudius +open Picture + +let test_valid_png _ = + (* Credits for tetris.png: https://publicdomainvectors.org/en/free-clipart/3D-Tetris-blocks-vector-illustration/6089.html *) + let pic = load "../test_assets/tetris.png" in + assert_bool "width > 0" (original_width pic > 0); + assert_bool "height > 0" (original_height pic > 0); + assert_bool "has pixels" (Array.length (pixels pic) > 0) + +let test_scaled_dimensions _ = + let pic = load "../test_assets/tetris.png" in + let w = original_width pic in + let h = original_height pic in + assert_equal w (Array.length (pixels pic) / h) + +let test_draw_picture_normal _ = + let pic = load "../test_assets/tetris.png" in + let pal = palette pic in + assert_bool "palette has entries" (Palette.size pal > 0); + assert_bool "pixels reference palette" (pixels pic |> Array.exists ((<>) 0)) + +let test_draw_picture_negative_offset _ = + let pic = load "../test_assets/tetris.png" in + let shifted = with_palette_offset pic (-1) in + Array.iteri + (fun i idx -> + if idx = 0 then assert_equal 0 (pixels shifted).(i) + else assert_equal (idx - 1) (pixels shifted).(i)) + (pixels pic) + +let test_draw_picture_scaled _ = + let pic = load "../test_assets/tetris.png" in + let w = original_width pic in + let h = original_height pic in + assert_equal (w * h) (Array.length (pixels pic)) + +let test_load_png_as_indexed_transparent _ = + let pic = Picture.load "../test_assets/tetris.png" in + let pal = Picture.palette pic in + let pixels = Picture.pixels pic in + let w = Picture.original_width pic in + let h = Picture.original_height pic in + assert_bool "image has width > 0" (w > 0); + assert_bool "image has height > 0" (h > 0); + (* palette[0] reserved for transparency *) + assert_equal 0x000000l (Palette.index_to_rgb pal 0); + assert_bool "transparent pixel present" (Array.exists ((=) 0) pixels) + +let test_with_palette_offset _ = + let pic = load "../test_assets/tetris.png" in + let shifted = with_palette_offset pic 10 in + Array.iteri + (fun i idx -> + if idx = 0 then assert_equal 0 (pixels shifted).(i) (* transparency stays 0 *) + else assert_equal (idx + 10) (pixels shifted).(i)) + (pixels pic) + +let suite = + "Picture tests" + >::: [ + "valid_png" >:: test_valid_png; + "scaled_dimensions" >:: test_scaled_dimensions; + "draw_picture_normal" >:: test_draw_picture_normal; + "draw_picture_negative_offset" >:: test_draw_picture_negative_offset; + "draw_picture_scaled" >:: test_draw_picture_scaled; + "load_png_as_indexed transparent" >:: test_load_png_as_indexed_transparent; + "with_palette_offset" >:: test_with_palette_offset; + ] + +let () = run_test_tt_main suite diff --git a/test_assets/tetris.png b/test_assets/tetris.png new file mode 100644 index 0000000000000000000000000000000000000000..291d3b7647e046091e603c00ddb8c42ad1aa4225 GIT binary patch literal 123704 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

Isf+YsjXV(ms$6-HLw1*4tQK5 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 wX=Zrk07*qoM6N<$g5 Date: Wed, 27 Aug 2025 19:28:41 +0000 Subject: [PATCH 22/22] ran formatting --- test/dune | 3 ++- test/test_picture.ml | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/dune b/test/dune index 991b426..76f6e23 100644 --- a/test/dune +++ b/test/dune @@ -12,5 +12,6 @@ test_stats test_animation test_picture) - (deps (source_tree ../test_assets)) + (deps + (source_tree ../test_assets)) (libraries claudius ounit2)) diff --git a/test/test_picture.ml b/test/test_picture.ml index 717867b..8a0ca88 100644 --- a/test/test_picture.ml +++ b/test/test_picture.ml @@ -19,7 +19,7 @@ let test_draw_picture_normal _ = let pic = load "../test_assets/tetris.png" in let pal = palette pic in assert_bool "palette has entries" (Palette.size pal > 0); - assert_bool "pixels reference palette" (pixels pic |> Array.exists ((<>) 0)) + assert_bool "pixels reference palette" (pixels pic |> Array.exists (( <> ) 0)) let test_draw_picture_negative_offset _ = let pic = load "../test_assets/tetris.png" in @@ -46,14 +46,15 @@ let test_load_png_as_indexed_transparent _ = assert_bool "image has height > 0" (h > 0); (* palette[0] reserved for transparency *) assert_equal 0x000000l (Palette.index_to_rgb pal 0); - assert_bool "transparent pixel present" (Array.exists ((=) 0) pixels) + assert_bool "transparent pixel present" (Array.exists (( = ) 0) pixels) let test_with_palette_offset _ = let pic = load "../test_assets/tetris.png" in let shifted = with_palette_offset pic 10 in Array.iteri (fun i idx -> - if idx = 0 then assert_equal 0 (pixels shifted).(i) (* transparency stays 0 *) + if idx = 0 then assert_equal 0 (pixels shifted).(i) + (* transparency stays 0 *) else assert_equal (idx + 10) (pixels shifted).(i)) (pixels pic) @@ -65,7 +66,8 @@ let suite = "draw_picture_normal" >:: test_draw_picture_normal; "draw_picture_negative_offset" >:: test_draw_picture_negative_offset; "draw_picture_scaled" >:: test_draw_picture_scaled; - "load_png_as_indexed transparent" >:: test_load_png_as_indexed_transparent; + "load_png_as_indexed transparent" + >:: test_load_png_as_indexed_transparent; "with_palette_offset" >:: test_with_palette_offset; ]