Sprite Left Hand Wastage?
Andy S (2979) 504 posts |
I’m struggling to understand the full implications of a sprite with “left hand wastage” when trying to read the pixel values from memory. The docs say Although each row is word aligned, the first pixel of each row may not start on a word boundary. Use word 6 of the sprite header to determine which bit of the word constitutes the first bit of the image. This is known as ‘left-hand wastage’. But does this mean that sprites may exist with left hand wastage that’s not a whole number of bytes? For example, if a sprite had left hand wastage of 6 bits, won’t every byte on the row effectively have been shifted by 6 bits across byte boundaries? The doc does say For a sprite to be considered valid, the first used bit and last used bit (plus one) must be multiples of the sprite bits per pixel, i.e. sprite data must begin and end on a pixel boundary. So I suppose this rule has the effect that the pixel data will always stay byte aligned because the left hand wastage always has to be a whole number of pixels – am I understanding that correctly? |
Rick Murray (539) 13840 posts |
Just off the top of my head in the car, I think the wastage is (was?) an issue with low colour sprites such as those with 8, 4, or 2 pixels per byte; the wastage saying that the start of the pixel data won’t necessarily be the start of the data. |
Jeffrey Lee (213) 6048 posts |
Yes, the pixel data will always be aligned to the size of the pixel. But whether the pixels will be (at least) byte aligned is dependent on the colour depth – e.g. at 2bpp they’re only guaranteed to be aligned to 2 bit boundaries. Rick’s right about the wastage only really affecting <= 8bpp sprites; a valid sprite is only allowed to feature left hand wastage if it’s using a numbered mode, and the standard numbered modes are only 8bpp or lower (although there’s nothing stopping someone from creating their own numbered mode which is at a higher depth). The wastage also has to be less than 32, so if you’re processing the data a word at a time then the first word of each row is guaranteed to contain at least one valid pixel. |
Andy S (2979) 504 posts |
But whether the pixels will be (at least) byte aligned is dependent on the colour depth – e.g. at 2bpp they’re only guaranteed to be aligned to 2 bit boundaries. But don’t all the permissible bpp formats divide exactly into 8 (or are multiples of 8) – 1, 2, 4, 8, 16, 24, 32? If so I think that means a pixel value (or for > 8bpp the R, G, B or A value for a pixel) won’t ever be split across a byte boundary by left hand wastage. My worry was if I was reading the values into chars that I might have to read two at a time, do a shift and add them together to extract pixel data when there was left hand wastage but it sounds like this isn’t the case, which is good, thanks :) Is anyone going to complain if Paint just removes the left hand wastage from sprites under some circumstances? Is there any legitimate use for it? I can imagine some programmers trying to use it to store extra data in a sprite lol, I’m not sure if I’d feel more admiration or disgust for that! |
Jeffrey Lee (213) 6048 posts |
But don’t all the permissible bpp formats divide exactly into 8 (or are multiples of 8) – 1, 2, 4, 8, 16, 24, 32? Yes, that’s correct. (Well, except for 16bpp, where the G value will always be split across a byte boundary :-)) Is anyone going to complain if Paint just removes the left hand wastage from sprites under some circumstances? I’m not really sure why left hand wastage is supported by the sprite format. Part of me thinks it’s just Acorn being too lazy to have the OS remove the wastage when performing certain operations (e.g. adding/removing columns from the left edge of the sprite). Another part of me thinks it might be there because Acorn originally envisaged sprites as being a more generic thing – imagine having a sprite header, but instead of having the pixel data come directly after the header, you have a pointer to the pixel data. With a couple of tweaks (to allow for larger left or right hand wastage values) the sprite header is now flexible enough to be able to represent any arbitrary subrectangle of a larger buffer/sprite. And if the screen, sprites, subrectangles of the screen, subrectangles of sprites, etc. can all be represented as a sprite header and a data pointer then your “plot sprite to screen”, “create sprite from screen subrectangle”, etc. operations can all use the same routine for copying the pixel data around. |
Rick Murray (539) 13840 posts |
Consider it like this… We’re in a 1bpp mode, so one bit directly equals one pixel. For this example, bit 0 is on the left. 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 Here we have one word, which represents 32 pixels, in groups of eight on or off. Now let’s say we want to delete the three left-most columns from the entire image. There are two ways we can do this. The slow way is to move every pixel value three places to the left. While this can be done fairly easily by using bit rotation, it means subsequently rotating down the three extra bits from every subsequent word and ORing them in, repeat until the end of the line. Repeat for every row. Kinda slow. However since we have to do a fair amount of binary gymnastics to translate the bits into pixels, there is an easier method: x x x 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 There. Just mark the first three pixels as “wastage” and ignore them. Piece of cake, job done.
…which for the low-colour modes, you would need to do anyway.
Speed, I think. The original ARM clocked only four times faster than the BBC Micro’s 6502. As for stashing data there? Quite possible (four bits is a nibble) but very icky! Jeffrey – I’m inclined to think your first consideration is likely the truth, and your subsequent thoughts greatly overthinking it. :-) |