CMM2 graphics examples and explanation


Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11174
Posted: 01:55pm 10 May 2020      

BLIT

Blit does a memory to memory copy. End of lesson.

Well perhaps not but that is all it is doing behind the scenes. Lets look at the BLIT syntax

BLIT x1, y1, x2, y2, w, h [, page] [,orientation]


This says copy part of the image which has a top left position of x1,y1, a width of w, and a height of h to a new position with a top left position of x2, y2.

An example:

' Draw a simple shape on the screen
CLS
box 100,100,100,100,5,rgb(red),rgb(blue)

'copy the box to a new location with a top left corner at 300,300
blit 100,100,300,300,100,100


By the way that copy took 88 microseconds which equals 100*100/0.000088=113 Mbytes/Sec. BLIT is very fast

Thinking back to the first post, we know what was just happening and we could have done the copy in Basic


CLS
box 100,100,100,100,5,rgb(red),rgb(blue)

'copy the box to a new location with a top left corner at 300,300
page_address%=mm.info(page address 0)
x1%=100
y1%=100
x2%=200
y2%=200
w%=100
h%=100
for y%= 0 to h%-1
 for x%= 0 to w%-1

'calculate the address of the source pixel
   pix_in%=MM.HRES * (y% + y1%)+ x1% + x% + page_address%

'calculate the address of the destination pixel
   pix_out%=MM.HRES * (y% + y2%)+ x2% + x% + page_address%

'copy the pixel
   poke byte pix_out%, peek(byte pix_in%)
 next x%
next y%
 


This takes just over half a second - BLIT is faster!!!

Try the following commands:
timer=0:blit 100,100,300,300,100,100:?timer
timer=0:blit 100,100,301,301,100,100:?timer
timer=0:blit 101,101,301,301,100,100:?timer


The timings I get are 88uSec, 155uSec, and 214uSec. The STM32 is much faster when it can copy data that is aligned on 4 byte boundaries. For most applications this won't matter but for a very high performance game it is something to take into account.

Now lets explore the orientation parameter of the BLIT command. This is most easily explained by a couple of examples

CLS

' draw a large number 4
text 100,100,"4",,6,,rgb(red),rgb(blue)

' copy the "4" but mirror it left to right
blit 100,100,200,100,32,50,,1

' copy the "4" but mirror it top to bottom
blit 100,100,100,200,32,50,,2

' copy the "4" but mirror it top to bottom and left to right (rotate 180)
blit 100,100,200,200,32,50,,3

do:loop





CLS

' draw a large number 4
text 100,100,"4",,6,,rgb(red)

' draw a colour box
box 180,180,72,90,0,rgb(blue),rgb(blue)

' move the text but only non-transparent (non-zero) pixels
blit 100,100,200,200,32,50,,4

do:loop





Of course the orientation bits can combined in any combination

If you BLIT from one area to another that overlaps it then BLIT is clever enough to understand this and deal with it by buffering the original and then writing out the new version.

Up to now we have ignored the page parameter in BLIT but this is perhaps the most powerful aspect of the command.

As we saw in a previous post we can use PAGE WRITE to set drawing output to any of the video pages available but we will always see what is in page 0. The page parameter in BLIT specifies the page that BLIT will read from and then it will write to the page specified by PAGE WRITE.

Another example needed. We can use BLIT to create the basis of a sliding block puzzle

'set output to page 1
page write 1

' clear page 1 to blue
cls rgb(blue)

'write the numbers 1 to 8 spaced 50 pixels apart
' font 6 is 32x50 pixels
for i = 1 to 8
   text i*50+10,0,str$(i),,6,,rgb(red),-1
next i

'now we want to randomize the numbers for our grid including the missing one
dim r(8)=(9,9,9,9,9,9,9,9,9) 'create an array to hold the positions
for filled=0 to 8
 do
   test=rnd(8) 'get a random number between 0 and 8
   for j=0 to filled 'check all the filled cells to see if we have already used this number
     if r(j)=test then test=9 ' if yes then set no-good
   next j
   if test<>9 then r(filled)=test 'if OK then store the number
 loop while r(filled)=9 'loop until that cell is filled
next filled

'Now we will go back to the view page
page write 0
cls

' create a background for the grid
box 100,100,170,170,0,rgb(green),rgb(green)

' now copy the randomised numbers into our grid
for x=0 to 2
 for y=0 to 2

'get the x position of the randomised number in page 1
   xsource = r(x * 3 + y) * 50

' blit the number from page 1 to page 0
   blit xsource, 0, x * 55 + 105, y * 55 + 105, 50, 50, 1
 next y
next x





This simplistic example is how Mauro weaves his magic. You can create any useful graphics you want on one or more hidden graphics pages. Then you can use BLIT to move parts of the image between them, including potentially onto page 0. And, of course, you can mirror or rotate the parts of the image as you move them.

There are two more BLIT commands in the manual: BLIT READ and BLIT WRITE, but we will leave these until we deal with sprites.

Next post will look at the various graphics modes supported by the CMM2.