From 53610a8c1c700c72127d7b9abcb4f0efdc477231 Mon Sep 17 00:00:00 2001 From: klein panic Date: Fri, 27 Sep 2024 19:32:14 -0400 Subject: [PATCH] Initial Commit --- clock/README.md | 3 + clock/build/Makefile | 24 +++++ clock/build/clock | Bin 0 -> 21000 bytes clock/include/clock.h | 37 +++++++ clock/obj/clock.o | Bin 0 -> 8760 bytes clock/src/clock.c | 168 +++++++++++++++++++++++++++++++ clock/src/clock.c.bak | 165 +++++++++++++++++++++++++++++++ render/README.md | 3 + render/build/Makefile | 26 +++++ render/build/cube_render | Bin 0 -> 16896 bytes render/obj/main.o | Bin 0 -> 6144 bytes render/src/cube.c.bak | 189 +++++++++++++++++++++++++++++++++++ render/src/main.c | 196 +++++++++++++++++++++++++++++++++++++ render/src/pixeltest.c.bak | 114 +++++++++++++++++++++ render/src/slow_cube.c.bak | 189 +++++++++++++++++++++++++++++++++++ riceapp/README.md | 3 + riceapp/build/Makefile | 24 +++++ riceapp/build/cube_app | Bin 0 -> 16552 bytes riceapp/include/cube.h | 21 ++++ riceapp/obj/cube.o | Bin 0 -> 4392 bytes riceapp/src/cube.c | 178 +++++++++++++++++++++++++++++++++ 21 files changed, 1340 insertions(+) create mode 100644 clock/README.md create mode 100644 clock/build/Makefile create mode 100755 clock/build/clock create mode 100644 clock/include/clock.h create mode 100644 clock/obj/clock.o create mode 100644 clock/src/clock.c create mode 100644 clock/src/clock.c.bak create mode 100644 render/README.md create mode 100644 render/build/Makefile create mode 100755 render/build/cube_render create mode 100644 render/obj/main.o create mode 100644 render/src/cube.c.bak create mode 100644 render/src/main.c create mode 100644 render/src/pixeltest.c.bak create mode 100644 render/src/slow_cube.c.bak create mode 100644 riceapp/README.md create mode 100644 riceapp/build/Makefile create mode 100755 riceapp/build/cube_app create mode 100644 riceapp/include/cube.h create mode 100644 riceapp/obj/cube.o create mode 100644 riceapp/src/cube.c diff --git a/clock/README.md b/clock/README.md new file mode 100644 index 0000000..7653c0e --- /dev/null +++ b/clock/README.md @@ -0,0 +1,3 @@ +# clock Project + +This is a C project generated with the setup tool. diff --git a/clock/build/Makefile b/clock/build/Makefile new file mode 100644 index 0000000..f0e7f35 --- /dev/null +++ b/clock/build/Makefile @@ -0,0 +1,24 @@ +# build/Makefile +CC = gcc +CFLAGS = -Wall -I../include +SRCDIR = ../src +OBJDIR = ../obj +BINDIR = ../build +TARGET = clock + +# Gather all source files in src directory +SOURCES = $(wildcard $(SRCDIR)/*.c) +OBJECTS = $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES)) + +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(CC) $(CFLAGS) -o $(BINDIR)/$(TARGET) $(OBJECTS) -lm + +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET) + +.PHONY: all clean diff --git a/clock/build/clock b/clock/build/clock new file mode 100755 index 0000000000000000000000000000000000000000..2355aae407d1235952af03e6fd7b49cbb2f717db GIT binary patch literal 21000 zcmb<-^>JfjWMqH=W(GS35Klo6BH{p{7(Be73!)Oi&mw_3oPXfeXU|>L}WuWR{G{{XLArK9+55&fXB{(6XFq%OC!UySN z1u>y~m^h5SC=8NhV1UsuagaW+eFhMD1~mE()cr6TSsy5D4%kBU9q>h?q2Y1@O2hPl zxFCHOp!zOA^}*;5AO|rpFu-V7c!Jyr!WK~XpwkKv>lt7)y1odgK6Kgzst-nk>;MS` zKP^cCvC-{;@nQDBXqbHgP<<;5L8dS;pwl@JVFnltvI8U(__QPi6fPh(F&GxjK~Vc} z#e)MVz(MI3N<)K}K|d!m$;?DQCq*|WGq1Elx5C0q*UUt(IA6~QY(2RLMW;-%zkj{3CtWjy!Ty85xr}6x8ju+vJs>q8gF(>% zbqa{f0AhoZCP)p$|BYaAkQj(@G4)(7h{lDdGcYg+VUf(kAr7(!7H7!Xw%|~|5Qq2* z9OCP6h`Zqsmt|mpr&(n8q~K7WfI~bJhj<7MaZquGE!_HXsE@`Wu7ktuUt&CiQ3E=epZiH~OhE5)iX zIlq{pI5Ur-I43o=fT19@s3^aPA+;j2grT^kD6J$jHDZek`# zB)K9nJ}omZF( zAty5_7nE(xK&)g4%iYJ*$vNIg&q&Xd0me2qVPIfjVqj)qWMG0q78Eu}6e0%-5=I6_ zhMf!y;9?V$UQ4AiIYBkiS&$?H16b!_s60q$%fxAHpxk&9Dh5%{!~jzdE1zNI6fD!6 zfR?{7@dMC$u_6FuDgy&d9L7K34-p6DRZ!lA@E90QAc=$WI86Kkk~p;L0!!UM5{Fs| z7Jq;w4l4t|5>WTBgZ&N`0TUcZ;-K;dEC>n%Byms~1{0S+5(oJKCa!=a4zdF#u7M;D z3k#5(0g^ZuNC1j0ki@y6Vj#)^Nt_2H0L30i;=E8X5EXzV&Ib~J;s_*heyA9TN5Y9jn$ClqgYDV#B2#kinXb6mkz-R~zw-E4Xe#7C>&3e?Hfx)BoKnc_T3m(l! zI6y5Yh)@5Up0a0P_^*1#o`Hd1-htu2Du|x}l6?8#|NsC0RS(%SFl2zb4KFW%`MW@T zP}Aq-0Wg0Ph!1M=yxaihuLAKwO_7%i!2CrZKBx)uasrq?3&aOCJzh3|`IA6=P?O_j z0hr$f;)9wRFB8E0CJ-Ogbb1*8=2wCEpeDyl2Qa?~#0NDsUK)V;Ss*^BiSbea%ufRG zK~0O70$~0rI|hcd2_O%Gu;E+J&Wmv#osT@4pL_@iaWy<(c+#WSb~8T%!++6wI|ha? zX?pzfEg+@f@bT!i)dYoQFRK!WviwmZ>e0;_X9o#h&i@biMue;?d2j3zBR-P{Q&5K^nij3je(4PT(CPc8x%LY~gzhud39*Mk<_3E-zj5&Bti8}# zdZsh7U3$i&yY_-d z95$@4Fw*zdyM}bFYM1@CpFDQw5bkCgu7VQA5>6`&p z)7=YpYWG}FC)%U41FW)h21un#=fM|2|Nj5?XgmT^0|~BD4oGN}Sc0PBK&R`2Zr2Ca zt}kkMKw;tfrQ7ulqw5*4*a!apC;$Hc?{@vb2oit7=z8Mi<$wSGPnh7*9sA=XT5Nql zjjRsWGYz$8^!fWvFfuSS)Sj{A@88GBz`(!H^-S{%gHG2c$6ddGQozf3j0_CNT|a=? zEsP8d-L4-zl0S62KJl2*9s0#1`IJZJA&-NPSUfZjd32ueU_9W#c*2A6f=922fk!W^ zrVImv2jd0)Z45Ss{H+dPv)+Ks(g3qxfZ04?bHDJfcRkQ~sN3}jD8;>S>1AO8CrXIm z36S8MUK6J7&^^N_5p-U3={)qp`wu)BG`qfF>~?)&?RtQ}=f%JO|C?RkFm}7X0rSs* z`5zdYYdmC^^8lW?+K4? z*Bc(4t{+~4hKfBvLA;HDf8Pg}Zr>9w-L7X`xNgI_a{H` zYn}MSFTi?Bl7Zn9f8@bW`~tk!!0fn#pZKE=eC8K)eUZlh{?cdusL&T_9{hC|(meR{ z4!pSd;N#lQi`!j!3ELi;wi29FE^^M5tb-?N$bceq2 z=ykp8(aS3>0V);Gd2}A%0m@e|PX7QE4-Z^=1HN^;KIskk=FwYv*Q2}k#4w3i$DRNG z|7URA0cw%BbY6VH{1+)3y&6?)+lzhLNr zH2(KbKJ!PVUI9he14slYdDu*FAj?Gh=ZT_bq;j8z5zwrCw{G1kO{FM z6W)I2kIDs`0E)-F126Q@O*jfRAqHx~3sBzcE`0%t&F%gqGJNJUVM%bcf1xyGrn{KZMc>d9e?apglT|zexZ3|G!6f=!;kE%=*B9Lm9N7otV1*Jygaw+e zFM!IZI8ji7jXd;;ACzbzWz&<-`~t2Zf;T{vfq_5#AV~jb{wQz?XN7106>6f4q6`da z{2C`d@yDG48D%55wNSk zmdp`Bwd4#~4q?d+mu}Yw9^H`O7#?lFU7!MNA7}z3%@I^DL?e=d3#ghNhMt|qz`y|U zY~C+;x(DazUe^YX&Wj$sqG5sz4EsQXxu67p>?0__mo^Nqh)1rvc1AEUFn~+Q7mnZ1 zf}|DH(S?MHrvOr@Z1?~Qm91deVU;sKa zc=WRB^Me{d(ALk~_y7NQy1r?yee=Im(xaDE79#m#>ihry_k-GVFLu8N1>#gtAa=XH z*~j3XkSpNb;aw+jN;J{7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5I}?gXhkK0hsjb+VNi|KRn64}F+8kPeXUf38T3<9%kX*~TtQ1ntrU_I^YZdb z6hMnd71D|lb5oN_)6!Cl6jD;lGLutb>J*An6H_wt(iO@Qi!wngR~0hz((;RP6H7Al zK?{=M>T(kc3P9>GjZ!GdSIAAx%`d8ixYf|m(9i&ez#IcZ0|)}~3_%n+_5HOTuL#42WI^1_@o4kl%`&kZlkRX%Lzr6G~S? z=mSL%n&E*x#5Z6PG!+bHfCz{=KkXT%nXN%<;z0`+D(?ON51OpWxc~qE0|o|$iu?cn zgC>p>AN>FSgMooz=Y#+MB^VhP(jWc*Z^OvIknrUH{{%(`h9yt`{|8OSRz3g!e+450 zgTTxG|IaWoFettH|NjFc1B2W9|NlimLlg`Q44}2^Ap04sf*2Sp1Q?}x*f}OJvI~I3 zL3=V@-249@d7Uyy98*05g9-x!14#XjyZ`@#CxrO~-1sEC__@nD8W`-QthJ0)z{Y^| zgZ3CS-249@w73Ig76^m%#xO82B;No3KLRA+$S2Uop){9FnQNzX67Y~a5bRWa^;8r|Nlf+^B$q*2m=Gdk4OLiyP&JFLZ|^vK1)3L|Nk1g znllJBpsDFoPyhd)hOVXup~irbfx+ha|NlbhYB&&TLKqnsv|jxGuL4>f1M`{-g(GVC7fzc2c4S~@R7!85Z5EzCb0Nu0%+m{Av zPJ(<1o;O6=3kF-!4eCFDPsKm-E=18AW(hzV-j zf@o0?frO#j7+yg4!GW5+An5?8$3guF5FfN)97KzQ2nGg*6Hoyt#lQh&z}$TRst&Y} z9K?j#|NB40KMc^Ve*d8S9Z-+_hw@?W_yFbiK;?fz`7n2b%pM2~+dqzOw;6OZoEwx5 zgVJeGx(rIULFs8wdKr}72BnWd>1$B>8I=A8rP+`-F@pLnprslN3=Hnh&Q=N;Wx`rm2P$s%-5qwZ|voL)8j}U>dK=H@Oz`{@i4RFxjP>>90uOv40a^PL3 z{0sqT?gQy#V&G?JKod8Hs)yw_kl7&Y3C?R$3=L3!f!qfY4+V>hGQjc+NDPEQeO8e9 zuzjW=F%Smz;~5!5;Q0?E2Exn1=OtkJcRkpAL52gM!59VxhG`(h3=9mo{JRaTUYOwq z$Rkj-FbZ4vfcnIY3}OuE=?AiJRtUa-A7%zF!2bGy-WfOuyPM3 z9tRSKaggYIusA=%4rl=g?zb~AFw{fEIm94}!D9yu3=Ex6@l((O6x@erU|^UE7Kf-s zCPCvd*!;T-hkDSs4L0?6!0P!K_@M@b6T*XK#NDvVrn4zjd%5P z0iA!~66xpY>*>r8AMfrL8t>{650Uk731WzM_wjdf^ojR(a|?D2i4Spf@^Ou4NGVDz zk5A4lO3q0|9BJU-j&w``#)$}USz{B(feVPRK|PxxH6^hmkpb*m@QDa;jiA#HAQpo> z6Q7otoC2c|m!xFo#g`VRra+trl7g^uGV@Xy;#2cd7~uyg=A zG6U;57~u0S(DWgnZ-FWWN_`9rdc~EwC5cH4dc`G05IO_K%FHWCEh=Ep%gZlG)l1JS z)hj5Vh&CSb0WbaR!54N@ZSgWiEs+DPjQ2l%*CG zgXTt%Iq^jddPS)@i69M7RzXe)gC5wKdIdQpdg=Kk40_;Hq?eYNm&u@4ln+jXdZ`)E zY?YBx!~o|(v_kS116T))ol=>Xn46i*05TC|GJ_t(oTTDn2EF9`+}zZ>5>TN*IR;ge zpf(e%9gXWeD40zkwJ-vO3!-859*7OXp!OfKepvexMx)!0u0NcCf#KW#|M@WY!}?D!8fHJVTLC|J1Y|b| zCqny9F#WLp6^woW4KR=!K}?wcVf`G?`8c2^GfY3MzXqdW{WFkVAPh1CM8j|)0|Nu7 zF9g#M>;J%L4X8qx`(f%}bR7c&1E_BW4*6rbWRc|PMjdx;r&HezY*5I1nCFqLDvsD2MH7=AbGG6(0&iB zpABvHf~7zN$Sx2K!*jsxat82uY9KKMsD2m?o;w3cKrvJrW;_F^e}HVi0JPr%qhaoa zYKNyEnD_>C`=R<_?X4Bi_7Y4#%zhXj(yu_cAJ(ph(VQ@aP#WF;d!Y7%;ufp~+Mj{7 zGePZRusD=J&rgtk3L^e-oht^_4nDIE#s<-s(Cn9h9P`BhqmO_B7o-r1Vc`blGTdQc zU;v#%1Ij}nG1&MC?A$SQ^)Nn+2F)vi&Z~jxhxHdvK+l1LsRNk}!Z1FJ25r0rr9GH_ zSbq(6jvQ!y7o-oG9pLc~i^tVa|HJgd&M`UwotcK^UyvCf46_$T|3%Xe8=rXr)eq{| zg7m>KOdpJ9V+5Vq1UjJ!q5{@WDS*z9!`umxg$~BRI1CI7pgC8NSupp*`U4G6{UA9c z<=`_8k@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 600 +#define CENTER_X (SCREEN_WIDTH / 2) +#define CENTER_Y (SCREEN_HEIGHT / 2) +#define RADIUS 200 +#define HOUR_HAND_LENGTH 100 +#define MINUTE_HAND_LENGTH 150 + +typedef struct { + int x; + int y; +} Point; + +void draw_circle(int *framebuffer, struct fb_var_screeninfo vinfo); +void draw_hand(int *framebuffer, struct fb_var_screeninfo vinfo, float angle, int length, int color); +void draw_clock_face(int *framebuffer, struct fb_var_screeninfo vinfo); +void update_time(int *framebuffer, struct fb_var_screeninfo vinfo); +void draw_text(int *framebuffer, struct fb_var_screeninfo vinfo, const char *text, int x, int y, int size, int color); + +#endif diff --git a/clock/obj/clock.o b/clock/obj/clock.o new file mode 100644 index 0000000000000000000000000000000000000000..b3ab4adf06b31c7ce8fc50f557c455f748110f1c GIT binary patch literal 8760 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 +#include +#include +#include +#include +#include +#include +#include +#include + +// Set a pixel at (x, y) with color in the framebuffer +void set_pixel(int *framebuffer, struct fb_var_screeninfo vinfo, int x, int y, int color) { + if (x >= 0 && x < vinfo.xres_virtual && y >= 0 && y < vinfo.yres_virtual) { + framebuffer[y * vinfo.xres_virtual + x] = color; + } +} + +// Bresenham's line algorithm for drawing lines +void draw_line(int *framebuffer, struct fb_var_screeninfo vinfo, int x0, int y0, int x1, int y1, int color) { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + + while (1) { + set_pixel(framebuffer, vinfo, x0, y0, color); + if (x0 == x1 && y0 == y1) break; + e2 = 2 * err; + if (e2 >= dy) { err += dy; x0 += sx; } + if (e2 <= dx) { err += dx; y0 += sy; } + } +} + +// Draw a simple filled rectangle to represent text characters +void draw_char(int *framebuffer, struct fb_var_screeninfo vinfo, char c, int x, int y, int size, int color) { + static const char font[10][5][3] = { + { "111", "101", "101", "101", "111" }, // '0' + { "110", "010", "010", "010", "111" }, // '1' + { "111", "001", "111", "100", "111" }, // '2' + { "111", "001", "111", "001", "111" }, // '3' + { "101", "101", "111", "001", "001" }, // '4' + { "111", "100", "111", "001", "111" }, // '5' + { "111", "100", "111", "101", "111" }, // '6' + { "111", "001", "001", "001", "001" }, // '7' + { "111", "101", "111", "101", "111" }, // '8' + { "111", "101", "111", "001", "111" } // '9' + }; + + if (c >= '0' && c <= '9') { + int index = c - '0'; + for (int row = 0; row < 5; ++row) { + for (int col = 0; col < 3; ++col) { + if (font[index][row][col] == '1') { + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + set_pixel(framebuffer, vinfo, x + col * size + i, y + row * size + j, color); + } + } + } + } + } + } +} + +// Draw a string of characters +void draw_text(int *framebuffer, struct fb_var_screeninfo vinfo, const char *text, int x, int y, int size, int color) { + for (const char *p = text; *p; ++p) { + draw_char(framebuffer, vinfo, *p, x, y, size, color); + x += size * 4; // Move to the next character position + } +} + +// Draw numbers around the clock face +void draw_circle(int *framebuffer, struct fb_var_screeninfo vinfo) { + for (int i = 1; i <= 12; ++i) { + float angle = (i * 30 - 90) * M_PI / 180.0; + int x = CENTER_X + (int)(RADIUS * cos(angle)); + int y = CENTER_Y + (int)(RADIUS * sin(angle)); + + char buffer[3]; + sprintf(buffer, "%d", i); + draw_text(framebuffer, vinfo, buffer, x - 10, y - 10, 3, 0xFFFFFF); // Increased the size to '3' for visibility + } +} + +// Draw clock hands +void draw_hand(int *framebuffer, struct fb_var_screeninfo vinfo, float angle, int length, int color) { + int x_end = CENTER_X + length * cos(angle); + int y_end = CENTER_Y - length * sin(angle); + draw_line(framebuffer, vinfo, CENTER_X, CENTER_Y, x_end, y_end, color); +} + +// Draw the clock face with numbers +void draw_clock_face(int *framebuffer, struct fb_var_screeninfo vinfo) { + memset(framebuffer, 0, vinfo.yres_virtual * vinfo.xres_virtual * sizeof(int)); // Clear screen + draw_circle(framebuffer, vinfo); // Draw the numbers +} + +// Update the clock hands and date/time display +void update_time(int *framebuffer, struct fb_var_screeninfo vinfo) { + time_t rawtime; + struct tm *timeinfo; + char date_buffer[80]; + char time_buffer[80]; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + // Calculate the angle for the hour hand + float hour_angle_degrees = (30 * timeinfo->tm_hour) + (timeinfo->tm_min * 0.5); + float hour_angle = - hour_angle_degrees * M_PI / 180.0 + M_PI / 2; // Convert to radians and adjust to 12 o'clock start + + // Calculate the angle for the minute hand + float minute_angle_degrees = 6 * timeinfo->tm_min; + float minute_angle = - minute_angle_degrees * M_PI / 180.0 + M_PI / 2; // Convert to radians and adjust to 12 o'clock start + + // Draw both hands in white (0xFFFFFF) + draw_hand(framebuffer, vinfo, hour_angle, HOUR_HAND_LENGTH, 0xFFFFFF); // Hour hand is shorter + draw_hand(framebuffer, vinfo, minute_angle, MINUTE_HAND_LENGTH, 0xFFFFFF); // Minute hand is longer + + // Display the date + strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", timeinfo); + draw_text(framebuffer, vinfo, date_buffer, CENTER_X - 100, CENTER_Y + 300, 3, 0xFFFFFF); // Moved lower and increased size + + // Display the time + strftime(time_buffer, sizeof(time_buffer), "%H:%M:%S", timeinfo); + draw_text(framebuffer, vinfo, time_buffer, CENTER_X - 80, CENTER_Y + 350, 3, 0xFFFFFF); // Moved lower and increased size +} + +int main() { + // Open the framebuffer device + int fbfd = open("/dev/fb0", O_RDWR); + if (fbfd == -1) { + perror("Error: cannot open framebuffer device"); + exit(1); + } + + // Get variable screen information + struct fb_var_screeninfo vinfo; + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { + perror("Error reading variable information"); + close(fbfd); + exit(2); + } + + // Map the framebuffer to user memory + size_t screensize = vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8; + int *framebuffer = (int *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if (framebuffer == MAP_FAILED) { + perror("Error mapping framebuffer device to memory"); + close(fbfd); + exit(3); + } + + // Continuously update the clock + while (1) { + draw_clock_face(framebuffer, vinfo); + update_time(framebuffer, vinfo); + sleep(1); // Sleep for 1 second to update the clock every second + } + + // Cleanup + munmap(framebuffer, screensize); + close(fbfd); + + return 0; +} diff --git a/clock/src/clock.c.bak b/clock/src/clock.c.bak new file mode 100644 index 0000000..63481b4 --- /dev/null +++ b/clock/src/clock.c.bak @@ -0,0 +1,165 @@ +// src/clock.c +#include "../include/clock.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Set a pixel at (x, y) with color in the framebuffer +void set_pixel(int *framebuffer, struct fb_var_screeninfo vinfo, int x, int y, int color) { + if (x >= 0 && x < vinfo.xres_virtual && y >= 0 && y < vinfo.yres_virtual) { + framebuffer[y * vinfo.xres_virtual + x] = color; + } +} + +// Bresenham's line algorithm for drawing lines +void draw_line(int *framebuffer, struct fb_var_screeninfo vinfo, int x0, int y0, int x1, int y1, int color) { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + + while (1) { + set_pixel(framebuffer, vinfo, x0, y0, color); + if (x0 == x1 && y0 == y1) break; + e2 = 2 * err; + if (e2 >= dy) { err += dy; x0 += sx; } + if (e2 <= dx) { err += dx; y0 += sy; } + } +} + +// Draw a simple filled rectangle to represent text characters +void draw_char(int *framebuffer, struct fb_var_screeninfo vinfo, char c, int x, int y, int size, int color) { + static const char font[10][5][3] = { + { "111", "101", "101", "101", "111" }, // '0' + { "110", "010", "010", "010", "111" }, // '1' + { "111", "001", "111", "100", "111" }, // '2' + { "111", "001", "111", "001", "111" }, // '3' + { "101", "101", "111", "001", "001" }, // '4' + { "111", "100", "111", "001", "111" }, // '5' + { "111", "100", "111", "101", "111" }, // '6' + { "111", "001", "001", "001", "001" }, // '7' + { "111", "101", "111", "101", "111" }, // '8' + { "111", "101", "111", "001", "111" } // '9' + }; + + if (c >= '0' && c <= '9') { + int index = c - '0'; + for (int row = 0; row < 5; ++row) { + for (int col = 0; col < 3; ++col) { + if (font[index][row][col] == '1') { + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + set_pixel(framebuffer, vinfo, x + col * size + i, y + row * size + j, color); + } + } + } + } + } + } +} + +// Draw a string of characters +void draw_text(int *framebuffer, struct fb_var_screeninfo vinfo, const char *text, int x, int y, int size, int color) { + for (const char *p = text; *p; ++p) { + draw_char(framebuffer, vinfo, *p, x, y, size, color); + x += size * 4; // Move to the next character position + } +} + +// Draw numbers around the clock face +void draw_circle(int *framebuffer, struct fb_var_screeninfo vinfo) { + for (int i = 1; i <= 12; ++i) { + float angle = (i * 30 - 90) * M_PI / 180.0; + int x = CENTER_X + (int)(RADIUS * cos(angle)); + int y = CENTER_Y + (int)(RADIUS * sin(angle)); + + char buffer[3]; + sprintf(buffer, "%d", i); + draw_text(framebuffer, vinfo, buffer, x - 10, y - 10, 3, 0xFFFFFF); // Increased the size to '3' for visibility + } +} + +// Draw clock hands +void draw_hand(int *framebuffer, struct fb_var_screeninfo vinfo, float angle, int length, int color) { + int x_end = CENTER_X + length * cos(angle); + int y_end = CENTER_Y - length * sin(angle); + draw_line(framebuffer, vinfo, CENTER_X, CENTER_Y, x_end, y_end, color); +} + +// Draw the clock face with numbers +void draw_clock_face(int *framebuffer, struct fb_var_screeninfo vinfo) { + memset(framebuffer, 0, vinfo.yres_virtual * vinfo.xres_virtual * sizeof(int)); // Clear screen + draw_circle(framebuffer, vinfo); // Draw the numbers +} + +// Update the clock hands and date/time display +void update_time(int *framebuffer, struct fb_var_screeninfo vinfo) { + time_t rawtime; + struct tm *timeinfo; + char date_buffer[80]; + char time_buffer[80]; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + // Correcting hour and minute hand angles + float hour_angle = ((timeinfo->tm_hour % 12) * 30 + timeinfo->tm_min * 0.5) * (M_PI / 180.0) - M_PI / 2; + float minute_angle = (timeinfo->tm_min * 6 + timeinfo->tm_sec * 0.1) * (M_PI / 180.0) - M_PI / 2; + + // Draw both hands in black color + draw_hand(framebuffer, vinfo, hour_angle, HOUR_HAND_LENGTH, 0x000000); // Hour hand in black + draw_hand(framebuffer, vinfo, minute_angle, MINUTE_HAND_LENGTH, 0x000000); // Minute hand in black + + // Display the date + strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", timeinfo); + draw_text(framebuffer, vinfo, date_buffer, CENTER_X - 100, CENTER_Y + 300, 3, 0xFFFFFF); // Moved lower and increased size + + // Display the time + strftime(time_buffer, sizeof(time_buffer), "%H:%M:%S", timeinfo); + draw_text(framebuffer, vinfo, time_buffer, CENTER_X - 80, CENTER_Y + 350, 3, 0xFFFFFF); // Moved lower and increased size +} + +// Main function +int main() { + // Open the framebuffer device + int fbfd = open("/dev/fb0", O_RDWR); + if (fbfd == -1) { + perror("Error: cannot open framebuffer device"); + exit(1); + } + + // Get variable screen information + struct fb_var_screeninfo vinfo; + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { + perror("Error reading variable information"); + close(fbfd); + exit(2); + } + + // Map the framebuffer to user memory + size_t screensize = vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8; + int *framebuffer = (int *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if (framebuffer == MAP_FAILED) { + perror("Error mapping framebuffer device to memory"); + close(fbfd); + exit(3); + } + + // Continuously update the clock + while (1) { + draw_clock_face(framebuffer, vinfo); + update_time(framebuffer, vinfo); + sleep(1); // Sleep for 1 second to update the clock every second + } + + // Cleanup + munmap(framebuffer, screensize); + close(fbfd); + + return 0; +} diff --git a/render/README.md b/render/README.md new file mode 100644 index 0000000..76ba9e5 --- /dev/null +++ b/render/README.md @@ -0,0 +1,3 @@ +# render Project + +This is a C project generated with the setup tool. diff --git a/render/build/Makefile b/render/build/Makefile new file mode 100644 index 0000000..a052d2e --- /dev/null +++ b/render/build/Makefile @@ -0,0 +1,26 @@ +CC = gcc +CFLAGS = -Wall -O2 + +SRC_DIR = ../src +OBJ_DIR = ../obj +BUILD_DIR = . + +TARGET = $(BUILD_DIR)/cube_render + +SRCS = $(wildcard $(SRC_DIR)/*.c) +OBJS = $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ -lm + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c + @mkdir -p $(OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -rf $(OBJ_DIR)/*.o $(TARGET) + +rebuild: clean all + diff --git a/render/build/cube_render b/render/build/cube_render new file mode 100755 index 0000000000000000000000000000000000000000..ccf50d70fd124ae303fbd01986d910a95eefb578 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/render/obj/main.o b/render/obj/main.o new file mode 100644 index 0000000000000000000000000000000000000000..db05e4bfe4356244be72b32a5f3b871a9274a457 GIT binary patch literal 6144 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 literal 0 HcmV?d00001 diff --git a/render/src/cube.c.bak b/render/src/cube.c.bak new file mode 100644 index 0000000..e815f31 --- /dev/null +++ b/render/src/cube.c.bak @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Cube parameters +#define CUBE_SIZE 200.0 +#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit +#define FRAME_DELAY 16000 // Microseconds (about 60fps) +#define ROTATION_SPEED 0.02 + +// Structure for framebuffer info +struct framebuffer_info { + int fb_fd; + uint8_t* fb_ptr; + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + long int screensize; +}; + +// Structure for 3D point +typedef struct { + float x, y, z; +} Point3D; + +// Cube vertices +Point3D cube[8] = { + {-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, + { CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, + { CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, + {-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, + {-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, + { CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, + { CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, + {-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} +}; + +// Cube edges +int edges[12][2] = { + {0, 1}, {1, 2}, {2, 3}, {3, 0}, // Bottom face + {4, 5}, {5, 6}, {6, 7}, {7, 4}, // Top face + {0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges +}; + +// Function to initialize framebuffer +struct framebuffer_info init_framebuffer(const char* fb_path) { + struct framebuffer_info fb_info; + + fb_info.fb_fd = open(fb_path, O_RDWR); + if (fb_info.fb_fd == -1) { + perror("Error opening framebuffer device"); + exit(1); + } + + // Get fixed screen information + if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) { + perror("Error reading fixed information"); + exit(1); + } + + // Get variable screen information + if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) { + perror("Error reading variable information"); + exit(1); + } + + // Calculate the screen size in bytes + fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length; + + // Map framebuffer to memory + fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0); + if ((intptr_t)fb_info.fb_ptr == -1) { + perror("Error mapping framebuffer to memory"); + exit(1); + } + + return fb_info; +} + +// Function to clear the screen +void clear_screen(struct framebuffer_info* fb_info) { + for (int i = 0; i < fb_info->screensize; i++) { + fb_info->fb_ptr[i] = 0; // Set each pixel to black + } +} + +// Function to set a pixel in the framebuffer +void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) { + if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) { + long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) + + (y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length; + + // Handle different bits per pixel + if (fb_info->vinfo.bits_per_pixel == 32) { + *((uint32_t*)(fb_info->fb_ptr + location)) = color; + } else if (fb_info->vinfo.bits_per_pixel == 16) { + uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3); + *((uint16_t*)(fb_info->fb_ptr + location)) = rgb565; + } else { + printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel); + } + } +} + +// Bresenham's Line Algorithm +void draw_line(struct framebuffer_info* fb_info, int x0, int y0, int x1, int y1, uint32_t color) { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + + while (1) { + set_pixel(fb_info, x0, y0, color); + if (x0 == x1 && y0 == y1) break; + e2 = 2 * err; + if (e2 >= dy) { err += dy; x0 += sx; } + if (e2 <= dx) { err += dx; y0 += sy; } + } +} + +// Function to rotate 3D point +void rotate(Point3D* p, float angleX, float angleY, float angleZ) { + // Rotation around X-axis + float y = p->y * cos(angleX) - p->z * sin(angleX); + float z = p->y * sin(angleX) + p->z * cos(angleX); + p->y = y; + p->z = z; + + // Rotation around Y-axis + float x = p->x * cos(angleY) + p->z * sin(angleY); + z = -p->x * sin(angleY) + p->z * cos(angleY); + p->x = x; + p->z = z; + + // Rotation around Z-axis + x = p->x * cos(angleZ) - p->y * sin(angleZ); + y = p->x * sin(angleZ) + p->y * cos(angleZ); + p->x = x; + p->y = y; +} + +// Function to project 3D point onto 2D screen +void project(Point3D p, int* x2D, int* y2D, int screenWidth, int screenHeight, float dist) { + *x2D = (int)(screenWidth / 2 + p.x * (dist / (p.z + dist))); + *y2D = (int)(screenHeight / 2 + p.y * (dist / (p.z + dist))); +} + +// Main function +int main() { + struct framebuffer_info fb_info = init_framebuffer("/dev/fb0"); + + float angleX = 0, angleY = 0, angleZ = 0; + float dist = 400.0f; + + while (1) { + clear_screen(&fb_info); + + Point3D transformed[8]; + int projected[8][2]; + + // Rotate and project each vertex + for (int i = 0; i < 8; i++) { + transformed[i] = cube[i]; + rotate(&transformed[i], angleX, angleY, angleZ); + project(transformed[i], &projected[i][0], &projected[i][1], fb_info.vinfo.xres, fb_info.vinfo.yres, dist); + } + + // Draw the cube edges + for (int i = 0; i < 12; i++) { + draw_line(&fb_info, projected[edges[i][0]][0], projected[edges[i][0]][1], + projected[edges[i][1]][0], projected[edges[i][1]][1], COLOR); + } + + // Increment angles for rotation + angleX += ROTATION_SPEED; + angleY += ROTATION_SPEED * 0.5; + angleZ += ROTATION_SPEED * 0.25; + + usleep(FRAME_DELAY); // Sleep for ~60fps + } + + munmap(fb_info.fb_ptr, fb_info.screensize); + close(fb_info.fb_fd); + return 0; +} + diff --git a/render/src/main.c b/render/src/main.c new file mode 100644 index 0000000..fb2c3ad --- /dev/null +++ b/render/src/main.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define CUBE_SIZE 200.0 +#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit +#define FRAME_DELAY 50000 // Slower: Microseconds (~20fps) +#define ROTATION_SPEED 0.003 // Slower rotation speed + +// Structure for framebuffer info +struct framebuffer_info { + int fb_fd; + uint8_t* fb_ptr; + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + long int screensize; +}; + +// Structure for 3D point +typedef struct { + float x, y, z; +} Point3D; + +// Cube vertices +Point3D cube[8] = { + {-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, + { CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, + { CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, + {-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, + {-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, + { CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, + { CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, + {-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} +}; + +// Cube edges +int edges[12][2] = { + {0, 1}, {1, 2}, {2, 3}, {3, 0}, // Bottom face + {4, 5}, {5, 6}, {6, 7}, {7, 4}, // Top face + {0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges +}; + +// Function to initialize framebuffer +struct framebuffer_info init_framebuffer(const char* fb_path) { + struct framebuffer_info fb_info; + + fb_info.fb_fd = open(fb_path, O_RDWR); + if (fb_info.fb_fd == -1) { + perror("Error opening framebuffer device"); + exit(1); + } + + // Get fixed screen information + if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) { + perror("Error reading fixed information"); + exit(1); + } + + // Get variable screen information + if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) { + perror("Error reading variable information"); + exit(1); + } + + // Calculate the screen size in bytes + fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length; + + // Map framebuffer to memory + fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0); + if ((intptr_t)fb_info.fb_ptr == -1) { + perror("Error mapping framebuffer to memory"); + exit(1); + } + + return fb_info; +} + +// Function to clear the screen +void clear_screen(struct framebuffer_info* fb_info) { + for (int i = 0; i < fb_info->screensize; i++) { + fb_info->fb_ptr[i] = 0; // Set each pixel to black + } +} + +// Function to set a pixel in the framebuffer +void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) { + if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) { + long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) + + (y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length; + + // Handle different bits per pixel + if (fb_info->vinfo.bits_per_pixel == 32) { + *((uint32_t*)(fb_info->fb_ptr + location)) = color; + } else if (fb_info->vinfo.bits_per_pixel == 16) { + uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3); + *((uint16_t*)(fb_info->fb_ptr + location)) = rgb565; + } else { + printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel); + } + } +} + +// Improved Bresenham's Line Algorithm with edge cases handling +void draw_line(struct framebuffer_info* fb_info, int x0, int y0, int x1, int y1, uint32_t color) { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + + while (1) { + set_pixel(fb_info, x0, y0, color); + if (x0 == x1 && y0 == y1) break; + + e2 = 2 * err; + if (e2 >= dy) { err += dy; x0 += sx; } + if (e2 <= dx) { err += dx; y0 += sy; } + } +} + +// Function to rotate 3D point +void rotate(Point3D* p, float angleX, float angleY, float angleZ) { + // Rotation around X-axis + float y = p->y * cos(angleX) - p->z * sin(angleX); + float z = p->y * sin(angleX) + p->z * cos(angleX); + p->y = y; + p->z = z; + + // Rotation around Y-axis + float x = p->x * cos(angleY) + p->z * sin(angleY); + z = -p->x * sin(angleY) + p->z * cos(angleY); + p->x = x; + p->z = z; + + // Rotation around Z-axis + x = p->x * cos(angleZ) - p->y * sin(angleZ); + y = p->x * sin(angleZ) + p->y * cos(angleZ); + p->x = x; + p->y = y; +} + +// Function to project 3D point onto 2D screen +void project(Point3D p, int* x2D, int* y2D, int screenWidth, int screenHeight, float dist) { + float scale = dist / (p.z + dist); // Perspective scaling + *x2D = (int)(screenWidth / 2 + p.x * scale); + *y2D = (int)(screenHeight / 2 + p.y * scale); + + // Ensure the projected point remains within screen bounds + if (*x2D < 0) *x2D = 0; + if (*x2D >= screenWidth) *x2D = screenWidth - 1; + if (*y2D < 0) *y2D = 0; + if (*y2D >= screenHeight) *y2D = screenHeight - 1; +} + +// Main function +int main() { + struct framebuffer_info fb_info = init_framebuffer("/dev/fb0"); + + float angleX = 0, angleY = 0, angleZ = 0; + float dist = 400.0f; + + while (1) { + clear_screen(&fb_info); + + Point3D transformed[8]; + int projected[8][2]; + + // Rotate and project each vertex + for (int i = 0; i < 8; i++) { + transformed[i] = cube[i]; + rotate(&transformed[i], angleX, angleY, angleZ); + project(transformed[i], &projected[i][0], &projected[i][1], fb_info.vinfo.xres, fb_info.vinfo.yres, dist); + } + + // Draw the cube edges + for (int i = 0; i < 12; i++) { + draw_line(&fb_info, projected[edges[i][0]][0], projected[edges[i][0]][1], + projected[edges[i][1]][0], projected[edges[i][1]][1], COLOR); + } + + // Increment angles for slower rotation + angleX += ROTATION_SPEED; + angleY += ROTATION_SPEED * 0.5; + angleZ += ROTATION_SPEED * 0.25; + + usleep(FRAME_DELAY); // Slower frame rate for smoother rotation + } + + munmap(fb_info.fb_ptr, fb_info.screensize); + close(fb_info.fb_fd); + return 0; +} + diff --git a/render/src/pixeltest.c.bak b/render/src/pixeltest.c.bak new file mode 100644 index 0000000..c83e7c8 --- /dev/null +++ b/render/src/pixeltest.c.bak @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Cube parameters +#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit + +// Structure for framebuffer info +struct framebuffer_info { + int fb_fd; + uint8_t* fb_ptr; + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + long int screensize; +}; + +// Function to initialize framebuffer +struct framebuffer_info init_framebuffer(const char* fb_path) { + struct framebuffer_info fb_info; + + fb_info.fb_fd = open(fb_path, O_RDWR); + if (fb_info.fb_fd == -1) { + perror("Error opening framebuffer device"); + exit(1); + } + + // Get fixed screen information + if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) { + perror("Error reading fixed information"); + exit(1); + } + + // Get variable screen information + if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) { + perror("Error reading variable information"); + exit(1); + } + + // Calculate the screen size in bytes + fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length; + + // Map framebuffer to memory + fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0); + if ((intptr_t)fb_info.fb_ptr == -1) { + perror("Error mapping framebuffer to memory"); + exit(1); + } + + // Debugging: print framebuffer info + printf("Framebuffer resolution: %dx%d, %d bpp\n", fb_info.vinfo.xres, fb_info.vinfo.yres, fb_info.vinfo.bits_per_pixel); + printf("Framebuffer screensize: %ld bytes\n", fb_info.screensize); + + return fb_info; +} + +// Function to clear the screen +void clear_screen(struct framebuffer_info* fb_info) { + for (int i = 0; i < fb_info->screensize; i++) { + fb_info->fb_ptr[i] = 0; // Set each pixel to black + } +} + +// Function to set a pixel in the framebuffer +void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) { + if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) { + long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) + + (y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length; + + // Handle different bits per pixel + if (fb_info->vinfo.bits_per_pixel == 32) { + // 32-bit color (ARGB or XRGB) + *((uint32_t*)(fb_info->fb_ptr + location)) = color; + } else if (fb_info->vinfo.bits_per_pixel == 16) { + // 16-bit color (RGB565) + uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3); + *((uint16_t*)(fb_info->fb_ptr + location)) = rgb565; + } else { + printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel); + } + } +} + +// Main function +int main() { + // Initialize framebuffer + struct framebuffer_info fb_info = init_framebuffer("/dev/fb0"); + + // Clear the screen first + clear_screen(&fb_info); + + // Draw a pixel at the center of the screen to test framebuffer access + int center_x = fb_info.vinfo.xres / 2; + int center_y = fb_info.vinfo.yres / 2; + printf("Drawing pixel at center: (%d, %d)\n", center_x, center_y); + + // Use appropriate color depth + set_pixel(&fb_info, center_x, center_y, COLOR); // Draw white pixel at the center + + // Hold for a while to inspect + printf("Framebuffer test complete. Pixel drawn at the center.\n"); + sleep(10); // Wait for 10 seconds to allow visual inspection + + // Unmap and close the framebuffer + munmap(fb_info.fb_ptr, fb_info.screensize); + close(fb_info.fb_fd); + + return 0; +} + diff --git a/render/src/slow_cube.c.bak b/render/src/slow_cube.c.bak new file mode 100644 index 0000000..42ec6f8 --- /dev/null +++ b/render/src/slow_cube.c.bak @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define CUBE_SIZE 200.0 +#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit +#define FRAME_DELAY 50000 // Slower: Microseconds (~20fps) +#define ROTATION_SPEED 0.005 // Slower rotation speed + +// Structure for framebuffer info +struct framebuffer_info { + int fb_fd; + uint8_t* fb_ptr; + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + long int screensize; +}; + +// Structure for 3D point +typedef struct { + float x, y, z; +} Point3D; + +// Cube vertices +Point3D cube[8] = { + {-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, + { CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, + { CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, + {-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, + {-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, + { CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, + { CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, + {-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} +}; + +// Cube edges +int edges[12][2] = { + {0, 1}, {1, 2}, {2, 3}, {3, 0}, // Bottom face + {4, 5}, {5, 6}, {6, 7}, {7, 4}, // Top face + {0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges +}; + +// Function to initialize framebuffer +struct framebuffer_info init_framebuffer(const char* fb_path) { + struct framebuffer_info fb_info; + + fb_info.fb_fd = open(fb_path, O_RDWR); + if (fb_info.fb_fd == -1) { + perror("Error opening framebuffer device"); + exit(1); + } + + // Get fixed screen information + if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) { + perror("Error reading fixed information"); + exit(1); + } + + // Get variable screen information + if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) { + perror("Error reading variable information"); + exit(1); + } + + // Calculate the screen size in bytes + fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length; + + // Map framebuffer to memory + fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0); + if ((intptr_t)fb_info.fb_ptr == -1) { + perror("Error mapping framebuffer to memory"); + exit(1); + } + + return fb_info; +} + +// Function to clear the screen +void clear_screen(struct framebuffer_info* fb_info) { + for (int i = 0; i < fb_info->screensize; i++) { + fb_info->fb_ptr[i] = 0; // Set each pixel to black + } +} + +// Function to set a pixel in the framebuffer +void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) { + if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) { + long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) + + (y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length; + + // Handle different bits per pixel + if (fb_info->vinfo.bits_per_pixel == 32) { + *((uint32_t*)(fb_info->fb_ptr + location)) = color; + } else if (fb_info->vinfo.bits_per_pixel == 16) { + uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3); + *((uint16_t*)(fb_info->fb_ptr + location)) = rgb565; + } else { + printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel); + } + } +} + +// Improved Bresenham's Line Algorithm with edge cases handling +void draw_line(struct framebuffer_info* fb_info, int x0, int y0, int x1, int y1, uint32_t color) { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = (dx > dy ? dx : -dy) / 2, e2; + + for (;;) { + set_pixel(fb_info, x0, y0, color); + if (x0 == x1 && y0 == y1) break; + e2 = err; + if (e2 > -dx) { err -= dy; x0 += sx; } + if (e2 < dy) { err += dx; y0 += sy; } + } +} + +// Function to rotate 3D point +void rotate(Point3D* p, float angleX, float angleY, float angleZ) { + // Rotation around X-axis + float y = p->y * cos(angleX) - p->z * sin(angleX); + float z = p->y * sin(angleX) + p->z * cos(angleX); + p->y = y; + p->z = z; + + // Rotation around Y-axis + float x = p->x * cos(angleY) + p->z * sin(angleY); + z = -p->x * sin(angleY) + p->z * cos(angleY); + p->x = x; + p->z = z; + + // Rotation around Z-axis + x = p->x * cos(angleZ) - p->y * sin(angleZ); + y = p->x * sin(angleZ) + p->y * cos(angleZ); + p->x = x; + p->y = y; +} + +// Function to project 3D point onto 2D screen +void project(Point3D p, int* x2D, int* y2D, int screenWidth, int screenHeight, float dist) { + float scale = dist / (p.z + dist); // Perspective scaling + *x2D = (int)(screenWidth / 2 + p.x * scale); + *y2D = (int)(screenHeight / 2 + p.y * scale); +} + +// Main function +int main() { + struct framebuffer_info fb_info = init_framebuffer("/dev/fb0"); + + float angleX = 0, angleY = 0, angleZ = 0; + float dist = 400.0f; + + while (1) { + clear_screen(&fb_info); + + Point3D transformed[8]; + int projected[8][2]; + + // Rotate and project each vertex + for (int i = 0; i < 8; i++) { + transformed[i] = cube[i]; + rotate(&transformed[i], angleX, angleY, angleZ); + project(transformed[i], &projected[i][0], &projected[i][1], fb_info.vinfo.xres, fb_info.vinfo.yres, dist); + } + + // Draw the cube edges + for (int i = 0; i < 12; i++) { + draw_line(&fb_info, projected[edges[i][0]][0], projected[edges[i][0]][1], + projected[edges[i][1]][0], projected[edges[i][1]][1], COLOR); + } + + // Increment angles for slower rotation + angleX += ROTATION_SPEED; + angleY += ROTATION_SPEED * 0.5; + angleZ += ROTATION_SPEED * 0.25; + + usleep(FRAME_DELAY); // Slower frame rate for smoother rotation + } + + munmap(fb_info.fb_ptr, fb_info.screensize); + close(fb_info.fb_fd); + return 0; +} + diff --git a/riceapp/README.md b/riceapp/README.md new file mode 100644 index 0000000..27612cb --- /dev/null +++ b/riceapp/README.md @@ -0,0 +1,3 @@ +# riceapp Project + +This is a C project generated with the setup tool. diff --git a/riceapp/build/Makefile b/riceapp/build/Makefile new file mode 100644 index 0000000..a63f9fe --- /dev/null +++ b/riceapp/build/Makefile @@ -0,0 +1,24 @@ +CC = gcc +CFLAGS = -I../include -Wall -O2 +LDFLAGS = -lm +SRCDIR = ../src +OBJDIR = ../obj +BUILDDIR = ../build +TARGET = cube_app + +SOURCES = $(wildcard $(SRCDIR)/*.c) +OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) + +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(CC) $(OBJECTS) $(LDFLAGS) -o $(BUILDDIR)/$(TARGET) + +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJDIR)/*.o $(BUILDDIR)/$(TARGET) + +.PHONY: all clean + diff --git a/riceapp/build/cube_app b/riceapp/build/cube_app new file mode 100755 index 0000000000000000000000000000000000000000..8a22307da507a1d337105a38fb0f5e3a1b7a914b GIT binary patch literal 16552 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 PWey@47^KiNpm7-h^#>Q1 literal 0 HcmV?d00001 diff --git a/riceapp/include/cube.h b/riceapp/include/cube.h new file mode 100644 index 0000000..995a038 --- /dev/null +++ b/riceapp/include/cube.h @@ -0,0 +1,21 @@ +#ifndef CUBE_H +#define CUBE_H + +typedef struct { + float x, y, z; +} Vertex; + +typedef struct { + int width, height; +} Screen; + +// Function declarations +void init_framebuffer(); +void draw_cube(Vertex vertices[8], Screen *screen); +void translate(Vertex *v, float dx, float dy, float dz); +void rotate_cube(Vertex vertices[8], float angleX, float angleY); +void update_screen(Screen *screen); +void handle_collision(Vertex *v, Screen *screen); + +#endif + diff --git a/riceapp/obj/cube.o b/riceapp/obj/cube.o new file mode 100644 index 0000000000000000000000000000000000000000..9213c2bf2e11dfdc4ed462de63d0c62a161585cf GIT binary patch literal 4392 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 GT|WRjlQ&fW literal 0 HcmV?d00001 diff --git a/riceapp/src/cube.c b/riceapp/src/cube.c new file mode 100644 index 0000000..1c6a0a6 --- /dev/null +++ b/riceapp/src/cube.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "cube.h" + +// Framebuffer and screen parameters +int fbfd = 0; +struct fb_var_screeninfo vinfo; +struct fb_fix_screeninfo finfo; +long int screensize = 0; +char *fbp = 0; + +// Cube vertex data +Vertex vertices[8] = { + {-50, -50, -50}, {50, -50, -50}, {50, 50, -50}, {-50, 50, -50}, + {-50, -50, 50}, {50, -50, 50}, {50, 50, 50}, {-50, 50, 50} +}; + +float velocityX = 2.0, velocityY = 1.5; +float rotationSpeed = 0.02; +float cubeX = 300, cubeY = 200; +Screen screen = {800, 600}; // Screen resolution + +// Initialize framebuffer +void init_framebuffer() { + fbfd = open("/dev/fb0", O_RDWR); + if (fbfd == -1) { + perror("Error opening framebuffer device"); + exit(1); + } + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { + perror("Error reading fixed information"); + exit(2); + } + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { + perror("Error reading variable information"); + exit(3); + } + screensize = vinfo.yres_virtual * finfo.line_length; + fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if ((int)fbp == -1) { + perror("Error mapping framebuffer device to memory"); + exit(4); + } +} + +// Clear screen +void clear_screen() { + for (int y = 0; y < screen.height; y++) { + for (int x = 0; x < screen.width; x++) { + long int location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) + (y + vinfo.yoffset) * finfo.line_length; + *((unsigned int*)(fbp + location)) = 0x000000; // Black color + } + } +} + +// Put pixel on screen +void put_pixel(int x, int y, unsigned int color) { + if (x >= 0 && x < screen.width && y >= 0 && y < screen.height) { + long int location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) + (y + vinfo.yoffset) * finfo.line_length; + *((unsigned int*)(fbp + location)) = color; + } +} + +// Draw line between two points (Bresenham's line algorithm) +void draw_line(int x1, int y1, int x2, int y2, unsigned int color) { + int dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1; + int dy = -abs(y2 - y1), sy = y1 < y2 ? 1 : -1; + int err = dx + dy, e2; + + while (1) { + put_pixel(x1, y1, color); + if (x1 == x2 && y1 == y2) break; + e2 = 2 * err; + if (e2 >= dy) { err += dy; x1 += sx; } + if (e2 <= dx) { err += dx; y1 += sy; } + } +} + +// Project 3D coordinates to 2D +void project(Vertex v, int *x, int *y) { + float scale = 200 / (v.z + 200); // Perspective projection scaling + *x = (int)(v.x * scale + cubeX); + *y = (int)(v.y * scale + cubeY); +} + +// Draw the 3D cube +void draw_cube(Vertex vertices[8]) { + int projectedX[8], projectedY[8]; + for (int i = 0; i < 8; i++) { + project(vertices[i], &projectedX[i], &projectedY[i]); + } + + // Draw front face + for (int i = 0; i < 4; i++) { + draw_line(projectedX[i], projectedY[i], projectedX[(i+1)%4], projectedY[(i+1)%4], 0xFFFFFF); + } + + // Draw back face + for (int i = 4; i < 8; i++) { + draw_line(projectedX[i], projectedY[i], projectedX[((i+1)%4)+4], projectedY[((i+1)%4)+4], 0x00FF00); + } + + // Draw edges between front and back faces + for (int i = 0; i < 4; i++) { + draw_line(projectedX[i], projectedY[i], projectedX[i+4], projectedY[i+4], 0xFF0000); + } +} + +// Translate vertices +void translate(Vertex *v, float dx, float dy, float dz) { + v->x += dx; + v->y += dy; + v->z += dz; +} + +// Rotate cube vertices around X and Y axes +void rotate_cube(Vertex vertices[8], float angleX, float angleY) { + float cosX = cos(angleX), sinX = sin(angleX); + float cosY = cos(angleY), sinY = sin(angleY); + + for (int i = 0; i < 8; i++) { + float x = vertices[i].x, y = vertices[i].y, z = vertices[i].z; + + // Rotation around X-axis + vertices[i].y = y * cosX - z * sinX; + vertices[i].z = y * sinX + z * cosX; + + // Rotation around Y-axis + vertices[i].x = x * cosY - z * sinY; + vertices[i].z = x * sinY + z * cosY; + } +} + +// Handle screen edge collision +void handle_collision() { + if (cubeX >= screen.width - 100 || cubeX <= 100) velocityX = -velocityX; + if (cubeY >= screen.height - 100 || cubeY <= 100) velocityY = -velocityY; +} + +int main() { + init_framebuffer(); + + float angleX = 0.0, angleY = 0.0; + + while (1) { + // Clear the screen + clear_screen(); + + // Translate the cube across the screen + cubeX += velocityX; + cubeY += velocityY; + handle_collision(); + + // Rotate the cube + rotate_cube(vertices, angleX, angleY); + + // Draw the cube on the screen + draw_cube(vertices); + + // Update rotation angles for the next iteration + angleX += rotationSpeed; + angleY += rotationSpeed; + + // Add delay to control frame rate (~60 FPS) + usleep(16000); + } + + munmap(fbp, screensize); + close(fbfd); + return 0; +} +