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 pattern with a blob produces a visible object, aka a Sprite. (However, nowadays we can also have solid sprites, ie sprites consisting only of a pattern and no blob (aka mask).)

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 long word
  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 4094 pixels, ie nominally 64x64 pixels in size
  13. In practice it appears that QL mode pointer sprites are limited to 64x48 pixels (= 3072 pixels?)
  14. Patterns and blobs need not be of the same mode!

There is more, much more. For the excuciating detail you need the Qptr manual (at time of writing V6.5). A 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 124 - 158). 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: The program below requires EasyPtr's ptrmen_cde to display the blob, or exchange WBLOB to Qptr's LBLOB.

Either supply your own blob or sprite or use the in-built one. 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! Notice that the supplied blob, Snow, is a QL mode 4 sprite!

Similar routines to the ones below do the magic in QOMBI, that allow the card symbols be of any colour you choose.


100 rem Use built-in blob or load one
102 IF 0 THEN
104  rem You can find some blobs in the QOMBI dat directory
106  blb = LoadDat('win1_qmb_dat_s3_OF_blb'): ERT blb
108 ELSE
110  blb = Snow:                            rem Use built-in blob
112 END IF
114 :
116 ch = FOPEN('con')
118 sx% = PEEK_W(blb + 4): sy% = PEEK_W(blb + 6): rem Assumes origen = 0, 0
120 WINDOW#ch; sx% * 4.8, sy% * 2, 20, 20
122 BORDER#ch; 1, 2
124 PAPER#ch; 7: CLS#ch
126 :
128 gap% = 4.5 * sx% / 4
130 xp% = 10
132 yp% = (sy% * 2 - 3 * sy% / 2)
134 :
136 pat = MkPat64:                          rem Init
138 CHG_COL64 pat, 0:                       rem Set black
140 :
142 WBLOB#ch; xp%, yp%, blb, pat
144 xp% = xp% + gap%
146 :
148 CHG_COL64 pat, $FF0000:                 rem Red
150 WBLOB#ch; xp%, yp%, blb, pat
152 xp% = xp% + gap%
154 :
156 CHG_COL64 pat, $FF:                     rem Blue
158 WBLOB#ch; xp%, yp%, blb, pat
160 xp% = xp% + gap%
162 :
164 CHG_COL64 pat, $FF00:                   rem Green
166 WBLOB#ch; xp%, yp%, blb, pat
168 PAUSE#ch
170 QUIT
172 :
174 :
176 :
178 rem + ------------------------------------------------------------------------ +
180 rem |<                                MkPat64                                 >|
182 rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +
184 rem |                    Create RGB 16 X 1 colour pattern                      |
186 rem |                                                                          |
188 rem | Creates the container for a RLE-compressed pattern.                      |
190 rem | Set or change the colour with CHG_COL64                                  |
192 rem + ------------------------------------------------------------------------ +
194 rem | V0.02, pjw, 2018 Dec 02                                                  |
196 rem | V0.03, pjw, 2021 Nov 16, new name, streamlined code, no GLOBal variables |
198 rem + ------------------------------------------------------------------------ +
200 :
202 DEFine FuNction MkPat64
204 LOCal ad
206 ad = ALCHP(37): IF ad <= 0: RETurn -3:  rem 24 + 8 + 5
208 :
210 rem     Create sprite header
212 POKE   ad,       2, 64, 0:              rem GD2 mode 64 sprite..
214 POKE   ad +  3, %1000011:               rem Pattern compressed, dont cache
216 POKE_W ad +  4, 16, 1, 0, 0:            rem Size, origen
218 POKE_L ad + 12, 12,  0, 0:              rem Offset to data
220 POKE$  ad + 24, 'RLE4':                 rem Compression header
222 POKE_L ad + 28, 64:                     rem Expanded data size
224 RETurn ad
226 END DEFine MkPat64
228 :
230 DEFine PROCedure CHG_COL64(adr, rgb)
232 POKE_L adr + 32, rgb
234 POKE   adr + 32, CHR$(241):             rem 257 - 16
236 END DEFine CHG_COL64
238 :
240 :
242 :
244 rem + ************************************************************************ +
246 rem *<                         Help routines and Data                         >*
248 rem + ************************************************************************ +
250 :
252 DEFine FuNction LoadDat(fnm$)
254 LOCal fl, ad
256 ad = FOP_IN(fnm$): IF ad < 0: RETurn ad
258 fl = FLEN(#ad): CLOSE#ad
260 ad = ALCHP(fl): IF ad <= 0: RETurn -3
262 LBYTES fnm$, ad
264 RETurn ad
266 END DEFine LoadDat
268 :
270 :
272 DEFine FuNction Snow
274 LOCal ad
276 rem 57 x 48, mode 4, blob
278 :
280 ad = ALCHP(792): IF ad <= 0: RETurn -3
282 :
284 POKE_W  ad + 0, $100,$0:        rem form, time/adaption
286 POKE_W  ad + 4, $39,$30:        rem x size, y size
288 POKE_W  ad + 8, $0,$0:          rem x origin, y origin
290 POKE_L  ad + 12, 0:             rem pointer to colour pattern
292 POKE_L  ad + 16, 8:             rem pointer to pattern mask
294 POKE_L  ad + 20, 0:             rem pointer to next definition
296 :
298 POKE_W  ad + 24, $0,$0,$0,$808,$0,$0,$0,$0
300 POKE_W  ad + 40, $0,$0,$0,$7F7F,$0,$0,$0,$0
302 POKE_W  ad + 56, $0,$0,$202,$3E3E,$2020,$0,$0,$0
304 POKE_W  ad + 72, $0,$0,$606,$7E7E,$6060,$0,$0,$0
306 POKE_W  ad + 88, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
308 POKE_W  ad + 104, $0,$0,$F0F,$FFFF,$F8F8,$0,$0,$0
310 POKE_W  ad + 120, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
312 POKE_W  ad + 136, $0,$0,$303,$FFFF,$F0F0,$0,$0,$0
314 POKE_W  ad + 152, $0,$2020,$303,$FFFF,$E0E0,$101,$0,$0
316 POKE_W  ad + 168, $303,$FCFC,$1F1F,$FFFF,$FCFC,$F0F,$E0E0,$0
318 POKE_W  ad + 184, $1111,$F8F8,$8F8F,$FFFF,$F8F8,$4747,$C4C4,$0
320 POKE_W  ad + 200, $3333,$F9F9,$9F9F,$FFFF,$F8F8,$CFCF,$CCCC,$0
322 POKE_W  ad + 216, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
324 POKE_W  ad + 232, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
326 POKE_W  ad + 248, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
328 POKE_W  ad + 264, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FEFE,$0
330 POKE_W  ad + 280, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FCFC,$0
332 POKE_W  ad + 296, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
334 POKE_W  ad + 312, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
336 POKE_W  ad + 328, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
338 POKE_W  ad + 344, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
340 POKE_W  ad + 360, $1111,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$C4C4,$0
342 POKE_W  ad + 376, $303,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$E0E0,$0
344 POKE_W  ad + 392, $0,$7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$8080,$0
346 POKE_W  ad + 408, $0,$3F3F,$FFFF,$FFFF,$FFFF,$FFFF,$0,$0
348 POKE_W  ad + 424, $303,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$E0E0,$0
350 POKE_W  ad + 440, $1111,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$C4C4,$0
352 POKE_W  ad + 456, $3333,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$CCCC,$0
354 POKE_W  ad + 472, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
356 POKE_W  ad + 488, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
358 POKE_W  ad + 504, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
360 POKE_W  ad + 520, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FEFE,$0
362 POKE_W  ad + 536, $1F1F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FCFC,$0
364 POKE_W  ad + 552, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
366 POKE_W  ad + 568, $7F7F,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
368 POKE_W  ad + 584, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$0
370 POKE_W  ad + 600, $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$8080
372 POKE_W  ad + 616, $1111,$F8F8,$8F8F,$FFFF,$F8F8,$4747,$C4C4,$0
374 POKE_W  ad + 632, $303,$FCFC,$1F1F,$FFFF,$FCFC,$F0F,$E0E0,$0
376 POKE_W  ad + 648, $0,$6060,$303,$FFFF,$E0E0,$101,$0,$0
378 POKE_W  ad + 664, $0,$0,$707,$FFFF,$E0E0,$0,$0,$0
380 POKE_W  ad + 680, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
382 POKE_W  ad + 696, $0,$0,$F0F,$FFFF,$F8F8,$0,$0,$0
384 POKE_W  ad + 712, $0,$0,$1F1F,$FFFF,$FCFC,$0,$0,$0
386 POKE_W  ad + 728, $0,$0,$303,$3F3F,$3030,$0,$0,$0
388 POKE_W  ad + 744, $0,$0,$202,$3E3E,$2020,$0,$0,$0
390 POKE_W  ad + 760, $0,$0,$0,$7F7F,$0,$0,$0,$0
392 :
394 RETurn ad
396 END DEFine Snow
398 :
400 :

Generated with sb2htm on 2019 Jun 06
©pjwitte March 2oi9