The comp.sys.acorn Application Writer's GuideThe following document was taken from the usenet newsgroup comp.sources.acorn on 22nd June 1992
The comp.sys.acorn Application Writer's GuideThis guide contains a lot of small hints from some of the gurus on comp.sys.acorn. Most of them are pet hates - things that many applications do that really annoy us. When writing applications, please read through this list and check that your application conforms to as many as possible of the items...
Many of these things might seem complicated at first, but they are all very simple when you know what you are doing. All the information needed can be found in the Programmers Reference Manuals, or ask someone for some help!
This guide is kept by Jason Williams (firstname.lastname@example.org), so please email any new suggestions for the guide to him. Any suggestions made on comp.sys.acorn should also be caught and included...
"Public Domain"Public Domain means that everything in the application can be used, changed, copied, etc. exactly as the user wishes. They can even include portions of your application in their own (commercial) programs if they so wish.
Public Domain and Copyright are MUTUALLY EXCLUSIVE!
If you wish to place distribution conditions on your software, then call it FREEware, and clearly state your conditions. Using this term, you can also claim copyright on your software.
Legally, if you choose to use the term 'Public Domain', then you don't have a leg to stand on, even if you stated that the software was copyright, etc.
Icon sprites/Screen modesNever include additional sprites (eg your own definitions of system sprites) in the !Sprites file of your application.
Always include small icons as well as large ones in your sprite
Always include a !Sprites22 (Mode 20) and !Sprites23 (Mode 23) file as well as !Sprites (Mode 12) - even if you can't display multisync sprites on your monitor, you can still create & edit them provided you use at least 2x magnification.
Make sure all your sprites have a core RISC OS 2 ROM mode number (Sprites should be defined in mode 0, 12, 20, or 23). Be very careful about this if you start using screen snapshots to help you design sprites. Similarly make sure you remove the sprite's palette after doing a screen shot to create an icon.
Always try your !Sprites in MODEs 8 and 0 (4 and 2 colour) to make sure they don't disappear. Careful choice of colours will ensure they don't Similarly aways try !Sprites22 in MODEs 19 and 18 as well as Mode 20. Your !Sprites23 should look similar to your !Sprites22 in MODE 18, but some difference is reasonable since you can hand stipple !Sprites23 as they are for monochrome display only.
RUN your program in ALL screen modes you can lay your hands on. Do all your icons dissapear due to colourtransing in mode 0? Do your 256-colour icons go SPLAT in mode 12?
Does your code fall over in mode 66, 78, 120? (Not checking the size of the screen is a very common fault. DO NOT assume that the screen other people are using is identical to the one you use!
Get the size of the iconbar icon RIGHT! If in the program you declare the iconbar icon bounds as 0,0;68,68 then make the sprite you use 34x17 in mode 12/0 or 34x34 in mode 20/23! Try 'dabbing' at the edges of your icons with a window or menu and see if you can cause bits of the icon to be 'rubbed out' and not correctly redrawn.
Info windows like those used by BASS are pretty with all their sprites, but how much memory does this take? Place these sprites into a file we can edit (don't compact them in with the !RunImage), and preferably give an option that stops unnecessary sprites being loaded/displayed.
!Boot & !Run filesOnly include a !Boot file if it is absolutely necessary. Remember that other users may not appreciate an unnecessary !Boot file, particularly if they are Econet users.
If a !Boot file is missing, then the equivalent of
ALWAYS put an IconSprites <Obey$Dir>.!Sprites into your !Run file. If the application is launched with !Menon or similar, the sprites will not have been loaded by your app. dir. being 'seen'.
Suggestion: rather than having a !Run file which goes "Obey <foo$Dir>. !Boot", include the contents of the !Boot file in line in the !Run file. This way the application starts up quicker over Econet, as the !Boot file doesn't have to be loaded.
Never have anything (not even blank lines) after the "Run <foo$Dir>. !RunImage" in your !Run file, otherwise the !Run file stays open while your application is running and only gets closed when it quits.
Don't make your program auto-run in a !Boot file. If you want people to have the option of this, give them a file they can rename to !boot...
Help filesAlways include a !Help file. This should be a plain text file, and never one of these !Help applications which are springing up.
IF you MUST use a non-text !Help file, then use an Obey file that checks if the application your Helpfile needs is loaded, and reverts to just RUNning the text version of the help if the special application is not found.
Always call the help file '!Help', not 'ReadMe' or other names. This allows help to be offered on the filer menu.
Always include your name in the !Help file, as well as the application. You don't have to include your address, but without a name, it can be very difficult to identify pieces of software. DON'T include your name if you are re-releasing somebody else's work - passing off someone else's program as your own is bad, and could get you into a lot of trouble.
Always credit other people for any help/code they supplied you for your application.
A nice option is to check if your help file exists from within the application, and offer a 'help' option on your main menu, which simply RUNs the text file...
Always include an indication of the legal status of the software, and whether or not it may be freely distributed.
Other files/resourcesDon't put lots of subdirectories inside the application if it can be helped. People with hard drives typically lose 14k for each directory you bung in, which often wastes more space than the total size of a small PD application... :-(
Get all your resources with <App$Dir>.Name, where Name is the filename
of the resource, and App is the name of your application. Set this
variable (*Set App$Dir <Obey$Dir>) in your !Run file.
Alternatively do "*Set App$Path <Obey$Dir>." (note the trailing
period character) and reference files as App:Name. This only
works for reading though.
Preferably, use a SEPARATE variable for your config. files, so that someone else can easily move your config. data to a central place and then rename your variable to point there instead. This can allow your program to be run from read-only filing systems (e.g. on econet, etc)
Always use <Wimp$Scrap> and <Wimp$ScrapDir> for storing temporary files
in. Never store them inside your own application's directory. In this way
the user is free to put temporary files where he wants them, rather than
ending up with them spread over 4 different floppy discs with attendant
unecessary disc swapping. The disc with <Wimp$ScrapDir> on it is probably
already in the drive.
WindowsEven if you only have an info window, make sure you process OPENWINDOW requests, or your windows won't be movable.
Info windows that go away when you move the pointer out of them are *incredibly* annoying! Likewise, Info windows that limit the pointer (BASS!) are a hassle. (Especially in Protracker where the limit is a window *behind* the one you are looking at... I *hate* that!)
Always open windows as defined in the templates file. Reposition them if you like, but don't change their size! Some people have bigger screen modes than you and they like to have bigger windows when they are first opened!
Open windows centered in the *current* screen mode, or over a parent window. I hate windows appearing as squitty little things in the corner of large multisync modes. I also hate windows appearing off the top/side of mode 12...
Preferably, check the window position when things happen - if the window is fullsized, or if the screen mode changes, check if you need to 'bump' the window back onto the screen. At least the titlebar should be available so it can be dragged back onto the screen! Preferably also allow your windows to be dragged off the screen (This means if fullsize is clicked, you must ensure that the window doesn't get bigger than the current screen mode)
Window TemplatesIf you get memory for templates, DON'T trim down the allocated memory to the exact byte needed for *your* templates. Add a few hundred bytes so we can alter/add to templates without your program crashing. This is especially a good idea when you are only using half of the WIMPSLOT memory anyway... (Acorn, do you hear me? ;-)
If this is a big problem and you are supplying source, give a constant./variable that is easily found to change the allocation.
In RISC OS 3.00, there is a call to tell you how much memory is needed for your Templates to be loaded.
3-d 'plinthy' windows look nice. Some people don't think so, though, and it would be very nice if you supply two sets of templates, one for 3-d and one for 2-d icons.
Note that 'Interface' is incompatible with RISC OS 3.00's way of redrawing 3-d icons, so your application will look really crappy in RISC OS 3.00.
MenusPut your menu 96 OS units above the menu bar (40% of PD apps. fail this one, and it is a right pain!). The TOP menu item of your iconbar menu should be INFO, and the bottom one should be QUIT. This calculation is:
y = 96 + (number_of_items * 44) + (number_of_dotted_lines * 24)
Menu items should be 44 OS units high, and the item gap should be 0.
Don't put dangerous items next to innocuous one ins menus. A very bad example of brain-dead design lies over your floppy :0 drive icon - notice how dismount, format, verify, are all bunched together? How many times have *you* hit format instead of dismount?
FontsGo to the command-line. Type *FX25
If using outline fonts, AT LEAST put an easy to find option or variable that can be set to allocate enough room for the font menu... most people seem to make their programs to use their 5 fonts, and don't realise some people have around 300 fonts on their hard drives! It is in fact possible to count the number of available fonts, and allocate enough memory to read them all.
If replacing BFONT with an outline font, remember these points:
Filing systemsDon't leave files open.
Don't close open files with CLOSE#0 !!!
DON'T assume anything about the FS you are run from.
Don't set the CSD or library or alter any FS paths. Don't alter the current filing system.
If doing file operations in C, try using setvbuf. I found in CBAdecode that a 150% speed improvement resulted off floppies (using 16k buffers in place of OS 4k buffers), and seeking was drastically reduced on my hard drive.
ConfigurationIf your program alters the machine in any way (eg redefines system beep, or changes mouse pointer), make sure that they are restored when it finally terminates. Be especially careful to make this work when the program crashes! (And don't assume that it won't crash!)
Don't use *CONFIGURE commands in your applications. They are NOT needed for anything you should be doing.
Don't *UNPLUG modules you want to kill- *RMKILL them. Never include a *RMCLEAR command in your programs.
Make sure that your program doesn't use any unusual modules or screen modes, unless they are included with the application.
If you need to RMEnsure modules from !System, try to check for the earliest possible version which will work with your software.
If your program uses a module, make sure that if the module is RMCLEARed, the application will quit cleanly, rather than going into an infinite loop.
Make sure that the memory you ask for in the WimpSlot command in your !Run file is equal to the actual amount displayed in the task manager window when the program starts running. 4 Megabyte machine will give you 32kB of memory even if you only ask for 8kB, but a 1MB machine will only give you 8kB! This causes lots of programs to fail to run on 1/2MB machines.
Bearing the above in mind, trim down the WIMPSLOT size to a safe minimum.
MiscellaneaCTRL-Break your machine and then hold down SHIFT so it doesn't autoboot. THis should give you a reasonably 'clean' machine, with no strange modules, screen modes, etc. Does your program still run fine on this 'bare' machine?
If a program will not allow users to return to the desktop, display a warning giving them the chance to return to the desktop before the program starts running.
Use % in front of any *commands you use, and specify ALL options
e.g. "%wipe file ~v ~c r f"
Get a program that protects zero page and run it. Now run your application. If you get "Abort on data transfer" errors, you are writing to places you shouldn't.
When files are saved to you from another app., you first get a
DataSave message including a suggested leafname. REMEMBER THIS LEAFNAME. When
you subsequently get a <Wimp$Scrap> or similar transfer, you can then
use the remembered leafname as the filename instead of <Wimp$Scrap>.
MASK OUT NULL POLLS while you aren't using them!
When doing long operations, multitask in the background. This is
not difficult to do, and doesn't affect the speed of your program
Oh, and while multitasking, don't use the hourglass!
-- _________________ "I'd like to answer this question in two ways: /____ _ _/_ __ First in my normal voice, and then // / //_//_ /_/ in a silly, high-pitched whine." (Monty Python)