Brian Stevens wrote: > This code was sent to me offlist with a request for help using with > FBtoC. > > The syntax: var;length = address as used by: > SpriteRect;8 = SpriteWorld +_portRect > looked suspect because SpriteWorld is a handle and not pointer. > > The line of compile failure is: > a = peek(alphaPixMapAddr+offset*4+1) > which translates into: > a = *(unsigned char*)(alphaPixMapAddr + offset * 4 + 1); > > '----------------------------------- > local fn GenerateSpriteAlpha (SpriteWorld as handle, alphaWorld as > handle) > dim @SpritePixMapH as handle > dim @SpritePixMapAddr as long > dim @alphaPixMapH as handle > dim @alphaPixMapAddr as long > dim @offset as handle ,r,g,b,a > dim @x as short > dim @y as short > dim @SpriteRect as rect > > SpritePixMapH = fn GetGWorldPixMap (SpriteWorld) > SpritePixMapAddr = fn GetPixBaseAddr (SpritePixMapH) > > alphaPixMapH = fn GetGWorldPixMap (alphaWorld) > alphaPixMapAddr = fn GetPixBaseAddr (alphaPixMapH) > > SpriteRect;8 = SpriteWorld+_portRect > for x = 0 to SpriteRect.right-1 > for y = 0 to SpriteRect.bottom-1 > offset = x+y*(SpriteRect.right+4) > a = peek(alphaPixMapAddr+offset*4+1) > poke SpritePixMapAddr+offset*4+4,a > next y > next x > end fn The function gives a flood of warnings from gcc because many of the variable and parameter declarations are wrong. The compilation error, also due to a wrong type, can be reproduced by this program: '--------- dim as Handle offset offset = offset*4 // error: invalid operands to binary * '--------- The reason for the error is simple: a Handle is a kind of address, and gcc knows that it is senseless to multiply an address by anything. The rewrite of GenerateSpriteAlpha() below specifies its var types correctly, obtains spriteRect by a correct method, and is formatted according to modern convention. '---------- local fn GenerateSpriteAlpha( spriteWorld as CGrafPtr, alphaWorld as CGrafPtr ) '~'1 dim spritePixMapH as Handle to PixMap dim alphaPixMapH as Handle to PixMap dim as pointer spritePixMapAddr, alphaPixMapAddr dim as long offset dim as short x, y dim as Rect spriteRect dim as unsigned byte a spritePixMapH = fn GetGWorldPixMap( spriteWorld ) spritePixMapAddr = fn GetPixBaseAddr( spritePixMapH ) alphaPixMapH = fn GetGWorldPixMap( alphaWorld ) alphaPixMapAddr = fn GetPixBaseAddr( alphaPixMapH ) spriteRect = spritePixMapH..bounds for x = 0 to spriteRect.right - 1 for y = 0 to spriteRect.bottom - 1 offset = x + y*(spriteRect.right + 4) // •• buggy a = peek( alphaPixMapAddr + offset*4 + 1 ) // •• buggy poke spritePixMapAddr + offset*4 + 4, a // •• buggy next y next x end fn '---------- It compiles cleanly. So it must be ready to rock-and-roll? Well, not if you care about correctness. The inner loop will in general read and write outside the PixMap bounds. It's not really possible to traverse a PixMap correctly without obtaining its rowBytes: toolbox fn GetPixRowBytes( PixMapHandle pm ) = long dim as long offset rowBytes = fn GetPixRowBytes( spritePixMapH ) There's also an off-by-one error: the pixel component set in alphaWorld derives from not from the corresponding pixel in spriteWorld, but from its neighbour. Robert P.