From 85a403556ea72dbb17333ebe3ab558f066ebc1df Mon Sep 17 00:00:00 2001 From: Michael Dales Date: Sat, 30 Aug 2025 13:05:27 +0100 Subject: [PATCH 1/4] Reorder README.md to be more user focussed rather than developer focussed. --- README.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b174526..6428ccc 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ Sincere thanks from Claudius team to all those who have contributed or made sugg Claudius uses [Tamzen font](https://github.com/sunaku/tamzen-font) as the default text font. +# Docs + +There are [odoc](https://github.com/ocaml/odoc) documentation for most of Claudius. You can find an online version [on the Claudius website](https://claudiusfx.org/claudius/index.html). + +There is also a large range of [example programs using Claudius](https://github.com/claudiusFX/claudius-examples/) that you are encourage to experiment with: try running them and then changing the code to see what else you can get them to do! + # Using Claudius Claudius is a library for OCaml to do retro-style graphics, and so you need to create a new project that uses Cladius. But because Claudius isn't currently in Opam, you'll need to add it into your project using one of the two methods: @@ -31,6 +37,14 @@ And then once that is installed, you can add it as a dependancy to your project To see examples of how Claudius is used and learn how it works, we recommend you checkout the [examples library](https://github.com/claudiusFX/claudius-examples), run those, and then try editing the examples to make them do different things! +## Standard keys + +Mostly Claudius doesn't have any interaction points beyond those you provide, but there are a few: + +* F1 - Show debug overlay +* F2 - Save a screenshot to a GIF +* F3 - Save an animation to a GIF + ## Developing Claudius If you want to make open-source contributions to Claudius, you are welcome to do so. For that you will need to use the below approach @@ -48,17 +62,7 @@ $ cd .. $ git submodule update --init --recursive ``` -## Standard keys - -Mostly Claudius doesn't have any interaction points beyond those you provide, but there are a few: - -* F1 - Show debug overlay -* F2 - Save a screenshot to a GIF -* F3 - Save an animation to a GIF - -# Docs - -There are [odoc](https://github.com/ocaml/odoc) documentation for most of Claudius. You can build that documentation with: +You can build that documentation with: ```shell $ dune build @doc From 65c91884171ac79cb55b3f386e6a6fb5d8cff9ef Mon Sep 17 00:00:00 2001 From: Michael Dales Date: Sun, 31 Aug 2025 09:28:48 +0100 Subject: [PATCH 2/4] Update odoc for images and palette updates. --- doc/index.mld | 7 +++++-- src/screen.mli | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/index.mld b/doc/index.mld index e0e6bbe..4deb98d 100644 --- a/doc/index.mld +++ b/doc/index.mld @@ -125,11 +125,10 @@ let = p Palette.generate_plasma_palette 14 |> Palette.of_list ]} -Aside: because you can't change the palette once Claudius has started, this may feel very restrictive compared to TIC-80 and other fantasy console systems, and you'd be correct. However, because a palette in Claudius allows for more than just 16 colours, you can take a functional approach and compose a palette that is the super set of the various palettes you will need and then use offsets when rendering to access the approapriate "bank" of colours. {2 Screens} -Once you have a colour palette defined, you can now create the screen mode you want to use for this program's lifetime: +Once you have a colour palette defined, you can now create the screen mode you want to use with {!Claudius.Screen.create}: {[ let s = Screen.create 640 480 1 (Palette.generate_mono_palette 16) @@ -143,6 +142,10 @@ let s = Screen.create 320 200 3 (Palette.generate_plasma_palette 256) Claudius will use this information to generate the initial framebuffer state if you don't provide a boot function, and it is used to generate and render the window Claudius will display on the screen. +In retro-graphics there are many effects that are powered by updating the palette, and to allow this Claudius supports updating the palette as your program is running. For example, it is a common to rotate the palette colours to get an on screen effect rather than rewriting all the pixels with new palette values. To update the palette you provide a new palette to the screen by calling {!Claudius.Screen.update_palette}. + +Screens also let you load a set of images ready to use in your program. By loading them at the start of your program Claudius can correctly allocate palette entries for the colours in the images, so the palette becomes the colours you specifed when you create the palette, plus the colours from any images you loaded. + {1 Details} {1 Pulling this together} diff --git a/src/screen.mli b/src/screen.mli index d53bd25..5c11603 100644 --- a/src/screen.mli +++ b/src/screen.mli @@ -23,9 +23,6 @@ val create : 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 - marks the screen as dirty.*) val create_with_font : int -> int -> int -> Font.t -> Palette.t -> t (** [create width height scale font palette] Deprecated: now use create with the @@ -39,6 +36,10 @@ val dimensions : t -> int * int val palette : t -> Palette.t (** [palette screen] Returns the palette associated with the [screen]. *) +val update_palette : t -> Palette.t -> unit +(**[update screen new_palette] updates the screen with provided palette and + marks the screen as dirty.*) + val scale : t -> int (** [scale screen] Returns the scaling factor used when drawing [screen] to a window. *) From 34e2e1acf8b6a7715386c22e692f8fa637e1198f Mon Sep 17 00:00:00 2001 From: Michael Dales Date: Sun, 31 Aug 2025 09:36:03 +0100 Subject: [PATCH 3/4] Simplify picture dimensions API, consistent with Screen/Font --- src/framebuffer.ml | 3 +-- src/picture.ml | 3 +-- src/picture.mli | 10 ++++------ src/screen.mli | 1 - test/test_picture.ml | 14 ++++++-------- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/framebuffer.ml b/src/framebuffer.ml index 7aa9644..a523424 100644 --- a/src/framebuffer.ml +++ b/src/framebuffer.ml @@ -463,8 +463,7 @@ let filled_polygon (points : (int * int) list) (col : int) (buffer : 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 src_w, src_h = Picture.dimensions 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 diff --git a/src/picture.ml b/src/picture.ml index e13f3a7..9821f66 100644 --- a/src/picture.ml +++ b/src/picture.ml @@ -71,8 +71,7 @@ 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 dimensions (pic : t) = (pic.width, pic.height) let pixels (pic : t) = pic.pixels let palette (pic : t) = pic.palette diff --git a/src/picture.mli b/src/picture.mli index d119e9a..86c339b 100644 --- a/src/picture.mli +++ b/src/picture.mli @@ -4,14 +4,12 @@ type t 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. *) - -val original_height : t -> int -(** [original_height pic] returns the original height in pixels. *) +val dimensions : t -> int * int +(** [dimensions pic] returns the width and height of the image in pixels. *) val pixels : t -> int array -(** [pixels pic] returns the indexed pixel array. *) +(** [pixels pic] returns the indexed pixel array. The pixels are arranged in + consecutive rows, with the top left pixel of the image first. *) val palette : t -> Palette.t (** [palette pic] returns the color palette of the picture. *) diff --git a/src/screen.mli b/src/screen.mli index 5c11603..6ed6493 100644 --- a/src/screen.mli +++ b/src/screen.mli @@ -23,7 +23,6 @@ val create : images will be loaded and their palettes merged into the screen's global palette.*) - val create_with_font : int -> int -> int -> Font.t -> Palette.t -> t (** [create width height scale font palette] Deprecated: now use create with the optional font. *) diff --git a/test/test_picture.ml b/test/test_picture.ml index 8a0ca88..f69a176 100644 --- a/test/test_picture.ml +++ b/test/test_picture.ml @@ -5,14 +5,14 @@ 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); + let width, height = dimensions pic in + assert_bool "width > 0" (width > 0); + assert_bool "height > 0" (height > 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 + let w, h = dimensions pic in assert_equal w (Array.length (pixels pic) / h) let test_draw_picture_normal _ = @@ -32,16 +32,14 @@ let test_draw_picture_negative_offset _ = 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 + let w, h = dimensions 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 + let w, h = Picture.dimensions pic in assert_bool "image has width > 0" (w > 0); assert_bool "image has height > 0" (h > 0); (* palette[0] reserved for transparency *) From 82940c9487995c5333f44dae6d97778e834c91a2 Mon Sep 17 00:00:00 2001 From: Michael Dales Date: Sun, 31 Aug 2025 11:11:43 +0100 Subject: [PATCH 4/4] Address review comments from Shreya --- README.md | 2 +- doc/index.mld | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6428ccc..1db4bcf 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Claudius uses [Tamzen font](https://github.com/sunaku/tamzen-font) as the defaul There are [odoc](https://github.com/ocaml/odoc) documentation for most of Claudius. You can find an online version [on the Claudius website](https://claudiusfx.org/claudius/index.html). -There is also a large range of [example programs using Claudius](https://github.com/claudiusFX/claudius-examples/) that you are encourage to experiment with: try running them and then changing the code to see what else you can get them to do! +There is also a large range of [example programs using Claudius](https://github.com/claudiusFX/claudius-examples/) that you are encouraged to experiment with: try running them and then changing the code to see what else you can get them to do! # Using Claudius diff --git a/doc/index.mld b/doc/index.mld index 4deb98d..1c4eb25 100644 --- a/doc/index.mld +++ b/doc/index.mld @@ -144,7 +144,7 @@ Claudius will use this information to generate the initial framebuffer state if In retro-graphics there are many effects that are powered by updating the palette, and to allow this Claudius supports updating the palette as your program is running. For example, it is a common to rotate the palette colours to get an on screen effect rather than rewriting all the pixels with new palette values. To update the palette you provide a new palette to the screen by calling {!Claudius.Screen.update_palette}. -Screens also let you load a set of images ready to use in your program. By loading them at the start of your program Claudius can correctly allocate palette entries for the colours in the images, so the palette becomes the colours you specifed when you create the palette, plus the colours from any images you loaded. +Screens also let you load a set of images ready to use in your program. By loading them at the start of your program, Claudius can correctly allocate palette entries for the colours in the images, so the palette becomes the colours you specifed when you create the palette, plus the colours from any images you loaded. {1 Details}