I do something similar to cut metasprites off at the edges of the screen. (This example assumes metasprites are never wider than 128 pixels.) Not using overflow, though.
Code:
sprite_draw:
; ... various sprite setup ...
; test for edge
lda sprite_x
rol
eor sprite_x
bpl draw_at_edge
; if (x & $80) ^ ((x<<1) & $40) then x >= 64 and x < 196, not at edge
draw_normal:
; ... draw sprite tiles normally ...
rts
draw_at_edge:
; ... setup for tile drawing loop ...
:
; ... generate Y, tile, attribute ...
lda (metasprite), Y ; this byte of metasprite is X-offset
iny
clc
adc sprite_x
sta tile_x ; tile_x = sprite_x + metasprite_x
; wrap test
; compute: (tile_x ^ sprite_x) & $80
; if the high bit of tile and sprite X do not match, it has wrapped
eor sprite_x
bpl @not_wrap
@wrap:
; ... skip tile, it has wrapped ...
@not_wrap:
; ... add tile, it is fine ....
; ... continue loop ...
rts
Actually, it's kinda funny how the overflow bit is used for the example you posted, since it's normal for a signed comparison to involve an eor #$80. Kind of what you expect to be doing for signed operations anyway, just applied here in a bit of clever code that was thinking about a different problem (that wasn't really as different as it looked).
I do something very similar for metasprites at screen edge too.
Nice trick! I too did something similar for clipping metasprites, but this method is simpler. This is inside a playfield that's smaller than 256x256 pixels though, meaning that all coordinates are inside the screen. In a game that scrolls, the initial coordinate might very well be outside the screen, and enter the screen after the delta is applied. This might need some extra logic, and the high byte of the coordinate may have to be considered at some point.
It'd still be useful for, say, destroying things that leave the screen in a scrolling game that uses screen-space coordinates for everything like Contra does.
tepples wrote:
a scrolling game that uses screen-space coordinates for everything
I can't get over how insane that is.
Yeah, once you've got 16-bit positions, detecting wrap is usually a really straightforward test of the high byte.
Once you've got 16-bit positions but 8-bit velocities, or 24-bit positions but 16-bit velocities, you still need a check on the high byte to determine whether the position has wrapped from the beginning of the level to the end of the level.