Beginner's Guide to WIMP Programming
Everything you need to know to start writing your own applications.
Chapter 2: Our New Directory
You will be aware from using your computer that each RISC OS software application is represented in a Filer directory window by an icon with an appropriate small picture and a name beginning with a pling (!) character. Each application is, in fact, a directory containing all the files that the application needs. Its name begins with a '!' to distinguish it from ordinary directories.
To see inside an ordinary directory, you double-click the mouse on its icon. If you double-click on an application directory, of course, you will run the application instead. To see inside an application directory, hold down Shift while you do the double-click. A directory window will open in the usual way, and you will be able to see the files inside. Try it on any application you like.
There will almost certainly be files called '!Run', '!RunImage' and '!Sprites', and most probably one called '!Boot' as well. There may be other files, connected with the particular application, but these need not concern us, except for the 'Templates' file, which we shall come to later.
This does not apply to applications such as Draw, Paint, Edit and other applications which come on the machine's ROM in some versions of RISC OS. These applications do not have !RunImage files, and their sprite files are stored elsewhere.
The four most common files found within an application directory
The !Boot and !Run files have a filetype called 'Obey'. You can see the contents of an Obey file by starting up your text editor then dragging the file icon to its icon on the icon bar. Alternatively, if you are using RISC OS 3 or later, you can simply hold down Shift while you double-click on the icon in order to load it into your text editor.
Obey files contain commands that are sent to the operating system. If you typed these commands yourself, you would precede each one with a '*', which is why they are frequently known as 'star commands'. From the desktop, you can get the '*' prompt by pressing F12.
Our application will probably not need a !Boot file. This file is run automatically when the parent directory window which contains the application directory is first opened, and usually contains commands for setting system variables and loading the !Sprites file. It is most useful where the application uses files of a particular type, such as a word processor. The machine has only to 'see' the application to know how to handle its files, which may be in another directory altogether. It can then represent them by the appropriate icon, and even start up the word processor application and load the file into it when you double-click on the file icon.
This is not getting us started, however, so let's get going with our application.
The Start of an ApplicationFirst, you need a directory and a name. We're testing our ability to program, so let's call our application 'Test'. If you can think of a better name, feel free to use it, but you'll have to watch out for '!Test' throughout the listings, and change it to your own name. Modern versions of RISC OS can handle long filenames; however, it's a very good idea to restrict application names to 10 characters, including the '!' at the beginning, in order to maintain compatibility with older versions and to avoid problems. In particular, sprite names are still restricted to 12 characters, and since the 'sm' prefix (used for small icons) uses up two characters, only 10-character names can be used for application sprites.
Open a window on the directory where you want to write your application and click Menu on it, then choose the New directory submenu and type in '!Test'. Your new application directory will appear in the window, represented by the generic RISC OS 'Application' icon.
Clearly, we need our own sprite to represent our application properly, both in the filing system window and on the icon bar, so we will design one using Paint.
The standard size for a sprite in a Filer window is 68 graphics units square. It's common RISC OS practice now for an application to contain two sprites files: one for rectangular-pixel screen modes, and one for the square-pixel modes which are now more commonly used. Some applications may have a third file containing monochrome sprites for use in two-colour modes. There should always be a file called !Sprites, containing one or more sprites for a rectangular pixel mode, such as mode 12. In this mode the main sprite will be 34 pixels wide by 17 high. There will usually be a second file, !Sprites22, containing square-pixel sprites of 34 × 34 pixels, and there may be a file called !Sprites23 containing monochrome sprites of the same dimensions. RISC OS selects the appropriate file automatically, depending on which mode the screen is in.
If you are stuck for an idea, you could always draw a simple filled circle. Give the sprite a mask and also give it the same name as your application ('!test' in our example). Note that sprite names are always lower case.
... you could always draw a simple filled circle
To save the sprite file, open your new application directory by holding down Shift and double-clicking Select. Then name the file '!Sprites' and drag it to the application directory. If you close the parent directory containing your application and open it again, you will see that the application is now represented by your new sprite.
You can click Menu on the Filer window, choose Display, then either Small icons or Full info to see what your new sprite looks like at half size. If you are not satisfied with its appearance, you can add a special half-size sprite. Load your !Sprites file into Paint again and create a new sprite called 'sm!test'. This one needs to measure 18 by 9 pixels. Remember to resave the file.
Your application will work satisfactorily in any desktop screen mode with just the !Sprites file, but you may wish to make it look smarter on-screen by having the correct sprites for any screen mode. Try creating a !Sprites22 file, containing the same sprites with the same names as before, but with square pixels. This time, the main application sprite should measure 34 × 34 pixels. If you create a small version, it should measure 18 × 18 pixels. The sprites themselves should still be called '!test' and 'sm!test' in each file.
If you try to run your new application, you will get an error message saying something like 'File '!Test.!Run' not found'. The operating system tried to run the application, starting with a file called !Run, and, of course, it couldn't find it because we haven't created it yet. That is our next step.
Load up your text editor and set it to create a new Obey file. A window will appear, into which you can type the following:
|Run file for !Test Set Test$Dir <Obey$Dir> IconSprites <Test$Dir>.!Sprites WimpSlot -min 32k -max 32k Run <Test$Dir>.!RunImage
When RISC OS runs this file, it will follow the instruction in each line in turn, as though you had typed it in at the star prompt.
The first line is a comment, which you can leave out or modify if you wish. It begins with the '|' character, which is on the shifted backslash key.
You may like to include the date, as a lot of applications do, to show when you created this particular version.
The second line sets up a system variable which will contain the name of your application directory, including the directory path leading up to it. RISC OS system variables always seem to have a '$' character somewhere in the middle, and we may as well stick to convention so we'll call our variable Test$Dir. We set it up by giving it the same contents as another system variable called Obey$Dir. Every time the system runs an Obey file, Obey$Dir is set to the full pathname of the directory containing the file being run. Because your !Run file is an Obey file, Obey$Dir will contain the pathname of your application directory.
When the operating system sees a system variable inside '<>' brackets, it replaces it in the string with the variable's actual contents. As a result, '<Obey$Dir>' is replaced by the pathname of your application directory, and that is what ends up in Test$Dir.
You can see all the system variables listed by typing '*Show'. Obey$Dir will show the pathname of the directory containing the last Obey file that you ran.
It is not always necessary to have our own system variable. We could probably do the rest of the operation using Obey$Dir to find the files we want. It might be useful, however, just in case our application wants, say, to open a file at a later stage. Before you do this, you might have run another Obey file elsewhere, which would have changed the contents of Obey$Dir.
In order to be able to use our application's sprite on the icon bar, it needs to be loaded into the Wimp sprite area. The IconSprites command does this for us. Although the command specifies the filename '!Sprites', the system will actually look for '!Sprites22' if the screen is in a square-pixel colour mode or '!Sprites23' if it's in a square-pixel monochrome mode, and the !Sprites file will only be loaded if these preferable alternative files cannot be found.
Some modern applications may also include different sets of sprites that are loaded according to the version of RISC OS in use, because the style of presentation of common icons, such as filetype icons, varies quite a lot between different versions of RISC OS. Therefore, it is not uncommon to find '4Sprites' and '4Sprites22' files for use by RISC OS 4, and '5Sprites' and '5Sprites22' for RISC OS 5 (and sometimes other variations), in addition to the standard set of '!Sprites' files. However, applications must make their own special provisions for loading such extra sets of files, as they are not handled automatically by RISC OS itself. We will therefore not discuss them further in this guide.
Setting the Memory LimitsIf you look at the Task Manager window, you will probably see that a sizeable chunk of the free memory is allocated to the next application to be started up, usually 640K. If we simply start our application by running the !RunImage file, it will grab all of this memory, even though it doesn't need it, leaving considerably less for any other applications we may want to run. This is what our one-line application in the previous section did. To avoid this happening, we use the WimpSlot command. In our example we are instructing the system to allocate 32K to our program, which should be ample. If, at a later stage, you start getting error messages suggesting you are running out of memory, such as 'No room for DIM', you can always edit the !Run file and change this figure.
Note, by the way, that the memory controller in older RISC OS computers allocates memory in blocks of 8K if you have 1 megabyte of RAM, 16K if you have 2Mb and 32K if you have 4Mb or more. More modern machines, from the Risc PC onwards, always uses 4K blocks. It is safest to set the figure in the WimpSlot command to be a multiple of 32K; this ensures that it will run on a machine with any block size.
The two suffixes, '-min 32k' and '-max 32k', between them set the memory that will be allocated to our task to 32K. If the 'next' amount of memory (as displayed against the 'Next' line in the Task Manager window) is less than this, the 'min' part of the command brings it up, and, if it is more, the 'max' part brings it down.
The final line runs the file containing the application's main program. By convention, this is normally called '!RunImage', and could be either a Basic or a machine code program.
When you have typed in the Obey file, give it the filename !Run and save it in your application directory. If you created the file properly, it should be represented by the 'Obey' file sprite. If not, change its filetype using the appropriate menu option in the Filer. If you try to run the application again, you will find, not surprisingly, that the error message has changed to 'File '!Test.!RunImage' not found', so, obviously, our next task is to write the main program.