Code check - Jump routine for a player

Post programming questions related to the CPC Here!
Post Reply
Kitsune Mifune
Posts: 33
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Code check - Jump routine for a player

Post by Kitsune Mifune » Sun Oct 27, 2019 4:28 pm

Thing have progressed and my player's move set is pretty much complete. I just have to make him jump up and down, which in theory is straightforward, but as always stuff doesn't work (the sprite goes all over the screen then crashes).

I did a routine for a jumping code which to my eyes should work. It combines two loops - one for going up and gradually slowing down (gravity pull) and one for going back down again (essentially reversing the process.

I'm too inexperienced to be able to see what's wrong. It could be the jump code, it could be the draw routine, or it could be my ropy attempt at a delay. Either way, if someone (we all know who) :) could take a quick scan to see what hidden messes I've made, it would be really appreciated (I'm approaching brain fry level).

The first bit of code is just the button press in the CONTROLS routine to activate the jump. The second is the actual jump code (both are housed in separate .asm files.

Many thanks!

(Excuse the big spaces between code lines. It makes it easier for my 42 year old eyes to read)

Code: Select all


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;CONTROLS_FLYINGKICK ;;
;;;;;;;;;;;;;;;;;;;;;;;;

		bit 5,a			; Set Bit that tests for Joystick JUMP (Fire Button 2) (Bit-5)
		jr z,JOYNOT_FLYINGKICK
		
		ld a,6			; Set STATE for JUMP animation
		ld(PLAYER_STATE),a

		ld (PLAYER_YPOS),hl	; Get current Y-Position BEFORE JUMP and store in 'hl

		ld a,5			; Jump amount
		ld (ZSPEED),a		; Load initial Jump value into ZSPEED before loops start
		call PLAYER_VARSETUP	; Sets up some player specific values for the DRAW routine
		jp JUMPLOOPS_ASM	; Jump (jp) to JUMP loops
	
	JOYNOT_FLYINGKICK:
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; JUMP LOOP(S) ;;
;;;;;;;;;;;;;;;;;;

JUMPUP_LOOP:
	
		ld bc,2000		; Set delay time
		ld (DELAY_AMOUNT),bc
		call DELAY		
		ld bc,&0000		; Clear 'bc'

		ld hl,(PLAYER_YPOS)	; Get current Y-POSITION in the jump and transfer to 'hl'
		
		ld bc,(ZSPEED)		; Jump speed loaded into 'bc'(Pre-loop set at 5, but will go down every loop)

		add hl,bc		; Jump up by whatever number is in 'bc'(ZSPEED) by adding to...  
					;...current 'hl' (PLAYER_YPOS)

		ld (PLAYER_YPOS),hl	; Load new 'hl' value back into PLAYER_YPOS variable

		call SPRITEPOSITION	; Send new information to DRAW code to display on screen

		dec bc			; Reduced jump (ZSPEED) amount by 1 (Pull down of Gravity)

		ld (ZSPEED),bc		; Load reduced value back into ZSPEED for next loop (should be 4,3,2...)
				
		ld a,(ZSPEED)		; Load new ZSPEED value into 'a'
			
		ld b,a			; Transfer ZSPEED value from 'a' to 'b'
		
		ld a,0			; set 'a' to 0

		cp b			; See if 'b' (ZSPEED) is 0

		jr nz, JUMPUP_LOOP	; If not then repeat loop until 'b' = zero

JUMPDOWN_LOOP:

		ld bc,2000		; Set delay time
		ld (DELAY_AMOUNT),bc
		call DELAY
		ld bc,&0000		; Clear 'bc'
		
		ld a,(ZSPEED)		; Load current jump speed (ZSPEED) to 'a'(should be 0 after other loop)
		
		ld b,a			; Load 'a' to 'b' (so b = ZSPEED)
		
		ld a,(PLAYER_YPOS)	; Get current Y-POSITION in the jump and load to 'a'

		sub b			; Jump down by whatever number is in 'b'(ZSPEED) by subtracting from 'a' (Y position)
				
		ld (PLAYER_YPOS),a	; Load new 'a' value back into PLAYER_YPOS

		call SPRITEPOSITION	; Send new information to DRAW code and update screen position

		inc b			; Increase jump amount by 1 (Fall back to ground)

		ld a,b			; Load new value from 'b' to 'a'
		
		ld (ZSPEED),a		; Load increased value from 'a' back into ZSPEED for next loop (should be 1,2,3...)
				
		ld a,(ZSPEED)		; Load new ZSPEED value into 'a'

		ld b,a			; Transfer ZSPEED value from 'a' to 'b'
		
		ld a,8			; set 'a' to 8

		cp b			; See if 'b'(ZSPEED) has increased enough to be = to 8

		jr nz, JUMPDOWN_LOOP	; If not then repeat loop until b = 8

		cp b
		
		jp z, BACKONGROUND	; if it is equal then jump back to the STANCE state and draw routine
		
BACKONGROUND:
		ld a,1
		ld (PLAYER_STATE),a
		jp SPRITEDRAW
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;; DELAY ;;
;;;;;;;;;;; 		** WILL NEED TO PUT THIS IN A FUNCTION SHEET LATER **
		
DELAY:
	ld bc,(DELAY_AMOUNT)
	ld a,0
	D_LOOP:	
		djnz, D_loop
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Programming: 90% failures, 10% victories, and 100% hair loss!

User avatar
akuyou
Posts: 563
Joined: Mon Apr 22, 2019 3:19 am
Contact:

Re: Code check - Jump routine for a player

Post by akuyou » Mon Oct 28, 2019 3:47 am

It's tough to say... even with my own code, I'd really have to run the code myself to know what was really going on.

I wonder if this is the problem?

During the UP part, you're treating Zspeed as a 16 bit number, using ADD HL,BC and DEC BC...

But during the down part it only seems to be 8 bit... I'm not sure how your screen drawing routines are working, but that's surprising to me - also at the end of the UP loop, you're only checking the B part of BC - so the C part could be 255? if Ypos is a line number, then that seems wrong for a 200 line screen.

Try stepping through your code in winape's debugger, and see what the registers hold when the screen goes crazy - try putting a breakpoint on the spriteposition function (for example)

The crash probably implies your sprite is going offscreen and corrupting general memory - does it happen during the up part or the down part?
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

Kitsune Mifune
Posts: 33
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Re: Code check - Jump routine for a player

Post by Kitsune Mifune » Mon Oct 28, 2019 11:09 am

Thanks for the reply Keith, you actually helped me solve the issue because my brain was so fried I didn't think about the debugger, so thanks for reminding me.

Just to say - I'm using the 8 bit registers in the down loop because SUB only works with them (as far as I know) and I couldn't do a SUB hl,bc like I did with the ADD in the up loop.

The reason it wasn't working was because I wasn't preserving the ZSPEED value. It was still held in 'bc' and that was being used for other things in the draw routine before it got returned to the loop, so obviously the value would be different.

Also, I forgot to put a command in to return to the stored "launch spot" (PLAYER_ZPOS) when the loops ended.

Here's the working code for comparison just in case anyone wants a look. The delay doesn't seem to do much even if the values are changed, but all in all the jump code works fine now.

Code: Select all

;;;;;;;;;;;;;;;;;;
;; JUMP LOOP(S) ;;
;;;;;;;;;;;;;;;;;;

		call FUNCTIONS		; Load DELAY code
JUMPUP_LOOP:
	
		ld b,8000		; Set delay time
		ld (DELAY_AMOUNT),bc
		call DELAY		
		
		ld bc,&0000		; Clear 'bc'
		ld hl,(PLAYER_YPOS)	; Get current Y-POSITION in the jump and transfer to 'hl'
		ld bc,(ZSPEED)		; Jump speed loaded into 'bc'(Pre-set at 5, but will go down every loop)
		
		add hl,bc		; Jump up by whatever number is in 'bc'(ZSPEED) by adding to...  
					;...current 'hl' (PLAYER_YPOS)
		ld (ZSPEED),bc		; Store (ZSPEED)and preserve the value
		ld (PLAYER_YPOS),hl	; Load new 'hl' value back into PLAYER_YPOS variable
		
		call SPRITEDRAW		; Send new information to DRAW code to display on screen

		ld bc,(ZSPEED)		; Reload saved ZSPEED value after drawing routine
		dec c			; Reduced jump (ZSPEED) amount by 1 (Pull down of Gravity)
		ld (ZSPEED),bc		; Load reduced value back into ZSPEED for next loop (should be 4,3,2...)	
		
		ld a,(ZSPEED)		; Load new ZSPEED value into 'a' for comparison
		ld b,a			; Transfer ZSPEED value from 'a' to 'b'
		ld a,0			; set 'a' to 0
		cp b			; See if 'b' (ZSPEED) is 0
		jr nz, JUMPUP_LOOP	; If not then repeat loop until 'b' = zero

JUMPDOWN_LOOP:

		ld b,8000		; Set delay time
		ld (DELAY_AMOUNT),bc
		call DELAY		
		
		ld bc,&0000		; Clear 'bc'

		ld a,(PLAYER_YPOS)	; Get current Y-POSITION in the jump and transfer to 'hl'
		ld bc,(ZSPEED)		; Jump speed loaded into 'bc'(Pre-set at 5, but will go down every loop)
		
		sub c 			; Jump down by whatever number is in 'bc'(ZSPEED) by adding to...  
						;...current 'hl' (PLAYER_YPOS)
		ld (ZSPEED),bc		; Store (ZSPEED)
		ld (PLAYER_YPOS),a
						
		call SPRITEDRAW		; Send new information to DRAW code to display on screen

		ld bc,(ZSPEED)		; Reload saved ZSPEED value after drawing routine
		inc c			; Increase jump (ZSPEED) amount by 1
		ld (ZSPEED),bc		; Load increased value back into ZSPEED for next loop (should be 4,3,2...)	
		
		ld a,(ZSPEED)		; Load new ZSPEED value into 'a' for comparison
		ld b,a			; Transfer ZSPEED value from 'a' to 'b'
		ld a,8			; set 'a' to 0
		cp b			; See if 'b' (ZSPEED) is 0
		jr nz, JUMPDOWN_LOOP	; If not then repeat loop until 'b' = zero
		
		jp z, BACKONGROUND	; if it is equal then jump back to the STANCE state and draw routine
		
BACKONGROUND:
		ld hl,(PLAYER_ZPOS)	; Load in position that the player was when he launched from jump
		ld (PLAYER_YPOS),hl	; Set the sprite to return to that position
		ld a,1			; Return to STANCE state
		ld (PLAYER_STATE),a

		ld a,0			; Set conditional RET to 'pass' in draw routine
		ld (JUMP_YES),a
		jp SPRITEDRAW		; Return to draw routine
RET
Programming: 90% failures, 10% victories, and 100% hair loss!

User avatar
akuyou
Posts: 563
Joined: Mon Apr 22, 2019 3:19 am
Contact:

Re: Code check - Jump routine for a player

Post by akuyou » Mon Oct 28, 2019 9:51 pm

there's no SUB HL,BC in Z80, but you can clear the carry (with OR A) and then do SBC... eg:

Code: Select all

     OR A ;Clear Carry
     SBC HL,BC ;subtract BC+Carry to HL
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

Kitsune Mifune
Posts: 33
Joined: Tue Oct 22, 2019 6:46 am
Location: Glasgow
Contact:

Re: Code check - Jump routine for a player

Post by Kitsune Mifune » Tue Oct 29, 2019 12:53 pm

That's good to know as I'm rewriting my code to make the player move and jump around by increments of 3 instead of 1, so using ADD, SUB, and now SBC will be really handy.

I guess I'm not as familiar with the wider instruction set as I'd like to be (or should be).

Thanks again!
Programming: 90% failures, 10% victories, and 100% hair loss!

Post Reply

Return to “Amstrad CPC Assembly Programming”