|
Forum Index : Microcontroller and PC projects : IFS fractal renderer for the CMM2 (CSUB based)
| Author | Message | ||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
Hello all, I've been playing around with writing CSUBs, as well as thinking about how to structure an application with multiple modes/states. I've written an IFS fractal renderer that uses a CSUB to do the rendering and basic to handle all of the IFS selection/editing and application state transitions. Currently it has three modes, an IFS fractal selection mode with a smaller preview rendering of the fractal. A full screen rendering mode with pan/zoom controls. And an IFS editing mode where each transform can be selected and modified. I haven't added any sort of load or save capabilities so after editing the transforms of the IFS there's no way to keep them. But that shouldn't be too hard to add. I just wanted to get this out there for people to check out and I've been fiddling with it for too long. ifs_renderer.zip I have learned some things about development on the CMM2 and have some ideas for quality of life improvements. These may already exist in new release candidates, or be bad ideas for other reasons. :) 1) A way to add line breaks to long lines would be really helpful. It could be as simple as a comma as the last token on a line means the line continues on the next line. That would be enough to be able to split up function/sub declarations as well as parameter lists at call sites. It would make things a lot more readable I think. 2) The ability to pass an array slice as a parameter and have the subroutine or function see it as an array of the sliced dimensions. I know one of the latest release candidates added a slice command, but that requires defining a new array variable and copying the data to it. Being able to pass a slice directly would allow for smoother API design in reusable components. The IFS renderer has a few helper classes that have to pass in a two dimensional array and an index of an slice of the array to process. This prevents the helper class from being truly reusable as it relies on the shape of the array passed to it. A minimal but very useful version of this would be the ability to fix an index for just the last dimensions of an array. That would keep the resulting array contiguous in memory and not require any additional information about the shape of the array. 3) A small one, but I couldn't figure out how to copy and paste part of a file into another file. This made it hard to refactor my program when I realized I had some helper routines that would be useful in other programs. Overall it was a fun project to work on! :) Thank you Peter and Geoff, Anton |
||||
| jirsoft Guru Joined: 18/09/2020 Location: Czech RepublicPosts: 533 |
+1 I'm doing it as COPY complete file under different name, then delete in new file everything else then routine needed, mostly when I find too late to put something into INC file... But then I'm missing again some faster BLOCK SEL (at least PAGE UP/DOWN with selection)... Jiri Napoleon Commander and SimplEd for CMM2 (GitHub), Â CMM2.fun |
||||
| twofingers Guru Joined: 02/06/2014 Location: GermanyPosts: 1680 |
@Anton, you can use F7, F8 (+F4+F5) in the built-in editor. Or epsilons Xedit! Regards Michael EDIT: In Teraterm: copy and paste. Edited 2020-11-17 22:58 by twofingers causality ≠correlation ≠coincidence |
||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
Ahh, I missed the F8 functionality. I probably saw it in the manual but forgot by the time I was needing it. :) Or epsilons Xedit! I like some things about Xedit. But I really miss color highlighting, even the minimal amount done by the built in editor is worlds better than none. I also prefer to edit in mode 9, font 7, which Xedit doesn't handle. -Anton |
||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
2) The ability to pass an array slice as a parameter and have the subroutine or function see it as an array of the sliced dimensions. I know one of the latest release candidates added a slice command, but that requires defining a new array variable and copying the data to it. Being able to pass a slice directly would allow for smoother API design in reusable components. The IFS renderer has a few helper classes that have to pass in a two dimensional array and an index of an slice of the array to process. This prevents the helper class from being truly reusable as it relies on the shape of the array passed to it. A minimal but very useful version of this would be the ability to fix an index for just the last dimensions of an array. That would keep the resulting array contiguous in memory and not require any additional information about the shape of the array. Some thoughts about this. Looking at the definition of the s_vartbl struct I'm guessing that the minimal version I mention above could be accomplished by passing a s_vartbl to the function that is a simple modification of the one in the variable table. The later dims[] entries could be set to zero and the fa or ia pointer could be updated to point to the specific subsection of the array that was selected. For example: function sum%(ints%()) local i% for i% = 0 to bound(ints%()) sum% = sum% + ints%(i%) next end function dim ints%(2, 2) = (0,1,2,3,4,5,6,7,8) print sum(ints(,1) ' would print 12 (3+4+5), by slicing on the second dimension And on the C side the updated s_vartbl would be: var.ia += var.dims[1] * 1; var.dims[1] = 0 I haven't seen the source to MMBasic, but I'm guessing that a new variable table entry is created for the parameters that are passed to a function or sub. In which case the newly created entry is just a modified version of the one describing the variable passed in. And I don't think the proposed slicing syntax above conflicts with anything. In fact it is quite consistent with passing a single array element to a function where all of the dimensions are specified. Thanks, Anton |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4147 |
I think things are passed by reference so probably a new entry is NOT created. John |
||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
John Hmm, I agree that that seems likely. However, what about the case where you pass in a single element of an array? There the new variable references just one entry of the array. So it can't use the original array variable table entry, I think... |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10588 |
Please stop trying to rewrite MMbasic. The generic parser doesn't cope with this sort of concept and it isn't going to happen. |
||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
My apologies, I'm guessing you're getting swamped with ideas and have many of your own as well. I didn't mean to add frustration. This didn't seem like a big change to me, but since I've never seen the code I couldn't know. :) |
||||
| twofingers Guru Joined: 02/06/2014 Location: GermanyPosts: 1680 |
But you know you have the opportunity to read it? causality ≠correlation ≠coincidence |
||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
But you know you have the opportunity to read it? Yes, I have to admit that filling in a web form to get to the source code was enough of an impediment that I didn't bother. But I probably should. Though it sounds like changes like I'm describing above might not be welcome anyway. I'll get the source and take a look regardless. -Anton |
||||
| twofingers Guru Joined: 02/06/2014 Location: GermanyPosts: 1680 |
i think it's worth it. ![]() causality ≠correlation ≠coincidence |
||||
| MachineEmpath Newbie Joined: 25/10/2020 Location: United StatesPosts: 12 |
i think it's worth it. ![]() Yeah, I got it and am reading it. I see Peter's point about how arguments are parsed. There is a function "findvar" that is responsible for getting the type and pointer to the argument. Calling a function or sub does create a new local variable (in DefinedSubFun), and sometimes it points to the memory used by the callers variable, and sometimes it is a complete variable that contains the result of some expression evaluation. How that information is passed back to the caller is a combination of global variables and void pointers, so it's not super easy to modify. I do think that there is nothing structurally preventing the new variable from pointing to a slice of an existing variable. But it wouldn't be easy! Anton |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |