English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 18 February 2018, 18:51   #1
mcgeezer
Registered User
 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
Direction of travel formula in asm

ughhhh... math, not my strong point.

here goes. As some of you know I'm recreating Bomb Jack, so if you know the game try and think about the little flying saucer enemy and how it moves.
To describe it, Jack will be at coordinates x1,y1 and the UFO will be at cordinates x2,y2, when the UFO hits a boundary wall it will move towards Jack in a direct straight line, if Jack moves then it will still travel to where Jack was.

Now first off I thought not a problem, I can just use a Bresenhan line draw to plot the points between the UFO and Jack, the problem is that the UFO has to keep travelling past Jack if he moves out of the way.

It's completely got me stuck. I've thought about just replaying the point offsets from the start when the UFO reaches Jack but I know in my heart of hearts that there is an easier mathematical formula that will be faster - probably involving radians and shit.

Can anyone give any advice with maybe some good examples of how I might solve it.

I'll still go for my original plan and replay the point offsets to get it going as I think that will work, but it's taking a fair bit of CPU time when it needs to plot that trajectory.

Geezer
mcgeezer is offline  
Old 18 February 2018, 20:30   #2
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
With (e.g.) bresenham, you can just keep iterating, and the ufo will keep the same trajectory even when passing where Jack was.

Last edited by hooverphonique; 19 February 2018 at 10:01.
hooverphonique is offline  
Old 19 February 2018, 09:15   #3
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,327
You can do that with any line drawing method.
Just apply the coordinate difference again to set a new target.

For example your UFO was at (3,10) and moves at (5,4) where Jack is.
What to do now ?
You can apply the coordinate offset once again : +2,-6 (computed by doing 5-3,4-10).
And therefore your new target will be (5+2,4-6) = (7,-2).
meynaf is offline  
Old 19 February 2018, 13:24   #4
mcgeezer
Registered User
 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
Quote:
Originally Posted by meynaf View Post
You can do that with any line drawing method.
Just apply the coordinate difference again to set a new target.

For example your UFO was at (3,10) and moves at (5,4) where Jack is.
What to do now ?
You can apply the coordinate offset once again : +2,-6 (computed by doing 5-3,4-10).
And therefore your new target will be (5+2,4-6) = (7,-2).


Thanks for this as it is good to know.

The issue I have is that the example line draw routines I have found in assembler swap around the x1/x2 and y1/y2 depending on where they are placed. I need these not to change otherwise I'd be swapping the direction of travel of the UFO.
mcgeezer is offline  
Old 19 February 2018, 14:41   #5
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,327
They swap them because they use the longest direction as a basis.
But normally they must operate with relative coordinates, and these do not change - only the source position does.

At least, this is how my own line drawing routine works.
See (d1-d2=origin, d3=color, d4-d5=offset) :
Code:
 movem.l d0/d4-d7/a0-a2,-(a7)
 movea.w #1,a0
 move.l a0,a1			; a0=a1=1 (init dir)
 tst.l d4
 bpl.s .abs1
 neg.l d4
 subq.l #2,a0			; will be -1
.abs1
 tst.l d5
 bpl.s .abs2
 neg.l d5
 subq.l #2,a1
.abs2
 move.l d4,d6			; counter (here x)
 cmp.l d4,d5
 blo.s .max
 move.l d5,d6			; counter (here y)
.max
 move.l d6,d0			; loop cntr
 move.l d6,a2			; save for addy
 lsr.l #1,d6			; round to avoid "last pixel" effect
 move.l d6,d7			; d6=x cntr, d7=y cntr
 bra.s .yp			; put 1st pix (+ finish if same pos)
.loop
 sub.l d4,d6
 bgt.s .xp
 add.l a0,d1			; depl x
 add.l a2,d6
.xp
 sub.l d5,d7
 bgt.s .yp
 add.l a1,d2			; depl y
 add.l a2,d7
.yp
 bsr setpixel                   ; set pixel at (d1,d2) to color d3
 dbf d0,.loop
 movem.l (a7)+,d0/d4-d7/a0-a2
 rts
The above code will update the coordinates d1,d2 to the new position.
Keep d4-d5 at the same value and you will redo the exact same move from the new position.
Just replace "setpixel" call by whatever output you need.
For your example, pass in d1=x2, d2=y2, d4=(x1-x2), d5=(y1-y2).
meynaf is offline  
Old 19 February 2018, 14:53   #6
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
From a video of the arcade game, it looks like a simple linear interpolation over about 1 second, probably 64 image frames.

Simple pseudo-example:
Code:
; initialize for each flight

move.w  ufo_x, d0
move.w  ufo_y, d1
move.w  jack_x, d2
move.w  jack_y, d3
sub.w   d0, d2
sub.w   d1, d3
lsl.w   #6, d0
lsl.w   #6, d1

; plot

move.w  d0, d4
move.w  d1, d5
lsr.w   #6, d4
lsr.w   #6, d5
bsr     plot_ufo

; move

add.w   d2, d0
add.w   d3, d1
Leffmann is offline  
Old 19 February 2018, 16:39   #7
mcgeezer
Registered User
 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
Quote:
Originally Posted by meynaf View Post
They swap them because they use the longest direction as a basis.
But normally they must operate with relative coordinates, and these do not change - only the source position does.

At least, this is how my own line drawing routine works.
See (d1-d2=origin, d3=color, d4-d5=offset) :
Code:
 movem.l d0/d4-d7/a0-a2,-(a7)
 movea.w #1,a0
 move.l a0,a1			; a0=a1=1 (init dir)
 tst.l d4
 bpl.s .abs1
 neg.l d4
 subq.l #2,a0			; will be -1
.abs1
 tst.l d5
 bpl.s .abs2
 neg.l d5
 subq.l #2,a1
.abs2
 move.l d4,d6			; counter (here x)
 cmp.l d4,d5
 blo.s .max
 move.l d5,d6			; counter (here y)
.max
 move.l d6,d0			; loop cntr
 move.l d6,a2			; save for addy
 lsr.l #1,d6			; round to avoid "last pixel" effect
 move.l d6,d7			; d6=x cntr, d7=y cntr
 bra.s .yp			; put 1st pix (+ finish if same pos)
.loop
 sub.l d4,d6
 bgt.s .xp
 add.l a0,d1			; depl x
 add.l a2,d6
.xp
 sub.l d5,d7
 bgt.s .yp
 add.l a1,d2			; depl y
 add.l a2,d7
.yp
 bsr setpixel                   ; set pixel at (d1,d2) to color d3
 dbf d0,.loop
 movem.l (a7)+,d0/d4-d7/a0-a2
 rts
The above code will update the coordinates d1,d2 to the new position.
Keep d4-d5 at the same value and you will redo the exact same move from the new position.
Just replace "setpixel" call by whatever output you need.
For your example, pass in d1=x2, d2=y2, d4=(x1-x2), d5=(y1-y2).
Quote:
Originally Posted by Leffmann View Post
From a video of the arcade game, it looks like a simple linear interpolation over about 1 second, probably 64 image frames.

Simple pseudo-example:
Code:
; initialize for each flight

move.w  ufo_x, d0
move.w  ufo_y, d1
move.w  jack_x, d2
move.w  jack_y, d3
sub.w   d0, d2
sub.w   d1, d3
lsl.w   #6, d0
lsl.w   #6, d1

; plot

move.w  d0, d4
move.w  d1, d5
lsr.w   #6, d4
lsr.w   #6, d5
bsr     plot_ufo

; move

add.w   d2, d0
add.w   d3, d1

Thank you guys, I will give these a try tonight and see where I get to.

What I have at the moment seems to be wayyyyyy too complicated and this feels about right of what I'm trying to do.
mcgeezer is offline  
Old 19 February 2018, 22:34   #8
mcgeezer
Registered User
 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
Quote:
Originally Posted by meynaf View Post
They swap them because they use the longest direction as a basis.
But normally they must operate with relative coordinates, and these do not change - only the source position does.

At least, this is how my own line drawing routine works.
See (d1-d2=origin, d3=color, d4-d5=offset) :
Code:
 movem.l d0/d4-d7/a0-a2,-(a7)
 movea.w #1,a0
 move.l a0,a1			; a0=a1=1 (init dir)
 tst.l d4
 bpl.s .abs1
 neg.l d4
 subq.l #2,a0			; will be -1
.abs1
 tst.l d5
 bpl.s .abs2
 neg.l d5
 subq.l #2,a1
.abs2
 move.l d4,d6			; counter (here x)
 cmp.l d4,d5
 blo.s .max
 move.l d5,d6			; counter (here y)
.max
 move.l d6,d0			; loop cntr
 move.l d6,a2			; save for addy
 lsr.l #1,d6			; round to avoid "last pixel" effect
 move.l d6,d7			; d6=x cntr, d7=y cntr
 bra.s .yp			; put 1st pix (+ finish if same pos)
.loop
 sub.l d4,d6
 bgt.s .xp
 add.l a0,d1			; depl x
 add.l a2,d6
.xp
 sub.l d5,d7
 bgt.s .yp
 add.l a1,d2			; depl y
 add.l a2,d7
.yp
 bsr setpixel                   ; set pixel at (d1,d2) to color d3
 dbf d0,.loop
 movem.l (a7)+,d0/d4-d7/a0-a2
 rts
The above code will update the coordinates d1,d2 to the new position.
Keep d4-d5 at the same value and you will redo the exact same move from the new position.
Just replace "setpixel" call by whatever output you need.
For your example, pass in d1=x2, d2=y2, d4=(x1-x2), d5=(y1-y2).


Hi there Meynaf,

I'm trying your code snippet. In order to update d1 and d2 I had to force the loop counter to 1 so that it would actually plot the co-ordinates each frame rather than draw whole the line each frame.

Here's what I have running.


Code:
; Constructor
;=============
.init:
	move.w	d1,(a2)			; Allocate this sprite
	move.w	#8,TS_SPR16_XPOS(a1)	; Set initial XPOS of UFO
	move.w	#200,TS_SPR16_YPOS(a1)	; Set initial YPOS of UFO

.check_and_move:	
	move.w	TS_SPR16_XPOS(a1),d1	; x2	 UFO Origin x
	move.w	TS_SPR16_YPOS(a1),d2	; y2	 UFO Origin y
	
	move.w	BJ_XPOS,d4		; x1	 JACK X
	move.w	BJ_YPOS,d5		; y1	 JACK Y
	
	sub.w	d1,d4			; d4=x1-x2
	sub.w	d2,d5			; d5=y1=y2

	bsr	DIRECTION      
	
	move.w	d1,TS_SPR16_XPOS(a1)
	move.w	d2,TS_SPR16_YPOS(a1)
.done:	
	moveq	#0,d1				; Animate UFO Sprite
	bra	ANIMATE
But here again, I get negative results when I'm doing this, I'm pretty sure I have the input parameters right but could you just give them a quick check to make sure I'm calling the routine correctly?
mcgeezer is offline  
Old 20 February 2018, 14:53   #9
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,327
Quote:
Originally Posted by mcgeezer View Post
Hi there Meynaf,

I'm trying your code snippet. In order to update d1 and d2 I had to force the loop counter to 1 so that it would actually plot the co-ordinates each frame rather than draw whole the line each frame.
If you do that, you will only get first move correct. Calling the routine again with updated coordinates will do you no good.
You have to separate init code from loop in the routine if you want a single move.


Quote:
Originally Posted by mcgeezer View Post
But here again, I get negative results when I'm doing this, I'm pretty sure I have the input parameters right but could you just give them a quick check to make sure I'm calling the routine correctly?
Parameters in the routine are longwords (.l), and you pass words (.w)...
meynaf is offline  
Old 20 February 2018, 18:39   #10
mcgeezer
Registered User
 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
Quote:
Originally Posted by meynaf View Post
If you do that, you will only get first move correct. Calling the routine again with updated coordinates will do you no good.
You have to separate init code from loop in the routine if you want a single move.



Parameters in the routine are longwords (.l), and you pass words (.w)...
Brilliant meynaf, I can't thank you enough for your help here!
mcgeezer is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
A500 joystick direction stuck Amiga1992 support.Hardware 34 01 June 2021 22:25
Tool to convert asm to gnu asm (gas) Asman Coders. Asm / Hardware 13 30 December 2020 11:57
A point in the right direction... vroom6sri New to Emulation or Amiga scene 15 26 November 2010 21:40
music from Dr Lutz and the Time Travel Machine (PC) s2325 request.Other 2 07 February 2010 14:52
New and need a point in the right direction robjbray Amiga scene 1 23 December 2007 12:19

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 05:11.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.07799 seconds with 15 queries