summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2025-09-16 01:36:57 -0400
committerLLLL Colonq <llll@colonq>2025-09-16 01:36:57 -0400
commit4ae21efc81f39ca805cefe5c1af722857f22f255 (patch)
treed877c34b806c61e9480f1c209fd104fffee43988 /crates
parent4db7ffbaafda249ecafa720e52479d5c7b132edb (diff)
Add poster maker
Diffstat (limited to 'crates')
-rw-r--r--crates/client/src/client.rs2
-rw-r--r--crates/renderer/Cargo.toml3
-rw-r--r--crates/renderer/src/assets/fonts/HennyPenny-Regular.ttfbin0 -> 80564 bytes
-rw-r--r--crates/renderer/src/assets/fonts/OFL.txt94
-rw-r--r--crates/renderer/src/assets/shaders/automata/frag.glsl1
-rw-r--r--crates/renderer/src/assets/shaders/irish/frag.glsl8
-rw-r--r--crates/renderer/src/assets/shaders/irish/vert.glsl4
-rw-r--r--crates/renderer/src/main.rs1
-rw-r--r--crates/renderer/src/overlay.rs4
-rw-r--r--crates/renderer/src/overlay/irish.rs113
-rw-r--r--crates/renderer/src/overlay/model.rs4
-rw-r--r--crates/renderer/src/overlay/shader.rs2
-rw-r--r--crates/renderer/src/terminal.rs4
13 files changed, 233 insertions, 7 deletions
diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs
index 713d022..55c3e07 100644
--- a/crates/client/src/client.rs
+++ b/crates/client/src/client.rs
@@ -31,7 +31,7 @@ impl teleia::state::Game for Game {
fn render(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> {
ctx.clear();
self.assets.font.render_text(
- ctx,
+ ctx, st,
&glam::Vec2::new(0.0, 0.0),
"hello computer",
);
diff --git a/crates/renderer/Cargo.toml b/crates/renderer/Cargo.toml
index ae24dd4..e66e198 100644
--- a/crates/renderer/Cargo.toml
+++ b/crates/renderer/Cargo.toml
@@ -25,4 +25,5 @@ base64 = "0.22.1" # base64 encoding/decoding
polling = "*" # polling sockets
termion = "*" # terminal escapes
device_query = "*" # get pressed keys when unfocused
-byteorder = "*" # read little-endian numbers \ No newline at end of file
+byteorder = "*" # read little-endian numbers
+image = "*" # read and write image files \ No newline at end of file
diff --git a/crates/renderer/src/assets/fonts/HennyPenny-Regular.ttf b/crates/renderer/src/assets/fonts/HennyPenny-Regular.ttf
new file mode 100644
index 0000000..ad308b7
--- /dev/null
+++ b/crates/renderer/src/assets/fonts/HennyPenny-Regular.ttf
Binary files differ
diff --git a/crates/renderer/src/assets/fonts/OFL.txt b/crates/renderer/src/assets/fonts/OFL.txt
new file mode 100644
index 0000000..0011741
--- /dev/null
+++ b/crates/renderer/src/assets/fonts/OFL.txt
@@ -0,0 +1,94 @@
+Copyright (c) 2011, BrownFox (gayaneh.b@gmail.com|www.brownfox.org),
+with Reserved Font Names "Henny Penny"
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/crates/renderer/src/assets/shaders/automata/frag.glsl b/crates/renderer/src/assets/shaders/automata/frag.glsl
index 29f5c71..05ee47d 100644
--- a/crates/renderer/src/assets/shaders/automata/frag.glsl
+++ b/crates/renderer/src/assets/shaders/automata/frag.glsl
@@ -5,5 +5,6 @@ void main()
{
vec2 tcfull = vec2(vertex_texcoord.x, 1.0 - vertex_texcoord.y);
vec4 texel = texture(texture_data, tcfull);
+ texel.a /= 1.15;
frag_color = texel;
}
diff --git a/crates/renderer/src/assets/shaders/irish/frag.glsl b/crates/renderer/src/assets/shaders/irish/frag.glsl
new file mode 100644
index 0000000..8fba8bf
--- /dev/null
+++ b/crates/renderer/src/assets/shaders/irish/frag.glsl
@@ -0,0 +1,8 @@
+uniform sampler2D texture_data;
+
+void main()
+{
+ vec2 tcfull = vec2(vertex_texcoord.x, vertex_texcoord.y);
+ vec4 texel = texture(texture_data, tcfull);
+ frag_color = texel;
+}
diff --git a/crates/renderer/src/assets/shaders/irish/vert.glsl b/crates/renderer/src/assets/shaders/irish/vert.glsl
new file mode 100644
index 0000000..e324f7e
--- /dev/null
+++ b/crates/renderer/src/assets/shaders/irish/vert.glsl
@@ -0,0 +1,4 @@
+void main()
+{
+ default_main();
+} \ No newline at end of file
diff --git a/crates/renderer/src/main.rs b/crates/renderer/src/main.rs
index 854eae2..1e16092 100644
--- a/crates/renderer/src/main.rs
+++ b/crates/renderer/src/main.rs
@@ -30,6 +30,7 @@ pub fn main() -> Erm<()> {
Box::new(overlay::automata::Overlay::new(ctx)),
Box::new(overlay::shader::Overlay::new(ctx)),
Box::new(overlay::drawing::Overlay::new(ctx)),
+ Box::new(overlay::irish::Overlay::new(ctx)),
// Box::new(overlay::model::Overlay::new(ctx)),
])
})?;
diff --git a/crates/renderer/src/overlay.rs b/crates/renderer/src/overlay.rs
index accf3bb..9d1f722 100644
--- a/crates/renderer/src/overlay.rs
+++ b/crates/renderer/src/overlay.rs
@@ -2,6 +2,7 @@ pub mod model;
pub mod shader;
pub mod drawing;
pub mod automata;
+pub mod irish;
use teleia::*;
@@ -71,6 +72,9 @@ impl State {
sexp!((avatar overlay cursor)),
sexp!((avatar overlay emacs)),
sexp!((avatar automata spawn)),
+ sexp!((overlay irish start)),
+ sexp!((overlay irish update)),
+ sexp!((overlay irish save)),
]),
fig_binary: fig::BinaryClient::new("shiro:32051", false, &[
b"background frame"
diff --git a/crates/renderer/src/overlay/irish.rs b/crates/renderer/src/overlay/irish.rs
new file mode 100644
index 0000000..6cf3d52
--- /dev/null
+++ b/crates/renderer/src/overlay/irish.rs
@@ -0,0 +1,113 @@
+use teleia::*;
+
+use lexpr::sexp;
+use base64::prelude::*;
+
+use crate::{fig, overlay, toggle};
+
+pub const WIDTH: f32 = 500.0;
+pub const HEIGHT: f32 = 700.0;
+
+pub struct Quote {
+ text: String,
+ start_time: u64,
+}
+
+pub struct Overlay {
+ fb: framebuffer::Framebuffer,
+ shader: shader::Shader,
+ font: font::TrueType,
+ quote: Option<Quote>,
+}
+
+impl Overlay {
+ pub fn new(ctx: &context::Context) -> Self {
+ Self {
+ fb: framebuffer::Framebuffer::new(ctx, &glam::Vec2::new(WIDTH, HEIGHT), &glam::Vec2::new(0.0, 0.0)),
+ shader: shader::Shader::new(ctx, include_str!("../assets/shaders/irish/vert.glsl"), include_str!("../assets/shaders/irish/frag.glsl")),
+ font: font::TrueType::new(ctx, 40.0, include_bytes!("../assets/fonts/HennyPenny-Regular.ttf")),
+ quote: None,
+ }
+ }
+ pub fn handle_start(
+ &mut self,
+ ctx: &context::Context, st: &state::State,
+ msg: fig::SexpMessage
+ ) -> Option<()> {
+ let bq = BASE64_STANDARD.decode(msg.data.get(0)?.as_str()?).ok()?;
+ let quote = String::from_utf8_lossy(&bq);
+ self.quote = Some(Quote { text: quote.to_string(), start_time: st.tick });
+ Some(())
+ }
+ pub fn handle_update(
+ &mut self,
+ ctx: &context::Context, st: &state::State,
+ msg: fig::SexpMessage
+ ) -> Option<()> {
+ let bq = BASE64_STANDARD.decode(msg.data.get(0)?.as_str()?).ok()?;
+ let quote = String::from_utf8_lossy(&bq);
+ if let Some(q) = &mut self.quote {
+ q.text = quote.to_string();
+ }
+ Some(())
+ }
+ pub fn handle_save(
+ &mut self,
+ ctx: &context::Context, st: &state::State,
+ msg: fig::SexpMessage
+ ) -> Option<()> {
+ let bq = BASE64_STANDARD.decode(msg.data.get(0)?.as_str()?).ok()?;
+ let path = String::from_utf8_lossy(&bq);
+ let mut buf = vec![0; (WIDTH * HEIGHT * 4.0) as usize];
+ self.fb.get_pixels_raw(ctx, &mut buf);
+ let img = image::RgbaImage::from_raw(WIDTH as u32, HEIGHT as u32, buf)?;
+ img.save_with_format(path.to_string(), image::ImageFormat::Png).ok()?;
+ Some(())
+ }
+}
+
+impl overlay::Overlay for Overlay {
+ fn reset(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ self.quote = None;
+ Ok(())
+ }
+ fn handle(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: fig::SexpMessage) -> Erm<()> {
+ let malformed = format!("malformed {} data: {}", msg.event, msg.data);
+ if msg.event == sexp!((overlay irish start)) {
+ if self.handle_start(ctx, st, msg).is_none() { log::warn!("{}", malformed) }
+ } else if msg.event == sexp!((overlay irish update)) {
+ if self.handle_update(ctx, st, msg).is_none() { log::warn!("{}", malformed) }
+ } else if msg.event == sexp!((overlay irish save)) {
+ if self.handle_save(ctx, st, msg).is_none() { log::warn!("{}", malformed) }
+ }
+ Ok(())
+ }
+ fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ if let Some(q) = &self.quote {
+ st.bind_framebuffer(ctx, &self.fb);
+ ctx.clear();
+ st.bind_2d(ctx, &ost.assets.shader_flat);
+ ost.backgrounds.drawing.bind(ctx);
+ ost.assets.shader_flat.set_f32(ctx, "transparency", 0.0);
+ ost.assets.shader_flat.set_mat4(ctx, "view", &glam::Mat4::IDENTITY);
+ ost.assets.shader_flat.set_mat4(ctx, "position", &glam::Mat4::IDENTITY);
+ st.mesh_square.render(ctx);
+ self.font.render_text_helper(ctx, st,
+ &glam::Vec2::new(0.0, 0.0),
+ &glam::Vec2::new(21.0, 40.0),
+ &q.text,
+ &[]
+ );
+ st.bind_render_framebuffer(ctx);
+ st.bind_2d(ctx, &self.shader);
+ self.fb.bind_texture(ctx);
+ self.shader.set_position_2d(
+ ctx,
+ &glam::Vec2::new(1000.0, 200.0),
+ &glam::Vec2::new(WIDTH, HEIGHT)
+ );
+ st.mesh_square.render(ctx);
+ }
+ Ok(())
+ }
+}
diff --git a/crates/renderer/src/overlay/model.rs b/crates/renderer/src/overlay/model.rs
index 98b008e..26c06bf 100644
--- a/crates/renderer/src/overlay/model.rs
+++ b/crates/renderer/src/overlay/model.rs
@@ -52,7 +52,7 @@ impl teleia::state::Game for Terminal {
self.terminal.update(ctx, &self.model_fb);
ctx.clear_color(glam::Vec4::new(0.0, 0.0, 0.0, 0.0));
ctx.clear();
- self.terminal.render(ctx, &glam::Vec2::new(12.0, 250.0));
+ self.terminal.render(ctx, st, &glam::Vec2::new(12.0, 250.0));
Ok(())
}
}
@@ -119,7 +119,7 @@ impl overlay::Overlay for Overlay {
self.terminal.update(ctx, &self.model_fb);
ctx.clear_color(glam::Vec4::new(0.0, 0.0, 0.0, 0.0));
ctx.clear();
- self.terminal.render(ctx, &glam::Vec2::new(12.0, 250.0));
+ self.terminal.render(ctx, st, &glam::Vec2::new(12.0, 250.0));
st.projection = old_projection;
Ok(())
}
diff --git a/crates/renderer/src/overlay/shader.rs b/crates/renderer/src/overlay/shader.rs
index 11133bf..dd35031 100644
--- a/crates/renderer/src/overlay/shader.rs
+++ b/crates/renderer/src/overlay/shader.rs
@@ -93,7 +93,7 @@ impl overlay::Overlay for Overlay {
authors.push(format!("music by {}", a));
}
let astr: String = authors.join(", ");
- ost.assets.font.render_text(ctx, &glam::Vec2::new(0.0, 0.0), &astr);
+ ost.assets.font.render_text(ctx, st, &glam::Vec2::new(0.0, 0.0), &astr);
Ok(())
}
}
diff --git a/crates/renderer/src/terminal.rs b/crates/renderer/src/terminal.rs
index 325c108..cca2de6 100644
--- a/crates/renderer/src/terminal.rs
+++ b/crates/renderer/src/terminal.rs
@@ -194,7 +194,7 @@ impl Terminal {
}
return (CharPair { first: ' ', second: Some(' ') }, glam::Vec3::new(0.0, 0.0, 0.0));
}
- pub fn render(&self, ctx: &context::Context, pos: &glam::Vec2) {
+ pub fn render(&self, ctx: &context::Context, st: &state::State, pos: &glam::Vec2) {
let mut s = String::new();
let mut colors = Vec::new();
for row in 0..self.height {
@@ -207,7 +207,7 @@ impl Terminal {
s += "\n";
colors.push(glam::Vec3::new(1.0, 1.0, 1.0));
}
- self.font.render_text_helper(ctx, pos, &s, &colors);
+ self.font.render_text_helper(ctx, st, pos, &s, &colors);
}
pub fn write_tty<W>(&self, out: &mut W)
where W: Write {