SpriteOp 35 (Append) Without Delete?
Michael Emerton (483) 136 posts |
Hi guys, I am using SpriteOp 35 to append sprites together and this works fine except that I loose the original sprite I am appending. I am currently getting around this using SpriteOp 27 to copy it first, however this is expensive in CPU. I have looked, but nothing jumps out at me. Is there a way to append without deleting the original, or would I need to get some assembler to do this (I am in BASIC). Background: I created a bitmap font engine ages ago which scrolls by re-plotting out each char at a different X co-ordinate, this was stupidly slow and you can see it update (on a Pi) if I have more than 1 on the screen at once. I tested and realised that having the whole bit of text (Track name) as one sprite is much better (obviously…fewer BASIC instructions), so I created code to render a sprite using the method above…but now rendering can take 4 seconds before anything appears. Cheers Michael |
Michael Emerton (483) 136 posts |
Or… Is there a better way? :@) |
Jeffrey Lee (213) 6048 posts |
Yes there is :-) Using OS_SpriteOp 35 is going to be pretty slow because it will have to keep moving memory around. If you’re appending horizontally, then each time it will have to copy (almost) the total size of both sprites. Perhaps more if there are other sprites within the area (I’m not sure whether it retains the order of the sprites or places the combined sprite at the end of the area). And each sprite that you append to the destination, the larger the destination will become, increasing the amount that needs moving the next time round. It would be much better to create a blank sprite that’s large enough to hold the text. Then redirect screen output to it using OS_SpriteOp 60, plot all the sprites to it using regular plot calls, then switch output back to the screen (just call OS_SpriteOp with the R0-R3 values that OS_SpriteOp 60 returned with). If you want a mask then you can redirect output to the mask using OS_SpriteOp 61 and then plot the letter masks using (e.g.) OS_SpriteOp 50. For best performance when rendering the result to the screen, make sure the sprite has the same mode (and palette if necessary) as the screen. However – unless you’re dealing with very small letters – I’d expect that the savings from pre-compositing into one sprite wouldn’t be that great compared to just plotting everything manually using OS_SpriteOp 34. OS_SpriteOp 34 doesn’t do any colour translation, so it will require the sprite mode + palette to match that of the screen. But this also means it’s the fastest way of plotting sprites. And the golden rule with any high-performance sprite code is to use sprite pointers, not sprite names. If you use sprite names then the OS has to look through all the sprites in the area until it finds the right one, which can be pretty slow when you’ve got lots of sprites in the same area (e.g. fonts) |
Michael Emerton (483) 136 posts |
Cheers guys, I have now written a version using SpriteOp 60. However I am now getting an issue where it throws Error &19 Not enough memory to change to this screen mode at line: SYS “OS_SpriteOp”,15+256,SpriteArea%,Name$,HasPalette%,W%,H%,ColourDepth% SpriteArea% contains the font sprites I am assuming it’s my ColourDepth% variable which is wrong here, I am using the OS StrongHelp manuals and I am not entirely happy I get the ‘Sprite Type’ definition… I think it should be decimal 64 to represent bit 6 being flaged? I used 60+256 instead of 60+512 as I was unsure of how to get the pointer to the sprite I have not yet created… Clearly doing something wrong! |
Michael Emerton (483) 136 posts |
Any ideas? |
edwardx (1628) 37 posts |
What you actually tried to create is a mode 64 sprite. Sprite mode words are documented here on the wiki, if that’s any clearer than StrongHelp. You need to put 6 in bits 27-31, the vertical dpi in bits 14-26, the horizontal dpi in bits 1-13, and bit 0 needs to be 1 so that the OS knows this isn’t a pointer to a mode selector. I think the value you want is (6<<27) + (90<<14) + (90<<1) + 1, but I haven’t tested this. |
Michael Emerton (483) 136 posts |
Cheers Guys! I thoguht it would be something like that, however, until now, I have never bit shifted! I think the strong help OS manual needs to be made a little bit clearer or an example put in? I would use SpriteOP 16, however my resultant sprite is MUCH wider than even 1920! I would like to confirm that that is …ALOT… faster, :@D Thanks again! |
Michael Emerton (483) 136 posts |
Ah, good point, I will look at that! OK, so I have somethine working (it does seem alot better than before, however I appear to be having issues deleting the sprites. I have 3 sprites for scrolling, when I update the text, I delete the old sprites and re-run the creation process. As I am using pointers I simply used SpriteOP 35+512 to remove them. When I delete the second one I get an Internal Error: AODT @ &FC02D134. I have made sure that the Sprite Area and Sprite Pointers are correct, and they were being used to plot to the screen. This is what Reporter’s Where gives me:
Cheers :@) |
Jeffrey Lee (213) 6048 posts |
I have 3 sprites for scrolling, when I update the text, I delete the old sprites and re-run the creation process. When you delete a sprite, all the sprites which occur after it in the sprite area will be shuffled down to fill the gap. So if you’re deleting the sprites in the same order that they were created then the first sprite you delete will invalidate your cached pointers for the other two sprites. Possible solutions:
|
Michael Emerton (483) 136 posts |
Thanks Jeffrey, I thought it would be something like that, as I was thinking about memory fragmentation… Another StrongHelp manual addition here ;@) |
Michael Emerton (483) 136 posts |
Yep, that indeed did do the trick! Only issue now is that something is causing BASIC to break now : |
Michael Emerton (483) 136 posts |
Yep, that indeed did do the trick! Only issue now is that something is causing BASIC to break now : |