5.2. Format of saved game files

New GamePos files are typed &3F7. Old files are typed &0D0 and will not be accepted by newer versions of Desktop Hacker. However, their contents are compatible, so old GamePos files may be converted simply by re-typing them.

GamePos files are (optionally compressed) copies of what's inside a stopped game's application memory whilst being hacked, with the following small header. The contents of a stopped game's application memory follow.

Position Length Contents
0 4 "Game"
4 4

Version ID string - currently 'D100' or 'D101'

D means Desktop Hacker (the creator). dHacker only loads 'D's. Extra data is added to the end of the file only, so dHacker can load files from later versions, and later versions will detect the bundle terminator, and know to stop. Any changes to bundle format can be controlled by taking note of the version number.

8 4 Compression ID string. 'None' for no compression, or 'Sqsh' for compression using RISC OS 3's Squash module. Other compression types may be defined. The error 'Unknown compression type' will appear with other types.
12 0 or 4 On compressed files only - length of following decompressed data.

There then follows (at 12 or 16) the data. When decompressed, it is exactly the same as what is stored from &8000 in a stopped game. There is a BASIC routine to decompress a game file with compression method 'Sqsh' in !GameInfo.!RunImage, look for 'Squash_Decompress' to find it.

Squashed game files are only supported by Desktop Hacker version 1.06 and later, and dHInfo version 1.04 and later.

Files with version ID 'D101' are only understood by Desktop Hacker 1.07 and later. They are only produced when the 'Don't keep screen memory' option has been switched on.

From &8000 upwards, the data is stored in bundles of:

Position Length Contents
+0 4 Offset to next bundle
+4 offset-4 Data
+offset ... Next bundle

The order of bundles is important. A null data length (ie. offset of 4) may be used. An offset of 0 terminates the list of bundles, and is the last word in the file.

Order of bundles defined so far under IDs 'D100' and 'D101':

  1. The game code itself. Since this starts in memory at &8004 (thanks to the bundle header), the word at &8000 is at the very end of the block, and all the memory from &8004 comes first in the block. This avoids major memory shunting. If data length 0, zero WimpSlot is used. This bundle must exist, even if with a data length of 0.
  2. Registers bundle. R0 to PC, all USR mode. This bundle must exist, and have a data length of 64 (16 words). A bundle terminator may occur at any bundle after this.
  3. FP registers bundle. Unlike the normal registers, this bundle may have a data length of 0, and indeed will if the machine the game was stopped on had no FP hardware and no FPEmulator loaded. If this bundle does have a non-null data area, it must be 64 bytes long. F0-F7 are stored in double precision (D) format. Some accuracy is lost in the 64-bit D format. This is likely to be insignificant. (E and EP formats cannot be used due to inter-FP system incompatibility.)
  4. Mode definition bundle. A data length of 0 means screen unimportant. A data length of 4 means it's a standard RISC OS 2/3.0/3.1 mode number. A data length of more than 4 can only be handled by RISC OS 3.5, and is a mode selector block. Position files saved out from RISC OS 3.5 with a mode selector rather than a mode number cannot be read under RISC OS 2 to 3.1. Desktop Hacker in itself fully supports the new mode and sprite formats. Note, if the mode is in old format, it may well be a shadow variant, so clear the seventh bit before using it where shadow modes are inappropriate, eg. sprites.
  5. Screen memory contents bundle. Screen memory must be a fixed number of pages. Transfer from a machine with a small page size to one with a bigger page size may cause problems (the screen appearing too far up, and flickering, generally) if the page boundaries where the screen starts don't coincide.

    Under files of ID "D101" or greater, a data length of 4 has a special meaning (as 4 bytes screen memory seems a tad unlikely!): the one word in such a bundle if the length of screen memory. The actual contents of screen memory in this case are not stored, to save memory on machines that are short on RAM.

  6. Miscellaneous info bundle.

    Position Length Contents
    +0 4 Mouse shape number and linkage flag (as from OS_Byte 106)
    +4 4 Mouse X co-ordinate
    +8 4 Mouse Y co-ordinate
    +12 4

    Flags

    bits 0-29 as from OS_Byte 200 (Escape/Break state)
    bit 30 set if mouse bbox is full-screen, else infinite
    bit 31 as from OS_Byte 229

    +16 4 Keyboard disable state (as from OS_Byte 201)
    +20 4 Escape key number (as from OS_Byte 220)
    +24 4 MonotonicTime when game was interrupted
    +28 4 Key initial delay (OS_Byte 11) when game interrupted
    +32 4 Key repeat delay (OS_Byte 12) when game interrupted

    Further data may be added to this bundle in future. Under Desktop Hacker 1.00, bit 30 of flags (+12) will always be unset. It is impractical to read mouse bboxes directly, more accurately than full- screen/infinite as there is no SWI to do this. However, Future versions of Desktop Hacker may trap the OS_Word calls that set the mouse bbox, and save the bbox, which would allow this. In this case, bit 30 will again become reserved, a new bundle will be added, and the version ID will be increased to D102.

  7. Screen info bundle. (If only screen context save areas were more flexible, I could just use them, but no...)

    Position Length Contents
    +0 4 Text foreground colour (*)
    +4 4 Text background colour (*)
    +8 4 Text foreground tint
    +12 4 Text background tint
    +16 4 Graphics foreground colour
    +20 4 Graphics backgound colour
    +24 4 Graphics foreground tint
    +28 4 Graphics background tint
    +32 4 Graphics foreground action
    +36 4 Graphics background action
    +40 4 Text window left
    +44 4 Text window bottom
    +48 4 Text window right
    +52 4 Text window top
    +56 4 Graphics origin X
    +60 4 Graphics origin Y
    +64 4 Graphics cursor X
    +68 4 Graphics cursor Y
    +72 4 Text cursor X
    +76 4 Text cursor Y
    +80 4 VDU status register
    +84 4 ScreenStart offset
    +88 4 DisplayStart offset
    +92 4 Screen bank (**)
    +96 4 Display bank (**)
    +100 4 Border colour word (ReadPalette)
    +104 4 Mouse colour 1 word (ReadPalette)
    +108 4 Mouse colour 2 word (ReadPalette)
    +112 4 Mouse colour 3 word (ReadPalette)

    Further data may be added to this bundle in future.

    (*) These values are not accurate in any mode with >16 colours, so you'll notice changing text colours in Desktop Hacker sometimes. This is not my fault - OS_ReadVduVariables simply doesn't return the correct values sometimes!

    (**) The default screen bank (0) in this position is not allowed - you will have to work out the real screen bank number from the shadowness of the mode, if the game has specified a default bank.

  8. Palette bundle, only in <16bpp modes. Data length always zero in 16/32 bpp modes. Data length is 256 double words in all 8bpp modes. List of double words (flash1, flash2) in OS_ReadPalette format, starting from the maximum colour, and going down to colour 0; ie. in reverse order. Don't ask why; it's just like that, and not worth changing now.
  9. Vector bundle. The data area contains a block of vectors as returned by OS_DelinkApplication.
  10. Device vector bundle. This data area contains 12-byte blocks as for the vector bundle, but for device vectors (interrupts). Types 8 and 13 (used by expansion cards) need extra registers, and are ignored - Desktop Hacker shouldn't touch expansion cards anyway.
  11. CallEvery ticker events bundle. Each ticker event has three words. The first is the interval, the second the address, the third the workspace.
  12. CallAfter ticker events bundle. Each ticker event has three words. The first is the monotonic time (as seen by the application) at which to interrupt, the second the address, the third the workspace.
  13. Module chain bundle. Each word is a pointer to a module in application space. This is to prevent games' modules in application space being called when the game is not paged in. However, the only way Desktop Hacker can delink these modules is by killing them and re-initialising them when returning (with OS_Module 10). This is not at all satisfactory (music modules may, for example, go silent), but it's all that can be done. Modules inserted in RMA are disabled by having their service and SWI decode entry points poked to 0.

Further bundles may be added in future. The Version ID will only be increased when the internal format of existing bundles changes, as old versions will refuse to load newer IDs. Bundles marked 'further data...' may be extended without increasing the version ID, so be prepared for them being longer than documented here - always use the bundle length header word to get the length.


--) /!\ Format of list files
(-- /!\ Writing code for Desktop Hacker
/\ /!\ Technical stuff


ajc@doggysoft.co.uk
23rd April 1998