From c1d0551d697dfc1a2e016fbbdc9364845fe8dba3 Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Tue, 3 Sep 2019 22:47:35 +0200 Subject: [PATCH] Support drawing images to display --- Cargo.lock | 16 +++++++++++++++ Cargo.toml | 2 ++ README.md | 1 + card10-l0dable/Cargo.toml | 1 + card10-l0dable/src/framebuffer/mod.rs | 21 ++++++++++++++++++++ card10-l0dable/src/framebuffer/text.rs | 4 ++-- draw-image/Cargo.toml | 16 +++++++++++++++ draw-image/README.md | 16 +++++++++++++++ draw-image/src/applewatch-160x80.raw | Bin 0 -> 25600 bytes draw-image/src/main.rs | 26 +++++++++++++++++++++++++ 10 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 draw-image/Cargo.toml create mode 100644 draw-image/README.md create mode 100644 draw-image/src/applewatch-160x80.raw create mode 100644 draw-image/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 2e82da8..c585c61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,7 @@ name = "card10-l0dable" version = "0.1.1" dependencies = [ "card10-sys 0.1.0", + "embedded-graphics 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -161,6 +162,20 @@ dependencies = [ "volatile-register 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "draw-image" +version = "0.0.0" +dependencies = [ + "card10-l0dable 0.1.1", + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-graphics 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "embedded-graphics" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "env_logger" version = "0.6.2" @@ -442,6 +457,7 @@ dependencies = [ "checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cortex-m 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3df5de9a9829f2ccb7defa8945fa020c6614cd2f6ba9b5f33db9241dcc01985e" +"checksum embedded-graphics 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "704679bfcb66cc748ec185ae62ccd5b03311a53793372e2abf1ff9a7e9875ff7" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" diff --git a/Cargo.toml b/Cargo.toml index 04452ac..7b1b7a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,11 +5,13 @@ members = [ "card10-l0dable", "example", "rkanoid", + "draw-image", ] default-members = [ "example", "rkanoid", + "draw-image", ] [profile.release] diff --git a/README.md b/README.md index 6896bb8..bc8f807 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,7 @@ extension (e.g `example` must be renamed as `example.elf`). | card10-l0dable | High-level crate for building l0dables | | example | l0dable example | | rkanoid | Arkanoid clone | +| draw-image | Example of drawing a static image to the display | ## Misc diff --git a/card10-l0dable/Cargo.toml b/card10-l0dable/Cargo.toml index 96880ce..d6c27f2 100644 --- a/card10-l0dable/Cargo.toml +++ b/card10-l0dable/Cargo.toml @@ -18,4 +18,5 @@ description = "make l0dables for the Card10 (CCCamp 2019) badge" [dependencies] card10-sys = { path = "../card10-sys", version = "^0.1" } +embedded-graphics = "0.5.2" diff --git a/card10-l0dable/src/framebuffer/mod.rs b/card10-l0dable/src/framebuffer/mod.rs index 7d1d07d..56faa3b 100644 --- a/card10-l0dable/src/framebuffer/mod.rs +++ b/card10-l0dable/src/framebuffer/mod.rs @@ -3,6 +3,10 @@ use card10_sys::*; use core::mem::{transmute, uninitialized}; use core::ops::{Index, IndexMut}; +use embedded_graphics::pixelcolor::Rgb565; +use embedded_graphics::prelude::Pixel; +use embedded_graphics::Drawing; + mod font; pub use font::*; mod text; @@ -71,6 +75,23 @@ impl<'d> IndexMut<(u16, u16)> for FrameBuffer<'d> { } } +impl<'d> Drawing for FrameBuffer<'d> { + fn draw(&mut self, item: T) + where + T: IntoIterator>, + { + for Pixel(coord, color) in item { + let x = coord[0] as u16; + let y = coord[1] as u16; + + if x >= Display::W || y >= Display::H { + continue; + } + self[(x, y)] = RawColor::rgb8(color.r(), color.g(), color.b()); + } + } +} + #[derive(Debug, Clone, Copy)] #[repr(C)] pub struct RawColor([u8; 2]); diff --git a/card10-l0dable/src/framebuffer/text.rs b/card10-l0dable/src/framebuffer/text.rs index 118e775..cb30d1f 100644 --- a/card10-l0dable/src/framebuffer/text.rs +++ b/card10-l0dable/src/framebuffer/text.rs @@ -1,6 +1,6 @@ +use super::{Font, FrameBuffer, RawColor}; +use crate::Display; use core::fmt::Write; -use super::{FrameBuffer, Font, RawColor}; -use crate::{Display}; pub struct TextRenderer<'a, 'd, 'f> { pub framebuffer: &'a mut FrameBuffer<'d>, diff --git a/draw-image/Cargo.toml b/draw-image/Cargo.toml new file mode 100644 index 0000000..c742384 --- /dev/null +++ b/draw-image/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "draw-image" +version = "0.0.0" +authors = ["Rafael Caricio "] +edition = "2018" + +[dependencies] +card10-l0dable = { path = "../card10-l0dable" } +embedded-graphics = { version = "0.5.2" } + +[build-dependencies] +cc = "1.0" + +[[bin]] +name = "draw-image" +path = "src/main.rs" diff --git a/draw-image/README.md b/draw-image/README.md new file mode 100644 index 0000000..65f12db --- /dev/null +++ b/draw-image/README.md @@ -0,0 +1,16 @@ +Draw Image +========== + +Images need to be converted to a bitmap of 16BPP for inclusion with `include_bytes!()`. You can convert an image using: + +``` +convert image.png -flip -type truecolor -define bmp:subtype=RGB565 -depth 16 -strip image.bmp +``` + +then + +``` +tail -c $bytes image.bmp > image.raw // where $bytes is w * h * 2 +``` + +This will remove the BMP header leaving the raw pixel data E.g 160x80 image will have 160 * 80 * 2 bytes of raw data. \ No newline at end of file diff --git a/draw-image/src/applewatch-160x80.raw b/draw-image/src/applewatch-160x80.raw new file mode 100644 index 0000000000000000000000000000000000000000..824710533766f2ce8eba4b8fabf5432f0e06b006 GIT binary patch literal 25600 zcmeHPe@GkIz8{~OrqIVrXyK-`e@tlVRk#--^bfuGhsjf)6$-X&L467uf6%ThSVX9Z z(55PF@fF-Fg@_7jlf}K)LJJmJNWj|8MfPrrEu^@GkzjYS*}XJZg&kDbdEf7xoX#Yf ziP7#B)@Fue&YWL!&S$>o`~9Bp_sn6L?C~K8upd%5Tb9Y<_hCek#qY!L%a-09ff$dmAf^#uy)OAs+b*IYF`?}^Rcy%wX{8u!wVI&({+ix zf6@0ObiW(pZeOr)JNyoR#yf3F%yTgBZqypK+aF-xaz_l?gG(5iZZ>RJ%)0A@b#HiZ z*$e03lGWZ)ZP@mO;ci7(7uIt}Fee^))<^S_v?_^yhKZCm#U{mzb9I~~J(?%!2mPOm zdY7?}gO9nb=TQvVrVedC?Q+*e)^n%uo*XW~FVBNvcQqFlqKVI_;o`7rTTlVap9VU5<%c5w_YF zu*ays0R7R<8^U zKQ#*3a2A0q0$BupJp`%4sJy_qG60p)mGS6()tKyT5cN!~o@zO%oogK+4T5%h- zFiIac^P3^)`aloFUOX5!>xa)aZWybMr^hNawE(DfanA_07d;%^951Y4Rqsv-4i&!| z9}AU5@azqKIjW>&7IK*$j`jx2B8^afEVMa31omaU<21BH&Kqltl||}<=ZE!j?iTN0 zQqjpY=Ej~7e9_kwli(EhuiFRDw@@ELC^41WmF z)WmB*B({Xq68bTj%G@N}-piVNvwq!5%0EiSLh82u*MO3Sq4UEe6}@3cT7AWLx=T1- zjtYpGSmnL|zXfLJ!5ew5bEx=8>udk2Twan)NzeK${-y$AX#PlRp0&NmH1H%uayLeN zX~ukFoAJ)2D>sI$hJk_{J=E0kyUUUL-E?I21_N?G6Y(1=CZnl8rhfnS0fNbi)!qDI ziAalqy~P3`g(&(FG*<8a&i^RJ_#u)cjaD6k{Xi}a;_bIF~KsAWuC}f zqbWwq+pL6AQ=f(F5eU6zF87}$%{L4=96!`&IE<85;Oqz*WGoBJL*oU(GzcC~&jZhO zo`{HkqDyGuXBt3^Qu!42nNpUbi4a62NkO2{Ny=;WoAA|DiL7zKRW7S?=475o@Fj0r zshOg#ccrw3c;RWt5&muvJG!e57nlu)Iin$`z+7;+W7Hs44I9$(!c3*G7Jfu72Slw_ zetm)PO9h)$`XiEiQoMaZs|G^vR09xNsa(7-C ztD?-&$|5vJ;+4=VrKxkB1iwgWVlHy`YMi7RGx7o7Fs9;%2pY`7x56(z`7}trdp;&T z?IC{8GSs6}@pBjnN5WMoT8BsGp4#Y=`~;yoPOCJ-5UD`X{g;a%bXk-Bh#ZroM9HjO zFT-eSegebYi=+25_lxjtzO$97alYvM9Il9z_W3r$8EYzjUzHN+K}T3}Ysq+}{ZCHC zds4nfC1cgO$e3)35qd4EA^ad&Qj-$B^1G5GwHBnVD>0mxfCX?mxc{TM>UbqjXwUac z6+cvb%Sm<1C!x=s+UTKeHL-5JyHxzn))0+GZ=ON8+r)bbnp!hKl594;6T-aUU;H7At%-VywSpM5ueC~j2E zDf?qz*JvZSfBbI8CB(l~ny=DEh9NvjTe^^Z1i#I3btxrGbU;O`qw~a9N%^hDvG+41 zy}FcIF{H*1^pzUnufkt_4Zh+bf#BEiEa!7ozU7`IX!^C~jvat-P(JNyZmTK0n9 zw?C$~3%nfX#FoO z6({U4?_d576*tNFspn(rb`t&LgpPKHIf?w$TQy2_lBQTof`;`|1JQbDw;Ch%0ju!` z$E1wwpEFvA<Q4t7as-+h7PLsq&X$((8YT`mY*U z8cv_%wXSwu=-eECH2-M6XYP*t1p~u;(?EKuJv*V#qgQJZ4+Gw36n^gT<6OhbG^yln zGIn@x3EWeachO3BxoY7@`meSTD3yQ(L2idyyS~%CIgYjndgvpBIo`-hNr{ejP3s_6 zyF3%0h-JEhH&FtE1jzyGflO8Zyr6}dI_~wnB8M}T9@_R7!r`+(AtwY))Vun?@~D+N?<&T{(?27JO15GWk(gP zOHkLEF04g=_q&PSswF`Pw!EbH$j0JY8lBNHjIWrqQwt+vzv0D9W@K&?k-~bMIJIA? zBbZ_`5VxG^Az06;M{lOq7j62Z9B?OPPEc7y^d|)?h9Nd4Nm7qU!U4)6?I|ngiDfWx z_V=RCG@#|bBJXNd`d6mR2mpO%>WEVuMUGy7D6Z!wV*xSsEQ?(9s%1x}x(mL)NU4_n z`B>Z|k*ot#TNSn5VGUnjXpHb;S)@p10U&%!l9K1ZM0b>=m#VqO{cfZQ3#aJLSS!Q) z1a^H)(dNS>PwGGW-rh`cQ?9Mde=z?I=c$A<7h)52KQ^^m-572B7>4LDyr{O+6MB#& zPbk@+o^0uJnFs|+lG+M!Wti~JlL@*HwbnifeXX(=-tUgLK>EM9EY|HpQo?>#9w-=h z?9qo#@Z+UK{}IC|{xeVTggf{N5lzI+cQHsdQJpd5D6Nekeb~c?W$yksoU5NmK0bH6Q7h`hP<9n$SGy zuJ^mO$_K<$PxIv(GRsvzhlKTX@O00`w9`5~P#-svQm~J8SoroQMPf}#Y}cPVDP_=} z^#(K3WJx`@FHqS`%fI2ZbQ*?Pv|OB5D(sLg`FhAzWmoW~1=J<4fbP(dDEVeL zlasc5HW7BTU}gYCwM;o}&Nt5(vm9@))WI@%W{)faSp>2OWD&?BkVW9vML_Krtt?X3 zDQ5B%R+UK|#%ODyH6co^H7W^8h*2Gm5=WuxR@MNl>IlYBVr7*G)@UtP?mk`!zk&#e zO)>P&6gtO3Xlvf#sr}mMEQ?^wM2vX9dV`a2H!0Q!zbbVYdxK9x#0p+nw8PgYtlo1J z`j&AIhrtClzM?j7B>zXcQ$fX)5OvqG7D3)KXmA1cxPe?OE3DW?z&6swg$)~q4c~H0 zwSolh&~)k+xrZHd!OtXtwOjKGc@d+{oZSw7Ms`f*+L*&5>Qv~VXQGe8GpA?n9L z{E#xgDwQPkO!UWy&qnm)3fGh1g&2d?L{{T>As(n!-RKHW-gUeeqHPaIJmLp?eAR;e z%7ge#Uvk(Z>#&m&;s^IF)odZ`12%<7#dmS3oxViM!meL84I57{8MfWcu+xyousz+J z1DGyeZJR~Beao=_3&UDq_p62E-8ESX4xY8Zh(DuiEYCy~RXWm2~18J>I?kNdZ%syWkT&e^#alary z0Pqvmk^Y{qv_1C0K7BBLW%~0j0i`ZiOeyHW-Y!eNWvd-V=oG`WJrLGe3u|=Mx$7Jy z@;h1}&+x9mes;#+0x9h}k>72O<4O?pT_Z2FaE|~J>iY`9y8<5lvo&QAq%MXz;|+*pbub;j_!R}x*F@~Q(D`Be0NRD!fZu1{7k!f=`lfqQ z@PpB|LB}rEYMT|pj1l%&T5o&MQX*_kUsCXcQOC5+3Q<653Ra8*O~Jn%F~ktVoEj0f zP#VFx<*o&Ox8bU08ArM8f#JuT_?~r`5B8i~!t2L6;EN^MH)Y{?aSg`fSZK!5Vif(8 zBJnyPe&>g0ESKe7-4H*;XHD>9m>nLa4Z&}yn680z!ERoIOAfZh&a$L8l|X;+h04gG zZ5(xn)bs~?s9_%18FH&)3etdTVSJjrOIQMr!6k0RVRzW4VPC6?*{Qli+wCCNt#&T# z1&PxB*s!tK#hPqTx6MOJe4PI^%Nw2t?S&Unx;`8Yh$kaE5JSCCxH5E7?2qBTP`F;F zKc;*|-~#!J>m_`}$QdsJkHnSklksmj+F^|0Zd1Y*2fUqy?zGK*4}G#U6Jo$ z4^%6QxjyD$8hABM{WNE5z8rlxO7E~0w=bOQ{8OtUPt;#c9BEa2XpvI%)$|7c5Fl;0 z7EU+2o2TJyDUZjL+^Ay#NmjmHY|eq}%q6RZWt_FnYK&x=nP!I_L+-lVk+qx6av1Mt zF0m|&0ocFPU5g=CZSKh8P1b~Q$nh4h=6clfMvnj8{fU0Mj_!BY^lXE(2pm8JfIGj} tM;&_(DP=(l#7k#hqt(d95v5!cYoT! = + Image16BPP::new(include_bytes!("applewatch-160x80.raw"), 160, 80); + framebuffer.draw(&image); + framebuffer.send(); + + loop { + let buttons = Buttons::read(); + if buttons.left_top() { + break; + } + } +} -- GitLab