Page Index Toggle Pages: 1 Send TopicPrint
Sauron's homework! (assignment #1 - bouncy) (Read 1015 times)
ggn
D-Bug member
Reboot Member
*****
Offline


D-Bug debugger

Posts: 1461
Location: Somewhere in Greece
Joined: 22.02.07
Gender: Male
Sauron's homework! (assignment #1 - bouncy)
01.05.11 at 08:30:33
Print Post  
Assignment #1 - bouncy thing!

So, let's say you want to control a bouncy ball. Here are its characteristics:

  • This ball moves diagonally in 1 pixel increments
  • Once it hits an axis, its direction changes (for example if it goes down and right and hits the bottom border, it'll go up and right)
  • The top and bottom border coords are (0,0) and (320,240)
  • Edited:
    The ball moves on its own, no user interraction is required.
  • Edited:
    The ball initially starts at the middle of the screen and moves down-left.



Task #1 - Provide code to control the ball
Task #2 (optional) - Assume that the borders aren't fixed and can vary. Change Task #1's code to reflect this change
Task #3 (optional) - Modify the Downfall source so it'll show that ball

That is all. Have fun, and again, everyone that wants to have a shot at this is very welcome to, not just Sauron Smiley
« Last Edit: 03.05.11 at 17:12:27 by ggn »  
Back to top
 
IP Logged
 
Sauron
Reboot Member
*****
Offline


D-BUGer

Posts: 22
Location: Las Vegas, NV
Joined: 11.09.08
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #1 - 02.05.11 at 23:09:42
Print Post  
Here's a partial, probably wrong answer, completely in pseudo-pseudo code:

define playfield (define borders of screen)
set up ball object
position ball object in center of screen
read joypad
  test direction of joypad press
    if pressed left, move ball left + down
    if pressed right, move ball right + down
compare position of ball to borders
  if ball = bottom border, move up + (left or right)
  if ball = top border, move down + (left or right)
  if ball = right border, move left + (up or down)
  if ball = left border, move right + (up or down)

I'll try to work out some actual code for this, provided I'm on the right track here.
  
Back to top
IP Logged
 
ggn
D-Bug member
Reboot Member
*****
Offline


D-Bug debugger

Posts: 1461
Location: Somewhere in Greece
Joined: 22.02.07
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #2 - 03.05.11 at 17:09:23
Print Post  
Hmm, it seems like the rules I made were a little vague. How about that for starters we throw interaction out of the window?

What I ideally wanted to see would be code to move a ball around and change direction when it hits corners. I know that this sounds boring, but I don't want you to worry about too much parameters, i.e. setting up the screen and creating objects - you can do this afterwards. (it's task #3 in the list anyway Smiley)

So, I altered the first post a bit, hope I'm more specific now, read it again and happy coding Smiley
« Last Edit: 03.05.11 at 17:13:22 by ggn »  
Back to top
 
IP Logged
 
Sauron
Reboot Member
*****
Offline


D-BUGer

Posts: 22
Location: Las Vegas, NV
Joined: 11.09.08
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #3 - 04.05.11 at 02:54:01
Print Post  
The interaction wasn't really a problem so much, that was probably the easier part of this. What I'm running into right now is translating the game logic into 68k asm. Looking at the Downfall source, this is the relevant bit to testing the borders of the screen:

Code
Select All
cmp.l	#240,player_y				; are we at the bottom of the screen?
bgt		gameover				; GAME OVER PLAYER ONE
cmp.l	#17,player_y				; are we at the top of the screen?
blt		gameover					; GAME OVER PLAYER ONE

moveq	#0,d7						; pad movement flag (0=no movement)

move.l	#-1,falling					; man falling flag (-1 = falling) 



So obviously what I need to change is the branch to gameover, for one, since hitting the top or bottom border will necessitate a change in direction of the player object (the ball). What I need to add in is this:

- Movement code for the ball
- testing left and right borders
- changing direction of ball when any borders are hit

I'm running into a mental block, and having to find the appropriate instructions on a 68k cheat sheet will always make me hate life.  Grin
  
Back to top
IP Logged
 
Sauron
Reboot Member
*****
Offline


D-BUGer

Posts: 22
Location: Las Vegas, NV
Joined: 11.09.08
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #4 - 04.05.11 at 05:08:37
Print Post  
Ok, I have an answer, even though I'm expecting problems with it. I'll just post what I have and let you guys correct me.

Code
Select All
ball_x		dc.l	160		; ball x position
ball_y		dc.l	120		; ball y position
x_direction	dc.l	1		; vertical direction of ball
y_direction	dc.l	1		; horizontal direction of ball
topborder	dc.l	0		; sets top border
bottomborder	dc.l	240		; sets bottom border
leftborder	dc.l	0		; sets left border
rightborder	dc.l	320		; sets right border


start:

	move.l	ball_x,d0		; x coordinate for ball
	move.l	ball_y,d1		; y coordinate for ball

	sub.l	x_direction,d0		; moves ball left by one pixel
	add.l	y_direction,d1		; moves ball down by one pixel


moveball:

	move.l	d0,ball_x		; updates ball_x variable
	move.l	d1,ball_y		; updates ball_y variable

	cmp.l	leftborder,ball_x	; compares left border to x position
	beq	.move_right		; branches if equal to left border

	cmp.l	rightborder,ball_x	; compares right border to x position
	beq	.move_left		; branches if equal to right border

	cmp.l	topborder,ball_y	; compares top border to y position
	beq	.move_down		; branches if equal to top border

	cmp.l	bottomborder,ball_y	; compares bottom border to y position
	beq	.move_up		; branches if equal to bottom border

	rts				; returns to moveball

.move_right:

	add.l	x_direction,d0		; then starts moving the ball right
	rts				; returns to moveball

.move_left:

	sub.l	x_direction,d0		; then starts moving the ball left
	rts				; returns to moveball

.move_down:

	add.l	y_direction,d1		; then moves the ball down
	rts				; returns to moveball

.move_up:

	sub.l	y_direction,d1		; then moves the ball up
	rts				; returns to moveball 



I think my biggest problem is with syntax (remembering the 68k instruction set, more specifically), but we'll see.
  
Back to top
IP Logged
 
Sauron
Reboot Member
*****
Offline


D-BUGer

Posts: 22
Location: Las Vegas, NV
Joined: 11.09.08
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #5 - 04.05.11 at 05:32:14
Print Post  
CJ helped me a bit with some corrections in IRC, so here's the udpated code.

Code
Select All
ball_x		dc.l	160		; ball x position
ball_y		dc.l	120		; ball y position
x_direction	dc.l	1		; vertical direction of ball
y_direction	dc.l	1		; horizontal direction of ball
topborder	dc.l	0		; sets top border
bottomborder	dc.l	240		; sets bottom border
leftborder	dc.l	0		; sets left border
rightborder	dc.l	320		; sets right border


start:

	move.l	ball_x,d0		; x coordinate for ball
	move.l	ball_y,d1		; y coordinate for ball

	sub.l	x_direction,d0		; moves ball left by one pixel
	add.l	y_direction,d1		; moves ball down by one pixel


moveball:

	move.l	d0,ball_x		; updates ball_x variable
	move.l	d1,ball_y		; updates ball_y variable

	cmp.l	leftborder,ball_x	; compares left border to x position
	beq	.move_right		; branches if equal to left border

	cmp.l	rightborder,ball_x	; compares right border to x position
	beq	.move_left		; branches if equal to right border

	cmp.l	topborder,ball_y	; compares top border to y position
	beq	.move_down		; branches if equal to top border

	cmp.l	bottomborder,ball_y	; compares bottom border to y position
	beq	.move_up		; branches if equal to bottom border

	rts				; returns to moveball

.move_right:

	move.l	#1,x_direction		; then starts moving the ball right
	rts				; returns to moveball

.move_left:

	move.l	#-1,x_direction		; then starts moving the ball left
	rts				; returns to moveball

.move_down:

	move.l	#1,y_direction		; then moves the ball down
	rts				; returns to moveball

.move_up:

	move.l	#-1,ydirection		; then moves the ball up
	rts				; returns to moveball 

  
Back to top
IP Logged
 
ggn
D-Bug member
Reboot Member
*****
Offline


D-Bug debugger

Posts: 1461
Location: Somewhere in Greece
Joined: 22.02.07
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #6 - 07.05.11 at 16:49:35
Print Post  
Well, it took long for someone to reply here Smiley.

Of course it's all very good and fine. There is one small potential bug there, that is if the ball touches 2 borders at once it'll fail to flip both directions. In any case, I'll just add some variations to this to make some other points.

First in line is, how to make it run faster. Now, of course it's a bit moot to speed up such a small routine, but it's mostly to give some ideas.

So here's a faster version:

Code
Select All
ball_x		dc.l	160		; ball x position
ball_y		dc.l	120		; ball y position
x_direction	dc.l	1		; vertical direction of ball
y_direction	dc.l	1		; horizontal direction of ball
topborder	dc.l	0		; sets top border
bottomborder	dc.l	240		; sets bottom border
leftborder	dc.l	0		; sets left border
rightborder	dc.l	320		; sets right border


start:

	movem.l ball_x(pc),d0-d3	;load ball_x in d0, ball_y in d1, x_direction in d2 and y_direction in d3

	sub.l	d2,d0		; moves ball left by one pixel
	add.l	d3,d1		; moves ball down by one pixel


moveball:

	move.l	d0,ball_x		; updates ball_x variable
	move.l	d1,ball_y		; updates ball_y variable

	cmp.l	leftborder,d0	; compares left border to x position
	bne.s	.check_right	; branches if not equal to left border
	moveq	#1,d2		; then starts moving the ball right
	bra.s	.check_top	; now go check for top/bottom

.check_right:
	cmp.l	rightborder,d0	; compares right border to x position
	bne.s	.check_top	; branches if not equal to right border
	moveq	#-1,d2		; then starts moving the ball left

.check_top:
	cmp.l	topborder,d1	; compares top border to y position
	bne.s	.check_bottom	; branches if not equal to top border
	moveq	#1,d3		; then moves the ball down
	bra.s	.check_done

.check_bottom:
	cmp.l	bottomborder,d1	; compares bottom border to y position
	beq.s	.move_up	; branches if equal to bottom border
	moveq	#-1,d3		; then moves the ball up

.check_done:
	movem.l d0-d3,ball_x
	rts			;all done, thank you, drive thru! 



A bit different, isn't it? Smiley Now, let me comment my changes a bit.

  • I changed all move.l statements to moveq - it is one of the fastest cpu instructions on the 68000. It has a small drawback though, that being that you can only use it if you want to load values from -128 to 127, so use with care!
  • Also obvious, I changed all branches to their short sizes (for example beq.s instead of beq.w). Again, these work only if the branched code is less or equal to 128 bytes from the instruction executed. Usually I make all my branches short and let the assembler whine if any passes the limit Smiley
  • Generally, I tend to use registers as much as possible, as it's much faster than accessing memory all the time. Since we will be using x_direction and y_direction more than once in the code, I load them too and save them after all processing is finished. On the other hand, the border values are only used once, so I let them be.
  • The 68000 has a special instruction for loading multiple registers to and from memory, called movem. You need to care that what you load is sequentially in memory. Fortunately Sauron had all lined up for a movemSmiley
  • Finally, I restructured the code a bit, so it'll be a bit tighter, and also a bit easier to check, as you have all the relevant code close by and your eyes don't have to search for branches all the time. Dunno, I just think it's nice, it's not a necessity Smiley
  
Back to top
 
IP Logged
 
ggn
D-Bug member
Reboot Member
*****
Offline


D-Bug debugger

Posts: 1461
Location: Somewhere in Greece
Joined: 22.02.07
Gender: Male
Re: Sauron's homework! (assignment #1 - bouncy)
Reply #7 - 07.05.11 at 17:16:47
Print Post  
Right, while I'm on the subject, I thought I'd make a quick point about abstraction as well. It may be more advanced for a simple first exercise, so you might want to skip reading it and come back later when we've done more assignments Smiley.

So, say we want to control 10 bouncy balls like this. How would we do it with the code we have so far? Well, one solution would be to copy/paste the code 10 times and change labels, and it would work. But... what about if we found a bug? We'd then have to change it to 10 points in the code! And then maybe we'll need a change later on. 10 changes again! Etc, etc. Soon it becomes ultra tedious to say the least!

What could we do then? Well...

Code
Select All
the_balls:
	rept 10
	dc.l	160		; ball x position
	dc.l	120		; ball y position
	dc.l	1		; vertical direction of ball
	dc.l	1		; horizontal direction of ball
	endr

topborder	dc.l	0		; sets top border
bottomborder	dc.l	240		; sets bottom border
leftborder	dc.l	0		; sets left border
rightborder	dc.l	320		; sets right border

mainloop
	move.l	#the_balls,a0
	bsr.s	bouncy
	bra.s	mainloop

bouncy:

	movem.l (a0),d0-d3	;load ball_x in d0, ball_y in d1, x_direction in d2 and y_direction in d3

	sub.l	d2,d0		; moves ball left by one pixel
	add.l	d3,d1		; moves ball down by one pixel


moveball:

	move.l	d0,ball_x		; updates ball_x variable
	move.l	d1,ball_y		; updates ball_y variable

	cmp.l	leftborder,d0	; compares left border to x position
	bne.s	.check_right	; branches if not equal to left border
	moveq	#1,d2		; then starts moving the ball right
	bra.s	.check_top	; now go check for top/bottom

.check_right:
	cmp.l	rightborder,d0	; compares right border to x position
	bne.s	.check_top	; branches if not equal to right border
	moveq	#-1,d2		; then starts moving the ball left

.check_top:
	cmp.l	topborder,d1	; compares top border to y position
	bne.s	.check_bottom	; branches if not equal to top border
	moveq	#1,d3		; then moves the ball down
	bra.s	.check_done

.check_bottom:
	cmp.l	bottomborder,d1	; compares bottom border to y position
	beq.s	.move_up	; branches if equal to bottom border
	moveq	#-1,d3		; then moves the ball up

.check_done:
	movem.l d0-d3,(a0)
	rts			;all done, thank you, drive thru! 




Eh what?

Firstly, I've defined 10 balls. They're set up at the top. rept and endr define a block to be repeated as many times as we want. Saves some typing Smiley. As a consequence, each ball's values are directly after the previous one. So what, you'll ask. We still have to reference them somehow, right?

What I basically did there was to use pointers. Registers a0 to a7, as we all know, are called address registers. In addition to just holding numbers, they have some extra functionality. For example, if an address register holds a valid address, then we can access the memory in that address by the use of parentheses. So, if a0 is loaded with the value $10000, then executing

Code
Select All
move.l (a0),d0 



will fetch the longword that a0 points to and load it in a0. Cool huh? Smiley Of course there are limits to what one can do, but most of the 68000 instruction set is very flexible and we can use pointer logic in lots of places.

So, how does this help in our case? Simple. To control the first ball, I just load the address of the first element of the first ball, its ball_x to be precise, to a0. I then call the subroutine bouncy. Assuming that a0 contains the address of the ball's structure we want to check, I just go ahead and read all variables with the movem, but instead of a fixed address I use the one stored in a0!

Code
Select All
	movem.l (a0),d0-d3	;load ball_x in d0, ball_y in d1, x_direction in d2 and y_direction in d3 



After all processing is done, I simply write it back to the address of a0:

Code
Select All
	movem.l d0-d3,(a0) 



So, can you guess how to process the 2nd bacll? Quite simply, we can load the address of the 2nd ball's structure. We can calculate that quite easily; since each ball uses 4 longwords to store its data, the 2nd ball is located at 4bytes*4longwords=16 bytes after the first one. So,

Code
Select All
	move.l	#the_balls+4*4,a0 



will point to our 2nd ball! (yes, arithmetic expressions are allowed as long as they're not too complex)



And that's it really, as you see turning an ordinary routine to a more generic one isn't as difficult as you might first think Smiley
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint
 
  « Board Index ‹ Board  ^Top