Preliminary documentation to most of the enhancements to SMSQ/E v3.00, mostly directed at programmers. "Preliminary" means that here is at least some text to see what's new and how to use it. This documentation certainly needs to be enhanced and improved. "Preliminary" does not mean that facts stated herein are going to get changed, due to the release of SMSQ/E v3.00 they are now fixed. All the best, Marcel Kilgus Contents: I - New CON Drivers Vectors II - New Wman vectors III - New Sprite definition IV - New WMAN colour format V - System palette entries I - New CON driver vectors =-=-=-=-=-=-=-=-=-=-=-=-=- A new vector block has been introduced to provide direct access to new screen driver functions. To call one of those functions, one first needs a pointer to the CON linkage block. This can either be obtained in the traditional way or by reading the sys_clnk ($c4) system variable. It is planned that future PTR_GEN/WMANs for non-SMSQ/E version will also support this system variable. On current non-SMSQ/E systems its value should be 0. The pointer to the vector table itself is located in the new pt_vecs variable within the linkage block. A typical call sequence can thus look like this: moveq #sms.info,d0 trap #1 ; get ptr to system variables in a0 move.l sys_clnk(a0),a3 ; ptr to CON linkage move.l pt_vecs(a3),a0 ; vector table jsr pv_fspr(a0) ; actual call PLEASE NOTE: All vectors so far expect a3 to be the pointer to the CON linkage block on entering the call. With the above code, this is done automatically. The keys (e.g. the values of pv_pinf, pv_fspr etc) are contained in the file "dev8_keys_con". | | | Vector $00 pv_pinf | | | | Like iop.pinf, but one doesn't need a channel to call this routine. | | | | Call parameters | | D1 D1 pointer version number | | D2 D2 preserved | | D3 D3 preserved | | | | A0 A0 preserved | | A1 A1 pointer to WMAN | | A2 A2 preserved | | A3 pointer to CON linkage block A3 preserved | | | No error returns - this routine always succeeds. | | | Vector $06 pv_fspr | | | | Look in linked sprite list for the definition that would actually | | be used in the current display mode. | | | | Call parameters Return parameters | | D1 D1 preserved | | D2 D2 preserved | | D3 D3 preserved | | | | A1 ptr to 1st sprite A1 ptr to fitting sprite | | A2 A2 preserved | | A3 ptr to CON linkage block A3 preserved | | | No error returns - this routine always "succeeds". If no fitting sprite is found, a pointer to the arrow sprite is returned! | | | Vector $0C pv_sspr | | | | Set system sprites/Get system sprite address | | | | Call parameters Return parameters | | | | D1.w sprite number / -ve D1 pres./ Max allowed | max current | | D2 D2 preserved | | D3 D3 preserved | | | | A0 A0 preserved | | A1 pointer to sprite / 0 A1 preserved / pointer to sprite | | A2 A2 preserved | | A3 pointer to CON linkage block A3 preserved | | | | Error returns: | | IPAR Illegal sprite number (set/get) | | ITNF there are no system sprites ! | | | This gets or sets a system sprite or returns the max nbr of system sprites * if d1 is a negative nbr (-1 is suggested), then on return d1 contains: max nbr of space in table for sys sprites | highest nbr of current system sprite else: * if a1 = 0, then one gets the address of the system sprite the number of which is passed in D1. The address is returned in a1. This address MAY be 0, in which case the system sprite requested does not exist. This will only happen if somebody fiddled with the table contrary to recommendations * if a1 <> then it contains the address of a sprite that will be a system sprite, d1 contains the number of that sprite. This sprite is not " copied to a safe place", it is the responsibility of the calling job to make sure that the sprite doesn't just disappear For a list of the system sprites defined thus far see keys_sysspr. The sprite table has the following format: -2 max nbr of sprites possible in table 0 nbr of sprites currently in table 2+ long word absolute pointers (i.e real addresses of sprites) ======== ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- II - New WMAN vectors =-=-=-=-=-=-=-=-=-=-= | | | Vector $7C WM.SETSP | | | | Set system palette entries | | | | Call parameters Return parameters | | | | D1.w start index D1 preserved | | D2.w number of elements D2 preserved | | D3.w number of palette (0-3) D3+ all preserved | | | | A0 A0 preserved | | A1 pointer to palette entries / 0 A1 preserved | | A2 A2 preserved | | A3 A3 preserved | | A4 A4 preserved | | A5 not used by any routine | | A6 not used by any routine | | | | Error returns: | | IPAR Illegal index number / invalid number of elements | | | Set the entries of the system palette indexed in D3 (from 0 to 3) to the values in the buffer, beginning with the index in D1 (counting from 0) and ending with the index D1 + D2 - 1. If A1 = 0 then the entries are taken out of the default table. Otherwise the buffer must hold an array of words with the colour values of the different items. The colour format is the standard WMAN colour format as described elsewhere. | | | Vector $80 WM.GETSP | | | | Read system palette entries | | | | Call parameters Return parameters | | | | D1.w start index D1 preserved | | D2.w number of elements / -1 D2.w preserved / item count | | D3.w number of palette (0-3) D3+ all preserved | | | | A0 A0 preserved | | A1 pointer to entry buffer A1 preserved | | A2 A2 preserved | | A3 A3 preserved | | A4 A4 preserved | | A5 not used by any routine | | A6 not used by any routine | | | | Error returns: | | IPAR Illegal index number / invalid number of elements | | | Copies entries of the system palette indexed in D3 (from 0 to 3) into the given buffer, beginning with the index in D1 (counting from 0) and ending with the index D1 + D2 - 1. The buffer must be big enough to hold all requested entries. If D1 is given as -1 the function just returns the number of items held in the system palette. This can increase when more items get defined in new WMAN version. This is guaranteed to be below 256. | | | Vector $84 WM.TRAP3 | | | | Trap #3 replacement that handles WMAN colour codes | | | | Call parameters Return parameters | | | | D0.l function code D0 error code | | D1.w colour code D1 preserved | | D2+ parameter D2+ result according to trap | | | | A0.l channel id A0 preserved | | A1+ parameter A1+ result according to trap | | | | Error returns: | | same as original traps | | | This is a drop-in replacement for a "trap #3" call. D0 reacts to any of the codes iow.defb, iow.defw, iow.spap, iow.sstr, iow.sink and iow.blok. Those routines are exchanged by some that can handle the extended WMAN colour codes. Other function codes are directly passed to an ordinary "trap #3" call. The condiditon codes are guaranteed to be set properly according to D0, for all traps. | | | Vector $88 WM.OPW | | | | Emulate OPW.WIND, OPW.CON and OPW.SCR vectored routines | | | | Call parameters Return parameters | | | | D0.l OPW.WIND, OPW.CON or OPW.SCR D0 error code | | D1 D1 smashed | | D2 D2 smashed | | D3 D3 smashed | | | | A0.l ptr to name (OPW.WIND only) A0.l channel ID | | A1.l ptr to parameter block A1 smashed | | A2 A2 smashed | | A3 A3 smashed | | | | Error returns: | | same as original functions | | | This is a replacement for the OPW.WIND, OPW.CON and OPW.SCR vectored routines. In contrast to the originals the paramater block pointed to by A1 is in words instead of bytes: $00 border colour (word) $02 border width (word) $04 paper/strip colour (word) $06 ink colour (word) OPW.CON and OPW.SCR define the window using an additional block of four words: $08 width (word) $0A height (word) $0C X-origin (word) $0E Y-origin (word) | | | Vector $8C WM.SSCLR | | | | Set single colour pattern | | | | Call parameters Return parameters | | | | D0 D0 0 | | D1.w colour number D1 preserved | | D2+ all preserved | | | | A1.l ptr to window status area A1 preserved | | A2.l ptr to pattern space A2 preserved | | A3 A3 preserved | | A4 A4 preserved | | A5 not used by any routine | | A6 not used by any routine | | | Returns a pattern that is filled with the given colour. The space pointed to by A1 must hold at least $60 bytes. Does not work for stippled colours. | | | Vector $90 WM.JBPAL | | | | Set system palette number of job | | | | Call parameters Return parameters | | | | D1.l job ID / -1 D1 preserved | | D2 D2 preserved | | D3.w palette number / -1 D3+ all preserved | | | | A0 A0 preserved | | A1 ptr to job palette or 0 (D3=-1) A1 preserved | | A2 A2 preserved | | A3 A3 preserved | | A4 A4 preserved | | A5 not used by any routine | | A6 not used by any routine | | | | Error returns: | | IJOB Invalid job ID | | | Sets the active system palette for the given job. If D1 is -1 then the current job will be used. D3 can be supplied as -1 which can be used to give the job its very own palette. In this case a pointer to the palette can be supplied in A1. Attention: the contents of this area is not copied, it is used directly and must remain there as long as the job uses this palette! If A1 is supplied as 0 the palette pointer will not be touched. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- III - New sprite definition =-=-=-=-=-=-=-=-=-=-=-=-=-= A - Sprite Mode byte B - Sprite control byte C - Alpha channel D - Sprite compression E - Sprite block F - Options pointer The sprite definition has been extensively modified, but in such a way that it should continue to be compatible with older sprites. The sprite header is now as follows: pto_form $00 byte sprite mode $01 byte colour mode / system sprite number pto_vers $02 byte dynamic sprite version number pto_ctrl $03 byte sprite control pto_xsiz $04 word X size pto_ysiz $06 word Y size pto_xorg $08 word X offset pto_yorg $0a word Y offset pto_cpat $0c long relative pointer to colour pattern pto_mask $10 long relative pointer to mask/alpha channel pto_nobj $14 long relative pointer to next object pto_opts $18 long OPTIONAL (relative pointer to) options pto_blk $1c long OPTIONAL relative pointer to sprite block (the keys can be found in DEV8_keys_qdos_pt) A - Sprite MODE byte -------------------- Sprite mode can be any of the following: 0 system sprite 1 traditional QL colour sprite (as before) 2 GD2 colour sprite System sprite: When the sprite mode is 0 for system sprites then the second byte is the number of the sprite. ALL other values are ignored in that case, i.e. a system sprite reference is only 2 bytes long. QL colour sprite: If this is a traditional Ql colour sprite, then the colour mode byte has one of the following values (as before) 0 mode 4 1 mode 8 GD2 colour sprite: 0 1 bit black&white 3 1 bit palette mapped 4 2 bit fixed gr palette 7 2 bit palette mapped 8 4 bit fixed irgb palette 15 4 bit palette mapped 16 8 bit fixed palette (equals Aurora palette) 31 8 bit palette mapped 32 16 bit QPC/QXL %gggbbbbbrrrrrggg format 33 16 bit Q40 %gggggrrrrrbbbbbw format 64 32 bit $RRGGBB00 format B - Sprite control byte: ------------------------ The sprite control bit is formatted as follows %mpao0bcc cc stands for a chache version number. Programs can increment this value to signal the cache that the sprite has changed. A special value is pto.fupd (force update, %11), which causes the system to never use the cached version. key: pto.cver a flags whether the sprite uses an alpha channel instead of a mask (see below) key: pto.alph m and p signal whether the pattern (p) or the mask (m) is compressed (see below) key: pto.pcmp and pto.mcmp b signals that the optional pointer to a sprite block is present (bit x=1) or is not present (bit x=0) (see below) key pto..blk o signals that options are present (=1) or not (=0)(see below) key pto..opt currently unused C - Alpha channel: ------------------ When the pto.alph flag is set in the sprite control byte, the mask is considered to be an alpha channel. An alpha channel allows gradual mixes between the background and the sprite pattern. Every pixel is represented by exactly one byte. 0 means the pixel is completely transparent, 255 means the pixel is completely opaque. Values in between determine the degree of mixing of background and foreground. Alpha channel information is not padded at the end of each line. There's one byte for every pixel and nothing more. D - RLE compression: -------------------- Both pattern and mask/alpha channel can be compressed using a simple RLE (run length encoding) algorithm. This is usefull with data that is largely homogene, which is often the case with masks. Compressed data must be signaled in the sprite control byte (pto.pcmp, pto.mcmp) and starts with the bytes 'RLEx', with 'x' being either 1, 2 or 4. This is the item size the algorithm is working with. 8 bit RLE compression of 32 bit data wouldn't yield in good results, therefore the algoritm can also work on 16 bit or 32 bit data. After the ID there's one long word containing the size of the data in uncompressed form. After that the compressed data itself is following. The compressed data always consists of one byte and one or more items. If the leading byte is in the range of 0<=x<128 then x+1 uncompressed items are following. Otherwise only one item is following, which represents 257-x times the same item in the uncompressed data. Examples: A small blue circle, with hard transparency mask in 8 bit mode: sp_circle dc.w $0210,0 ; 8 bit mode dc.w 5,5,0,0 ; size 5x5 pixels with origin at 0x0 dc.l s8p_circle-* dc.l s8m_circle-* dc.l 0 s8p_circle dc.b $00,$27,$27,$27,$00,0,0,0 ; Note the padding dc.b $27,$27,$27,$27,$27,0,0,0 dc.b $27,$27,$27,$27,$27,0,0,0 dc.b $27,$27,$27,$27,$27,0,0,0 dc.b $00,$27,$27,$27,$00,0,0,0 x equ -1 s8m_circle dc.b 0,x,x,x,0,0,0,0 ; Same padding as pattern dc.b x,x,x,x,x,0,0,0 dc.b x,x,x,x,x,0,0,0 dc.b x,x,x,x,x,0,0,0 dc.b 0,x,x,x,0,0,0,0 Now the same circle with some soft alpha shading sp_circle dc.w $0210,pto.alph ; 8 bit mode, alpha blending dc.w 5,5,0,0 ; size 5x5 pixels with origin at 0x0 dc.l s8p_circle-* dc.l s8a_circle-* dc.l 0 s8p_circle dc.b $00,$27,$27,$27,$00,0,0,0 ; Note the padding dc.b $27,$27,$27,$27,$27,0,0,0 dc.b $27,$27,$27,$27,$27,0,0,0 dc.b $27,$27,$27,$27,$27,0,0,0 dc.b $00,$27,$27,$27,$00,0,0,0 s8a_circle dc.b $00,$40,$40,$40,$00 ; Note: no padding! dc.b $40,$80,$80,$80,$40 dc.b $40,$80,$FF,$80,$40 dc.b $40,$80,$80,$80,$40 dc.b $00,$40,$40,$40,$00 Finally the same circle with alpha blending and compression sp_circle dc.w $0210,pto.alph+pto.pcmp+pto.mcmp ; 8 bit mode dc.w 5,5,0,0 ; size 5x5 pixels with origin at 0x0 dc.l s8p_circle-* dc.l s8a_circle-* dc.l 0 s8p_circle dc.b 'RLE1' ; bytes sized RLE algorithm dc.l 8*5 ; uncompressed data size dc.b $00,$00,$FE,$27,$FD,$00 ; 1st line dc.b $FC,$27,$FE,$00 ; 2nd line dc.b $FC,$27,$FE,$00 ; ... dc.b $FC,$27,$FE,$00 dc.b $00,$00,$FE,$27,$FD,$00 ; saved 8 bytes in total. Yeah s8a_circle dc.b 'RLE1' dc.l 5*5 dc.b $00,$00,$FE,$40,$01,$00 ; 1st line dc.b $40,$FE,$80,$FF,$40 ; 2nd line dc.b $02,$80,$FF,$80,$FF,$40 ; begins at 2nd byte of 3rd line dc.b $FE,$80,$01,$40 ; begins at 2nd byte of 4th line dc.b $00,$FE,$40,$00,$00 ; 5th line Of course RLE compression doesn't make much sense here, it's just for the sake of the example. Note also that the compression of pattern and mask are independant, in this case one could have left the alpha channel alone and only compress the pattern. If the 8 bytes are worth it... E - Sprite block ---------------- The object drawing routines have been amended so as to allow different sprites to be drawn in loose menu items, depending on the status of that item. In such a case, it behooves the application to supply the different sprites and to set up a "sprite block" which is just a block of 5 longword pointers, as defined just below. To keep things compatible with older versions of WMAN, this has been handled by setting a bit (pto..blk) in the sprite control byte. If this bit is set to 1, then there must be a pointer pointer to a sprite block. Please note that this pointer MUST be preceeded by the (pointer to) additional options (see section F below) which, currently is just a longword 0. IF pto..blk IS SET, THEN pto_opts MUST EXIST (AS A LONG WORD 0) AND pto_blk MUST POINT TO A VALID BLOCK. Example dc.w $0210,pto.blk ; 8 bit mode, sprite control block dc.w 5,5,0,0 ; size 5x5 pixels with origin at 0x0 dc.l s8p_circle-* ; Pattern dc.l s8m_circle-* ; Mask dc.l 0 ; Next sprite dc.l 0 ; Options - currently unused, set to 0 dc.l scb_circle-* ; Sprite control block The sprite pointer block is just a block of 5 longword pointers: pointer to sprite if item is available pointer to sprite if item is available AND is the current item pointer to sprite if item is selected pointer to sprite if item is selected AND is the current item pointer to sprite if item is unavailable In all cases, these are long word relative pointers. All but the first pointer may be 0. The first pointer (item available) MUST exist and point to a real sprite. 0 pointers are handled as follows - For available items: * The pointer to the available item sprite MUST exist. * If no pointer to an available AND current item sprite exists, then the available item sprite is taken instead - For selected items: * If no pointer to a selected item exists, then the pointer to the selected item AND current item is ALSO ignored. The avilable item sprite is taken instead for both. * If no pointer to a selected AND current item sprite exists, then the selected item sprite is taken instead. - For unavailavle items, the available item sprite is used. It is allowed, but not necessary, for any of these pointers including the first pointer (available item) to point back to the original sprite, which will then be drawn as a normal sprite! This allows three cases: 1 - The original sprite can be an ordinary QL mode sprite, which will be drawn normally by older versions of WMAN. The newer versions of WMAN will use the extended format. 2 - The original sprite could be a simple empty shell, with just the relevant data (bit pro..blk) and the pointer to a sprite block set. 3 - The original sprite could be a normal QL or 24 bit mode sprite which will be used by an item in any of its statusses. Alternative 1 above will ensure that your software remains compatible with older versions of WMAN. F - Options ----------- To provide for future expandability of the sprite format, a special bit in the sprite control byte indicates whether the sprite definition is followed by an options long word or pointer. If bit pto..opt is set, then this options long word or pointer must exist. At present, the options longword is unused. It has not been decided yet whether this will be a pointer to further options, or a bit map of further options. Thus, for the time being, this longword can be ignored and even omitted UNLESS the sprite also contains a pointer to a sprite block (see above), in which case the options longword MUST EXIST (and, for the time being should be set to 0). IV - New WMAN colour format =-=-=-=-=-=-=-=-=-=-=-=-=-= Colours for the new WMAN are always given as one word. The word may have any of the following formats: %00000000cccccccc exactly as before %00000001pppppppp palette %00000010pppppppp system palette %00000011gggggggg gray scale %00000100cc00tttd 3d border (border calls only!). see below %01ssxxxxxxyyyyyy palette stipple. see below %1rrrrrgggggbbbbb 15 bit RGB Stipple format -------------- s = stipple code (0 = dot, 1 = horizontal, 2 = vertical, 3 = checkers) x = stipple colour y = main colour As x and y can only hold 6 bit only the first 64 entries of the palette can be used for stippling. Due to the design of the palette those entries alone still cover the whole colour range quite well. 3d border format ---------------- d = direction (0 = raised, 1 = lowered) t = type c = compatibility mode To see what types are available have a look at the qlborders.gif file. The compatibility modes are avaiable on some border types and they tell how to sqeeze a non-standard border size into a QL border. Some modes paint areas with the current paper colour, therefore it is a wise idea to always set the paper colour before the border. The WMAN routines have already been changed to take this into account. In case of a non-standard border width another border call on this window MUST be made through the WMAN routines instead of the standard border calls (e.g. by calling wm.trap3). Otherwise the overall window size will be altered. The colours to paint the border are defined in the system palette (sp.3ddark and sp.3dlight). Future versions may shade the paper colour, therefore it's again a good idea to set the paper colour before the border call. V - System palette entries =-=-=-=-=-=-=-=-=-=-=-=-=- The keys for this are defined in the file dev8_keys_syspal. Name Number Meaning ------------------------------------------------------------------------------ sp.winbd $0200 Window border sp.winbg $0201 Window background sp.winfg $0202 Window foreground sp.winmg $0203 Window middleground sp.titlebg $0204 Title background sp.titletextbg $0205 Title text background sp.titlefg $0206 Title foreground sp.litemhigh $0207 Loose item highlight sp.litemavabg $0208 Loose item available background sp.litemavafg $0209 Loose item available foreground sp.litemselbg $020a Loose item selected background sp.litemselfg $020b Loose item selected foreground sp.litemunabg $020c Loose item unavailable background sp.litemunafg $020d Loose item unavailable foreground sp.infwinbd $020e Information window border sp.infwinbg $020f Information window background sp.infwinfg $0210 Information window foreground sp.infwinmg $0211 Information window middleground sp.subinfbd $0212 Subsidiary information window border sp.subinfbg $0213 Subsidiary information window background sp.subinffg $0214 Subsidiary information window foreground sp.subinfmg $0215 Subsidiary information window middleground sp.appbd $0216 Application window border sp.appbg $0217 Application window background sp.appfg $0218 Application window foreground sp.appmg $0219 Application window middleground sp.appihigh $021a Application window item highlight sp.appiavabg $021b Application window item available background sp.appiavafg $021c Application window item available foreground sp.appiselbg $021d Application window item selected background sp.appiselfg $021e Application window item selected foreground sp.appiunabg $021f Application window item unavailable background sp.appiunafg $0220 Application window item unavailable foreground sp.scrbar $0221 Pan/scroll bar sp.scrbarsec $0222 Pan/scroll bar section sp.scrbararr $0223 Pan/scroll bar arrow sp.buthigh $0224 Button highlight sp.butbd $0225 Button border sp.butbg $0226 Button background sp.butfg $0227 Button foreground sp.hintbd $0228 Hint border sp.hintbg $0229 Hint background sp.hintfg $022a Hint foreground sp.hintmg $022b Hint middleground sp.errbg $022c Error message background sp.errfg $022d Error message foreground sp.errmg $022e Error message middleground sp.shaded $022f Shaded area sp.3ddark $0230 Dark 3D border shade sp.3dlight $0231 Light 3D border shade sp.vertfill $0232 Vertical area fill sp.subtitbg $0233 Subtitle background sp.subtittxtbg $0234 Subtitle text background sp.subtitfg $0235 Subtitle foreground sp.mindexbg $0236 Menu index background sp.mindexfg $0237 Menu index foreground sp.separator $0238 Separator lines etc. Some sort of design guide to help deciding what colour to use (or what some colour is supposed to mean anyway) will hopefully be written at a later stage.