day0 day1 day2 day3 day4 day5 day6 day7 day8 day9 day10 day11 day12 day13 day14 day15 day16 day17 day18 day19 day20 day21 day22 day23 day24 day25 day26 day27 day28 day29 day30 day31

here to recap my December Adventure 2024. More info about this and other people doing it here

DAY 0

December is starting tomorrow, so let's speak about what are my goals for this december adventure 2024. I have a UXN software that I would like to complete. It's some spin off Noodle, just a screen and you can draw some 1 bit image in it, the twist being that in the same time it's generating a SVG file of your drawing.

For now it's still missing a lot of feature so I think I will work on implementing them so it will finally be an usable software. The list of feature I will work on this december:

Honestly not sure how much time I will need to add all of that. We will see, I guess that's why it's an adventure !

DAY 1

Here we go for this first day of december! Today in the menu is drawing rectangle.

As a rectangle is basically just two straight line and two vertical line, that's really not that hard. For now, I will not bother with filled rectangle, I don't have any use for them I can think of in top of my head. So my strategy was simple, just draw the two horizontal line, then draw the two vertical line. So overall I just did two loop, one for each axis. Honestly I didn't have any real difficulty putting this out, I just lost 10 min because I did the classic mistake of writing GTH in place of GTH2.

So to finish this first day review I will share the little bit of code I wrote. Please note it's litteraly the first draw, there is a lot of duplication, typically I just STA value many time when I could have just load them one time and DUP them as much as needed, but it was early in the morning and was not feeling tracking the stack so I did it the lazy way.
Please note the code assume you STA x0 in @x and y0 in @y and jump into this with x1 and y1 in the stack

----------------------------------------------------------- @draw-rectangle ( x1* y1* | adress ) DUP2 ;y LDA2 NEQ2 ?{ ;y LDA2 INC2 ;y STA2 } OVR2 ;x LDA2 GTH2 ?{ ;x LDA2 ROT2 ;x STA2 SWP2 } DUP2 ;y LDA2 GTH2 ?{ ;y LDA2 SWP2 ;y STA2 } ;x LDA2 STH2 ;y LDA2 .Screen/y DEO2 &horizontal-line ( x1* y1* | adress x0* ) ;x LDA2 .Screen/x DEO2 #41 .Screen/pixel DEO ;x LDA2 .Screen/x DEO2 DUP2 .Screen/y DEO2 #41 .Screen/pixel DEO ;y LDA2 .Screen/y DEO2 OVR2 ;x LDA2 NEQ2 ?{ ;draw-rectangle/vertical-line JMP2 } ;x LDA2 INC2 ;x STA2 ;draw-rectangle/horizontal-line JMP2 &vertical-line ;y LDA2 .Screen/y DEO2 #41 .Screen/pixel DEO ;y LDA2 .Screen/y DEO2 STH2kr .Screen/x DEO2 #41 .Screen/pixel DEO ;x LDA2 .Screen/x DEO2 ;y LDA2 INC2 ;y STA2 DUP2 ;y LDA2 NEQ2 ?{ POP2 POP2 POP2r JMP2r } ;draw-rectangle/vertical-line JMP2 BRK @x $2 @y $2 -----------------------------------------------------------

DAY 2

Hello ! Today I didn't have much time as most of it have been used by my employer to make people richer. So I went for the low effort stuff and just put what I did in day 1 in the main rom. So I litteraly just copy and paste the previous UXN code into another file. But the particularity of this rom ( one day I will find a name for it I swear ) is that the rectangle I'm now able to draw in the screen should also be included in a svg file who is generated on the fly when you are using the rom. The way it works is quite simple, I just build a string and then put this string in a file. In this case the string look like this:

@rect-svg "<rect 20 "x= 27 20 20 20 20 20 27 20 "y= 27 20 20 20 20 20 27 20 "width= 27 20 20 20 20 20 27 20 "height= 27 20 20 20 20 20 27 20

After that I just need to fill the string with the x,y width, height and these are info I can easily obtain. If you are curious about how I fill this string, I use a modified version of the pdec routine available in this page, I left as an exercise for the reader to find what the modification is... Sorry always dreamed about saying that, the truth is I'm just not motivated to explain it right now.

To end today post, no code this time but a simple svg file with rectangle in it, produced by an uxn rom :)

DAY 3

Hello ! Here we go for day 3 of this adventure. Today I wanted to challenge myself. To be exact, I have one goal for this month where I'm fully clueless about how it should be done. The goal in question is "Being able to draw ellipse". I litteraly never implemented any algorithm who let you do that, for the simple reason that I never need to draw ellipse. So I first check for these algorithm, I find plenty of variant of the mid point algorithm, all writen in C. Most of them use negative number, something UXN didn't provide properly. But well, I still tried to take the C code and convert it... It was a total failure, the result is litteraly just a pixel in the screen and then the stack is broken. I have no idea why. For 45 min I carefully follow the stack, checking line by line and yet, it's just not working. Beetbug is showing me that the program work fine the first time, and then when it's looping, the stack got destroyed... It make no sense ? I can't keep checking everything today, I have other things to do. I come with no clue about how draw ellipse in UXN and after a day of working, I still have no clue. I don't know if I'm just bad at converting C code into tal, or if I'm just bad a following a stack, or if the algorithm just don't work or if all of that is just hard because of the way uxn have been thought.

The fact that algorithm are just a list of stuff to do and not being able to just rewrite these step is really an easy way to make you feel dumb. Let's hope sleeping give me inspiration to climb this wall

DAY 4

Hello ! Busy day on my side, I did not really had the energy to really code something, so I just read a bunch of research paper about ellipse algorithm. Some are really fun, I enter a rabbit hole of people trying to draw curve using Logarithmic number system. I never hear about this concept and it was fun to discover it. But it was funnier to see each paper speaking about how you can use a look up table to make addition and substraction and yet most of them didn't explain how you could generate such table. It seem to be common knowledge for all of them, but in a sense me reading stuff about this topic for 2 hours and still not being able to see how I could practically build it is a big L for their cause. That's it for today, slowly but surely I'm understanding ellipse and how to build them, be careful because a circle can hide an ellipse behind it !

DAY 5

Hello ! Still stuck into this issue of drawing ellipse, I don't see any good way of doing it. I retry to take an algorithm in C and just translate it, but it was another faillure. I feel like I'm lacking option, a tool or a concept that unlock the whole things.

I don't report much for the last few days, but it's just one of these typical moment in programing when you face a wall

DAY 6

Big headache/tiredness. Let's call it a day off

DAY 7

Feeling better but was not in the mood to really work on something.

DAY 8

Fooling around doing some stuff in UXN. Mostly stuff about calculate some coordinate, and playing around doing loop. It's more or less related to an other project than the one I'm talking in this december adventure, but for now I got nothing to show about that so it's not really interesting to speak a lot about it.

DAY 9

Hello ! So today I decide it will be the last day I work on this ellipse drawing stuff. At this point I feel like I know all the different way you can draw that in a computer, and have to say none really seem to straightforward translate in UXN. So I will drop that and just do the other stuff of the list.

To close this arc, I will just share my attempt of the day. I went back to the first idea and tried to just take a C algorithm and implement it in UXN, but in the most direct way I could think of. It didn't work, it's just a giant loop who never end, after checking with beetbug it seem to never meet any condition, so the whole stuff stay in the initial state and obvisouly never hit the condition ending the loop. I have no idea why. I tried to switch some GTH to LTH but it change nothing.

There is the UXN code, as it's not that long I just copy and pasted everything, in case you want to make a rom on your side. Remember : it didn't work. You will find the C code who serve as reference just after.

----------------------------------------------------------- |00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] |a0 @File &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 |20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ] |80 @Controller &vector $2 &button $1 &key $1 |90 @Mouse &vector $2 &x $2 &y $2 &state $5 &scrolly &scrolly-hb $1 &scrolly-lb $1 |0100 #0208 .Screen/width DEO2 #0140 .Screen/height DEO2 #f009 .System/r DEO2 #f000 .System/g DEO2 #f005 .System/b DEO2 #0100 .Screen/x DEO2 #0050 .Screen/y DEO2 #0040 ;ellipse/a STA2 #0040 ;ellipse/b STA2 @ellipse-paint #0000 ;ellipse/a LDA2 SUB2 ;ellipse/x STA2 #0000 ;ellipse/y STA2 ;ellipse/b LDA2 ;ellipse/e2 STA2 ;ellipse/x LDA2 #0002 MUL2 INC2 ;ellipse/e2 LDA2 DUP2 MUL2 MUL2 ;ellipse/dx STA2 ;ellipse/a LDA2 DUP2 MUL2 ;ellipse/dy STA2 ;ellipse/dx LDA2 ;ellipse/dy LDA2 ADD2 ;ellipse/err STA2 ;ellipse/a LDA2 DUP2 #0002 MUL2 MUL2 ;ellipse/a STA2 ;ellipse/b LDA2 DUP2 #0002 MUL2 MUL2 ;ellipse/b STA2 &draw-ellipse .Screen/x DEI2 ;ellipse/x LDA2 ADD2 .Screen/x DEO2 .Screen/y DEI2 ;ellipse/y LDA2 ADD2 .Screen/y DEO2 #41 .Screen/pixel DEO .Screen/x DEI2 ;ellipse/x LDA2 SUB2 .Screen/x DEO2 .Screen/y DEI2 ;ellipse/y LDA2 SUB2 .Screen/y DEO2 ;ellipse/err LDA2 #0002 MUL2 ;ellipse/e2 STA2 ;ellipse/e2 LDA2 ;ellipse/dx LDA2 LTH2 ?{ ;ellipse/x LDA2 INC2 ;ellipse/x STA2 ;ellipse/dx LDA2 ;ellipse/a LDA2 ADD2 ;ellipse/dx STA2 ;ellipse/dx LDA2 ;ellipse/err LDA2 ADD2 ;ellipse/err STA2 } ;ellipse/e2 LDA2 ;ellipse/dy LDA2 GTH2 ?{ ;ellipse/y LDA2 INC2 ;ellipse/y STA2 ;ellipse/dy LDA2 ;ellipse/b LDA2 ADD2 ;ellipse/dy STA2 ;ellipse/dy LDA2 ;ellipse/err LDA2 ADD2 ;ellipse/err STA2 } ;ellipse/x LDA2 #0000 NEQ2 ?{ BRK } ;ellipse-paint/draw-ellipse JMP2 BRK @ellipse &a $2 &b $2 &x $2 &y $2 &e2 $2 &dx $2 &dy $2 &err $2 ----------------------------------------------------------- void plotOptimizedEllipse(int xm, int ym, int a, int b) { long x = -a, y = 0; /* II. quadrant from bottom left to top right */ long e2 = b, dx = (1+2*x)*e2*e2; /* error increment */ long dy = x*x, err = dx+dy; /* error of 1.step */ do { setPixel(xm-x, ym+y); /* I. Quadrant */ setPixel(xm+x, ym+y); /* II. Quadrant */ setPixel(xm+x, ym-y); /* III. Quadrant */ setPixel(xm-x, ym-y); /* IV. Quadrant */ e2 = 2*err; if (e2 >= dx) { x++; err += dx += 2*(long)b*b; } /* x step */ if (e2 <= dy) { y++; err += dy += 2*(long)a*a; } /* y step */ } while (x <= 0); } } -----------------------------------------------------------

DAY 10

Hello ! So today objective is to think about some feature I want to implement. Mainly two things, the free draw element and the construction line.

To be honest I mostly check the first one. Main issue is that in SVG you desribe the shape you want to draw, but when you are doing "free drawing" you are just clicking around to put pixel on the screen. So how do you transcribe this action in a SVG format ? So far, my reflexion is the following : if your free draw in UXN is just something like : when a move my mouse and the left button of the mouse is clicked then get the coordinate of the mouse and draw the pixel at this position then you can in the same time build a <path> element who will contain all the coordinate of the mouse. In my head, I think it will work. Issue being, I don't know how long the path will be, because you can just move around with your mouse for a very long time and it will mean a lot of coordinate to put in the path element. I'm fearing that if I just stock everything in a position in memory in UXN like I do, it will just start overwrite everywhere and break the whole stuff. My final thought is that I probably need to put have a fix amount of element in each path, something like 50 coordinate and if the user just click for longer than that, just start creating a new path. In theory it work, but I will need to really code the feature to see if it's alright.

DAY 11

Hello ! Today is still in the same brainstorm mood than yesterday. I have not write anything new, I just check what I wrote before, for a long time. I swear I'm not that weird ! It's just that I was thinking about how put the construction line stuff. Just to be explicit, construction line for me is like the stuff you draw to help you draw the main stuff you want to draw. Like perspective line, the cross you do to position eyes/nose/mouth in a face. I'm weirdly convince it have another name, but that's the only one I can think of. Anyway, it's not very hard to implement this idea, because UXN offer you the tool to draw stuff, and in my case it's just mean that the construction line will not be added to the SVG, so I just need to take all the shape I can draw and draw them without building the SVG in the side. But I didn't really think about that from the get go, so both operation of drawing and building the SVG are interlock in many case. So it's calling for some refactoring and I mostly spend today time to think about how I want to do that. I'm not fully convinced about a way of doing that because I'm not sure how much time I want to spend rewrite some part of this project. Overall this week I have very low motivation to code so I want to go for the lazy way, but I have a guts feeling the lazy way will kick my butt in the future. So I decide to not commit today, we will see later what option I will take !

DAY 12

Hello ! Today coding is criminal. The crime is to code something work related when you are out of work !! I'm not proud of it, but a very specific issue I have at work was rent free in my mind and I was sure I could find a way to deal with it but didn't have proper time to test it at so, I just use today time to test it at home. I plead guilty, hoping my father will become the president and cancel my crime.

DAY 13&14&15&16

Hello ! Long time no see, I guess ? I will group these days together, because I just work on one thing and I did it in the spend of these 4 days. Also i didn't upload the website for 4 days so it's also showing that. Anyway, I finish implementaing the free drawing tool !

Funnily enough, I didn't lose much time thinking about how to make it work, because the idea I had at day 10 is working fine. But it take a long time because I do the classic coding move of trying to do something, it's not working, you try everything and then you realise the issue is solvable by making the whole stuff more simple. In this case, I was buiding the path element in the memory space of the program, but I was focusing on one issue : if I'm doing a very long line at some point it will overflow the space memory I allocate to this element and starting breaking everything else. So my counter for this situation was to just track down how much point I'm adding to the element and just write in the SVG file and reset it. So in theory it should work fine, it give the user the ability to just do a very long line. In practice it was not working that well, because I have a succesion of path element in the svg, but if you were moving your mouse too quickly, the rate of checking the mouse position is not high enough to capture every pixel your mouse go through, so if you skip some pixel and then create and new path element the result will have a gap between the two path. It have some aesthetic value, but that's not really the behavior you expect. I already encounter this issue, and the classic way of solving it is to not really draw every pixel, but to draw line between each mouse position you capture. But in my case, I'm already building line between point using the path element, so it would mean that I should create a new path to connect the two path and this path would just have like the last coordinate value of the first path and the first coordinate of the second path. For some reason, I really tried to do that. It was not working that well because keeping track of all that was not straightforward. After hours spend over several days, I just realise that I just needed to build the path element on the way. I don't need to build the path and then copy it in the file and be careful of the amount I do, I can just stream the writing. So I start drawing, it initialize the path element, and then everytime you capture the mouse position, you just add the write the coordinate in the file, and then when you stop drawing, you close everything. No more memory space issue, no more gap between path, easy to tracks. We are good to go !

So I'm now able to draw random stuff like that :

I hope you are not too moved by my drawing skill.

DAY 17

Nothing to declare for today, I was just busy with life, no code have been edited today.