Drawing Speed of Sprite/Tile in Assembler

Anything QL Software or Programming Related.
User avatar
t0nyt
Gold Card
Posts: 385
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Drawing Speed of Sprite/Tile in Assembler

Post by t0nyt »

I was wondering if anyone has any thoughts on this Assembler topic please?

Basically I'm drawing an animated image (say 24 columns x 40 rows, nearly double rows is to get a more square perspective) on the screen in mode 8, though the animation part is irrelevant at this point

The image (sprite/tile or whatever you'd like to call it) has every 4 bits encoded as a word of colours (e.g. $6666 is 4 yellow bits) and, apart from the 8 colours (0-7), also has $F as a transparent bit

Currently I see 3 ways of writing the tile to the screen (the first 2 I have working, the third is just a thought at the moment):

1) write each word (colour converted to mode 8) which seems to work very well. The problem is that when moving the image it has to move 4 bits at a time, which isn't great. I could write much more complicated code but that will obviously mean a lot more processing

2) plot each individual pixel. Again this works well, but I can easily see the image being written to screen, so that seems a non-starter

3) This would involve the same principle as 1 above but on load the program would generate in memory 6 extra copies of the image (3 to the left, 3 to the right) and then the program would apply the image as per 1 but choose which of the 7 images it needs to stay on a word boundary. Memory hungry but should work in theory

But I was wondering if anyone has any other ideas or thoughts or has done something similar you'd be willing to share please?

I'm considering using a 2 screen switching technique, which would hide the updates between switching, but speed is still going to be important regardless of whether it's visible on screen (or even 3 screens, which would mean I wouldn't have to save the background area behind each tile at each rewrite and tiles could overlap each other without complication)

My own thought, currently, is option 3

Many thanks


User avatar
NormanDunbar
Forum Moderator
Posts: 2280
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Drawing Speed of Sprite/Tile in Assembler

Post by NormanDunbar »

t0nyt wrote: Tue Feb 27, 2024 10:10 am 3) This would involve the same principle as 1 above but on load the program would generate in memory 6 extra copies of the image (3 to the left, 3 to the right) and then the program would apply the image as per 1 but choose which of the 7 images it needs to stay on a word boundary. Memory hungry but should work in theory.
I'm definitely not a graphics guru, but if there is something in code that has to be done frequently, and takes "too long" time-wise --- whatever "too long" happens to be --- the usual fix is to do it once and use it many times. So, load your sprite tiles into RAM, convert them to screen format, and drop the original from memory. After that, it's a "simple" case of simply blitting the converted sprite tiles to the screen, or to a buffer ready to update the main screen.

Alternatively, the pointer environment has a sprite/blob writing function that might be useful. Caveat: I've never used it myself and it might not like your sprite format.


HTH

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Drawing Speed of Sprite/Tile in Assembler

Post by tofro »

On the QL, whatever your sprite format is, convert it to "screen-compatible format" not in the drawing loop, but rather outside if you want to be fast. On the QL it makes a lot of sense to pre-process the sprite data upfront (either by doing it in an initialisation routine or even outside your program).

You may also want to pre-shift your sprite data. That is, don't supply one single sprite to your drawing loop, but rather an array of 4 pre-shifted versions (in MODE 8) that you can simply pick and move/AND/OR/XOR directly into screen memory on word boundaries. This leaves the expensive shift operations out of the drawing loop.

On other than a totally unexpanded QL, memory normally is no problem at all (and even there, it's not a big one). CPU, however, is. So you need to supply as much pre-calculated data as possible. Also, sprites on the QL tend to be considerably small, no problem (normally) having several versions of them at once.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
t0nyt
Gold Card
Posts: 385
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: Drawing Speed of Sprite/Tile in Assembler

Post by t0nyt »

Thanks both, great info for me to mull over thanks

It does mean, as far as I can get my head around currently, that I'll have to sacrifice "black" so I can use 0 for transparency, but given the speed savings of pre-expanding my sprites I think that's fine

Many thanks


User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Drawing Speed of Sprite/Tile in Assembler

Post by tofro »

t0nyt wrote: Tue Feb 27, 2024 1:16 pm Thanks both, great info for me to mull over thanks

It does mean, as far as I can get my head around currently, that I'll have to sacrifice "black" so I can use 0 for transparency, but given the speed savings of pre-expanding my sprites I think that's fine

Many thanks
You can, of course, sacrifice "black", but a better (and much more popular) mehod is to have a sprite mask (or, rather, four of them, pre-shifted) in addition to the sprite itself that holds "1" bits for parts that are relevant to the sprite and a "0" bit for transparent areas. You can then "stencil out" the background where the sprite is going to end up (an AND with the inverse mask) and simply "OR" the sprite data in.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
t0nyt
Gold Card
Posts: 385
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: Drawing Speed of Sprite/Tile in Assembler

Post by t0nyt »

tofro wrote: Tue Feb 27, 2024 1:44 pm
t0nyt wrote: Tue Feb 27, 2024 1:16 pm Thanks both, great info for me to mull over thanks

It does mean, as far as I can get my head around currently, that I'll have to sacrifice "black" so I can use 0 for transparency, but given the speed savings of pre-expanding my sprites I think that's fine

Many thanks
You can, of course, sacrifice "black", but a better (and much more popular) mehod is to have a sprite mask (or, rather, four of them, pre-shifted) in addition to the sprite itself that holds "1" bits for parts that are relevant to the sprite and a "0" bit for transparent areas. You can then "stencil out" the background where the sprite is going to end up (an AND with the inverse mask) and simply "OR" the sprite data in.
Many thanks

Will code it that way then


User avatar
t0nyt
Gold Card
Posts: 385
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: Drawing Speed of Sprite/Tile in Assembler

Post by t0nyt »

Well I've implemented all of the suggestions/recommendations and got it working great, many thanks

But now I've started to add more sprite data it now won't assemble as it says the LEA is "value out of range" (with more failing as I add more sprite data & workspace)

I'm assuming this is something to do with the distance between the LEA commands and ds.w sections I've created to hold the bit adjusted versions

I'm going to have to go back to the drawing board and try to understand how memory addressing works in qmac (& in general on the QL)


User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Drawing Speed of Sprite/Tile in Assembler

Post by tofro »

t0nyt wrote: Wed Feb 28, 2024 6:42 pm Well I've implemented all of the suggestions/recommendations and got it working great, many thanks

But now I've started to add more sprite data it now won't assemble as it says the LEA is "value out of range" (with more failing as I add more sprite data & workspace)

I'm assuming this is something to do with the distance between the LEA commands and ds.w sections I've created to hold the bit adjusted versions

I'm going to have to go back to the drawing board and try to understand how memory addressing works in qmac (& in general on the QL)
That's probably because you are using PC-relative adressing and your address is more than +/- 32k away. The 68000/8 simply cannot do that (later 68k CPUs can).

A simple way to extend that reach and still have fully reloctable code is to use something along the following:

Code: Select all

* This macro loads an address register in a "PC-relative" 
* way with an address value that would normally be 
* unreachable for PC-relative addressing. 
FARREF          MACRO   target,register           
                lea     .lab[.L],[register]           
                add.l   ([register]),[register]           
                bra.s   .across[.L] 
.lab[.L]        dc.l    [target]-*
.across[.L]
                ENDM
If you want to load an address register with a faraway location, simply use it like

Code: Select all

        FARREF    farawayLabel,A5
         
That is obviously taking a few more cycles than a simple LEA, so you might want to hold that value as long as you can in a register.

This will load a5 with the address of "farawaylabel" which can be further than 32k away.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
t0nyt
Gold Card
Posts: 385
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: Drawing Speed of Sprite/Tile in Assembler

Post by t0nyt »

Thanks Tofro, will give that a try

Many thanks


User avatar
t0nyt
Gold Card
Posts: 385
Joined: Wed Nov 22, 2023 6:46 pm
Location: UK

Re: Drawing Speed of Sprite/Tile in Assembler

Post by t0nyt »

t0nyt wrote: Wed Feb 28, 2024 7:11 pm Thanks Tofro, will give that a try

Many thanks
That's worked a treat, thanks

Will have a play around though to see if I can restructure what little code I've done so far

Many Thanks


Post Reply