As you might know, DataTypes on the Amiga is a universal system for managing files in different formats. This lets an application query the datatypes.library to load or save a file, while the OS takes care of converting the format. If a user installs new DataTypes on their computer, all existing programs using the DataTypes system will instantly work with the new format.
Happy happy DataTypes.
For a more in-depth explanation on how to use DataTypes in your application, I suggest checking out this link:
Since DataTypes are based on BOOPSI, a DataType object essentially is as a Gadget and can therefore be added to a Window. This isn’t the approach I’m aiming for in this article. Instead, I’ll demonstrate how to load an image from a file and populate a BitMap for further processing with graphics.library. The example below will open a window, load a .png file, and copy it to the window’s rastport for display. The result is a small program that’s similar to the MultiView utility, but much simpler.
When using datatypes.library, it’s a good idea to test your code on different versions of AmigaOS. For example, ApolloOS will automatically handle high-color images, while AmigaOS 3.2 needs to be explicitly told to use newer modes. These small differences between AmigaOS variants can be tricky to anticipate without thorough testing.
Support for high-color pictures was introduced in datatypes.library version 43, which means you’ll need AmigaOS 3.5 or later. You can refer to this table to see which versions of DataTypes are included in different AmigaOS releases.
OS
version of datatype.library
AmigaOS 3.0
v39
AmigaOS 3.1
v40
AmigaOS 3.5
v43
AmigaOS 3.9
v44
AmigaOS 3.2
v47
ApolloOS
v45
I’ll let the actual source code speak for itself. Here’s how to load pictures into a Bitmap using DataTypes in assembler.
MUI, or Magic User Interface, is a popular UI system on the Amiga that offers users an attractive and consistent interface to work with. For developers, it delivers an object-oriented way to code UIs, with perks like automatic layout management and simple Arexx integration.
MUI
MUI coding is an advanced topic, but one that’s worth learning properly. There’s no doubt MUI was designed with C programmers in mind, and little has been done to accommodate those of us who prefer assembler syntax. The MUI development package hides much of its functionality behind C macros and libraries, making it tricky to find documentation on how it really works. That’s the kind of insight assembler coders need.
I highly recommend checking out the developer guide and autodocs included with the MUI developer package. They offer a solid understanding of how the system works. Here, I’ll highlight the parts specific to the assembler and share examples you can use as a starting point for your own applications.
To get started, we need to open “muimaster.library”. Although MUI objects are technically Intuition BOOPSI classes, we should use MUI functions to create new objects and set their attributes. Another important thing to note is that the UI is built from the bottom up. That’s why, in the later example, we start by creating the buttons and text, then the groups they belong to. Only after that do we create the window, and finally, the application to host everything. The reason for this is that each object we create needs to have a pointer to its children. As a result, when we create our window, for example, the application isn’t ready yet. This means we can’t actually open the window at that moment. We need to build the entire chain of objects first, then open the window using _LVOMUISetAttrsA.
Creating new objects is done using the _LVOMUINewObjectA function. Like other functions ending with a capital “A,” its attributes are provided using a taglist. In the example, I use my own macros to build a taglist on the stack. They’re the same ones I’d use with, for instance, _LVOOpenScreenTaglist, which is actually an alias for _LVOOpenScreenA, by the way.
Every new object we create needs to be of a MUIC_<class>. In the C documentation for MUI, you’ll see references to MUIC_Window, MUIC_Text, and so on, but these don’t appear in the assembler includes. The fix is to add the necessary classes ourselves in the assembler source. These aren’t constants representing numbers like other labels, but pointers to strings containing the class names. Here is how it’s done in assembler:
One big advantage of having the entire application and its UI as a single chain of objects is that when it’s time to exit and clean up, we just make one call to _LVOMUI_DisposeObject with our application as the parameter. MUI will then automatically close all its child objects and free up all used resources in one go.
With our application and its UI elements now created and visible on screen, it’s time to add functionality to bring everything to life. The ideal MUI application has a minimalistic event handler that only checks whether the program should quit or continue running. All other functionality should be added as hooks to the UI elements, with MUI handling the calls to these routines. This is exactly the approach we took in the example.
Important: When MUI calls your hook, don’t assume any data will be in the CPU’s registers. Retrieve all necessary parameters from variables or memory locations, and be sure to save and restore any registers you use on the stack.
In object-oriented programming, the functions an object can perform are called “methods”. In MUI, these methods are invoked using the DoMethod() command. However, DoMethod() isn’t actually an AmigaOS function; it resides in a linker library used by the C compiler, making it not particularly useful for assembler coders. To rub salt in the assembler coders’ wounds, the documentation on how to manually invoke these methods is flat-out wrong.
Here is what needs to be done:
Make a list of methods and their parameters stored in memory or on the stack.
Point a1 to this list
Point a2 to the relevant MUI object
Point a0 to the objects hook
execute h_entry from the hook
movea.l mt_MUI_Application(a5),a2
movea.l -4(a2),a0 ; Offset to Hook Struct (Is this undocumented?)
movea.l h_Entry(a0),a6 ; Find entry to execute method
lea mt_Method_Input,a1
jsr (a6) ; DoMethod();
All of this could be made easier for the coder by creating macros to generate specific types of objects and invoke methods, but for clarity and understanding, I’ve chosen not to include them in this source.
To sum it up, here’s a list of what needs to be done to build a MUI application:
Open “muimaster.library”
Build your application starting from the bottom objects and up while linking any child objects to it
Set attributes that only become valid after creating the application, such as opening a window.
Use DoMethod() to set notify and hooks to your objects
Run a minimalistic eventhandler loop that fetch Application_ReturnID_Quit by calling DoMethod() and waiting for signal
Clean up by a single call to MUI_DisposeObject()
Close “muimaster.library”
Finally, here’s a complete example of source code showing how to accomplish all of the above.