SNES Programing Help 2
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Re: SNES Programing Help 2
Heh. I'm quite content doing literally everything in Hex. It's only taken a couple months or so for it to become second nature to me, and that way there's never any misunderstanding about what my code is doing. In most cases it's even easier than thinking in decimal: A standard tile is $10 or 16, so say 17 of them would be $170 or (let me get a calculator).
Speaking of you can always use the windows calculator in "Programmer" mode to do conversions and math in hex/binary that you can't do in your head (If you use Windows).
Speaking of you can always use the windows calculator in "Programmer" mode to do conversions and math in hex/binary that you can't do in your head (If you use Windows).
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES Programing Help 2
You know, I've been a bit busy with school so I haven't been able to work on anything, but I should have some free time and I wanted to implement the velocity thing for the bullets, but I just realized something. I was originally going to use a word for velocity and a word for the position, and I was going to only take the highest byte from the velocity and add that to the position, as this would allow for "sub pixel precision", but I later realized that I wouldn't be able to have "negative" velocity, because I couldn't get a 16 space to wrap around using an 8 bit number. Do you have any good ideas as to have both "sub pixel velocity" and "negative velocity"?
Re: SNES Programing Help 2
If you ignore the low byte and add only the high byte to the velocity, then you can't have motion slower than 1 pixel per frame. There is a workaround involving adding a bit-reversed version of the current frame number to the low byte of the velocity and then adding the carry from there and the high byte of the velocity to the displacement.
I don't see how a two's complement negative velocity would introduce problems. What problems have you seen?
I don't see how a two's complement negative velocity would introduce problems. What problems have you seen?
-
psycopathicteen
- Posts: 3001
- Joined: Wed May 19, 2010 6:12 pm
Re: SNES Programing Help 2
The way I've been doing subpixel negative values is by doing this:
Code: Select all
lda {x_velocity} //if greater than $8000, N flag is set
bpl + //branch if plus
dec {x_position_hi} //decrease high-word of x position if velocity is negative
+;
Re: SNES Programing Help 2
In my setup velocity is two bytes where the hi byte represents actual pixels/frame, and position is 3 bytes where the middle represents actual pixels. I branch based on whether velocity is positive or negative, add the sub-velocity to the sub-position in 16-bit mode, then bcc or bcs appropriately to increment or decrement the hi-byte of position.
I'm sure there's some better way...
I'm sure there's some better way...
Re: SNES Programing Help 2
That's what the carry/borrow part of ADC/SBC is for, to let you easily carry/borrow lower portions of a multi-byte(/multi-word, for SNES) addition/subtraction.
Re: SNES Programing Help 2
I'm not sure if this was being addressed to my comment but if so: Do you mean to say I'm doing things as intended or are you proposing a faster way? I've set it up like this:Myask wrote:That's what the carry/borrow part of ADC/SBC is for, to let you easily carry/borrow lower portions of a multi-byte(/multi-word, for SNES) addition/subtraction.
Code: Select all
lda.b objYVelo ;16-bit A initially
beq _doneObjYVelo
bpl _goinDown
clc ;goin' Up
adc.b objYPosnSub
sta.b objYPosnSub ;Velocity was NEGATIVE.
bcs _doneObjYVelo ;So if carry is CLEAR, we need to DECREMENT high byte
sep #$20 ;8-bit A
dec.b objYPosnHi
rep #$20 ;16-bit A
bra _doneObjYVelo
_goinDown:
clc
adc.b objYPosnSub
sta.b objYPosnSub ;Velocity was POSITIVE.
bcc _doneObjYVelo ;If carry is SET, we need to INCREMENT high byte
sep #$20 ;8-bit A
inc.b objYPosnHi
rep #$20 ;16-bit A
_doneObjYVelo:(P.S. I instinctively put the "beq _doneObjYVelo" at the start to eliminate all the processing when your velocity is zero. I do that a lot but I suddenly think that's a mistake - since it will speed up processing some of the time but ultimately make the worst-case scenario take slightly longer. I should refrain from doing that, right?)
Re: SNES Programming Help 2
It was, but...You're right. Silly of me to think that the obvious method would be cheaper. (if indexed/not direct page, the gap just widens, as the ADC method has two instructions gaining cycles rather than one.)
Small optimization: put the CLC before the LDA.b objYVelo, rather than in both branches. LDA doesn't affect carry.
...say, why AREN'T you using indexed modes here? Aren't you iterating over the list of objects?
I know you can use an ADC #$00 on the Hi byte to stuff the carry in there without a branch, at least on the second half, but that seems like it costs more cycles.
Code: Select all
LDA imm: 2b 2c
ADC/SBC mem: 2b, 3c
STA mem: 2b, 3c
total: 8b, 10c
vs
BC*: 2b, 2c (3c not, but ditches the SEP/REP too for net -3c)
INC/DEC mem: 2b, 5c
total: 5b, 8cSmall optimization: put the CLC before the LDA.b objYVelo, rather than in both branches. LDA doesn't affect carry.
Probably unnecessary/unuseful. It depends on what your 'worst-case' where you're actually needing time-saved looks like. Untaken branch takes 2 cycles each time, after all, so when is 2*moving_objects < (processing_time -3) * unmoving_objects?I instinctively put the "beq _doneObjYVelo" at the start [...] I should refrain from doing that, right?
...say, why AREN'T you using indexed modes here? Aren't you iterating over the list of objects?
-
psycopathicteen
- Posts: 3001
- Joined: Wed May 19, 2010 6:12 pm
Re: SNES Programing Help 2
To avoid repetitive index register juggling.
Re: SNES Programing Help 2
Yeah, I'm using direct page to iterate through my list of objects, hence all the ".b" instructions.
Thanks for the input!
Thanks for the input!
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES Programing Help 2
Sorry to steer this conversation off topic a little, but there's one thing I've been doing that I'm sure there's a better way to do. I have it to when whenever I set a certain bit to the metasprite routine, it creates a horizontally flipped version of the metasprite, but I wasn't sure how to efficiently make one routine be able to do both, so I literally did this...
Which means I completely copied the code again except I subtracted the sprites position from the objects instead of adding and I eor'd at one point to change the flip bit. I know there's a better way to do this, and at some point, I want to also have sprites flipped vertically, and that means I'd have to copy the routine 4 times... I know I could look to see if the bit was set to change direction every time I do something that related to the object being flipped, but this would use some more processing time so don't know...
Code: Select all
lda MetaspriteDirection
bne backwards_metasprite_loopRe: SNES Programing Help 2
Helping you is literally the topic.Espozo wrote:Sorry to steer this conversation off topic a little...
I personally found psycopathicteen's reply to you back in December very helpful for that. It needs a bit of adjustment to be functional (position is off-by-one on flipping and I have no clue what his plan was with the x-position and size bits for the second OAM table), but I found the approach downright elegant.Espozo wrote:I know there's a better way to do this, and at some point, I want to also have sprites flipped vertically, and that means I'd have to copy the routine 4 times... I know I could look to see if the bit was set to change direction every time I do something that related to the object being flipped, but this would use some more processing time so don't know...
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES Programing Help 2
Yeah...Khaz wrote:Helping you is literally the topic.Espozo wrote:Sorry to steer this conversation off topic a little...![]()
Oh, thanks for finding that again.Khaz wrote:I personally found psycopathicteen's reply to you back in December very helpful for that. It needs a bit of adjustment to be functional (position is off-by-one on flipping and I have no clue what his plan was with the x-position and size bits for the second OAM table), but I found the approach downright elegant.Espozo wrote:I know there's a better way to do this, and at some point, I want to also have sprites flipped vertically, and that means I'd have to copy the routine 4 times... I know I could look to see if the bit was set to change direction every time I do something that related to the object being flipped, but this would use some more processing time so don't know...
Re: SNES Programing Help 2
Try to avoid copying code. That's when it's best to use a macro, with parameters for the parts that vary. Same result, but it's always good to edit the code in one place instead of 4.
If you wanted to avoid subtraction, instead of SBC #8 you could do ADC #$F8 (or $FFF8) for the same result. Though I know that doesn't help much, that just moves the branch elsewhere, figured I'd throw that in as well.
If you wanted to avoid subtraction, instead of SBC #8 you could do ADC #$F8 (or $FFF8) for the same result. Though I know that doesn't help much, that just moves the branch elsewhere, figured I'd throw that in as well.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES Programing Help 2
I know. (Even if I did just learn recently...) The thing is that the number that is being sbc'd/adc'd is the same, so I cannot really change it. Hey, maybe at the beginning of the code, I could check if the object is backwards, and if it is, I then add #$F000 to the position of the sprite position that gets added to the metasprite position... To make sure it to where it loads either #$0000 or #$F000, I'll make it look at a register that will only ever have those 2 values. (This is the result of if the object is backwards or forwards that gets filled at the beginning of the code.)Memblers wrote:If you wanted to avoid subtraction, instead of SBC #8 you could do ADC #$F8 (or $FFF8) for the same result. Though I know that doesn't help much, that just moves the branch elsewhere, figured I'd throw that in as well.
By the way, what is the opcode "bit" do?