Diary of an Amiga fanatic

Tag Archives: Amiga C programming

I did manage to locate the bug that made my code crash. If you remember my previous posting you know how much that bug haunted me. The declaration “Object *winObj” was the one that caused it. By changing it to  “Object *winObj = NULL” I solved it. If you follow The Bucket Programming Corner you might remember me talking about setting pointers to NULL. I see a lot of ReAction examples which do not set this to NULL. Since it solved it for me and I can’t find any other info on this I will just leave the statement as it is.

Home free right? Not exactly. After solving this one I ran into another one that seems to be even worse. My window displays but when I click to close it nothing happens. After running some tests it seems the code never reaches the part that checks if the window needs to be closed. After staring at it till my eyes hurt and compare it to several examples I still have not found the bug and I decided I need some outside help. So I posted my problem over at OS4Coding for some outside help. Let’s hope I find it soon so I can continue.

Advertisements

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!


It is December which means Christmas is almost near. Which Amiga fan does not have happy memories about the Christmas period and the other winter months using their Amiga? I certainly do. I usually was still playing games on my Amiga while the Christmas dinner already started. One example was Cannon Fodder. Just five more minutes mum.

The famous Cannon Fodder title screen

Level 1 Cannon Fodder

Another only playing it during the holiday season game was Home Alone. Personally I don’t rate this game very high but because you usually watch the film you want to have a go at it yourself. It is more of a nostalgic feeling if you ask me.

Home Alone

Home Alone (time to set the traps)

The winter months are always a good time to play Amiga games and if you are in to it programming. And let’s not forget the Amiga demos. There are plenty of Amiga Christmas demos / intro’s out there. Another category are the disk magazines. Besides the paper magazines they provided another source of information.

Currently I am working on a top games list for Amiga games. My problem is that I can never come up with a permanent list. Once I would make one I would change my mind again at a later time. So I came up with variable top games list. It will change over time depending on various factors. For example I might play a game a lot and because of this it would go up in the list. Or a certain game I remember being really great is rather disappointing playing it after so many years.

I have also started work on the next article for The Bucket Programming Corner. This time it is about screens. I don’t have any experience with screens on the Amiga using the C programming language. Remember how easy it was in Amos? Well after reading the article you will also see that it is easy in C as well. The only difference is that we just need to type more code. My goal is to release the article this coming week.


The first thing that fascinated me when I tried programming for the Amiga were the libraries. The first language I used to open and close libraries and use it’s functions was Assembler. At that time it took me some time to understand how libraries worked. This was because of the available information I had. Even today when I look at some of that information I can see that the way it was explained was just too difficult. Would it have been done easier it would have been quicker for me to get to grips with it. The only source of information you had was the magazines and the odd programming book you might be able to purchase. Not like today when you have the internet which gives you access to unlimited resources.

But what are those libraries you keep talking about? The ROM Kernel Manual describes it as follow:

The Amiga has two kinds of libraries: run-time libraries and link libraries. Run-time libraries make up most of the Amiga’s operating system. There is another type of library known as a link library. Even though a link library is a collection of functions just like a run-time library, there are some major differences in the two types.

Run-time libraries
A run-time, or shared library is a group of functions managed by Exec that resides either in ROM or on disk (in the LIBS: directory). A run-time library must be opened before it can be used. The functions in a run-time library are accessed dynamically at run-time and can be used by many programs at once even though only one copy of the library is in memory. A disk based run-time library is loaded into memory only if requested by a program and can be automatically flushed from memory when no longer needed.

Link libraries
A link library is a group of functions on disk that are managed by the compiler at link time. Link libraries do not have to be opened before they are used, instead you must link your code with the library when you compile a program. The functions in a link library are actually copied into every program that uses them.

To sum it up in a simple way: Run-time libraries stored on the hard drive and are opened and closed by the program whenever needed. Link libraries are (actually it’s functions) copied into your program when you are compiling it.

I am discussing the run-time libraries here. I assume you have some understanding of the basics of C programming. If something is not clear (and in future articles) just let me know and I will explain it. Don”t worry if at first it, or something, makes no sense. Sooner or later the penny will drop and it suddenly makes sense.

So what are we going to do for a first example? We are going to open the Intuition library and check if it is opened successfully or not and in both cases display a message. 

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
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 }

Type the above code (without the line numbers) in the text editor of your choice or IDE you might use. As you can see in the below screenshot I saved it in the “RAM Disk” with the name “openlibraryos4.c”. Assuming you have installed the OS4 SDK you can compile the code by typing “gcc openlibraryos4.c” in the AmigaShell as shown in the below sceenshot. This will produce the executable with the name “a.out”. If things go as planned you will get the correct out put saying that both the Intuition library and interface could be opened when executing “a.out”.

Compiling our code

Congratulations! You just compiled your first working OS4 code. Cool! But of course you like to know what all the code is about. Time to have a look at the source code.

The first 4 lines of code are includes.

01 #include <stdio.h>
02 #include <intuition/intuition.h>
04 #include <proto/intuition.h>
05 #include <proto/exec.h>

“#include” is a preprocessor directive which sounds rather difficult but it is not. It inserts another file into our code. Take for example the <stdio.h> file which includes information regarding the printf statement we are using. The intuition includes for example contain information if you want to display a window. For a simple example as this we don’t need so much includes to get our work done but if you create a larger program you will have more includes to (pardon the pun) include. I usually have a standard set of includes I use even if not all of them are being used. You might get errors during compiling because your code uses a function for which you did not use a include. This might sound rather complicated but after some trial and error from your side it will suddenly make sense.

Before we go to our next two lines a bit of further explanation about libraries is needed. I won’t get to technical but address just enough for you to understand the concept. With the classic Amiga OS you just opened the library you wanted and that was it. With OS4 we also need to use something called a “interface”. With the classic way you open the library and you can use any function from that library. With OS4 we have the interface which sits between the library and the functions it has. Let’s say we want to use a function from the intuition library we use the interface to call/use that function. You can compare it with talking to your wife. The old way would be to directly ask her a question. With the new way we use another person to ask our wife that question. This seems like a great idea (the wife example) but is this not adding extra work (and not to forget make it more difficult) when writing our code? Not really. It is just adding the name of the interface in front of the function. But what about the extra code for getting the interface and check we got it and also close it again? Well (getting ahead now) this is something I will address in part 2 in which you will see we can skip all that opening, checking and closing. Curious? Good!

But why use that interface stuff? Well that has to do with compatibility with the classic software. There is a lot more to it but without scaring you too much we will leave it at this. Let’s have a look at the next two lines.

07 struct Library *IntuitionBase = NULL;
09 struct IntuitionIFace *IIntuition = NULL;

This is usually the part you loose it all. Includes I can follow but this? The two lines declare pointers to structures we need to open the intuition library and also the intuition interface. These structures are actually defined in the <intuition.h> file. When we open the intuition library and get the interface we need to store the value we get back from trying to open them. We can use those values to test if we succeeded in opening both library and interface. We need to set both pointers to zero (NULL) to make sure they don’t point to any random address in memory which might cause the whole system to crash. *IntuitionBase is going to hold the value we get back from trying to open the intuition library and *IIntuition is going to hold the value we get back from trying to open the Intuition interface.

The next line is the start of our program. All programs start with main. To get a better understanding of how C works (it can’t hurt to mention this again) I suggest you check out the Amiga C Programming Tutorial from Michael Ness.

11  int main (void)

The next line is going to (try) open the Intuition Library.

16  IntuitionBase = IExec->OpenLibrary(“intuition.library”, 50L);

Some of you might have spotted the “IExec” part in front of OpenLibrary. This is the interface of the Exec Library. Wait! Stop! Are we not suppose to open this first, including the Exec Library, like we are doing with the Intuition Library? We don’t have to. The Exec Library is always open when OS4 (also with the classic OS) is running. In this case we want to open version 50 or later of the Intuition Library.

Line 19 is going to check if we managed to open the Intuition Library. Since we set the IntuitionBase in the beginning of our program to NULL we know we succeeded if the value of IntuitionBase is not NULL.

19   if (IntuitionBase != NULL)

If we managed to open the Intuition Library our program is going to jump to line 22 and print on our screen that we succeeded in opening the library.

22     printf (“We opened the Intuition Library!!\n”);

If we failed to open the intuition Library the value would still be NULL. If this is the case our program is going to jump to lines 49 – 53.

49    else
50   {
51
52  printf (“Unable to open the Intuition Library!\n”);
53  }

Line 52 will print on our screen that we did not manage to open the intuition Library.

If we successfully opened the Intuition Library and also printed on the screen we did we need to get the interface of the Intuition Library.

25     IIntuition = (struct IntuitionIFace *) IExec->GetInterface (IntuitionBase, “main”, 1, NULL);

Line 25 is trying to get Intuition’s Interface. The value that is being returned after we are trying to get the interface will be stored in IIntuition. IExec->GetInterface  is the function that will try and get the interface of the Intuition Library. Looking at the part (IntuitionBase, “main”, 1, NULL); we can see that we are trying to get the Interface of the (IntuitionBase) Intuition Library. Looking further at (IntuitionBase, “main”, 1, NULL); we can see that we are trying to get the main interface and the version number is 1. The last parameter (NULL) is a pointer to a tag list which we won’t discuss here. 

What about the (struct IntuitionIFace *) part? Without getting to technical (and loose you all) I can tell you this is called a cast. It will make sure the value returned by IExec->GetInterface is of the type struct IntuitionIFace *.

After we tried to get the Interface we need to check if we are successful.

28      if (IIntuition != NULL)

Line 28 (just like line 19 when we checked if we managed to open the Intuition Library) will check if we got the Interface by checking if the value if IIntuition is not NULL.

If we did manage to get the Interface we will print this as we can see in line 31.

31        printf (“We did get the Intuition Interface!!\n”);

If we failed to get the Interface the program will jump to lines 38-42.

38     else
39    {
40
41    printf (“Unable to open the Intuition Library Interface!\n”);
42    }

Line 42 will print that we did not manage to get the Intuition Library Interface.

If we did manage to open the Intuition Library and get it’s Interface (and of course print it on our screen) we need to end our program which means we need to clean up. The golden rule is to close everything that you open. First part of the clean up starts at line 34.

34       IExec->DropInterface((struct Interface *)IIntuition);

First up we are going to drop the Interface of the Intuition Library. The function DropInterface speaks for itself.

Last part of the clean up starts at line 45. We need to close the Intuition Library.

45   IExec->CloseLibrary(IntuitionBase);

Our program ends at line 55.

55 return 0;

Return can be used to return error codes but we give it the value zero to keep everyone happy. Surely I don’t want to scare (if anyone is still left) what is left of our readers at the very end. That’s it! As I already mentioned earlier in part 2 I will show you how you can skip all that opening and checking of libraries and interfaces.

Happy programming!


A lot of people would love to program on the Amiga but won’t, or try but quit right away because it “seems” to be difficult. It certainly is not difficult but it can be made looking difficult. I have read plenty of tutorials and seen so called example code which made me run away and throw in the towel. But after reading and studying them over and over again I started to understand some bits and pieces. It was not me that just did not get it but the way it was explained or presented. If done differently I would have understood it much earlier. Another issue I always come across is that how come my code to do a certain task is looking differently compared to someone else’s code? There are “1000 ways” of doing a certain task and you just have to pick the one you feel comfortable with. I have been trying to get it exactly like the other(s) programmer(s) for too long. Even changing my code after I created it to look more like theirs. But now I stick to my way even if my code is different. But sometimes you actually pick up some new ideas by looking at other code so certainly don’t stop looking at other code.

Why am I writing these tutorials? By writing it I hope people start getting back into programming after giving up at first. Or maybe you always wanted to start but never did. Make sure you don’t get stuck at hurdles I had a lot of trouble getting by and which might make you want to stop. Also the fact that there is a serious lack of programming information out there. Remember to never give up if you hit a rough spot in your programming journey. Just step away from it for short moment and dive back in it again and you will see you will get by that hurdle. Another valuable asset is having a mentor. Someone you can contact when you just don’t get a certain part and who can explain it to you in a simple way and make you understand and continue with your journey. There is no greater feeling when you suddenly start to understand a topic you never could before. I still experience this often and many more will come.

If you have suggestions or need help please let me know. I would love to get feedback on my tutorials or if you have some suggestions regarding topics I could discuss please let me know. If you are an experienced Amiga programmer and happen to read the tutorials and see errors or have a better suggestion on how to do certain tasks please let me also know. I am also still learning so I am always open for feedback. Some topics I might discuss would also be new to me so I am bound to make an error or two somewhere down the line.

For starters I suggest you have a look at “Start programming – The totally free way” at OS4 Coding

It is an introduction to programming on OS4 emphasizing on the “free” part. It talks about Codebench as the (free) integrated development environment (IDE). Unfortunately Codebench needs AmigaOS 4.1 Update 1 or later and since I have OS4 running I am unable to use this.

Another free editor with syntax highlighting is Annotate. It works on AmigaOS 3.x, AmigaOS 4.x, MorphOS 1.x and AROS.

I use Cubic IDE  from Dietmar Eilert myself. It is not free and currently it costs Euro 49,90. There are special discount sales often which allows you to buy it at a discounted price. Usually around Easter and Christmas Dietmar sells it at a discount price. I am really happy with Cubic IDE and also the support from Dietmar. Every time I needed some help he was really quick to reply with the solution.

You would have to do some extra work to get the Amiga OS4 SDK to work with Cubic IDE. Trixie wrote a tutorial on how to get the latest OS4 SDK to work with Cubic IDE. SDK stands for Software Development Kit. The Amiga OS4 SDK contains everything developers need to take advantage of all the new AmigaOS 4.1 features including updated includes and autodocs.

To sum it up you will need the below to start programming on Amiga Os4:

– The Amiga OS4 SDK (Software Development Kit)
– Editor which can be a simple text editor with or without syntax highlighting or a IDE package (Integrated Development Environment) which contains a editor and various other tools

In this series of tutorials I am not going to teach the basics of the language C. There are other sources that are doing a great job on teaching you this. So instead of teaching the basics of C we start right away with programming on OS4. For me one of the best books that taught me programming in C is Sams’ Teach Yourself C in 24 hours from Tony Zhang. I would suggest you also check out the Amiga C Programming Tutorial from Michael Ness. I should say this is a must that you read this tutorial. Some of my first information can also be found in Mike’s tutorial but we will dive further into OS4. Till next time when I show you how deep the rabbit hole goes.


First thing I did when I arrived in Lampang (Thailand) was to check the book case for all my books I left behind when we moved to Holland. And to my surprise there it was; the Amos Professional User Guide. I can’t believe I left it behind in Thailand. When we moved I was working on some Amos related stuff for which I would require the manual. So what made me leave it here? I really can’t remember why I left it here. Besides the manual there was a lot more great stuff I left behind. There was the “Mastering Amiga Amos” book from Phil South. And also the “Mastering Amiga C” book from Paul Overaa. I also discovered the Amos Club Holland Newsletter 1, 2 and 3. And there was also the “Amos PD Catalogue November 1990”. I just had another look at the book case and I discovered my original “Amos the Creator” manual. I had an old 1.2 version of the manual in Holland which I bought, together with a lot of other Amos stuff, from another user some time ago. I already search for this manual for some time for which I was sure it was in Holland. Talking about a discovery of great significance.

I have some other books I left behind which range from the Microsoft history to Netscape and other computer related books. But my greatest love, and holy bible, is the book “Fire in the Valley – The Making of the Personal Computer” from Paul Freiberger and Michael Swaine. This is something I will save for back in Holland and reserve some time and piece for it each time I want to read it. I want to savour every page of that book once I read it again. I really recommend you to go out and purchase this book as this is a classic and great read. If you are like me and love the history about computers, especially the start of it, you will love this book. It tells you everything about the golden days of computers.

I started to read “Mastering Amiga C” and noticed (probably the reason I left it here) that the Amiga has a very small role to play in it. It does talk a great deal about the Amiga C compilers but when it comes too actually programming in C on the Amiga there is not much information. It mostly discussed C in general. There are better books out there that will teach you the skills of programming in C. None the less the Amiga info in the book is of valuable to anyone. I could have a lengthy blog posting about the lack of good programming information for Amiga OS4 but I better save it for another time.

Enjoy some pictures of my discovered treasures.