Page 2 of 2

Posted: Sat Oct 28, 2006 2:15 am
by Bregalad
Again, I prefer myself use only one byte for speed, and the high nyble is the integer part and the low nybble the fraction part.
You will never want to have something move less than 1/16th pixel per frame nor anything moving faster than 7+15/16th pixel per frame.
So :
$10 is move one pixel per frame forward
$18 is move one pixel and a half per frame forward
$e8 is the same speed as above, but backwards
etc...
You can also use the whole full 8-bits to allow to move up to 15+15/16th pixel per frame, and have a sign bit in a separate variable, I do that in my current game. (because when a monster is knocked back, I "cheat" and make it moving 15+15/16th pixel per frame for one frame, making them go back arround 16 pixels).
This will make you write a programm a little bit more complex, dealing with shifts and all, but save significant size of RAM arrays. Plus if you're new to the dev scene that will make you a good exercice, and it's nothing near impossible to deal with shifts.

Posted: Sat Oct 28, 2006 3:52 am
by Memblers
Bregalad wrote: This will make you write a programm a little bit more complex, dealing with shifts and all, but save significant size of RAM arrays.
Do you mean ROM? Because using a full 8-bits for the sub-pixel resolution still only requires one byte of RAM (unless you want the adjustable speeds in RAM. then you'll want a wider ranger of speeds anyways and it'll require 2 bytes, but I seriously doubt anyone would do that for much more than their main sprites). I guess it depends on the type of game. If you have a lot of individual objects, the extra processing for the shifts and stuff will really add up. If you have fewer objects made up of several sprites that move together, it won't matter as much.

Posted: Sat Oct 28, 2006 5:28 am
by Bregalad
No, I mean RAM, because the speed of projectiles is kept in RAM.
Only the speed of ennemies is kept in ROM, but they act just the same (they just are consant) in my game. But that all depdends of the game. But anyway I think it is easier to work with one single byte in most cases.

Posted: Sat Oct 28, 2006 10:45 am
by VanOccupanther
That was useful to me for figuring out how fast and slow the one byte speed method could go. (7+15/16th and 1/16th)
----------

Well, i tried the one byte method and it ended up using two bytes. Here's what's there:

Code: Select all

		lda $18
		sta speed

		lda speed
		and #%00001111
		sta speed_low
		
		lda speed
		and #%11110000
		lsr
		lsr
		lsr
		lsr
		sta speed_high
Is that the only way to do it? You said use one byte, but really, it ended up using two.

Posted: Sat Oct 28, 2006 12:38 pm
by Bregalad
Wait, you got the thing, but now you don't have to use two bytes. I'll just show you some example :

Code: Select all

lda Speed
asl A
asl A
asl A
asl A
clc
adc PositionL
sta PositionL
lda Speed
lsr A
lsr A
lsr A
lsr A
adc PositionH
sta PositionH
Note that only the 4 high bits of Position L are used, and the low bits aren't affected at all so they can be used for anything else.
To do it signed, just test the sign of the original Speed variable, and then do the whole thing using one routine that add, and one routine that substract in function of the original sign (but the negative bit must be masked when substractuing after the 4 "LSR A"s).[/code]

Posted: Mon Oct 30, 2006 5:50 pm
by VanOccupanther
Having problems. Here's the code:

Code: Select all

		;**************
		;	movement_speed start
		;**************
		
		lda #$10
		sta speed

		lda y_portion_decimal
		;sta look2
		sta multiplicand		
		lda speed
		asl 
		asl
		asl
		asl
		;sta look4
		jsr multiply
		lda product
		;sta look6
		sta bullettable+1	;y_portion_decimal
		lda y_portion
		;sta look	
		sta multiplicand
		lda speed
		lsr
		lsr
		lsr
		lsr
		;sta look3
		jsr multiply
		lda product
		;sta look5
		sta bullettable		;y_portion


		lda x_portion_decimal
		;sta look8
		sta multiplicand		
		lda speed
		asl 
		asl
		asl
		asl
		;sta lookA
		jsr multiply
		lda product
		;sta lookC
		sta bullettable+3		;x_portion_decimal
		lda x_portion	
		;sta look7
		sta multiplicand
		lda speed
		lsr
		lsr
		lsr
		lsr
		;sta look9
		jsr multiply
		lda product
		;sta lookB
		sta bullettable+2		;x_portion



		;**************
		;	movement_speed end
		;**************
here is multiply's header:

Code: Select all

multiply:	;******
		;must give multiplicand a value
		;multiplier value should be stored in accumulator
		;
		;answer will be stored in product
		;******
		
Multiply works multiplying a byte with a byte.

The problem.. for example when shooting toward the southwest

y_portion = 00
y_portion_decimal = D6

speed = 10 (one pixel per frame)

so speed_high = 01
and speed_low = 00

so y_portion * speed_high = 00
and y_portion_decimal * speed_low == 00


It takes 00D6 and changes it to 0000. :( It should take 00D6 and give back 00D6. Since this is multiplication maybe each 00 should be changed to a 01, but i don't know. The x_portion and x_portion decimal is FF72. But, it gives FF72 [-.72] * 0100 [1.0] = FF00 [-1.0].

Please help me to figure out what's wrong with the multiplication here?

Posted: Fri Nov 03, 2006 9:28 pm
by VanOccupanther
Multiplying two two byte numbers is hard. Here is my attempt (A,B,C,and D are variables.)

Code: Select all

  A.B
x C.D
-----

step1 = D * B
step2 = carry_from_step3 + C * A
step3 = C * B
step4 = carry_from_step1 + D * A

step1 x 1 =   val1
step2 x 100 = val2
step3 x 10 =  val3
step4 x 10 =  val4

val1 + val2 + val3 + val4 = answer


lda answer
tay
asl
asl
asl
asl
sta y_portion_decimal
tya
lsr
lsr
lsr
lsr
sta y_portion
But there's a problem with the answer. For example:

Code: Select all

  00.FC
x 01.00
-------
  0C.00
When calculating val3, it moves the bits 4 to the left, that's why we lost the F. Also, the answer should look like 00.FC00 so the whole number part is lost too. How can you do this? How would you do this? Please help me fix this.

Posted: Fri Nov 03, 2006 10:12 pm
by tepples
Multiplying 16 bits by 16 bits should be straightforward. The classic algorithm does four calls to the 8x8 multiply followed by several adds:

Code: Select all

    $aabb
  * $ccdd
    -----
     bdbd
   bcbc00
   adad00
+acac0000
---------
    value

I don't see where nibble-wise operation ever comes into play.