Spr2Asm
                                *******

Disassemble any Qdos-type (QL or GD2) sprite and output as an assembler
file


Uses
====

Complex sprites that change appearance depending on the status of a button,
or that change shape over time, or that have different mode definitions,
require that more than one sprite definition is linked together. The
available tools to do this in a simple, interactive manner are not very
versatile, and many are out of date. The simplest way to do this, then, is
to take individual sprite definitions, either self-made or from some
library, and string them together as assembler sprite definitions.

You don't need to know much assembler to do this, you only need to know the
rules for making such sprites. Those rules are described in detail in the
document _doc_Sprites_txt.

You could also use Spr2Asm to disassemble sprites made by others to see how
they are put together. Spr2Asm should be able to disassemble most legally
defined sprites, ie if the sprite can be correctly displayed via the
appropriate methods then it is likely that the sprite can be disassembled
so that when reassembled again the sprite looks and behaves like the original.

Some special cases can, however, not be catered for. See Limitations,
below.

Reassembling a sprite definition can be as easy as

        EW "dev8_extras_exe_Qmac"; "ram1_sprite_asm -nolink -errors"

Change the paths and file names to match your circumstances. The line
above would produce a file ram1_SPRITE_BIN - which is probably best renamed
to give it a _spr extension, or add the option -bin ram1_Sprite_spr to the
command line above.

Once you have assembled your sprite there are various ways in which you can
display it or add it to your programs and menus. The simplest is to use
ALCHP, followed by LBYTES. Then use SPRW to draw it, if you use the
EasyPointer system, or WSPRT, if you are of the Qptr persuasion. There is
also a knoware.no toolkit command, WSPT, to do the job.


Usage
=====

   er = FEW("<path>Spr2Asm_obj"; '/F<input file> [/O<output file>'])

where:

   er            is 0 or any error code resulting from the operation

   <path>        is the location of the program

   <input file>  is the filename and location of a sprite to disassemble

                 If the input filename is the only item on the command
                 line then no key is required and no quotes or forward
                 slashes / are wanted. Spaces are ok, though.
                 The output file name will then always be
                 ram1_sprite_asm (overwrite!)

   <output file> is the optional output file name
                 _asm is appended if not specified
                 If no output file name is given the program sends the
                 output <input file> with the spr extension changed to asm.
                 Note: The output file is oerwritten!

  /F             key for input filename
                 File names with spaces must be quoted
                 File names must not contain any forward slash / characters!

  /I             is synonymous with /F, ie Input filename

  /A             Address option. If address given /F and /I are ignored.
                 The address must point to a valid sprite in memory and is
                 supplied in hexadecimal. Zero, odd and invalid hex
                 numbers cause a Bad Parameter error, but no other
                 checking is done on the validity of the address.

  /O             key for output filename
                 If given, input file names must be keyed too
                 If name contains spaces it must be quoted.

  /Sxx           specify a larger stack size (xx = number of elements) if
                 needed, where there are lots of sprite definitions.
                 The default (and minimum) is an ample 20

  /R             No parameter. The output is formatted so as to be
                 assembled as a SROFF file (ie linkable, _rel)

  /G             No parameter. The output is suiable for reassembly by
                 the GWASS assembler.

Certain errors only show up in the disassembly. Such errors are signaled by
the return code -1, ie Incomplete. You can search for "error" in the
disassembly to find them and try to fix them manually. Typically these
would be stack overrun errors which can simply be fixed by adding a suitable
/Sxx instruction to the command line.

A note on hex:
--------------

A valid hex number is of the form
    [$]<hex digit>[<hex digit>] * 7
Where [] => optional, and hex digits are 0..9, A..F, a..f

The first non-hex charcter in an otherwise valid number terminates the
the number but does not invalidate it!

Numbers with more than 8 hex digits are truncated, but not invalidated!

Zero and odd numbers are rejected for the purposes of spr2asm.


Definitions
===========

Sprites can be simple, single sprites, ie they contain a single sprite
definition. These can be of the type sprite, pattern or blob. A pattern
sprite can also be seen as simply a solid sprite.

There can also be chained sprites. These are sprites containing more than
one sprite definition, linked together via the pto_nobj link in the header.
These are sprites that in certain circumstances are displayed one after the
other with a timeout in between, and usually in a circular fashion, ie the
last definition loops back to the first one. Chains are terminated by
setting the last pointer to the next sprite (pto_nobj) to zero.

Sprites can also be chained together via pto_nobj for another reason: The
same, or a similar sprite, can be defined for different display modes. The
system will then scan the chain of sprites and display the first one it
finds of the same mode as the current display mode.

Furthermore, sprite data - patterns and masks - can be compressed or
uncompressed.

Finally there are complex sprites. These are sprites that contain more than
one sprite definition but also contain other structures such as a Sprite
Block to determine which definition is visible depending on the state of
the object (normally a so called Loose Item) the pointer is in.

Sprites can also contain other structures such as an Option Block, the
function of which is not yet entirely properly defined (but see below).

Complex sprites could in theory contain a mix of all the different types
and structures mentioned, at once.

The Graphics Definition type 2 (GD2) driver can cope with all of these
across all systems, although when mode 0 and mode 8 colour drivers are
active the high-colour sprites cannot be displayed and may cause an error
or display a placeholder sprite instead.

GD1 systems, ie older "QRAM" systems, normally only to be found on original
QLs, can not properly understand or display most GD2 objects, only simple
and chained sprites of mode 0 and/or mode 8. GD1 systems do also not
understand compression, nor alpha, nor solid sprites. Im unsure how well it
copes with chained sprites of colour definitions it doesnt understand. They
wont (cant) be displayed, but will they be ignored?


+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +
*                                                                           *
*  WARNING: Attempting to display a malformed sprite can crash the system,  *
*  causing loss of data!                                                    *
*                                                                           *
*  Some convoluted hand-made sprite definitions may work as intended in     *
*  the original, but be malformed when disassembled and reassembled again.  *
*  Therefore you should test any such sprites in a safe environment before  *
*  using them!                                                              *
*                                                                           *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +


Further reading
===============

The most precise and correct (but sometimes hard to follow) descriptions
and definitions of sprites - and all matters pertaining to the QL Graphical
User Interface, can be found in the QPTR manual. You can download this from
www.wlenerz.com/qlstuff/. The current version of this manual is 6.05.

Regarding sprites, check out the chapters under Concepts, for a basic
overview, and Assembler/Data Structures/Pointer Interface/Channel >>
>> Definition Block/Graphics Objects. (Yes, this information is buried
deep!) for the nitty-gritty detail.


Limitations
===========

Note: Spr2Asm output is suitable for reassembly with the Qmac assembler
or, if you use the /G option on the command line, GWASS. If you are
addicted to any other assembler you may have to manually reformat the
output.

A sprite that is designed in such a way that the pattern or mask of one of
the sprite definitions it contains is a subset of a larger definition, will
be incorrectly disassembled:

        sprite1 header
              |
              v
        +----------+----------+
        |          |          |      This could be a perfectly legal
        | pattern1 |          |      sprite definition but it can
        |          |          |      not be properly disassembled
        +----------+          |      with Spr2Asm. You could fix it
        |            pattern2 |      manually after disassembling,
        |                     |      though.
        +---------------------+
               ^
               |
        sprite2 header


Similarly, a sprite with pointers into itself or its own structures will
not be disassembled the same. However, it may still be legal and ok.

This sprite:

spr0
         dc.b  $01,$00,$00,$00    ;Simple QL mode 0 sprite
         dc.w  $0002,$0001        ;x size, y size

msk
         dc.w  $0000,$0000        ;x/y origin re-purposed as mask
         dc.l  0                  ;no colour pattern
         dc.l  msk-*              ;pointer to pattern mask
         dc.l  0                  ;no next definition

will be disassembled as:

sp1000
        dc.b    $01,$00,0
        dc.b    %00000000
        dc.w    2,1,0,0
        dc.l    0
        dc.l    ms0-*
        dc.l    0

ms0
        dc.w $0000,$0000


Ie it will be four bytes larger than the original. But valid.

A sprite containing other data or structures not part of the formal sprite
definition will lose that data on disassembly. You would have to add it
back manually post-disassembly.

Since the Option Block structure has not been formally defined it may not
be possible to disassemble it. The part of the option block structure that
has been informally adopted (suggested by mk79 and adopted by me (see
Appendix A) will, however, be correctly disassembled - although probably
not in human-readable form. (Im working on it..)

Illegally defined sprites may simply hang the program or fill your disk
with rubbish! Some may even crash your system when you try to display them!

Some complex sprites may appear to display properly in the original, but
are too messy to untangle by Spr2Asm. Again, they may crash Spr2Asm or
output rubbish.

Structures that refer to system sprites may not disassemble correctly. A
single system sprite definition should be fine, though.

If a disassembled sprite will not reassemble without errors, or when re-
assembled does not look right, may not have been correctly defined in the
first place! Untangle it yourself and try to reassemble.

With sprites containing compressed data, it is not possible to definitively
determine the size of that compressed data. For accuracy's sake, the data
needs to be uncompressed and then recompressed again. Spr2Asm does this,
but it could be slow work on some systems..

Large sprites, especially mode 64 ones, can quickly fill up your disk. This
is not error trapped by Spr2Asm; it should gently crash when it runs out of
room. However, if the destination is an unformatted, expandable RAM disk
which has eaten up all of memory, the system could potentially hang.

Finally, the data and structures in a disassembled sprite may not appear in
the same order or location as in the original. It will appear the same and
behave in exactly the same manner, and the binaries are likely be of the
same size, but a byte-by-byte comparison with the original may not match.


Program status
==============

V0.03, pjw, 2024 Oct 16

               Conditions of use and DISCLAIMER as per Knoware.no

Generated by QuickHTM, 2024 Oct 16