News:

11 March 2016 - Forum Rules

Main Menu

Flip a tile by recalculating the bytes?

Started by dACE, December 13, 2016, 02:28:52 AM

Previous topic - Next topic

dACE

On GB a tile is defined by 16 bytes.
Is there a way of flipping that tile (horizontally) by calculation?

I have space for custom ASM and thought I could save space by eliminating redundant tiles - if they can be flipped by code.

Anyone care to explain the math involved?

/dACE

BlackDog61

I guess... You just have to figure the bits per pixel, width, height, and flow.

The tile is generally expressed as a series of continuous bytes. And in general they go line-by-line (so if the tile is 8*8 in 2 bits per pixel, I assupme it's coded on 16 bytes with the first 2 bytes are the first line.)
Thus the operation to do is to read the 2-bits pairs in reverse series per line, and write them in series to a destination 16 bytes.
Reading bits involves reading 1 byte, then masking and shifting as needed.

Is that enough for you to propose pseudo ASM code here?

assassin

#2
<-- knows nothing about GB anything, so this is just from checking the format at http://fms.komkon.org/GameBoy/Tech/Software.html

if the tile is part of a sprite, it can be flipped in hardware.  otherwise, i think you'll want to do something like:

counter = 8
clear carry
loop:
rotate right bottom_byte
rotate left top_byte
dec counter
if (counter > 0), goto loop
rotate right bottom_byte
swap top_byte, bottom_byte


then repeat that for the remaining 7 lines.

dACE

Thanks guys.

I'll post a concrete example and some more info later today.

/dACE

assassin

#4
guess mine's more of a beginner algorithm, and not so fast.  it can be reduced by some cycles (at the tradeoff of some space) by ditching the loop and just typing out all 16 rotate instructions within.

some Googling comes up with speedier ways:
http://stackoverflow.com/questions/2602823/in-c-c-whats-the-simplest-way-to-reverse-the-order-of-bits-in-a-byte
http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious
http://www.retroprogramming.com/2014/01/fast-z80-bit-reversal.html

using a lookup table speeds things up, but you might not have 256 free bytes.  there's a method in the first link that uses a 16-byte lookup table as a middle ground, for instance.

assuming the third link is adaptable to the GB's custom CPU, it's pretty sweet.

dACE

OK - so now I have done a comparison between actual data.

UnFlipped:

80 01 C0 03 E0 07 F0 0F F0 0F F8 1F FC 3F FE 7F

Flipped:

01 80 03 C0 07 E0 0F F0 0F F0 1F F8 3F FC 7F FE

Assuming the register de contains the address to the UnFlipped byte sequence
and the register hl contains the address to the Flipped byte sequence, this snippet
should do the trick:


0E 08 ld c,08

13 inc de
1A ld a,(de)
22 ldi (hl),a

1B dec de
1A ld a,(de)
22 ldi (hl),a

13 inc de
13 inc de

0D dec c
79 ld a,c
B7 or a

20 F3 jr nz


Unless the pattern of this tile is to simple and the byte swapping just happen to work in this particular case. I have to test it IRL before I know for sure - but it looks promising.

/dACE

snarfblam

That's not a great image to test this sort of thing with. It looks like you're just swapping bitplanes, which in that case produces the same result as a horizontally flipped image.

I believe you need to reverse the order of the bits for each byte. So eight times for each byte, shift the source byte left, take the bit you shifted out, and shift it right into the destination byte.