Open stepcity opened 3 years ago
Many thanks for trying it out! I have uploaded a source snapshot for you, I'm not sure how useful it will be at the moment, as the whole thing is in such a state of flux, I am still changing things all the time. It's a mess, feel free to ask any questions you may have.
Although I have copied the old Amiga 1.3 GUI, the structure of my OS is actually far simpler than AmigaOS, as my design is scaled up from an embedded microcotroller kernel I built years ago, and have used in various projects over the past decade! I decided to clone this GUI as it seems like the simplest GUI design which provides the minimum functionality needed for a modern Desktop. It was a tossup between this (from 1985) and the Classic Mac GUI (from 1984), but the Amiga provided full colour and multitasking from the outset, so better meets my design goals.
There is a graphics library which abstracts the graphics drawing routines (plotting pixels, drawing primitives, blitting, etc...), but this should not be called by user code, ever.
The GUI is conceptually very simple. It is really just a multiplexed frame buffer. Any task which wants to display graphics, must open the GUI library (called Intuition, simply because that it was the Amiga's GUI was called), then open a "Window", task may open as many windows as it wishes. The window it added to Intuition's window list. This also allocates an offscreen bitmap upon which all drawing by the task will be done.
Tasks should always use the Intuition graphics calls to draw to the window's bitmap. Each window has a "cliprect" list, this is a list of visible rectangles which make up a window. A window unobscured by another, only has one cliprect which covered the whole visible window area. But if another window is partially covering it, then the cliprect list will be the window area divided into visible portions. Every time a window is moved, resized, or depth changed all the windows need to recalculate their cliprects. Currently their is a subtle bug where under a certain set of conditions a window will have a visible cliprect where it shouldn't have... But it's not a critical bug, shows up too infrequently to be easily identified, and I'm fed up of debugging this part of the code, it took ages to get right! :-)
If a task draws to a window via the intuition graphics functions, the visible cliprects where the drawing took place are marked as needing a redraw.
Every Vertical Blank (screen refresh), Intuition will traverse the window list and if any of it's cliprects are flagged as needing a redraw are blitted to the framebuffer. Since I'm using GRUB's VBE frame buffer, I have no real Vertical Blank interrupt, so I'm just faking it with a 16ms timer interrupt, that is why there is flickering when there shouldn't be.
The surprising part of all this is that Intuition is just a library, it has no task, instead the 16ms refresh is handled by the timer device task, and the window move and depth change is handled by the input device task. The resize happens in the context of the window's owning task. When the resize gadget is pressed and the window moved, a message is sent to the task which then has to call the intuition resize function, and handle any relaying out of the window content (see how the boot shell task has to layout the text as the window size changes). If the task crashes, then the window can't be resized, as the messages will just be ignored... But can still be moved and depth sorted, these operations are handled by the input task.
Although not fully implemented yet, each window has a gadget list, when events happen to these gadgets, messages will be sent to the underlying task which will decide how to handle them.
-edit- Almost forgot, keyboard event messages are just sent by the input task, to a window's message port if the focused window has a message port. A task doesn't have to assign a message port to a window... If it doesn't, then Intuition doesn't bother sending any event messages.
The code in cli.c will eventually be spilt into a separate boot task (which will do most of what kernel.c currently does), and a console device for handling the command line interface for all tasks. Right now it is a bit of a dumping ground, while I'm building the dos library to get file access working.
Woah, that's pretty cool! I only really looked at your Intuition implementation because I'm a sucker for graphics but from what I've seen of the original Intuition source code it's actually fairly on-point. Obviously less advanced in many aspects but in others (like using a doubly-linked list rather than a singly-linked list) it's way cooler. Anyways, like I said it's all very cool and it seems like a reasonably (for where it's at hehe) well rounded system. Also, I'd be willing to help with any docs where I can, I don't know much about how it all fits together but the code doesn't seem too complicated for me to figure it out :P
I have to thank you again for your comments. I've been struggling to find time to work on the project over the last week or so, and having someone to talk to about this really helps my motivation.
I would welcome any contributions to move the project forward, I suspect it's a little early for documentation, as there is going to be a quite bit of change, I'm totally open to suggestions as to how to progress. For example I am considering turning the graphics library into a device (It will probably keep its library functions for now, so there will be a choice of interface), but modern graphics system fit the device model better, and it would be nice to move all gfx operations to their own execution context (especially when I add multiprocessor support). I am also thinking that the device model of interface is probably what should be the "primary" interface (as opposed to the library model), as this would support more advanced memory protection and security paradigms.
Also, I do need to put a proper build system in place! π€£
Hopefully I can find some time (and motivation) today to work on the file system interface. I am very keen to get disk loading, and the command line interpreter working.
My idea is that there will be two layers of device to handle this, a low level device to pull the data blocks from the physical hardware, and a "middle man" device which will implement the FAT file system and present a traditional TripOS style command line user interface. This would help toward getting an even more authentic AmigaOS experience. (I've been talking with Thomas Richter, who is the developer working on the latest AmigaOS, about the best approach for the CLI, and he's given me some good pointers and tips to avoid falling for the same problems/limitations AmigaDOS has).
@stepcity If my memory isn't too faulty, I seem to remember that you were working on building a 68k computer.
It really shouldn't be too difficult to port this to the 68k, as I originally designed my kernel on an old 50Mhz 68030! The only real changes you would need to make is replace all the uint64_t variables to uint32_t and halve the number of available signal bits.
That I am! Currently it's an m68k although I'm certainly eyeing the option of using a full blown custom chip. I think your kernel would be very fun to use on there so I'll try it out once the emulator's closer to being done. I've been tinkering with your GUI quite a bit because I prefer monochrome and dithering (I know, I'm a sadist) like the original Macintosh or the Xerox Alto (which I actually used some source code from to build my emulator!). Sadly, the emulator itself is probably the hardest part for me to write and currently it's not nearly far enough along to run something advanced like this. When it does though, I'll be sure to try and run this on it!
You just need to fiddle with the window decoration function, I will add a "classic Mac" theme version of that function if I get time, for you. Then you can just switch out whichever decoration theme you want.
Not sure if it will help you, but look at my Omega project. That's an (m68k) Amiga hardware emulator.
I've actually looked at that emulator, it's obviously not the best Amiga emulator out there but it's certainly very small. If I use it as the base then I'd have to restart some of the higher level pieces but it's probably worth it in the long run to start with what already works. Also, you don't need to implement a Macintosh theme just for me; while I'm very honored you should focus on what you want to do with it :P
Yeah, Omega is not a great example of an emulator it uses the older technique of lots of state machines (as opposed to using an event scheduler). My approach does have the advantage that it is much simpler to debug and also to be able to shutdown parts as and when I don't need them. Which suits my design goal. As you say it has the distinction of being the smallest and simplest working Amiga emulator ever written!
I do want to make my GUI 100% themeable, no one should ever have to use the old AmigaOS 1.3 theme! Since you are the first and possibly only other person to have used (and may ever use) this I'm happy to add something you would find useful. This also takes my mind off my filesystem struggles!
Two changes to the source that will interest you. In intuition.c where the function table is built at the end of the file, you can set the mouse pointer style (I've included a classic Mac style pointer) and also the GUI background can be set globally, you can now have a nice grey GUI! π
This is incredibly fun. It's just good old fashioned fun to be able to change the color so simply (well, reasonably simply hehe). I can't help but notice that it looks like you're getting a filesystem coming along. I do actually have a suggestion - you should move away from hdiutil when building it. For now I'm just using grub-mkrescue to make disk.img since I don't have access to a Mac, although if you used a different method to make the original image then that'll stop working once you get a working filesystem.
Ahh, yes I never envisioned anyone else using the source code, certainly not before I had a proper build system in place... so I just used hdiutil for simplicity!
I managed to move the filesystem interface on quite a bit today, and have started merging my old FAT32 driver code into this current version... It's a bit jarring as code styles are different, but for now I just want to get it working, I can clean it up later.
I've added a new source snapshot, this separates out the window decoration function, the library function table how has the "master" decoration function.
You can theme the GUI by altering these public functions: void DrawDecoration(window_t window); //The master function will draw the window decoration void GimmeZeroZero(window_t window); // call (usually after a resize) to set the inner dimensions of the window (if you keep in the current decoration dimensions, you can ignore this).
And then these private functions are for the current theme: void drawWindowDecorationOld(window_t window); void GimmeZeroZeroOld(window_t window); void drawWindowBorder(window_t window); void drawWindowTitleBar(window_t window); void DrawSizeGadget(window_t window); void DrawDepthGadget(window_t window); void DrawCloseGadget(window_t* window);
You can theme to your heart's content, note that current the gadgets only have single state image, they will eventually get an "active state".
More themeing feature to come... which is probably too much work, given how desparately my GUI system needs a rewrite π But it's fun stuff like that that keeps me going.
-edit- included at the top of intuition.c is "theme" variable, use it adjust the GUI theme...
This is really neat! Once you get the filesystem working so that you can read/write from files, it would be interesting to store themes as sets of pixmap files. Also, I'd say that the main thing that could be done to improve the GUI system is to switch to a smaller/more efficient framebuffer instead of using GRUB's VBE (to get rid of all the flickering). This could be started directly in intuition.c but the architecture is fundamentally yours so place it wherever you think is best. That being said, the GUI itself is very good as far as very small windowing systems go, and the level of customization (even if it's only at a source level) makes it very fun to tinker with. Keep going with the good work, it's really fun to play with your OS and I like watching it grow!
December 9th Source Snapshot has cleaned up the themeing quite a bit, THEME_OLD, THEME_NEW, and THEME_MAC are all looking quite good now. I improved the window resizing so the window contents is visible during a resize and window moving is smoother.. but, and there Is always a but... The CaclulateBlitRect function bug (which I had hidden, by carefully ordering the blits) is now very visible, and when full screen width windows overlap, sometimes a part of the lower window shows through...
I hated writing this function... I'll have to debug it again... I know the error is in one of my conditional branches, but there are so many that I just can't visualise what is going wrong.
This looks great! Just so you know, the reason MacOS 6 and below had an extra line on the bottom and right borders was to give a sense of depth - somewhat like a shadow. The two new themes look really great, and I can see the bug with CalculateBlitRect and I (might?) be able to take a look at it but I doubt I'd be able to figure that out since I haven't worked much with really low level graphics yet.
I would genuinely welcome you at least looking over the CalculateBlitRect code. I had to code the whole function directly from theory as there was no way to really test it in stages. Even just looking over the logic of what I'm doing might reveal something quite obvious to you. The problem I have now, is that the code is executing correctly in my head, so when I read through the code I'm somewhat blind to what it is actually doing. -edit- it looks like the problem occurs when windows have the same x position...
The theory is that each window starts as a single blitRect, covering the whole area, this bit rect then gets divided into (up to 4) visible rects and one obscured rect (which I don't bother to record, as the window is backed by its own buffer). Then each of those visible rects are further divided into upto 4 visible rects, and so on... until there are no more windows above obscuring the window... The algorithm favours horizontal rectangles (i.e. wider than taller ones) as the blitting code using the x86 "movsd" string instruction to optimise the copy of horizontal lines.
In the intution->RedrawBlitRects() function you will see two lines of DrawRect() functions commented out, activating them, and commenting out the BlitRect() function will make the BlitRects visible on the screen... it does help a bit to see what is going on sometimes.
I'm glad you convinced me to make the Mac Theme, as I rather like the very clean look of the grey desktop, white windows and clear delineation of window decoration! I spent a few hours yesterday trying to build a Chicago font set so we could get more authentic classic Mac look... But the font set has a few characters which fall out side of the 8x16 limits imposed by my current glyph renderer. That's really annoying... I guess I'll have to rewrite the Font engine.
I hope to push forward with making the window decoration gadgets (close, resize, depth, etc) real gadgets rather than just hard coded images/events in the input routine, the current "kludge" was never meant to be a long term thing, I just wanted to test the event code.
I also want to get the screen title bar menus working, because all this is a lot more fun than Filesystem work π
Fixed the CalculateBlitRect() function... It was so simple, I had accidentally allowed the algorithm to recheck clipRects which were already marked as non visible, for visibility against other Windows, which may or may not be covering them, if the window wasn't covering them they would then be marked as visible! That would make them show up, when really they should be invisible! I can now optimise the GUI drawing routine, and get a bit more speed. I'm so pleased by this!
I'll put up some new sources and builds tomorrow!
Also the window decoration is now using proper gadgets (with different states), so events are handled properly too. This is turning into a proper GUI now π
-edit- I've started work on a proper font handling system, too.
Nice! I realize you probably think that your work isn't the best but it's really very impressive to me. I never got the chance to use a real Amiga, I've only ever run emulators to try out AmigaOS so your work is really quite interesting. (The Macintosh, on the other hand, I have used, and it is still my favorite computer). Sorry for replying sooner, I was a bit sidetracked with a (new) project and haven't checked Github in a while.
No need to apologise! Honestly, if it hadn't been for your encouragement (nearly a month a go now!) I might easily have lost motivation to continue, never underestimate the power of a few kind words. As the holiday period descends upon us, I'm probably not going to have much time myself... and getting motivated to work on filesystems is always a problem for me π (They are just so boring... but vital).
I have updated the sources (and the builds) to the latest versions. I have added an "autorise" feature for the windows, as double clicking to bring a window to the front is very much an Amiga thing, the Mac always brings the active window to the front, so that behaviour is now replicated (hopefully improving your Mac user experience). Sorry the font (and title/menu bar) is still isn't right... I'm working on getting the theme as Classic Mac like as possible!
The GUI drawing needs to be optimised, there are loads of places when I can massively speed it up now the BlitRects work properly, but that can wait as it is better to add functionality first.
If you've been following OSDev, I'm pondering integrating a realmode emulator so I can access the gfx card's BIOS... I really would love to have accelerated gfx... but, I know, file system first π
-Edit- Looking over the VMWare GFX driver (seems like a good place to start, if I can accelerate gfx in QEmu/VBox/VMWare that will get the ball rolling) https://sourceforge.net/p/vmware-svga/git/ci/master/tree/doc/svga_interface.txt#l199 it looks like I need to get a PCI driver working first π€
Howdy! I haven't said anything here in a while but I'd like to ask so I'm gonna :P
A while back I was working on Plan-B, which was an Emulator + Operating System in one big package. I ended up scrapping that project because I realize I was in over my head, but I'm working on a new project that's meant to be similar to the original Macintosh. The Macintosh didn't really have a mechanism for shared libraries, but instead had a mechanism called the Resource Manager which provided pretty much anything including code to any application. The specific api, essentially "LoadResource," reminded me a lot of the Library api of your operating system. Would you mind if I used the same type of Library api but refactored it into being more general purpose?
By the way, my system is designed to only draw with the CPU because there's fewer steps and also because the original Macintosh did it that way. I've been browsing through the source code of QuickDraw, which is mostly in 68k assembly and partially patented, but still very useful for optimization. You should check it out if you want to try and speed up your graphics!
Certainly good to hear from you! We entered our third Lockdown in the UK at the beginning of January, so all my time has been spent on childcare. Iβve had no time to work on my OS project... Though I have redesigned to filesystem namespace on paper multiple times, Iβm still not 100% sure how I want to proceed!
I hope the design of my library API is useful to you, and I'm happy to "brainstorm" any architectural goals with you, if that would help!
Apologies, I actually wrote this ages ago, but forgot to click send (I'm using the iOS GitHub app).
hello how exactly do you run this dec27th2023 thank you cuz i dont see run build instructions in the readme file unless i missed it thank you
hello how exactly do you run this dec27th2023 thank you cuz i dont see run build instructions in the readme file unless i missed it thank you
Hi Lisa, if you just want to try it then run either the disk.img or disk.vdk in your favourite x86 emulator.
To build from the source code, run one of the build.sh (standard bash scripts) in the source code folder.
The build process is very simple, it doesnβt require any external libraries, So you just compile the .c files into .o files and then link them into a single binary which can be run directly by the CPU.
hello okay i will try that and see how it goes thank you for the reply i will update as needed best regards
Hey! This is really cool. I haven't actually used an Amiga in person but as a GUI you seem to get it pretty spot-on. I'm also an OSDev-er myself, and I'm not nearly hardcore (or patient enough) to bother writing everything from the ground up so my system is a complicated mess that is technically based off of NetBSD. Since my choice not to use an X or Wayland based windowing system (I'm thinking of using Ghostscript or PDF and building off of that) I've been looking around for inspiration on what to put in a "quality" GUI. While I can tell that this isn't finished, I'm excited to see the source code and see just how it works! The GUI ran very smooth when I emulated it in QEMU, and it's multitasking seems to work very well. So, I must say that this is deserving of a "Well done" and I hope it continues to grow because I can imagine quite a future for it as a hobbyist system.