BlbCol

Patterns and Blobs are two basic Wman objects that havent had the attention they deserve. A pattern is a (repeating) pattern of colours, but has no limits and so no shape. A blob defines a shape, but has no colour or pattern. Combining a blob with a pattern produces a visible object, aka a Sprite. (However, nowadays we can also have solid sprites, ie sprites consisting only of a blob and no pattern.)

Here are some "fun facts" about these objects that I have collected over the years. Some of these you can find spread around in the various literature, others you would normally just have to figure out yourself. So I decided to put some of the core facts down in one place:

  1. A repeat pattern as a combine partner for a blob has to be a multiple of 16 pixels wide
  2. A pattern is just a sprite without a blob
  3. A blob is just a sprite without a pattern
  4. Any sprite can be used as a (repeat) pattern, provided rule 1, above, is adhered to
  5. Any sprite can also be used as a blob
  6. Blobs are sometimes refered to as Masks or pattern masks
  7. While sprites can have "any" dimension, their data must be padded in the x-dimention to a multple of a word (QL modes)
  8. GD2 mode sprite data must be padded in the x-dimension to a multiple of a longword
  9. The rules above apply to both the pattern and the blob
  10. Alpha channel masks, however, are different: they sport extactly one byte per pixel with no padding
  11. QL mode sprites dont support alpha channels
  12. Sprites to be used as pointer sprites are limited to a maximum of 64x64 pixels
  13. Patterns and blobs need not be of the same mode!

There is more, much more. For the excuciating detail you need the Qptr manual. A very good and compact summary of the latest GD2 sprite formats can be found in the display_txt text file that comes with the SMSQ/E sources, in the extras directory. While there are other useful sources of information, these are the ones I always return to for reference.

BTW: Convention (not a strong concept in the anarchic QL world) suggests that blobs get the file extension _blb , and patterns _pat

Now to the program below: It demonstrates the colouring of a blob using a simple, programmed pattern (lines 100 - 154). In this example the pattern is created as a mode 64 object, as RGB colour coding is simple to manage. If the colour required were to come off the screen, the Channel Definition Block, or the Wman palette, it is simpler to use a Native colour pattern of the current display mode.

Note: Requires EasyPtr's ptrmen_cde to display the blob, or exchange WBLOB to Qptr's LBLOB.

To take first things first: The blob to colour is loaded. Either use your own blob or sprite or use the one supplied. Notice that the supplied blob, Snow, is a QL mode 4 sprite. The harness is not very sophisticated, so there is no guarantee that just any sprite or blob will display properly or not crash the program!

For ease and brevity, the pattern is "RLE compressed" as this then just requires a single poke to update. The RLE "instruction" to repeat the pattern 16 times is $F1, so that is the significance of line 17: To initialise the global valiable rlecnt (the 3 byte RGB code is added to this, to make up one long word).

The the display window etc is then prepared. The idea is that this program is EXecuted as an SBASIC job, so it doesnt bother to tidy after itself.

Line 29,pat = SP_COL64($000000) sets up the pattern and gives it an initial colour (black, here). You will recall that a pattern is very similar to a sprite, so the routine at line 124, SP_COL64.., reserves memory and sets up a complete 16 x 1 pixel, GD2 mode 64, sprite header and indicates that it contains an RLE compressed pattern of the supplied colour.

Line 30: Since the colour is to be changed frequently, it is necessary that SMSQ/E does not simply redraw the pattern using the old colour from the sprite cache. Hence the poke to force flush the cache. (Try REMing out line 30 and see what happens!) It could have been built into SP_COL64, but the default behaviour is desirable, and since this is a universal routine, it has been left as an ad hoc amendment.

Thereafter the CHG_COL64 routine is called each time a colour change is desired. Only a single longword poke is required.

These are the routines that do the magic in QOMBI, that allow the card symbols be of any colour you choose. <plug>If you download the program, you can try out the various blobs in the dat directory.</plug> :o)


10 rem Use built-in blob or load one
11 IF 0 THEN
12  rem You can find some blobs in the QOMBI dat directory
13  blb = LoadDat('win1_qmb_dat_s3_OF_blb'): ERT blb
14 ELSE
15  blb = Snow
16 END IF
17 rlecnt = $F1000000:                     rem GLOBal rle count = "16 of"
18 :
19 ch = FOPEN('con')
20 sx% = PEEK_W(blb + 4): sy% = PEEK_W(blb + 6): rem Assumes origen = 0, 0
21 WINDOW#ch; sx% * 4.8, sy% * 2, 20, 20
22 BORDER#ch; 1, 2
23 PAPER#ch; 7: CLS#ch
24 :
25 xi% = 4.5 * sx% / 4
26 xp% = 10
27 yp% = (sy% * 2 - 3 * sy% / 2)
28 :
29 pat = SP_COL64($000000):                rem Black initially
30 POKE pat + 3, PEEK(pat + 3) || %11:     rem Force flush cache
31 :
32 WBLOB#ch; xp%, yp%, blb, pat
33 xp% = xp% + xi%
34 :
35 CHG_COL64 pat, $FF0000:                 rem Red
36 WBLOB#ch; xp%, yp%, blb, pat
37 xp% = xp% + xi%
38 :
39 CHG_COL64 pat, $0000FF:                 rem Blue
40 WBLOB#ch; xp%, yp%, blb, pat
41 xp% = xp% + xi%
42 :
43 CHG_COL64 pat, $00FF00:                 rem Green
44 WBLOB#ch; xp%, yp%, blb, pat
45 PAUSE#ch
46 QUIT
47 :
48 :
49 :
100 rem + ------------------------------------------------------------------------ +
102 rem |<                               SP_COL64                                 >|
104 rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +
106 rem |                    Create RGB 16 X 1 colour pattern                      |
108 rem |                                                                          |
110 rem | Creates the container for a RLE-compressed pat. The colour can easily    |
112 rem | be changed by setting a new colour with CHG_COL64                        |
114 rem | Reads GLOBal rlecnt (number of times to repeat 24 bit colour).           |
116 rem + ------------------------------------------------------------------------ +
118 rem | V0.02, pjw, 2018 Dec 02                                                  |
120 rem + ------------------------------------------------------------------------ +
122 :
124 DEFine FuNction SP_COL64(rgb)
126 LOCal adr
128 adr = ALCHP(38)
130 POKE_W adr, 576, 64, 16, 1, 0, 0
132 POKE_L adr + 12, 12, 0, 0, 0, 64
134 POKE$  adr + 24, 'RLE4'
136 POKE_L adr + 32, rlecnt + rgb
138 RETurn adr
140 END DEFine SP_COL64
142 :
144 DEFine PROCedure CHG_COL64(adr, rgb)
146 POKE_L adr + 32, rlecnt + rgb
148 END DEFine CHG_COL64
150 :
152 :
154 :
1000 rem + ************************************************************************ +
1001 rem *<                         Help routines and Data                         >*
1002 rem + ************************************************************************ +
1003 :
1004 DEFine FuNction LoadDat(fnm$)
1005 LOCal fl, ad
1006 ad = FOP_IN(fnm$): IF ad < 0: RETurn ad
1007 fl = FLEN(#ad): CLOSE#ad
1008 ad = ALCHP(fl)
1009 LBYTES fnm$, ad
1010 RETurn ad
1011 END DEFine LoadDat
1012 :
1013 :
1014 DEFine FuNction Snow
1015 LOCal ad
1016 rem 57 x 48, mode 4, blob
1017 :
1018 ad = ALCHP(792)
1019 :
1020 POKE_W  ad +   0, $100,$0: rem form, time/adaption
1021 POKE_W  ad +   4, 57,48  : rem x size, y size
1022 POKE_W  ad +   8, 0,0    : rem x origin, y origin
1023 POKE_L  ad +  12, 0      : rem pointer to colour pattern
1024 POKE_L  ad +  16, 8      : rem pointer to pattern mask
1025 POKE_L  ad +  20, 0      : rem pointer to next definition
1026 :
1027 POKE_W  ad +  24, $0,$0,$0,$808,$0,$0,$0,$0
1028 POKE_W  ad +  40, $0,$0,$0,$7F7F,$0,$0,$0,$0
1029 POKE_W  ad +  56, $0,$0,$202,$3E3E,$2020,$0,$0,$0
1030 POKE_W  ad +  72, $0,$0,$606,$7E7E,$6060,$0,$0,$0
1031 POKE_W  ad +  88, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
1032 POKE_W  ad + 104, $0,$0,$F0F,$FFFF,$F8F8,$0,$0,$0
1033 POKE_W  ad + 120, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
1034 POKE_W  ad + 136, $0,$0,$303,$FFFF,$F0F0,$0,$0,$0
1035 POKE_W  ad + 152, $0,$2020,$303,$FFFF,$E0E0,$101,$0,$0
1036 POKE_W  ad + 168, $303,$FCFC,$1F1F,$FFFF,$FCFC,$F0F,$E0E0,$0
1037 POKE_W  ad + 184, $1111,$F8F8,$8F8F,$FFFF,$F8F8,$4747,$C4C4,$0
1038 POKE_W  ad + 200, $3333,$F9F9,$9F9F,$FFFF,$F8F8,$CFCF,$CCCC,$0
1039 POKE_W  ad + 216, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1040 POKE_W  ad + 232, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
1041 POKE_W  ad + 248, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1042 POKE_W  ad + 264, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FEFE,$0
1043 POKE_W  ad + 280, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FCFC,$0
1044 POKE_W  ad + 296, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1045 POKE_W  ad + 312, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
1046 POKE_W  ad + 328, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
1047 POKE_W  ad + 344, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1048 POKE_W  ad + 360, $1111,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$C4C4,$0
1049 POKE_W  ad + 376, $303,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$E0E0,$0
1050 POKE_W  ad + 392, $0,$7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$8080,$0
1051 POKE_W  ad + 408, $0,$3F3F,$FFFF,$FFFF,$FFFF,$FFFF,$0,$0
1052 POKE_W  ad + 424, $303,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$E0E0,$0
1053 POKE_W  ad + 440, $1111,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$C4C4,$0
1054 POKE_W  ad + 456, $3333,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$CCCC,$0
1055 POKE_W  ad + 472, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1056 POKE_W  ad + 488, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
1057 POKE_W  ad + 504, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1058 POKE_W  ad + 520, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FEFE,$0
1059 POKE_W  ad + 536, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FCFC,$0
1060 POKE_W  ad + 552, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1061 POKE_W  ad + 568, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
1062 POKE_W  ad + 584, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
1063 POKE_W  ad + 600, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
1064 POKE_W  ad + 616, $1111,$F8F8,$8F8F,$FFFF,$F8F8,$4747,$C4C4,$0
1065 POKE_W  ad + 632, $303,$FCFC,$1F1F,$FFFF,$FCFC,$F0F,$E0E0,$0
1066 POKE_W  ad + 648, $0,$6060,$303,$FFFF,$E0E0,$101,$0,$0
1067 POKE_W  ad + 664, $0,$0,$707,$FFFF,$E0E0,$0,$0,$0
1068 POKE_W  ad + 680, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
1069 POKE_W  ad + 696, $0,$0,$F0F,$FFFF,$F8F8,$0,$0,$0
1070 POKE_W  ad + 712, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
1071 POKE_W  ad + 728, $0,$0,$303,$3F3F,$3030,$0,$0,$0
1072 POKE_W  ad + 744, $0,$0,$202,$3E3E,$2020,$0,$0,$0
1073 POKE_W  ad + 760, $0,$0,$0,$7F7F,$0,$0,$0,$0
1074 :
1075 RETurn ad
1076 END DEFine Snow
1077 :
1078 :
  
Generated with sb2htm on 2019 Jun 06
©pjwitte March 2oi9