Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
What was the problem Oblo?
Read: <!-- l --><a class="postlink-local" href="http://www.boriel.com/forum/how-to-tutorials/tutorial-how-to-put-inline-assembly-functions-into-zx-basic-t729.html?hilit=mirror">how-to-tutorials/tutorial-how-to-put-inline-assembly-functions-into-zx-basic-t729.html?hilit=mirror</a><!-- l -->
This is the discussion where that came about. The fastest mirror solution is the one at the bottom of the page you linked to - faster and shorter by far than any other solution I've seen, though the maths are a bit brain aching if you try to understand how it does it.
If you want to vertically mirror, it's a matter of swapping the byte order - so instead of first byte to last, you read it last byte to first. Easier if you just peek then poke to your sprite buffer in forward or reverse order when switching the up/down direction.
Left to right you read the bytes into your live sprite buffer poke sprite1, peek (data1) Right to left, you do poke sprite1, hmirror(peek data1)
Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
Yes - it doesn't mirror a sprite. It returns the input number with the bits reversed.
So hmirror (1) = 128 or in binary hmirror (%00000001) = %10000000
And hmirror (64) =2 or in binary hmirror (%01000000) = %00000010
And so on.
You have to run it over the sprite's data to retrieve each byte the other way around. This means you have a couple of choices - you can reverse each byte of the sprite using hmirror and write it back, so the sprite graphic changes direction in memory (either in a buffer, or where it's stored). You'll have to print multiple square sprites in reverse order too - so a 16 pixel wide sprite tha't's AB becomes mirrored B followed by Mirrored A.
Alrternatively your routine to put it on the screen can choose to poke up reversed bytes if you are doing more direct screen manipulation.
But if you had a standard UDG you could left right reverse it by doing
for i = USR "A" to USR "A" +7
poke i, hmirror (peek i)
next i
For example. This would iterate over the UDG and mirror it left/right - you'd presumably run this when changing directions.
Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
Another way of doing it is to have (maybe compressed?) sprite data in storage, and unpack the sprites you need for this particular screen or part of the game to a buffer or workspace. You could then write out the reverse versions of these from one part of the workspace to another using the mirroring function.
Note that the fastest way to mirror a byte is a lookup table - so the first entry in the table is the mirror of "1" (128) and the second entry is the mirror of "2" (64), the third entry is the mirror of "3" (192) and so on.
The mirror code is pretty small and tight, though - and especially if you are using this to buffer out sprites in a screen by screen scenario, probably not too bad.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
Another (memory expensive) faster way to reverse the bit in a byte is to have a table:
[0] -> [0]
[1] -> [BIN 10000000]
[2] -> [BIN 01000000]
.. and so on
but yet again you still have to reverse the byte order (this can be done in the routine if it reads the bytes in reverse order in memory)