Someone may find this useful, a routine I made to multiply two numbers. The main benefit of this is that you can multiply two 8-bit numbers, a 16-bit number and a 8-bit number, or two 16-bit numbers.
; Multiplication routine - works with 8-bit and 16-bit numbers.
; It won't however give a 24-bit number (it could probably be edited to do so).
; A should be 00(00) when entering (unless you want to add the multiplied number to what is already in A)
; $00 should be the number you want to multiply and $02 is what you are multiplying it by. $00 * $02
; You can enter in either 8-bit or 16-bit mode A
; Result will go in A
; $00 and $02 will no longer hold their original values
In order to use it, load a 16-bit value into A, with the carry bit acting as a 17th bit and call it. It will return the approximation to the square root as a 16-bit value in A, with the carry bit acting as a 17th bit. The return value should be interpreted as 9.8 fixed point.
For example, a return value of $45A0 (C) should be interpreted as $0145.A0.
Using an inlined reciprocal square root routine, I've created a pretty accurate aiming routine. Link
In order to use it, set $00 to be the 16-bit value (shooter_x - target_x), set $02 to be the 16-bit value (shooter_y - target_y), and set A to be the 8-bit projectile speed. It will return the projectile's X speed in $00 and the projectile's Y speed in $02. Note that distances over $0100 pixels are not allowed.
Explanation: Suppose one fired the projectile with X speed dx, and Y speed dy. Then its speed would be sqrt(dx2+dy2). Thus, we can adjust its speed by multiplying by speed / sqrt(dx2+dy2). This routine calculates the reciprocal 1 / sqrt(dx2+dy2), multiplies by speed, then multiplies by either dx or dy.
erik edit: fixed link because dropbox
added the sa-1 compatible variant (requires a !SA1 detection if you're using spritetool)
%palette(!destination, #$XX, #$XX)
macro palette(destination, lowbyte, highbyte)
LDA <lowbyte> ; Yes, you need a high byte too
STA $2122 ; Remember: $2122 is a ‘write twice’ register (you must store again into the address).
But it can slow down a bit if you're using it to much (I didn't used it).
If you use an acurate emulator not ZSNES than the palette will screw up when you change the palette with that code in a sprite...
thats the reasen why all SMW sprites which modify the palette use the table at $0682
Oh right, ZSNES is inaccurat. And not only with the palette, every adress in the SNES regrister must have a mirror to not screw up the other things (with esception of [like MarioEdit has written] [H]DMA).
And not only with the palette, every adress in the SNES regrister must have a mirror to not screw up the other things (with esception of [like MarioEdit has written] [H]DMA).
Not really true. Some only can be written during a blank yes, but, most registers can not be read, so having mirrors allows you to read what will be put in that register. Direct writes to registers should with no problems.
I wrote that late at night and I meant to say most direct writes to registers should work with no problems, I already knew things like CGRAM/VRAM/etc. couldn't be written to outside of a blank, but I meant things like the H/V scroll registers, screen brightness, screen settings, window settings, etc. They are just easier to work with with mirrors.