AtariAge Forums: sprite display not as expected - AtariAge Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

sprite display not as expected

User is offline yllawwally Icon
Posted Wed Feb 3, 2010 3:32 PM


  • Icon
  • Combat Commando
  • PM this member
  • Posts: 9
  • Joined: 15-May 09
I'm trying to learn 2600 programming. I took the face example from one of the tutorials here. I modified it to have alternate pics of the player every 8 screens. So that I could do a walking animation. However the top line seems to be a copy of the bottom line. I can't see what I'm doing wrong. I was hoping someone could help me find my error.

; move a happy face with the joystick by Kirk Israel
; (with a can't'dodge'em line sweeping across the screen)

	processor 6502
	include vcs.h
	org $F000

YPosFromBot = $80;
VisiblePlayerLine = $81;
PICS = $93;
PICSNUM = $94;

;generic start up stuff...
Start
	SEI	
	CLD  	
	LDX #$FF	
	TXS	
	LDA #0	
	STA PICSNUM
	
ClearMem 
	STA 0,X		
	DEX		
	BNE ClearMem	
	
	LDA #$00   ;start with a black background
	STA COLUBK	
	LDA #$1C   ;lets go for bright yellow, the traditional color for happyfaces
	STA COLUP0
;Setting some variables...
	LDA #80
	STA YPosFromBot	;Initial Y Position



;; Let's set up the sweeping line. as Missile 1

	
	LDA #2
	STA ENAM1  ;enable it
	LDA #33
	STA COLUP1 ;color it

	LDA #$20	
	STA NUSIZ1	;make it quadwidth (not so thin, that)

	
	LDA #$F0	; -1 in the left nibble
	STA HMM1	; of HMM1 sets it to moving


;VSYNC time
MainLoop
	LDA #2
	STA VSYNC	
	STA WSYNC	
	STA WSYNC 	
	STA WSYNC	
	LDA #43	
	STA TIM64T	
	LDA #0
	STA VSYNC 	


;Main Computations; check down, up, left, right
;general idea is to do a BIT compare to see if 
;a certain direction is pressed, and skip the value
;change if so

;
;Not the most effecient code, but gets the job done,
;including diagonal movement
;

; for up and down, we INC or DEC
; the Y Position

	LDA #010000	;Down?
	BIT SWCHA 
	BNE SkipMoveDown
	INC YPosFromBot
SkipMoveDown

	LDA #100000	;Up?
	BIT SWCHA 
	BNE SkipMoveUp
	DEC YPosFromBot
SkipMoveUp

; for left and right, we're gonna 
; set the horizontal speed, and then do
; a single HMOVE.  We'll use X to hold the
; horizontal speed, then store it in the 
; appropriate register




;assum horiz speed will be zero
	LDX #0	


	LDA #%01000000	;Left?
	BIT SWCHA 
	BNE SkipMoveLeft
	LDX #$10	;a 1 in the left nibble means go left


;; moving left, so we need the mirror image
	LDA #001000   ;a 1 in D3 of REFP0 says make it mirror
	STA REFP0

SkipMoveLeft

	LDA #%10000000	;Right?
	BIT SWCHA 
	BNE SkipMoveRight
	LDX #$F0	;a -1 in the left nibble means go right...

;; moving right, cancel any mirrorimage
	LDA #000000
	STA REFP0

SkipMoveRight


	STX HMP0	;set the move for player 0, not the missile like last time...



; see if player and missile collide, and change the background color if so

	;just a review...comparisons of numbers always seem a little backwards to me,
	;since it's easier to load up the accumulator with the test value, and then
	;compare that value to what's in the register we're interested.
	;in this case, we want to see if D7 of CXM1P (meaning Player 0 hit
	; missile 1) is on. So we put 10000000 into the Accumulator,
	;then use BIT to compare it to the value in CXM1P

	LDA #%10000000
	BIT CXM1P		
	BEQ NoCollision	;skip if not hitting...
	LDA YPosFromBot	;must be a hit! load in the YPos...
	STA COLUBK	;and store as the bgcolor
NoCollision
	STA CXCLR	;reset the collision detection for next time

	INC  PICSNUM

	LDA PICSNUM
	AND #15		;every 8th screen swap to next image of player
	CMP #8
	BEQ PICSET4
	JMP PICSET3
PICSET4	LDA  PICS
	CMP  #8
	BEQ PICSET
	LDA  #8
	JMP PICSET2
PICSET	LDA  #0
PICSET2	STA PICS
PICSET3

WaitForVblankEnd
	LDA INTIM	
	BNE WaitForVblankEnd	
	LDY #191 	


	STA WSYNC	
	STA HMOVE 	
	
	STA VBLANK  	


;main scanline loop...



PreScanLoop
;set player graphic to all zeros for this line, and then see if 
;we need to load it with graphic data
	LDA #0		
	STA GRP0  

ScanLoop 
	STA WSYNC 	

; here the idea is that VisiblePlayerLine
; is zero if the line isn't being drawn now,
; otherwise it's however many lines we have to go

CheckActivatePlayer
	CPY YPosFromBot
	BNE SkipActivatePlayer
	LDA #8
	STA VisiblePlayerLine 
SkipActivatePlayer





;set player graphic to all zeros for this line, and then see if 
;we need to load it with graphic data
	LDA #0		
	STA GRP0  

;
;if the VisiblePlayerLine is non zero,
;we're drawing it now!
;
	LDX VisiblePlayerLine	;check the visible player line...
	BEQ FinishPlayer		;skip the drawing if its zero...
IsPlayerOn	
	


	TXA		;Transfers the byte in the X Register to the Accumulator
	ADC PICS	;add value of pics to Accumulator
	TAX		;Transfers the byte in the Accumulator to the X Register
	LDA BigHeadGraphic-1,X	;shift to change which pic were showing
	
	


;	ORA #1		;creates a shield

	STA GRP0		;put that line as player graphic
	DEC VisiblePlayerLine 	;and decrement the line count
FinishPlayer




	DEY		

	BNE ScanLoop	


	LDA #2	

	STA WSYNC  	
	STA VBLANK 	
	LDX #24		



OverScanWait
	STA WSYNC
	DEX
	BNE OverScanWait
	JMP  MainLoop      


; here's the actual graphic! If you squint you can see its
; upsidedown smiling self
BigHeadGraphic
	.byte #010100
	.byte #010100
	.byte #011000
	.byte #011000
	.byte #%01111110
	.byte #010000
	.byte #011000
	.byte #011000


	.byte #010010
	.byte #010100
	.byte #011000
	.byte #011000
	.byte #%01111110
	.byte #010000
	.byte #011000
	.byte #011000

	.byte #010100
	.byte #010100
	.byte #011000
	.byte #011000
	.byte #%01111110
	.byte #010000
	.byte #011000
	.byte #011000


	.byte #010010
	.byte #010100
	.byte #011000
	.byte #011000
	.byte #%01111110
	.byte #010000
	.byte #011000
	.byte #011000

	org $FFFC
	.word Start
	.word Start

0

User is offline e1will Icon
Posted Wed Feb 3, 2010 9:03 PM


  • Icon
  • Chopper Commander
  • PM this member
  • Posts: 204
  • Joined: 24-April 09
You're setting the "first" GRP0 line AFTER you turn the screen on, so whatever was in GRP0 from the last pass gets drawn at the top.

If you put the "LDA #0" and "STA GRP0" lines BEFORE the STA WSYNC/STA HMOVE/STA VBLANK group, that should clear it out.

Hope this helps.

--Will
0

User is offline yllawwally Icon
Posted Fri Feb 5, 2010 10:38 AM


  • Icon
  • Combat Commando
  • PM this member
  • Posts: 9
  • Joined: 15-May 09
Sorry I mischaracterized the issue. Really the problem was the first line of the player was a copy of the previous last line. However that wasn't what was happening. I used ADC to add a counter for each step. I didn't realize that if the carry flag was set an additional 1 would be added. So I placed a CLC before adc, which has fixed it.
0

User is offline yllawwally Icon
Posted Thu Feb 11, 2010 3:29 PM


  • Icon
  • Combat Commando
  • PM this member
  • Posts: 9
  • Joined: 15-May 09
I seem to now have a problem using too many cycles. When the player and enemy are on the same lines, they get twice as tall. It seems that I should have cycles to spare. What am I doing wrong?


	processor 6502
	include vcs.h
	org $F000

;Variables ------

YPosFromBot = $80;
VisiblePlayerLine = $81;
PICS = $82;
ROLLING_COUNTER = $83;
Graphics_Buffer = $84
YPosFromBotE1 = $85;
VisibleEnemyLine = $86;
VisibleEnemyLineCurrent = $87;
EnemyLineBuffer = $88;
VisiblePlayerLineCurrent = $90;



; Constants ------
playerheight      ds #8;
enemyheight       ds #8;



;generic start up stuff...
Start
	SEI	
	CLD  	
	LDX #$FF	
	TXS	
	LDA #0	
	STA ROLLING_COUNTER
	STA PICS
	STA EnemyLineBuffer
	
ClearMem 
	STA 0,X		
	DEX		
	BNE ClearMem	
	
	LDA #$00   ;start with a black background
	STA COLUBK	
	LDA #$1C   ;lets go for bright yellow, the traditional color for happyfaces
	STA COLUP0
;Setting some variables...
	LDA #80
	STA YPosFromBot	;Initial Y Position
	STA YPosFromBotE1



;; Let's set up the sweeping line. as Missile 1

	
	LDA #2
	STA ENAM1  ;enable it
	LDA #33
	STA COLUP1 ;color it

	LDA #$10	
	STA NUSIZ1	;make it quadwidth (not so thin, that)

	LDA #000000	; set to not move
	STA HMM1	; of HMM1 sets it to moving



;VSYNC time
MainLoop
	LDA #2
	STA VSYNC	
	STA WSYNC	


; for up and down, we INC or DEC
; the Y Position

	LDA #010000	;Down?
	BIT SWCHA 
	BNE SkipMoveDown
	INC YPosFromBot
	INC YPosFromBotE1
	INC YPosFromBotE1
SkipMoveDown

	LDA #100000	;Up?
	BIT SWCHA 
	BNE SkipMoveUp
	DEC YPosFromBot
	DEC YPosFromBotE1
	DEC YPosFromBotE1
SkipMoveUp

; for left and right, we're gonna 
; set the horizontal speed, and then do
; a single HMOVE.  We'll use X to hold the
; horizontal speed, then store it in the 
; appropriate register




;assum horiz speed will be zero
	LDX #0	


	LDA #%01000000	;Left?
	BIT SWCHA 
	BNE SkipMoveLeft
	LDX #$10	;a 1 in the left nibble means go left


;; moving left, so we need the mirror image
	LDA #001000   ;a 1 in D3 of REFP0 says make it mirror
	STA REFP0

SkipMoveLeft

	LDA #%10000000	;Right?
	BIT SWCHA 
	BNE SkipMoveRight
	LDX #$F0	;a -1 in the left nibble means go right...

;; moving right, cancel any mirrorimage
	LDA #000000
	STA REFP0

SkipMoveRight


	STX HMP0	;set the move for player 0, not the missile like last time...



; see if player and missile collide, and change the background color if so

	;just a review...comparisons of numbers always seem a little backwards to me,
	;since it's easier to load up the accumulator with the test value, and then
	;compare that value to what's in the register we're interested.
	;in this case, we want to see if D7 of CXM1P (meaning Player 0 hit
	; missile 1) is on. So we put 10000000 into the Accumulator,
	;then use BIT to compare it to the value in CXM1P

	LDA #%10000000
	BIT CXM1P		
	BEQ NoCollision	;skip if not hitting...
	LDA YPosFromBot	;must be a hit! load in the YPos...
	STA COLUBK	;and store as the bgcolor
NoCollision
	STA CXCLR	;reset the collision detection for next time



	STA WSYNC ;//////////////////////////////////////////////

;setup pic animations ----------------------------------------------
	INC ROLLING_COUNTER

	LDA ROLLING_COUNTER
	AND #15		;every 8th screen swap to next image of player
	CMP #8
	BEQ PICSET4
	JMP PICSET3
PICSET4	LDA  PICS
	CMP  #8
	BEQ PICSET
	LDA  #8
	JMP PICSET2
PICSET	LDA  #0
PICSET2	STA PICS
PICSET3


	LDA ROLLING_COUNTER
	AND #25		;how often to move enemy, larger number is slower
	CMP #8
	BEQ PICSET5
	LDA #001111	; +1 in the left nibble
	JMP PICSET6
PICSET5	LDA #011111	; 0 in the left nibble
PICSET6	STA HMP1	; of HMP1 sets it to moving the enemy

	

	LDA #8
	CLC
	ADC PICS	;add value of pics to Accumulator 
	STA VisibleEnemyLineCurrent	
	
	LDA #8
	CLC
	ADC PICS	;add value of pics to Accumulator 
	STA VisiblePlayerLineCurrent

;setup pic animations ----------------------------------------------
	
	STA WSYNC ;//////////////////////////////////////////////	
	LDA #43	
	STA TIM64T	
	LDA #0
	STA VSYNC 	

;-------------------------
;-------------------------



WaitForVblankEnd
	LDA INTIM	
	BNE WaitForVblankEnd	
	LDY #191 	


	STA WSYNC	
	STA HMOVE 	
	
	STA VBLANK  	


;main scanline loop...



PreScanLoop

	LDA #0

ScanLoop ;start of kernal +++++++++++++++++++++++

	STA GRP0	;put that line as player graphic 0	 ;2 cycles
AFTERPLAYERDRAW


	LDA EnemyLineBuffer						 ;2 cycles
	STA GRP1	; put player 1 into grp1 2 cycles
AfterEnemyDraw

	DEY		;count down number of scan lines	  1 cycles

	LDA #8			;2 cycles

CheckActivatePlayer
	CPY YPosFromBot		;2 cycles
	BNE SkipActivatePlayer	;2 cycles
	STA VisiblePlayerLine 	;2 cycles
SkipActivatePlayer

CheckActivateEnemy
	CPY YPosFromBotE1	;2 cycles
	BNE SkipActivateEnemy	;2 cycles
	STA VisibleEnemyLine 	;2 cycles
SkipActivateEnemy




	LDA #0						 	;2 cycles
	STA EnemyLineBuffer					 ;2 cycles

	LDA VisibleEnemyLine	;check the visible enemy line... 2 cycles
	BEQ FinishEnemy		;skip the drawing if its zero... 2 cycles
IsEnemyOn	
	LDX VisibleEnemyLineCurrent		;2 cycles
	LDA EnemyGraphics-1,x			;2 cycles
	STA EnemyLineBuffer
	DEC VisibleEnemyLine			;2 cycles
	DEC VisibleEnemyLineCurrent		;2 cycles
FinishEnemy

	LDA VisiblePlayerLine	;check the visible player line... 2 cycles
	BEQ FinishPlayer	;skip the drawing if its zero...  2 cycles
IsPlayerOn	
	LDX VisiblePlayerLineCurrent				 ;2 cycles
	LDA MainPlayerGraphics-1,x	;shift to change which pic were showing 2 cycles
;	ORA #1		;creates a shield
	DEC VisiblePlayerLineCurrent				 ;2 cycles
	DEC VisiblePlayerLine					 ;2 cycles
FinishPlayer


	CPY #0						         ;2 cycles

	STA WSYNC 						 ;2 cycles
	BNE ScanLoop		 				 ;2 cycles
EndScanLoop ;end of kernal +++++++++++++++++

	STA WSYNC  	
	STA VBLANK 	
	LDX #24		



OverScanWait
	STA WSYNC
	DEX
	BNE OverScanWait
	JMP  MainLoop      



MainPlayerGraphics
	.byte #010100
	.byte #010100
	.byte #011000
	.byte #011000
	.byte #%01111110
	.byte #010000
	.byte #111000
	.byte #111000


	.byte #010010
	.byte #010100
	.byte #011000
	.byte #011000
	.byte #%01111110
	.byte #010000
	.byte #111000
	.byte #111000

EnemyGraphics
	.byte #%01111000
	.byte #%10000100
	.byte #001000
	.byte #010000
	.byte #010000
	.byte #010000
	.byte #111000
	.byte #111000


	.byte #%01111000
	.byte #%01001000
	.byte #010000
	.byte #100000
	.byte #100000
	.byte #100000
	.byte #%01110000
	.byte #%01110000

	org $FFFC
	.word Start
	.word Start

0

User is offline Nukey Shay Icon
Posted Thu Feb 11, 2010 5:29 PM


  • Icon
  • Sheik Yerbouti
  • PM this member
  • Posts: 18,856
  • Joined: 24-June 01
  • Location: Minnetropolis, Yimminysota
You are using too many cycles...and you seem to be confused regarding how many cycles are taken by the various instructions / addressing modes. There are NO instructions that only take a single cycle (DEY above should be 2 cycles). Most of the LDAs and STA's above are 3 cycles (not 2). The DEC's are 5 cycles (again, not 2). Branches are 2 cycles if not taken, but 3 cycles if they are.

Worst-case scenario...which is when the program takes the long path (i.e. no branches taken to skip ahead)...is 84 cycles.

This post has been edited by Nukey Shay: Thu Feb 11, 2010 5:45 PM

0

User is offline Nukey Shay Icon
Posted Thu Feb 11, 2010 6:24 PM


  • Icon
  • Sheik Yerbouti
  • PM this member
  • Posts: 18,856
  • Joined: 24-June 01
  • Location: Minnetropolis, Yimminysota
Correction...89 cycles worst-case in the scanline loop :P
0

User is offline yllawwally Icon
Posted Thu Feb 11, 2010 6:44 PM


  • Icon
  • Combat Commando
  • PM this member
  • Posts: 9
  • Joined: 15-May 09
Thank you very much. I was using number of bytes as the cycle time. Which is why I was totally confused.
0

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic


1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users