|
Subject: Re: [stella] Another day, another problem... From: "Andrew Davie" <adavie@xxxxxxxxxxxxx> Date: Fri, 9 Mar 2001 22:56:07 +1100 |
Its a bit hard to figure exactly the context in which you need this.
As Thomas's reply suggests, if you just want to know if you've wrapped under
0 or over 160... then it's pretty trivial. He suggests a value of $5F,
which is really just comparing with 160 in a round-about way. If you're >,
then you're out of bounds. Why? Because -1, -2, etc... are represented in
binary as $FF, $FE, etc.... which as unsigned numbers are > 160 (ie: you can
use your right bound to determine BOTH a left/right bound overflow).
But I don't think that's what you were asking.
If you want to bound the values, either wrapping or bouncing off the
edges... its a bit more difficult.
This code simply halts movement at left/right edge
'increment' is assumed to be movement value (+ or -)
clc
lda value
adc increment
cmp #$A0
bcc OK
ldx increment
bmi wrapleft
lda #159 ; restrict to right edge
bne OK
wrapleft lda #0 ; restrict to left edge
OK sta value
The following code will, instead, wrap the bullet to the other side of the
screen
It doesn't need to know the increment... it just assumes the bullet has just
been moved.
sec
lda value
sbc #$A0
bcs OK ; within range, so OK
cmp #$20 ; >C0 (A0+20) means a decrement overflow, <$C0 means an
increment overflow
bcc save
adc #$3F
save sta value
OK
It allows a bullet to be traveling up to 32 pixels/step before it fails to
correctly detect/wrap.
Consider a bullet at pixel 2, moving left by 8 pixels/frame.
The movement will set the new value to -6 (2-8) = $FA or so.
We WANT it to wrap to 160-6 = 154... which is $9A
The code then goes
$FA-$A0 = $5A
which is > $20, so it adds $40 (3F+carry) = 9A... QED
Consider when the missile is at 154 and it moves right by 20
The movement will set the new value to 174.
We WANT it to wrap to 14 (174-160)
The code goes
174-160 = 14
which is <$20, so it stores the new result
Disclaimer: Looks OK to me. I may have made some trivial errors, as I
haven't thoroughly tested the math... just presenting the idea.
Now, to tackle the other possibility... if you wanted it to bounce off the
boundary (ie: -6 -> 6 and 174 -> 160-14 = 146)
This is a bit more tricky. The assumption is you just have the value, and
you don't know if you've incremented or decremented. If you knew which, of
course, the solution would be more trivial (cmp #160 / bcc OK / etc)
lda value
cmp #$A0
bcc OK ; within 0-160
cmp #$C0 ; detect left/right overflow
bcc roverfl
eor #$FF
adc #0
bcc save
roverfl
sbc #$A0
eor #$FF
adc #160
save sta value
OK
I'm probably out +/-1 in my quick hack... the values need to be checked
carefully.
If you knew the increment, as I said, it's trivial
I'll leave it to you to figure out what's happening in the next bit :))
lda value
cmp #$A0
bcc OK
ldx increment
bmi goingleft
sbc #160
eor #$FF
adc #0
bcc save ;unconditional
goingleft
eor #$FF
adc #0
save sta value
OK
Finally, there's the table-driven approach (always my favourite, right
Thomas?)
This is a 256 byte table which simply gives you your bounded value, given an
unbounded value (it could give either a bouncing-value, or a wrap-value...
depending on what you want).
ldx value
lda bounded,x
sta value
...
bounded
; first 160 OK values (0-159)
BOUND set 0
REPEAT 160
.byte BOUND
BOUND set BOUND+1
REPEND
; then 32 ">160" values which can be bounced or wrapped. Here they're
bounced
BOUND set 1
REPEAT 32
.byte 160-BOUND
BOUND set BOUND+1
REPEND
; then 32 "<0" values which can be bounced or wrapped. Here they're
bounced
BOUND set 0
REPEAT 32
.byte 31-BOUND
BOUND set BOUND+1
REPEND
Next time we have a question like this one, a bit more context will make my
reply shorter :))
I'm still not sure if what you were asking is as simple as "how can I
tell".... or "how can I cater for"... Now I've typed all that, I think
Thomas was probably closer to the mark with what you wanted. Oh well :)
The above code snippets are probably buggy... it's the method you're looking
at, not my code!!!
Cheers
A
--
_ _ _| _ _ _| _ * _ _ ,
(_|| )(_|( (/_\/\/ (_|(_|\/(_(/_ ,~' L_|\
,-' \
see my Museum of Soviet Calculators at ( \
http://www.taswegian.com/MOSCOW/soviet.html \ __ /
L,~' "\__/
@--> v
----- Original Message -----
From: "Manuel Polik" <manuel.polik@xxxxxxxxxxx>
To: <stella@xxxxxxxxxxx>
Sent: Friday, March 09, 2001 9:36 PM
Subject: [stella] Another day, another problem...
> Hi there!
>
> Maybe this sounds like a trick question, but I find this a problem:
>
> How do I determine if a value decremented below $00 or incremented above
> $A0?
>
> One would need to implement a switch-case like structure, I'd assume?
>
> Any elegant solutions for that?
>
> Greetings,
> Manuel
>
> -
> Archives (includes files) at http://www.biglist.com/lists/stella/archives/
> Unsub & more at http://www.biglist.com/lists/stella/
>
-
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [stella] Another day, another probl, Manuel Polik | Thread | Re: [stella] Another day, another p, Manuel Polik |
| Re: [stella] Another day, another p, Manuel Polik | Date | Re: [stella] Another day, another p, Tim Böscke |
| Month |