Copyright (c) Hyperion Entertainment and contributors.

Release 4 Compatibility

From AmigaOS Documentation Wiki
Jump to navigation Jump to search

Release 4 Compatibility

If you are developing new software or updating older software, you need to avoid compatibility traps. This is a partial list of Release 4 compatibility problem areas can help you avoid and diagnose compatibility problems.

General Compatibility Problem Areas

The following improper Amiga programming practices are likely to fail on new OS versions or hardware.

  • Requiring all free RAM.
  • Overwriting memory allocations. With 32-bit addresses, a 1-byte overwrite of a string array can wipe out the high byte of a pointer or stack return address.
  • Improper flags or garbage in system structures. A bit that means nothing under one OS may drastically change the behavior of a function in a newer version of the OS. Clear structures before using, and use correct flags.
  • Misuse of function return values. Use function prototypes and read the Autodocs for the functions you are using. Some system functions return just success or failure, or nothing at all (void). In such cases, the value which the function happens to return must not be used except as it is documented.
  • Depending on unsupported side effects or undocumented behavior. Be sure to read the Autodocs, include file comments and other documentation.
  • Assuming current choices, configurations or initial values. If the current possibilities are A, B, or C, do not assume C if it isn't A or B. Check specifically for the choices currently implemented, and provide default behavior for unexpected values.

Amiga debugging tools such as MemGuard can find many program bugs that may affect compatibility. A program that is MemGuard clean stands a much better chance of working well under current and future versions of the OS.

Release 4 Changes That Can Affect Compatibility

There are several areas where Release 4 OS changes and enhancements can cause compatibility problems for some software.

Exec

  • When an Exec device gets an IORequest, it must validate io_Command. If the io_Command is 0 or out of range, the device must return IOERR_NOCMD and take no other action. The file system now sends new commands and expects older devices to properly ignore them.

DOS

  • Process structure is bigger. "Rolling your own" Process structure from a Task fails. Use dos.library System() or NewCreateProc().
  • Unless documented otherwise, you must be a process to call DOS functions. DOS function dependence on special process structures can change with OS revisions.

Timer Device

  • The most common mistake programmers make with timer.device is to send off a particular TimeRequest before the previous use of that TimeRequest has completed. Use IO_Torture to catch this.
  • IO_QUICK requests may be deferred and be replied as documented.

Intuition

  • If you are opening on the Workbench screen, be prepared to handle larger screens, new modes, new fonts, and overscan. Also see "Font Compatibility" information.
  • Left-Amiga-Select is used for dragging large screens. Do not use left-Amiga-key combinations for application command keys. The left-Amiga key is reserved for system use.
  • For compatibility reasons, GetScreenData() lies if the Workbench screen is a mode only available after 1.3. It will try to return the most sensible mode that old OpenScreen() can open. This was necessary to prevent problems in applications that cloned the Workbench screen. To properly handle new modes, see LockPubScreen(), GetVPModeID(), and the SA_DisplayID tag for OpenScreenTags().
  • MENUVERIFY/REQVERIFY/SIZEVERIFY can time out if you take too long to ReplyMsg().
  • Menu-key equivalents are ignored while string gadgets are active.
  • You can't type control characters into string gadgets by default. Use Ctrl-Amiga-char to type them in or use IControl Prefs to change the default behavior.
  • Don't modify gadgets directly without first removing them from the gadget list, unless you are using a system function designed for that purpose, such as NewModifyProp() or SetGadgetAttrs().
  • Don't rely on NewModifyProp() to fully refresh your prop gadget after you've changed values in the structure. NewModifyProp() will only correctly refresh changes which were passed to it as parameters. Use Remove/Add/RefreshGList() for other kinds of changes.
  • Window border rendering has changed significantly for 2.0. Note that the border dimensions are unchanged from 1.x (Look at window->BorderLeft/Top/Width/Height if you don't believe us!). If your gadget intersects the border area, although it may have looked OK under 1.3, a visual conflict may occur under 2.0. If Intuition notices a gadget which is substantially in the border but not declared as such, it treats it as though it were (this is called "bordersniffing"). Never rely on Intuition to sniff these out for you; always declare them explicitly (see the Gadget Activation flags GACT_RIGHTBORDER, etc.). See "Intuition Gadgets and Window Borders" in the "Additional Information" section below.

Workbench

  • The Workbench screen may not be open at startup-sequence time until some output occurs to the initial Shell window. This can break startup-sequence-started games that think they can steal WB's screen bitplanes. Do not steal the Workbench screen's bitplanes. (For compatibility, booting off pre-2.0 disks forces the initial screen open. This is not guaranteed to remain in the system.) Use startup code that can detach when RUN (such as cback.o) and use CloseWorkbench() to regain the screen's memory. See "Workbench and Startup" in the "Additional Information" section below.

Layers

  • Use NewLayerInfo() to create, not FattenLayerInfo(), ThinLayerInfo(), InitLayers().
  • Simple-refresh preserves all of the pixels it can. Sizing a SIMPLE_REFRESH window no longer clears the whole window.

Graphics

  • Graphics and layers functions which use the blitter generally return after starting the final blit. If you are mixing graphics rendering calls and processor access of the same memory, you must WaitBlit() before touching (or deallocating) the source or destination memory with the processor. For example, the Text() function is faster in Release 2, causing some programs to trash partial lines of text.
  • Changing the display mode of an existing screen or viewport while open is still not a supported operation.
  • GfxBase DisplayFlags and row/cols may not match Workbench screen.
  • Do not hardcode modulo values - use BitMap->BytesPerRow.
  • LoadRGB4() used to poke colors into the active copperlist with no protection against deallocation of that copperlist while it was being poked. Under 2.0, semaphore protection of the copperlist was added to LoadRGB4() which makes it totally incorrect and extremely dangerous to call LoadRGB4() during an interrupt. The general symptom of this problem is that a system deadlock can be caused by dragging one screen up and down while another is cycling. Color cycling should be performed from within a task, not an interrupt. In general, the only functions which may be safely called from within an interrupt are the small list of Exec functions documented in the "Exec Interrupts" chapter.

Fonts

  • Any size font will be created via scaling as long as TextAttr.Flags FPF_DESIGNED bit is not set.
  • Do not use -1 for TextAttr.Flags or Styles, nor as the flags for AvailFonts() (one high bit now causes AvailFonts to return different structures). Only set what you know you want. A kludge has been added to the OS to protect applications which currently pass -1 for AvailFonts flags.

CLI / Shell

  • Shell windows now have close gadgets. The EOF character is passed for the close gadget of a Shell. This is -1L with "CON:" getchar(), and the Close Gadget raw event ESC sequence with "RAW:".
  • Some degree of unofficial support has been put in for programs which use SMART_REFRESH console windows, and use graphics.library calls mixed with console.device sequences to scroll, draw text, clear, etc. This is not supported in SIMPLE_REFRESH windows with character maps, and is strongly discouraged in all cases.
  • Closing an Intuition window before closing the attached console.device will now crash or hang the machine.
  • Note that SIMPLE_REFRESH character mapped consoles are immediately redrawn with the global background color when changed-this is not possible with SMART_REFRESH windows.

Additional Information

Task Switching

A task runs until either its Quantum is up, or a higher priority task preempts it. When the Quantum time is up, the task will now lose the CPU.

Intuition Gadgets and Window Borders

If Intuition finds a gadget whose hit area (gadget Left/Top/ Width/Height) is substantially inside the border, it will be treated as though it was declared in the border. This is called "bordersniffing". Gadgets declared as being in the border or detected by Intuition as being in the border are refreshed each time after the border is refreshed, and thus aren't clobbered.

Noteworthy special cases:

  • A gadget that has several pixels not in the border is not bordersniffed. An example would be an 18-pixel high gadget in the bottom border of a SIZEBBOTTOM window. About half the gadget will be clobbered by the border rendering.
  • A gadget that is not substantially in the border but has imagery that extends into the border cannot be sniffed out by Intuition.
  • A gadget that is substantially in the border but has imagery that extends into the main part of the window will be sniffed out as a border gadget, and this could change the refreshing results. A common trick to put imagery in a window is to put a 1x1 or 0x0 dummy gadget at window location (0,0) and attach the window imagery to it. To support this, Intuition will never bordersniff gadgets of size 1x1 or smaller.
  • All these cases can be fixed by setting the appropriate GACT_xxxBORDER gadget Activation flag.
  • In rare cases, buttons rendered with Border structures and JAM1 text may appear invisible.

The height of the window's title bar is affected by the current font settings. See the discussion of "Screen Attributes" in the "Intuition Screens" chapter. To predict your window's titlebar height before you call OpenWindow():

topborder = screen->WBorTop + screen->Font->ta_YSize + 1

The screen's font may not legally be changed after a screen is opened.

Be sure the screen cannot go away on you. This is true if:

  1. You opened the screen yourself.
  2. You currently have a window open on the screen.
  3. You currently hold a lock on this screen (see LockPubScreen()).

IntuiText rendered into a window (either through PrintIText() or as a gadget's GadgetText) defaults to the Window RastPort font, but can be overridden using its ITextFont field. Text rendered with the Text() function appears in the Window RastPort font.

The Window's RPort's font shown above is the initial font that Intuition sets for you in your window's RastPort. It is legal to change that subsequently with SetFont().

Workbench and Startup

Avoid any output from your "s:startup-sequence". If your program opens a screen it will be the first screen the user ever sees. Note that if EndCLI is ever hit, the screen will pop open.