In our previous tutorial in the “File Attributes” series we opened a file and printed if we managed to open it or not. In this tutorial we are going to obtain some information of a certain file. We will obtain it’s name, comment info and the file size.
If you are not familiar with the comment part you just have a look at the above picture. For this example I created a file called “example.txt” for which I added a comment as well. Make sure you have this file in the same folder in which you would run the example.
Click here to download the (fileinfo.c) source code file.
In order for us to get this info we will use the function “ExamineObject” from the DOS Library. As you know we don’t have to open the DOS Library but we also don’t have to open our file to get the info we want. On to the show!
Line 8 is setting up our ExamineData structure called “data”. In here all the info of our file will be stored if we succeed to get this. And as you might have guessed we will also use this to check if we managed to get all the file info.
Line 13 will try to get all the info of our file. IDOS->ExamineObjectTags is the function that will obtain this. It will require us to tell it a few things. EX_StringNameInput is telling it that the file we want to use is not open and will be given in a text string which we will provide in the next part. I don’t want to make it to complicated but we can also tell it to use a file that is already open and if we would we would use for example EX_FileHandleInput. Next up is indeed the name of our file in a text string. TAG_END will tell it that we have reached the end of our instructions. So what we are doing is get the info from a file called “example.txt” which is not currently open and store it in a box called data.
Line 15 will check if we succeeded in doing this. Our pointer (or box if you like) called data will be empty if we failed and full if we succeeded. Line 22 till 28 will take care of the part if it failed. If you want to see if this part actually works if it does fail try to change the name of the file (in the source code or the actual file) and you will be greeted by the failure message.
Line 18 till 20 will get the info we want. As you might have guess line 18 will get the name, line 19 the comment info and line 20 the files size. This will be printed on the screen and in my case I will be greeted with the below info.
There is one more part left which is what we are doing on line 30. We need to cleanup and on line 30 we are freeing up what we have used using the IDOS->FreeDosObject function. We are telling it that we have DOS info in our data box which we no longer need so dispose of it. That’s it! Please let me know if something is not clear, you can’t get it to work or you have any other questions. I hope you learned something and until next time; Happy coding!
In this series called File attributes we will do some C programming related to files. In our first article we will open a file, check if we succeeded and close it again. Really basic stuff but also really cool to learn. When I say really basic stuff I mean in the eyes of experienced programmers. I talked about this before but I will bring it up again. Doing simple examples might seem silly. Why is this useful to me? It’s just opening a file and not programming some really cool demo effects. Remember The Karate Kid? Pointless exercises leading to nothing only to realize they do teach you and make you understand. It is the same with these simple examples. After doing so many you start to see the bigger picture at a certain moment.
We are going to use the Dos library to open our file. Just like the Exec library the Dos library is also already open when OS4.x is booted up. So there is no need for us to open it up and to close it when we are done.
I created a file called “example.txt” containing one line of text in it that I use in our example. I place it in the same folder in which we will execute our example code.
One of the problems is to get the source code displayed in such a way that it is readable. To overcome this problem I have the source code file available for download and use screen shots showing parts of the code to explain it. Click here to download the (openfile.c) source code file.
The above lines of code are called includes. They include other files with code into our program. For example <stdio.h> includes code that will allow us to use the printf() statement in our program. The <dos/dos.h> include will allow us to use the dos functions to open and close files in our program. Normally I have a lot more in there even if I don’t use them. You might get some errors during the compiling of your code which is caused by not having a certain include file in there that provides the code for a function that you use. You will end up, like me, having a certain set of includes in your code even if you don’t use them. But I did not want to make it difficult by including a lot of includes.
Now we are getting to the start of our program. The line “BPTR fh;” is setting up our file handle. What this means is that once we open our file we will store all the info in “fh”.
The line “int main(void)” plus the open curly bracket is the start of our program.
Now we are getting to the main part of our program that will open our file. As you can see we will store all our info in “fh”. The statement “IDOS->FOpen” will open our file of choice. As you might have guessed the “example.txt” is the file we are trying to open here. The “MOD_OLDFILE” part indicates we want to open an existing file. There are other access modes but for now we will leave it at this. The last “0” bit has to do with the buffer size. The buffer size will determine how many bytes the stream buffer will have. What? Let’s say you want to move stuff from your house to the car and you have the choice of several boxes each having a different size. Will you pick a small box which can hold just a few items or a really big box that can hold a lot more items? Each has pros and cons. In our example we set it to 0 which means the default value. We won’t do anything with our file like reading or writing to it so it has no influence on our example.
Next up we will have to check if the successfully opened our file. As you can see we use “fh” which will hold all the info including if we managed to open it or not. Actually it will be empty when we failed to open it. So if the value is anything but 0 we managed to open it. The statement “if (fh != 0)” will check if our file handle “fh” is not 0. The “!=” means NOT. If it is NOT 0 we managed to open the file and we will print that we managed to open the file. If we failed the “else” statement will print that we failed to open the file. Sounds rather easy doesn’t?
What’s left to do is to close our file if we managed to open it. The statement “IDOS->FClose” will close our file. Again we use “fh” which is our file handle containing everything regarding our file. It makes sense to close whatever we have opened. The “return 0;” will end the program and let the system know we are done.
If you successfully compiled the program you will get the below output.
That’s it for the first article regarding files. Next time we will do something else with our file. I hope you enjoyed it and more important learned something. Please let me know if something is not clear or if you have any other questions.
It was going to be a series of 4 articles explaining how to open a ReAction window in C on OS4.x. I had 3 released already with the fourth on pending. Instead of writing the fourth article I decided to take the three articles off-line and use them in my new Amiga Editor project.
Time for part 2 in our basics tour. This time we are going to talk about Procedures. Procedures will allow you to create separate blocks of code that perform a specific task. Let’s say you need to perform certain tasks often. Instead of writing the same code (a smart person would copy and paste it of course) every time you could write it once as a Procedure and just call upon that Procedure whenever you need it. Another benefit is that your code will be more easy to maintain and read. Let’s take our example from our first tutorial and turn it in to a Procedure.
Procedure XPRINTING
x=0
While X<11
Inc X
Print X
Wend
Print “We left the loop!”
End Proc
As you can see we only added “Procedure XPRINTING” and “End Proc” to our code. The first line gave our Procedure a name and the second will indicate the end of the Procedure. Just having this in your code will not actually execute it. You need to call the Procedure in order for it to execute. We call it by just mention it’s name:
>XPRINTING
Another way of calling it is:
>Proc XPRINTING
The same rules that apply for the name of a variable apply for the name of a Procedure. Another near thing about Procedures is that you can close them so only the name will show but not all the code inside. Make sure the cursor is on the Procedure line and press the F9 key to fold/unfold it. You can also select the [Procedures] option from the [Editor] menu and trigger the [Open/Close] option.
I hate to do this but now I am going to get a bit technical and even maybe scare you. The variable X (X=0) in our example without being wrapped neatly in a Procedure is different than being wrapped in the Procedure. Outside the Procedure we call X a global Variable and inside the Procedure a local variable. Let’s say you change X inside the Procedure it would not effect Variable X that is outside the Procedure and the other way around. You can of course imagine a scenario in which you would like to use X in a way that if you change it outside the Procedure X inside the Procedure X will also change and the other way around. This is possible but for now I will leave it at this and discuss it in another tutorial.
Let’s use our new Procedure to learn something new. Have a look at the below code.
Procedure XPRINTING X=0 While X<11 Inc X Print X Wend Print "We left the loop!" End Proc Print "Click the left mouse button to execute the Procedure" Print "Click the right mouse button to exit" Do M=Mouse Click If M=1 Then Proc XPRINTING If M=2 Then Exit Loop Print "We have left our program"
I pressed the left mouse button first to execute our Procedure and after this press the right mouse button to exit our program. The below screenshot will show you how it will look like.
The newly added code (we know what the two PRINT statements do) is the Do – Loop part. If you understood the While – Wend control structure you will also understand the Do – Loop control structure. The Do – Loop control structure will repair what is inside it’s structure forever. We can leave the Do – Loop control structure by using the “Exit” command which you of course already spotted. It is actually really simple what we are doing in the D0 – Loop control structure. We have it check for a left and right mouse click and for each click it will do something. The left click will execute the Procedure and the right click will exit the Do – Loop control structure.
The “M=Mouse Click” command will check if the left or right mousse button was clicked.
It will store the value in M. There are three values as we can see below.
Bit 1 Single test for left mouse button
Bit 2 Single test for right mouse button
Bit 3 Single test for third mouse button, if available
All we need to do is check the value of M and execute the corresponding action. This is what we do with
If M=1 Then Proc XPRINTING If M=2 Then Exit
If M has the value of 1 which is the left click we will execute our Procedure. If M has the value of 2 which is the right click we will exit our Do-Loop control structure and with it end our program. I hope everything is clear enough to understand it. That’s it for this time and I will see you next time.
Unlike my OS4.x programming tutorials in C I will start with the basics for Amos Professional. This, and further, tutorials are aimed at the absolute beginners. People that really want to start programming but want to start with something easy (cue Amos!) and need a lot of guidance. Once you master Amos you can move on to something else. Why Amos? Is it not a dead language? Absolutely not! I am actually using it to create a new disk magazine for the classic Amiga’s. What makes Amos so great is that it will allow you to learn programming the easy way and get better along the way. No 100 lines of code to open a screen but just one line only in Amos. It takes away the difficult part so you you won’t be scared away and stick around. Are you still with me? Good! Let’s get started….
As a programmer you should put comments in your code to describe what it is doing. You might know what it does when you write the code but several months later you might not. Also if someone else is reading your code they can understand what is going on. Many times I had discovered how to fix something and not provide comments only to discover at a later stage that I had no clue what it was actually doing. There are two ways of providing comments in your code:
Rem This next line of code will make me rich!
‘ This next line of code will make me rich!
As you can see we can use “Rem” in front of our comments or the apostrophe ‘.
Now I am going to show you an example that will address a lot of points in one time. Don’t worry if you looked at it and don’t understand a thing.
x=0
While X<11
Inc X
Print X
Wend
Print “We left the loop!”
The run our example we can press F1 or select “Run” from the “Project” menu in Amos Professional.
What does example does is print the numbers 0 till 10 on the screen and once it has reached 11 it will print “We left the loop!”.
The first line “x=0” will set x to 0. We call X a variable. A variable means that it’s value can change. This will make sense in short moment when we discuss the rest of the example. Just to complete it you need to know that the name of a variable has to begin with a letter and cannot begin with a number. What is also not allowed is that the name starts with letters that make up one of the Amos Professional commands. I will show you….
FRIDAY=1
The above is allowed.
1FRIDAY= 1
The above is not allowed since it starts with a number.
FRIDAYPRINT=1
The above is allowed.
PRINTFRIDAY=1
The above is not allowed since the first part makes up the Amos Professional command “PRINT”.
Next we reach the “While – Wend” part. While – Wend will repeat a group of instructions till a certain condition is true. For example While – Wend will instruct your wife to go shopping till the wallet is empty. In our example While – Wend will print the value of X till X has reached the value 11. The instruction “While X<11” is taking care of this. The part “X<11” means till the value of X is less (<) than 11. The command “Inc X” in our While – Wend statement will increase the value of X each time with one. Remember I said earlier on that the value of a variable can change? In our example the value of our variable X will change. The command “Print X” will print the value of X. Once X has reached the value 11 our program will leave the While – Wend statement and execute our last part in which it will print “We left the loop!”.
So what do you think? Easy to understand? Please let me know if it is not clear or you have questions left. That’s all for now. Next time we will go a bit deeper but still maintain that level of easiness.
I know you are thinking what is he on about this time? Why bring Mr. Miyagi in to this? Remember Daniel question having to do these chores? Why waste his time on this while he wanted to learn karate? If you are like me you must have wondered at some stage if you would ever get to be any better at programming. Sure after trying really hard we understand all these small examples of source code but how would that ever turn us in to real programmers? Understanding and manage to open a window is nice but how would that ever make me create a full blown program? The beauty of it is that you can and will. Why? Because at some stage you understand that all those small examples made you realize you understand how it all works. All those small examples gave you a complete understanding on how you program. Let me give you a small example. You come across some source code plus information on a subject you never dealt with and you might not understand that new subject yet you do understand the source code. You understand what the source code is doing and at that moment you realize you actually have learned the art of programming. I call this the “Wax On, Wax Off” moment. Of course you still have a lot to learn but you have made a major break through.
One of the next big moments is that you actually will come up with your own routine(s). You want to do something and you start thinking what if I would do it like this? These are great moments because you finally have moved beyond the simple example stuff in to the big league. Mark my words when I say you will get there. Happy coding!
I have not been this excited about a Basic language since Amos. The strange thing is that this Basic version has been around for a long time already and I just re-discovered it. What basic version I am talking about? Well ACE Basic Compiler of course. The big difference, and one to win you over, is the GUI support it has. Without having played a lot with it I already decided I should start a series of tutorials about ACE Basic. I believe this to be the perfect language for beginners to start programming on the Amiga.
The begin with I would really recommend you subscribe to the Amiga ACE mailing list. Once you are subscribed you can also download the latest version of ACE Basic Compiler from the Files section. The latest version can also be downloaded from Aminet. The installation instructions are pretty easy to follow. Everything is well documented so you won’t have any problems and if you do there is the ACE Basic mailing list and me of course.
The ACE Basic Compiler packages comes with the AIDE (ACE Integrated Development Environment) which is a graphical front-end for the development of ACE programs. This makes it easy to compile your code compared to the more crude way of doing it from the shell. In this first tutorial I am going to show you how to compile ACE code both ways. First we need a very simple example that we can use for this.
print “Trying out ACE Basic Compiler”;
LOCATE 2
print “I like ACE Basic Compiler”;
LOCATE 3
Above you see our very simple example we are going to use in our compiling sessions. The command PRINT will print our sentence on the screen and the LOCATE command moves our cursor to the next line so that our two lines will not end up next to each other.
If you start AIDE and it is up and running you can select “Set” to get the file requester to open the source code file you want to run.
If you select “Run” in the “Program” section it will run our example code.
Of course we want to create an executable file. You can set the folder in which the executable file can be placed. In Project you can select AIDE setup in which we will be able to set our folder. In “Temp Dir” you can select the folder which I have set to “Applications:ACEBASIC”.
Once you click on “Executable” in the “Make” section our code will be compiled and the executable file will be placed in the “Applications:ACEBASIC” folder. Let’s move on to compiling from the shell. Let’s say our source code file is called “howtocompile.b” we would need to execute the below two commands.
ace howtocompile.b
bas howtocompile
The problem I ran in to is that “bas” would not run saying it is not executable. What you need to do is set the “script” option for the “bas” file. The “bas” file is located in the “bin” folder of “ACE:”.
By default the “bas” script is looking for your file in the “RAM:T” folder. You can change the location by editing the “bas” script file in the editor of your choice. I am not sure if it can be set somewhere else like for example in the AIDE set up. For now I just moved my file to the location the “bas” script file is looking for. The ACE package comes with a lot of documentation which I would recommend you read. That’s it for starters. Next time we will dive deeper in to basic programming.
Working with screens using the C programming language on the Amiga is a first for me. Remember how easy it was in Amos? I had seen some C code using screens before and frankly it scared me. Actually it is not really difficult to open a screen on the Amiga using C. As with all my articles I will try to take all the difficult information that is out there on a particular subject and make it understandable. The same goes for the example source code that is out there. I come across so many examples that even make me scratch my head. Especially when you can write in a much better and understandable way.
What steps do we need to take in order to open a screen?
Step 1 – Declare a pointer that will hold our screen structure (Line 10)
Step 2 – Setting up our screen’s parameters (Line 12 till 27)
Step 3 – Open the Intuition Library and Interface (Line 33 till 44)
Step 4 – Opening our screen and check if we managed to open it (Line 45 till 48)
Step 5 – Cleaning up by closing our screen, Intuition Library and it’s Interface (Line 50 till 79)
00 #include <stdio.h> 01 #include <exec/types.h> 02 #include <intuition/intuition.h> 03 04 #include <proto/exec.h> 05 #include <proto/intuition.h> 06 07 struct Library *IntuitionBase = NULL; 08 struct IntuitionIFace *IIntuition = NULL; 09 10 struct Screen *my_screen = NULL; 11 12 /* Declare and initialize our screen structure */ 13 struct NewScreen my_new_screen= 14 { 15 0, /* LeftEdge */ 16 0, /* TopEdge */ 17 320, /* Width */ 18 200, /* Height */ 19 3, /* Depth */ 20 0, /* DetailPen */ 21 1, /* BlockPen */ 22 CUSTOMSCREEN, /* Type of screen */ 23 SPRITES, /* ViewModes option */ 24 NULL, /* Font option */ 25 NULL, /* Title of the screen */ 26 NULL /* Gadgets option */ 27 }; 28 29 int main (void) 30 { 31 32 /* Opening the Intuition Library */ 33 IntuitionBase = IExec->OpenLibrary("intuition.library", 50L); 34 35 /* Could we open the Intuition Library? */ 36 if (IntuitionBase != NULL) 37 { 38 39 /* Open the Intuition Interface */ 40 IIntuition = (struct IntuitionIFace *) IExec->GetInterface (IntuitionBase, "main", 1, NULL); 41 42 /* Did we get the Intuition Interface? */ 43 if (IIntuition != NULL) 44 { 45 my_screen = IIntuition->OpenScreen(&my_new_screen); 46 47 if (my_screen !=NULL) 48 { 49 50 /* If the screen is still open we need to close it */ 51 IIntuition->CloseScreen(my_screen); 52 } 53 54 /* We could not open our screen */ 56 else 57 { 58 printf ("Unable to open our screen!\n"); 59 } 60 61 /* If the Intuition Library Interface is open, close it */ 62 IExec->DropInterface((struct Interface *)IIntuition); 63 } 64 65 /* We could not open the Intuition Library Interface */ 66 else 67 { 68 printf ("Unable to open the Intuition Library Interface!\n"); 69 } 70 71 /* If the Intuition Library is open, close it */ 72 IExec->CloseLibrary(IntuitionBase); 73 } 74 75 /* We could not open the Intuition Library */ 76 else 77 { 78 printf ("Unable to open the Intuition Library!\n"); 79 } 80 81 return 0; 82 }
When you compile the code and run it you will see it flashes a black screen for just a second. This is because we have not instruct our little example to do anything with our screen. We will do a lot more in the coming articles regarding screens.
Let’s analyse the source code.
10 struct Screen *my_screen = NULL;
Line 10 will set up a pointer called “my_screen” which will hold our screen structure. In other words if we open our screen successfully we will store the screens info in the “my_screen” pointer. We are going to use this to make our screen do things. To put it simple; every time we want to do things with our screen we need to refer to which screen we would like to use which means we will refer to “my_screen”. If my wife asks me to get a certain pair of shoes she will always refer to one of the 200 boxes she has. Without this info I would not be able to know what to do and shout some error codes.
12 struct NewScreen my_new_screen =
14 {
15 0, /* LeftEdge */
16 0, /* TopEdge */
17 320, /* Width */
18 200, /* Height */
19 3, /* Depth */
20 0, /* DetailPen */
21 1, /* BlockPen */
22 CUSTOMSCREEN, /* Type of screen */
23 SPRITES, /* ViewModes option */
24 NULL, /* Font option */
25 NULL, /* Title of the screen */
26 NULL /* Gadgets option */
27 };
Line 12 till 27 will define our screens parameters. Here we will define for example the width and height of our screen. For the moment we will not pay much attention to this. Going in to depth on this might just scare you away. Our screen will be of the type CUSTOMSCREEN and the width is 320 and the height is 200 is all you need to know at this stage. The width and height speaks for itself and a CUSTOMSCREEN means that we control how it looks, talks and breaths. In order words we decide the width, hight, colours etc.
45 my_screen = IIntuition->OpenScreen(&my_new_screen);
Line 45 will open our screen and store the info in our “my_screen” pointer. The part “(&my_new_screen)” tells the system how our screen should look like.
47 if (my_screen !=NULL)
48 {
Line 47-48 will check if we managed to open the screen. If not the program will jump to line 55-58 and display the message that the screen could not be opened.
51 IIntuition->CloseScreen(my_screen);
Line 51 will close our screen once we are done. Remember I was talking about the fact that we would use our “my_screen” pointer every time we would do something with our screen? Here we are closing our screen and referring to which screen we would like to close. In other words my wife asked me to put her pair of shoes back in box number 145. Next time we will actually keep our screen open until we decide it should be closed. Happy coding!
The idea for this article came from a posting from Hans de Ruiter over at OS4Coding.net in which he wanted to know how you could identify your machine. He talked about the function GetMachineInfo() from the expansion library that could do this. With that info I set out to create some code that would do exactly that; identifying our machine. Unfortunately the GetMachineInfo() function is not that detailed when it comes to identifying your machine. It can identify the below machines:
MACHINETYPE_UNKNOWN – Unknown hardware
MACHINETYPE_BLIZZARDPPC – BlizzardPPC in an A1200
MACHINETYPE_CYBERSTORMPPC – CyberStorm PPC in an A3000/A4000
MACHINETYPE_AMIGAONE – any AmigaOne model (including XE, SE, MicroA1 or XC).
The problem lies in the AmigaOne identifier since it will only report back “AmigaOne” and not if it is a XE, SE, MicroA1 or XC. I will do some more digging into this to see if there is way to determine what exact model of AmigaOne it is. For now this example will demonstrate some new programming code and get you to extend your knowledge. Let’s have a look at the code.
01 #include <stdio.h>
02 #include <expansion/expansion.h>
03
04 #include <proto/exec.h>
05 #include <proto/expansion.h>
06
07 struct Library *ExpansionBase = NULL;
08
09 struct ExpansionIFace *IExpansion = NULL;
10
11 int main (void)
12
13 {
14
15 /* Opening the Expansion Library */
16 ExpansionBase = IExec->OpenLibrary(“expansion.library“, 50L);
17
18 /* Did we manage to open the Expansion Library? */
19 if (ExpansionBase != NULL)
20 {
21
22 printf (“We opened the Expansion Library!!\n”);
23
24 /* Open the Expansion Interface */
25 IExpansion = (struct ExpansionIFace *) IExec->GetInterface (ExpansionBase, “main“, 1, NULL);
26
27 /* Did we get the Expansion Interface? */
28 if (IExpansion != NULL)
29 {
30
31 printf (“We did get the Expansion Interface!!\n”);
32
33 STRPTR machine;
34
35 IExpansion->GetMachineInfoTags(GMIT_MachineString, &machine, TAG_END);
36
37 printf(“Blimey! Your model = ‘%s’\n”, machine);
38
39 /* If the Expansion Library Interface is open, close it */
40 IExec->DropInterface((struct Interface *)IExpansion);
41 }
42
43 /* We could not open the Expension Library Interface */
44 else
45 {
46
47 printf (“Unable to open the Expansion Library Interface!\n”);
48 }
49
50 /* If the Expansion Library is open, close it */
51 IExec->CloseLibrary(ExpansionBase);
52 }
53
54 /* We could not open the Expansion Library */
55 else
56 {
57
58 printf (“Unable to open the Expansion Library!\n”);
59 }
60
61 return 0;
62 }
If we compile our program and run it from the shell we will get the below output.
As you can see I still add the code of printing if you managed to open a library or get the interface. You can leave that out if you wish.
The only strange piece of code on the block is:
02 #include <expansion/expansion.h>
05 #include <proto/expansion.h>
33 STRPTR machine;
34
35 IExpansion->GetMachineInfoTags(GMIT_MachineString, &machine, TAG_END);
36
37 printf(“Blimey! Your model = ‘%s’\n”, machine);
Line 02 and 05 will add some includes so that we can use the Expansion base library functions in our program. Line 33 till 37 is the code that will actually perform our little magic trick.
The AutoDocs from the SDK describe GMIT_MachineString as:
GMIT_MachineString (STRPTR *) — Machine model as a human-readable string.
GMIT_MachineString is part of the GetMachineInfoTags function. We use IExpansion-> to call upon GetMachineInfoTags. The value returned by GMIT_MachineString is stored in “machine”. We have set-up “machine” on line 33 which sets up “machine” as a string pointer. In line 35 the & sign will store the value as a string pointer. And at line 37 we are printing the value of “machine” which is in this case AmigaOne.
This example also shows one of the difficult parts of programming on the Amiga OS; trying to understand the AutoDocs which describes all the functions. At least for me this is the case. It does describe all the functions but not really how to use them. Well in some cases they do provide some examples but mostly it just mentions all the functions which make almost no sense. It certainly would scare some new programmers away since they might become frustrated in not understanding it. I will try to address the AutoDocs in some future articles to make it easier to understand and at some point make it possible to actually read and understand them yourself. Till next time and happy coding!
In the previous article I mentioned how you can skip all that opening and checking of libraries and interfaces. Let’s say we want to display a window displaying some text. Instead of writing the code I just write that we are going to open a window and display some text at the correct place in our code. Let’s have a look at the code.
01 #include <stdio.h>
02 #include <intuition/intuition.h>
03
04 #include <proto/intuition.h>
05 #include <proto/exec.h>
06
07 struct Library *IntuitionBase = NULL;
08
09 struct IntuitionIFace *IIntuition = NULL;
10
11 int main (void)
12
13 {
14
15 /* Opening the Intuition Library */
16 IntuitionBase = IExec->OpenLibrary(“intuition.library”, 50L);
17
18 /* Did we manage to open the Intuition Library? */
19 if (IntuitionBase != NULL)
20 {
21
22 printf (“We opened the Intuition Library!!\n”);
23
24 /* Open the Intuition Interface */
25 IIntuition = (struct IntuitionIFace *) IExec->GetInterface (IntuitionBase, “main”, 1, NULL);
26
27 /* Did we get the Intuition Interface? */
28 if (IIntuition != NULL)
29 {
30
31 printf (“We did get the Intuition Interface!!\n”);
32 — Display a small window with some text —
33 /* If the Intuition Library Interface is open, close it */
34 IExec->DropInterface((struct Interface *)IIntuition);
35 }
36
37 /* We could not open the Intuition Library Interface */
38 else
39 {
40
41 printf (“Unable to open the Intuition Library Interface!\n”);
42 }
43
44 /* If the Intuition Library is open, close it */
45 IExec->CloseLibrary(IntuitionBase);
46 }
47
48 /* We could not open the Intuition Library */
49 else
50 {
51
52 printf (“Unable to open the Intuition Library!\n”);
53 }
54
55 return 0;
56 }
The code is the same as in the previous article with the exception of line 32 which mentions our window that will display some text. Now we are going to rewrite the code leaving all the opening checking of libraries and interfaces out.
01 #include <stdio.h>
02 #include <intuition/intuition.h>
03
04 #include <proto/intuition.h>
05 #include <proto/exec.h>
06
07 struct Library *IntuitionBase = NULL;
08
09 struct IntuitionIFace *IIntuition = NULL;
10
11 int main (void)
12
13 {
14
15 — Display a small window with some text —
16
17 return 0;
18 }
Wow! What a difference, right? You might ask yourself how will this work? Skipping the checking if the libraries and interfaces if they are opened successfully might work but we can’t use the functions without opening the libraries and interfaces, right? Correct. The way this is going to work is how we will compile this code. With our previous example we compiled it with typing “gcc openlibraryos4.c”. For our new example to work we are going to add something to this. To compile this example successfully we type typing “gcc openlibraryos4.c -lauto”. By adding “-lauto” we are going to make use of the libauto library who can automatically open a number of system libraries and also set up their interface pointers.
I always did everything myself till recently when I started to use libauto. But just a short while ago I found out it is not the best way to go. If you read Trixie’s article Recommended Practice in OS4 ReAction Programming at OS4Coding he is talking about not using libauto.
2.3 The Autoinit
Quite a few ReAction examples are linked agains libauto, which performs automatic initialization of system libraries, including ReAction classes. The autoinit is comfortable in that it saves time and makes the code shorter. However, you should not rely on libauto in developing your own software. First, you have much better control over things when opening the resources yourself. Second, libauto opens ReAction classes using OpenLibrary(), which is another Don’t to be mentioned:2.4 OpenLibrary() for classes
ReAction classes are implemented as system libraries so traditionally they were supposed to be opened using the Exec function OpenLibrary(). This is not the case any more. OS4 has introduced a new function in Intuition, OpenClass(), which returns the class library base as well as something called the class pointer. The class pointer has actually been around since the beginning of BOOPSI but if you have been using the ReAction macros (see above), chances are you have not even noticed that there is such a thing. As the class pointer is highly relevant for OS4-compliant ReAction programming, it will be dealt with later on.
Since ReAction is going to be part of our coding almost every time we better follow Trixie’s advise. I have not heard anyone else comment on this who favours libauto in combination with ReAction. Trixie’s article about ReAction was the first one of it’s kind. I would love to see some more feedback on this. Till next time and happy coding!