Ignoring the signed stuff, since I think that actually complicates things:
Subtract the scroll position from the object position. Add the offset each hardware sprite is drawn to. If the high byte is non zero after these operations, the hardware sprite is offscreen.
So say you've got a 16x16 player, made of 4 hardware sprites (the four corners of the 16x16 player). The 16 bit position (OBJxlow and OBJxhigh) is the top left corner.
Code:
lda OBJxlow,x
sec
sbc scrollxlow
sta templow
lda OBJxhigh,x
sbc scrollxhigh
sta temphigh
beq spriteleftonscreen;The high byte is zero, so the left half of the sprite is on screen
cmp #$FF;If we're at a position like $FFFF, then adding the offset might still make the right two sprites appear, even though the left two are offscreen
beq spriterightstart
;Any other high byte is off screen. If it's 1 (or greater), this means the left part of our sprite is to the right of the screen,
;so the right parts will obviously also be to the right of the screen
;So just return
rts
spriteleftonscreen:
;Draw the left two sprites. It's possible for only the top left, or bottom left sprite to be on screen
;But this example ignores Y
jsr drawlefttwo
spriterightstart:
lda templow
clc
adc #8
sta templow
lda temphigh
adc #0;If the high byte is non zero for the right two sprites
bne spritedrawend;there's no more sprites to offset, so we're done
jsr drawrighttwo
spritetotallyoffscreen
spritedrawend:
rts
If the sprites are on screen, the X position for the left two sprites is templow (the result of the subtraction of scroll from position). The X position for the right two sprites is templow+8.
But for arbitrary sprites, it's templow+whatever their offset is from the "real" position.
Same for Y.
Edit: Okay, after thinking about it I know what you mean by signed.
Just sign extend, and you'll be good. Instead of adding 8 like the example, you'd do something like
Code:
lda #$FF
sta temp1;Start with negative high byte for the sprite's offset
ldy spriteoffsetindex;Load the signed 8bit offset however you do that
lda signedoffsettable,y
bmi nosignfix;If it's negative, the high byte in temp1 is already correct
inc temp1;Else, it should be zero
nosignfix:
clc
adc templow
lda temp1
adc temphigh
bne spriteoffscreen
;draw sprite here
spriteoffscreen:
rts
Edit2: One thing I might recommend is also subtracting the left most sprite offset from the object's position before the loop that checks for offscreen/draws for each sprite. This allows you to never need a negative offset. (If the offsets are -8, -4, 2, 6 and 10, they become 0, 4, 10, 14, and 18 and you subtract 8 from the overall position before you run the routine.)
If your objects are bigger than one sprite, you're potentially saving because you're doing one thing per object rather than per sprite and you get a speed boost out of not having to sign extend. That's what I do, but I had to write a program to go through my data so that getting the leftmost offset was easy.