Jump to content

Anyone think Ballblazer is possible on the 2600?


767 replies to this topic

#26  

    Stargunner

  • 1,274 posts
  • Joined: 22-June 01
  • Location:Tasmania

Posted Mon Sep 8, 2008 4:20 AM

View Postroland p, on Mon Sep 8, 2008 8:10 PM, said:

Two players should be possible. I'll take just small steps for now :)
I'm now doubling the vertical resolution, the tiles at the sides will benefit from this, well... it makes everything look better.

I also want to make a finer grained control of the movement to get that 'techy'-look. The horizontal movement is now 20 pixels, I precalculated a vector that turns 45 degrees in 20 steps and used that to control the movement of the grid. I like to calculate 256 pixels heigh vector and use only the upper 20 pixels of it so the horizontal movement has 256 possible positions. Anyone know how to calculate vectors?

For vertical tiles I have to make a sort of sinus-table to make the tiles smaller in the distance. Any ideas on this are also welcome.

The brown border of the checkerboard needs als to be done. I'll get to this when I've the checkerboard the way I want.

Very nice so far, and I'm watching this with interest too. The lines are sometimes a bit wonky, but it does show potential. I'd like to see the source code; I'm sure if you shared you'd get some great contributions from some of the regulars here. Keep up the good work.
Cheers
A

#27  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Mon Sep 8, 2008 4:27 AM

View Postcd-w, on Mon Sep 8, 2008 5:14 AM, said:

Very nice work! It looks like you are creating the stripes simply by changing the background colour at the right time? This is a nice approach as you should be able to create the checkerboard simply by fliping the colours at various points down the screen.
Yep, lots of STY, STY.w, STX, STX.w and NOP's. Trail and error based ;D. flipping colors happens already when you've moved 1 tile to the right/left.

View Postcd-w, on Mon Sep 8, 2008 5:14 AM, said:

It also frees up the PF/ball colour to be used for other things. However, this approach won't leave you much time for displaying the sprites over the board.

What is needed for sprites? I'm programming the 2600 since Thursday and I've read some tutorials. Positioning is tricky, could that be done outside the board? Then data has to be loaded at the beginning of a scanline right?

View Postcd-w, on Mon Sep 8, 2008 5:14 AM, said:

The alternative is to display an asymmetrical playfield, but this will require a lot of different patterns to be stored.
Lot's of shifting around I guess. Now I have the bonus of 3pixel resolution instead of 4. scrolling a part of the checkerboard is now just wait for 1 cycle and everything that comes next is moved 1 cycles (I don't wait for WSYNC) :cool:

#28  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Mon Sep 8, 2008 4:35 AM

the board says 'Upload failed. You are not permitted to upload this type of file'...

The project in it's current state:
It's a modified 'hello' demo. Maybe It's ugly, and not cleaned up... Please shoot on it :D

File main3.asm:
	processor 6502
	include vcs.h
	include macro.h
	include lines.h

	org $F000
       
Temp       = $80
PlayfieldY = $90
Direction  = $91
ScanLine   = $92
SubLineCount = $93

offsetLine0_7 = $94
offsetLine8_15 = $95
offsetLine16_19 = $96


PositionX   = $97
invert		= $98

Start
	SEI  ; Disable interrupts, if there are any.
	CLD  ; Clear BCD math bit.
	
	LDX  #$FF
	TXS  ; Set stack to beginning.
;
; Now the memory and TIA registers must be cleared.  You may feel the
; need to write a subroutine that only clears out a certain section of
; memory, but for now a simple loop will suffice.
;
; Since X is already loaded to 0xFF, our task becomes simply to ocunt
; everything off.
;
	LDA #0
B1      STA 0,X
	DEX
	BNE B1
;
; The above routine does not clear location 0, which is VSYNC.  We will
; take care of that later.
;
; At this point in the code we would set up things like the data
; direction registers for the joysticks and such.  
;
	JSR  GameInit
;
; Here is a representation of our program flow.
;
MainLoop
	JSR  VerticalBlank ;Execute the vertical blank.
	JSR  CheckSwitches ;Check console switches.
	JSR  GameCalc      ;Do calculations during Vblank
	JSR  DrawScreen    ;Draw the screen
	JSR  OverScan      ;Do more calculations during overscan
	JMP  MainLoop      ;Continue forever.

	
VerticalBlank  ;*********************** VERTICAL BLANK HANDLER
	LDX  #0
	LDA  #2
	STA  WSYNC  
	STA  WSYNC
	STA  WSYNC
	STA  VSYNC ;Begin vertical sync.
	STA  WSYNC ; First line of VSYNC
	STA  WSYNC ; Second line of VSYNC.
	
;
; But before we finish off the third line of VSYNC, why don't we
; use this time to set the timer?  This will save us a few cycles
; which would be more useful in the overscan area.
;
; To insure that we begin to draw the screen at the proper time,
; we must set the timer to go off just slightly before the end of
; the vertical blank space, so that we can WSYNC up to the ACTUAL
; end of the vertical blank space.  Of course, the scanline we're
; going to omit is the same scanline we were about to waste VSYNCing,
; so it all evens out.
;
; Atari says we have to have 37 scanlines of VBLANK time.  Since
; each scanline uses 76 cycles, that makes 37*76=2888 cycles.
; We must also subtract the five cycles it will take to set the
; timer, and the three cycles it will take to STA WSYNC to the next
; line.  Plus the checking loop is only accurate to six cycles, making
; a total of fourteen cycles we have to waste.  2888-14=2876.
;
; We almost always use TIM64T for this, since the math just won't
; work out with the other intervals.  2880/64=44.something.  It
; doesn't matter what that something is, we have to round DOWN.
;
	LDA  #44
	STA  TIM64T
;
; And now's as good a time as any to clear the collision latches.
;
	LDA #0
	STA CXCLR
;
; Now we can end the VSYNC period.
;
	STA  WSYNC ; Third line of VSYNC.
	STA  VSYNC ; (0)
;
; At this point in time the screen is scanning normally, but
; the TIA's output is suppressed.  It will begin again once
; 0 is written back into VBLANK.
;
	RTS  
;
; Checking the game switches is relatively simple.  
;
; It just so happens that I'm not going to check any game switches
; here.  I'm just going to set up the colors, without even checking
; the B&W switch!  HA!
;
CheckSwitches ;*************************** CONSOLE SWITCH HANDLER
       LDA #0
       STA COLUBK  ; Background will be black.
       RTS
;
; Minimal game calculations, just to get the ball rolling.
;
GameCalc ;******************************* GAME CALCULATION ROUTINES
	CLC
	
	LDX PositionX
	
	LDA SWCHA	;read joystick
	AND #$80
	CMP #$80
	BCS CONT
	
	INX
	STX PositionX
	
	CPX #20
	BCC CONT
	LDA invert
	EOR #$01
	STA invert
	LDX #0
	STX PositionX
CONT	


	LDA SWCHA	;read joystick
	AND #$40
	CMP #$40
	BCS CONT2

	DEX
	STX PositionX
	
	CPX #255
	BCC CONT2
	LDA invert
	EOR #$01
	STA invert
	LDX #19
	STX PositionX
CONT2

	
	
	
	
	
	LDA OFFSET_DATA_0_7,X
	STA offsetLine0_7
	
	LDA OFFSET_DATA_8_15,X
	STA offsetLine8_15
	
	LDA OFFSET_DATA_16_19,X
	STA offsetLine16_19


	
	

	
	RTS

	
	
ChangeDir
	LDA Direction
	EOR #$FE
	STA Direction
	RTS

;
; This is the scariest thing I've done all month.
;
DrawScreen ;**************************** SCREEN DRAWING ROUTINES
	LDA INTIM
	BNE DrawScreen ; Whew!
	STA WSYNC
	STA VBLANK  ;End the VBLANK period with a zero.

	LDA  #2
	STA  CTRLPF
	
	LDA #171
	STA ScanLine
	
BlueLines	
	JSR BlueLine
	DEC ScanLine
	LDA ScanLine
	CMP #120
	BNE BlueLines

	
	LDA #$88
	STA COLUBK
	DEC ScanLine
	STA WSYNC

	LDA #$8A
	STA COLUBK
	DEC ScanLine
	
	LDX	invert
	LDY	#$CC
	LDX	#$C4
	
	LDA invert
	CMP #$01
	BNE NOT_INVERT
	LDX	#$CC
	LDY	#$C4
NOT_INVERT
	
	STA WSYNC

	LDA #$9B
	STA COLUBK
	DEC ScanLine

	
	LDA PositionX
	CMP #07
	BCS Skip1
Skip1

	CMP #14
	BCS Skip2
Skip2

	SLEEP 62
	

	
	
	;LINE 0
	SLEEP 12
	
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	LINEY 3
	LINEX 3
	
	
	
	SLEEP 14


	LINEX 4
	LINEY 3
	LINEX 4
	LINEY 3
	LINEX 4
	LINEY 3
	LINEX 4
	LINEY 3
	LINEX 4 ; center L
	LINEY 3 ;center R
	LINEX 3
	LINEY 4
	LINEX 3
	LINEY 4
	LINEX 3
	LINEY 4
	LINEX 3
	LINEY 4

	
	;LINE 1
	LDA offsetLine0_7
	AND #%00000010
	BNE Line1NoOffset
Line1NoOffset

	
	SLEEP 13
	LINEY 4
	LINEX 4
	LINEY 4
	LINEX 4
	LINEY 4
	LINEX 4
	LINEY 4
	LINEX 4
	LINEY 4
	LINEX 4
	LINEY 4
	LINEX 4
	LINEY 4

	SLEEP 18
	
	
	
	STX.w COLUBK 
	STY.w COLUBK 
	STX.w COLUBK 
	nop
	STY COLUBK 
	STX.w COLUBK 

	STY.w COLUBK 
	nop
	STX COLUBK ;L
	STY.w COLUBK ;R
	STX.w COLUBK 
	nop
	STY COLUBK 
	STX.w COLUBK 
	STY.w COLUBK 
	STX.w COLUBK 
	STY.w COLUBK 

	;LINEX 4	
	;LINEY 4
	;LINEX 4
	;LINEY 4
	;LINEX 4
	;LINEY 4
	;LINEX 5;L
	;LINEY 4;R
	;LINEX 4
	;LINEY 4
	;LINEX 4
	;LINEY 4
	;LINEX 4
	;LINEY 4


	
	;LINE 2
	LDA offsetLine0_7
	AND #%00000100
	BNE Line2NoOffset
Line2NoOffset

	SLEEP 11
	LINEY 5
	LINEX 5
	LINEY 5
	LINEX 5
	LINEY 5
	LINEX 5	;L
	LINEY 5	;R
	LINEX 5
	LINEY 5
	LINEX 5
	LINEY 5
	LINEX 5
	



	SLEEP 13
	LINEY 5
	LINEX 6
	LINEY 5
	LINEX 6
	LINEY 5
	LINEX 6	;L
	LINEY 5	;R
	LINEX 5
	LINEY 6
	LINEX 5
	LINEY 6
	LINEX 5
	
	;LINE 3
	LDA offsetLine0_7
	AND #%00001000
	BNE Line3NoOffset
Line3NoOffset
	SLEEP 12
	LINEY 6
	LINEX 6
	LINEY 6
	LINEX 6
	LINEY 6
	LINEX 6
	LINEY 6
	LINEX 6


	SLEEP 27
	LINEY 6
	LINEX 6
	LINEY 6
	nop
	LINEX 5;L
	LINEY 6;R
	LINEX 6
	nop
	LINEY 5
	LINEX 5

	;LINE 4
	LDA offsetLine0_7
	AND #%00010000
	BNE Line4NoOffset
Line4NoOffset
	SLEEP 18
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 7

	
	SLEEP 19
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 8;R
	LINEY 7;L
	LINEX 7
	LINEY 8
	LINEX 7
	
	
	;LINE 5
	LDA offsetLine0_7
	AND #%00100000
	BNE Line5NoOffset
Line5NoOffset
	SLEEP 7
	LINEY 8
	LINEX 8
	LINEY 8
	LINEX 8
	LINEY 8
	LINEX 8
	LINEY 8
	LINEX 4


	SLEEP 15
	LINEY 8
	LINEX 8
	LINEY 8
	nop
	LINEX 7 ;L
	LINEY 8 ;R
	LINEX 8
	nop
	LINEY 7
	LINEX 8
	LINEY 4

	
	
	;LINE 6
	LDA offsetLine0_7
	AND #%01000000
	BNE Line6NoOffset
Line6NoOffset

	SLEEP 6
	LINEX 9
	LINEY 9
	LINEX 9
	LINEY 9
	LINEX 9
	LINEY 9
	LINEX 9
	LINEY 3


	SLEEP 9
	LINEX 9
	LINEY 9
	LINEX 10 ;L
	LINEY 9 ;R
	LINEX 9
	LINEY 10

	
	;LINE 7
	LDA offsetLine0_7
	AND #%10000000
	BNE Line7NoOffset
Line7NoOffset
	SLEEP 10
	LINEX 10
	LINEY 10
	LINEX 10
	LINEY 10
	LINEX 10
	LINEY 10


	SLEEP 16
	LINEX 10
	LINEY 10
	LINEX 10
	LINEY 10
	LINEX 10
	LINEY 10

	;line 8
	LDA offsetLine8_15
	AND #%00000001
	BNE Line8NoOffset
Line8NoOffset
	SLEEP 7
	LINEX 11
	LINEY 11
	LINEX 11
	LINEY 11
	LINEX 11
	LINEY 5

	
	SLEEP 15
	LINEX 11
	LINEY 11
	LINEX 10 ;L
	nop
	LINEY 11 ;R
	LINEX 11
	LINEY 3

	;line 9
	LDA offsetLine8_15
	AND #%00000010
	BNE Line9NoOffset
Line9NoOffset
	SLEEP 7
	LINEX 12
	LINEY 12
	LINEX 12
	LINEY 12
	LINEX 12
	LINEY 4

	SLEEP 12
	LINEX 12
	LINEY 12
	LINEX 12
	LINEY 12
	LINEX 12
	LINEY 4
	LINEX 8

	;line 10
	LDA offsetLine8_15
	AND #%00000100
	BNE Line10NoOffset
Line10NoOffset

	SLEEP 8
	LINEY 13
	LINEX 13
	LINEY 13
	LINEX 13
	LINEY 3
	LINEX 3

	SLEEP 18
	LINEY 13
	LINEX 13
	LINEY 13
	LINEX 13
	LINEY 3
	LINEX 3

	;line 11
	LDA offsetLine8_15
	AND #%00001000
	BNE Line11NoOffset
Line11NoOffset
	;SLEEP 18
	SLEEP 8
	LINEY 14
	LINEX 14
	LINEY 14
	LINEX 14

	SLEEP 20
	LINEY 14
	LINEX 14
	LINEY 14
	LINEX 4
	
	;line 12
	LDA offsetLine8_15
	AND #%00010000
	BNE Line12NoOffset
Line12NoOffset
	SLEEP 22
	LINEY 15
	LINEX 15
	LINEY 15
	LINEX 3
	
	SLEEP 28
	LINEY 15
	LINEX 15
	LINEY 15
	LINEX 3
	

	;line 13
	LDA offsetLine8_15
	AND #%00100000
	BNE Line13NoOffset
Line13NoOffset
	SLEEP 18
	LINEY 16
	LINEX 16
	LINEY 16
	LINEX 4
	
	SLEEP 24
	LINEY 16
	LINEX 16
	LINEY 16
	LINEX 4

	
	;line 14
	LDA offsetLine8_15
	AND #%01000000
	BNE Line14NoOffset
Line14NoOffset
	SLEEP 16
	LINEY 17
	LINEX 17
	LINEY 17
	LINEX 3

	SLEEP 22
	LINEY 17
	LINEX 17
	LINEY 17
	LINEX 3

	;line 15
	LDA offsetLine8_15
	AND #%10000000
	BNE Line15NoOffset
Line15NoOffset
	SLEEP 12
	LINEY 18
	LINEX 18
	LINEY 18
	LINEX 4

	SLEEP 18
	LINEY 18
	LINEX 18
	LINEY 18
	LINEX 4

	;line 16
	LDA offsetLine16_19
	AND #%00000001
	BNE Line16NoOffset
Line16NoOffset
	SLEEP 10
	LINEY 19
	LINEX 19
	LINEY 19
	LINEX 3

	SLEEP 16
	LINEY 19
	LINEX 19
	LINEY 19
	LINEX 3

	;line 17
	LDA offsetLine16_19
	AND #%00000010
	BNE Line17NoOffset
Line17NoOffset
	SLEEP 6
	LINEY 20
	LINEX 20
	LINEY 20
	LINEX 4

	SLEEP 12
	LINEY 20
	LINEX 20
	LINEY 20
	LINEX 4

	;line 18
	LDA offsetLine16_19
	AND #%00000100
	BNE Line18NoOffset
Line18NoOffset
	SLEEP 4
	LINEY 21
	LINEX 21
	LINEY 21
	LINEX 3

	SLEEP 10
	LINEY 21
	LINEX 21
	LINEY 21
	LINEX 3

	;line 19
	LDA offsetLine16_19
	AND #%00001000
	BNE Line19NoOffset
Line19NoOffset
	;SLEEP 7
	LINEY 22
	LINEX 22
	LINEY 22
	LINEX 4

	SLEEP 6
	LINEY 22
	LINEX 22
	LINEY 22
	LINEX 6

	LDA #$0
	STA COLUBK
	
	
; Draw other lines	
DrawLines
	STA WSYNC
	DEC ScanLine
	BNE DrawLines
	
	STA WSYNC  ;Finish this scanline.
	STA VBLANK ; Make TIA output invisible,
	RTS


	
	
	

;
; For the Overscan routine, one might take the time to process such
; things as collisions.  I, however, would rather waste a bunch of
; scanlines, since I haven't drawn any players yet.
;
OverScan   ;***************************** OVERSCAN CALCULATIONS
	LDX #30
KillLines
	 STA WSYNC
	 DEX
	 BNE KillLines
	RTS

BlueLine
	LDA #$85
	STA COLUBK
	STA WSYNC
	RTS
	
	
	
Line1
	STA COLUBK 
	NOP
	
	SLEEP 4
	
	LINEX 5
	LINEY 5
	LINEX 5
	LINEY 5
	LINEX 5
	LINEY 5
	LINEX 5
	LINEY 5
	LINEX 5
	LINEY 5

	STA WSYNC
	RTS

	
	
Line2
	STX.w COLUBK
	SLEEP 5
	
	LINEY 6
	LINEX 6
	LINEY 6
	LINEX 6
	LINEY 6
	LINEX 6
	LINEY 6
	LINEX 6

	STA WSYNC
	RTS

	
Line3
	SLEEP 6
	
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 7
	LINEY 7
	LINEX 3

	STA WSYNC
	RTS
	
	
	
	
Line4
	SLEEP 9
	
	LINEX 8
	LINEY 8
	LINEX 8
	LINEY 8
	LINEX 8
	LINEY 8
	LINEX 3

	STA WSYNC
	RTS
	
	






Line5
	SLEEP 7
	
	LINEX 9
	LINEY 9
	LINEX 9
	LINEY 9
	LINEX 9
	LINEY 9


	STA WSYNC
	RTS
	
	
Line6
	SLEEP 3
	
	LINEX 10
	LINEY 10
	LINEX 10
	LINEY 10
	LINEX 10
	LINEY 8

	STA WSYNC
	RTS
	
	
	
Line7
	;SLEEP 1
	
	LINEX 12
	LINEY 11
	LINEX 11
	LINEY 11
	LINEX 11
	LINEY 3
	

	STA WSYNC
	RTS
	
	
	
Line8
	;SLEEP 1

	LINEX 9
	LINEY 12
	LINEX 12
	LINEY 12
	LINEX 12
	LINEY 4

	STA WSYNC
	RTS
	
Line9
	;SLEEP 1

	LINEX 8
	LINEY 13
	LINEX 13
	LINEY 13
	LINEX 3

	STA WSYNC
	RTS
	
Line10
	;SLEEP 1

	LINEX 5
	LINEY 14
	LINEX 14
	LINEY 4
	LINEY 11
	LINEX 3

	STA WSYNC
	RTS


	
;
; GameInit could conceivably be called when the Select key is pressed,
; or some other event.
;
GameInit
	LDA #0
	STA PlayfieldY
	LDA #1
	STA Direction; Set Direction to 1
	
	LDA #0
	STA PositionX

	LDA #0
	STA invert
	

	RTS

;
; Graphics are placed so that the extra cycle in the PFData,X indexes
; is NEVER taken, by making sure it never has to index across a page
; boundary.  This way our cycle count holds true.
;

	org $FF00 ; *********************** GRAPHICS DATA
;
; This is the tricky part of drawing a playfield: actually
; drawing it.  Well, the display routine and all that binary
; math was a bit tricky, too, but still, listen up.
;
; Playfield data isn't stored the way most bitmaps are, even
; one-dimensional bitmaps.  We will use the left side of the
; screen only, knowing that the right side is either repeated
; or reflected from it.
;
; In PF0 and PF2, the most significant bit (bit 7) is on the RIGHT
; side.  In PF1, the most significant bit is on the LEFT side.  This
; means that relative to PF0 and PF2, PF1 has a reversed bit order.
; It's just really weird.
;
;    PF0  |     PF1       |      PF2
;  4 5 6 7|7 6 5 4 3 2 1 0|0 1 2 3 4 5 6 7
;
; This is important to remember when doing calculations on bytes intended
; for the PF registers.  Defender gives a good example of this.
;
; It will become necessary to write a program that makes this easier,
; because it is easy to become confused when dealing with this system.
;
	   
OFFSET_DATA_0_7
		.byte $0,$0,$80,$20,$10,$88,$48,$24,$94,$54,$B4,$AC,$6C,$DA,$BA,$76,$F6,$DE,$FE,$FE
OFFSET_DATA_8_15       
		.byte $0,$4,$20,$84,$11,$24,$4A,$95,$2A,$55,$AA,$B5,$DB,$6E,$BB,$DF,$FB,$7F,$FB,$FF
		
OFFSET_DATA_16_19
		.byte $0,$0,$0,$0,$2,$4,$4,$8,$2A,$A,$2A,$C,$C,$36,$36,$1A,$3A,$3E,$1E,$1E
	   
	org $FFFC
	.word Start
	.word Start



File Lines.h:



			MAC LINEY
			
.CYCLES     SET {1}

				IF .CYCLES < 3
					ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
					ERR
				ENDIF
				
				IF .CYCLES & 1
					STY COLUBK 
.CYCLES             SET .CYCLES - 3
				ELSE
					STY.w COLUBK 
.CYCLES             SET .CYCLES - 4
				ENDIF

				
				REPEAT .CYCLES / 2
					nop
				REPEND
			ENDM


			
			
			MAC LINEX
			
.CYCLES     SET {1}

				IF .CYCLES < 3
					ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
					ERR
				ENDIF
				
				IF .CYCLES & 1
					STX COLUBK 
.CYCLES             SET .CYCLES - 3
				ELSE
					STX.w COLUBK 
.CYCLES             SET .CYCLES - 4
				ENDIF

				
				REPEAT .CYCLES / 2
					nop
				REPEND
			ENDM
			


			
			
						MAC LINEY2
			
.CYCLES     SET {1}

				IF .CYCLES < 3
					ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
					ERR
				ENDIF
				
				IF .CYCLES & 1
.CYCLES2            SET .CYCLES - 3
				ELSE
.CYCLES2            SET .CYCLES - 4
				ENDIF

				REPEAT .CYCLES2 / 2
					nop
				REPEND
				
				IF .CYCLES & 1
					STY COLUBK 
				ELSE
					STY.w COLUBK 
				ENDIF
			ENDM


			

			
			MAC LINEX2
			
.CYCLES     SET {1}

				IF .CYCLES < 3
					ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
					ERR
				ENDIF
				
				IF .CYCLES & 1
.CYCLES2            SET .CYCLES - 3
				ELSE
.CYCLES2            SET .CYCLES - 4
				ENDIF

				REPEAT .CYCLES2 / 2
					nop
				REPEND
				
				IF .CYCLES & 1
					STX COLUBK 
				ELSE
					STX.w COLUBK 
				ENDIF
			ENDM


	

; EOF


#29  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Mon Sep 8, 2008 4:37 AM

I'll make it cleaner when I have the time.

Edit:
As Andrew suggested, the project is now opensource!
I truly believe it will be better if everyone is able to put their part in it.

There is lot's to be done like game play-code, sounds.

Edited by roland p, Mon Sep 8, 2008 4:59 AM.


#30  

    Stargunner

  • 1,169 posts
  • Joined: 12-March 05
  • Juno First!
  • Location:Glasgow, UK

Posted Mon Sep 8, 2008 4:59 AM

View Postroland p, on Mon Sep 8, 2008 11:27 AM, said:

Yep, lots of STY, STY.w, STX, STX.w and NOP's. Trail and error based ;D. flipping colors happens already when you've moved 1 tile to the right/left.

If you also flip the colours as you move down the screen then you can create the checkerboard. My Juno First game displays moving lines to simulate movement. If you used this kind of approach to determine when to flip the colours then I think you would have a nice fully-functioning checkerboard.

Quote

What is needed for sprites? I'm programming the 2600 since Thursday and I've read some tutorials. Positioning is tricky, could that be done outside the board? Then data has to be loaded at the beginning of a scanline right?

Horizontal sprite positioning can be done outside the kernel. Inside the kernel you need to decide what sprite data to display on each line. I think Ballblazer only has two sprites that overlap the board (the other player, and the goalposts)? You will need to switch on/off these sprites on the right lines while drawing the grid. A good summary of the different approaches (skipdraw, switchdraw etc.) was posted in this thread.

Quote

Lot's of shifting around I guess. Now I have the bonus of 3pixel resolution instead of 4. scrolling a part of the checkerboard is now just wait for 1 cycle and everything that comes next is moved 1 cycles (I don't wait for WSYNC) :cool:

If you stored all of the different possible patterns in ROM then you could just display the appropriate one on each frame, but I think this would require a LOT of ROM space!

Thanks for sharing the code - you should get some good feedback from this. To upload code directly onto the forum, place it inside a ZIP file first.

Chris

Edited by cd-w, Mon Sep 8, 2008 5:09 AM.


#31  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Mon Sep 8, 2008 5:37 AM

Juno First looked really good, it's exactly what I am looking for.

I just hope that I have enough cycles left for sprites...

#32  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Thu Sep 11, 2008 3:22 AM

Just a small update to keep it alive. I did not have much time to work on the project but some improvements have been made.
Things improved this time:

1. vertical resolution is now doubled.
2. precalculation of the movement is now correct :) maybe some small glitches, but much better then before.
3. I use a vanishing point up in the sky, where it really is.
4. the horizontal scrolling is now at a high precision at 1 virtual colorclock :cool:

The precalculated vector for the movement is still at half the vertical resolution of the checkerboard....

Attached Files


Edited by roland p, Thu Sep 11, 2008 3:44 AM.


#33  

    Stargunner

  • 1,274 posts
  • Joined: 22-June 01
  • Location:Tasmania

Posted Thu Sep 11, 2008 4:12 AM

View Postroland p, on Thu Sep 11, 2008 7:22 PM, said:

Just a small update to keep it alive. I did not have much time to work on the project but some improvements have been made.
Things improved this time:

1. vertical resolution is now doubled.
2. precalculation of the movement is now correct :) maybe some small glitches, but much better then before.
3. I use a vanishing point up in the sky, where it really is.
4. the horizontal scrolling is now at a high precision at 1 virtual colorclock :cool:

The precalculated vector for the movement is still at half the vertical resolution of the checkerboard....

This is very nice; well done!

If it were me, the next thing I'd do would be put a bit of inertia on the movement, so when you move in a direction, it takes a little while to accelerate, and when you let go, it takes a little while to stop. I think this would really accentuate the effect. Also, I'm wondering how much better it will look with the squares done -- that is, alternating the colours and making it a real chequerboard.

You could also just repeat the first bunch of scanlines again to give yourself a dual-window display, which would be pretty cool too.

Good work so far, keep going!

Cheers
A

#34  

    Thrust, Jammed, SWOOPS!

  • 16,625 posts
  • Joined: 25-April 01
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Thu Sep 11, 2008 4:42 AM

I agree with Andrew, pretty impressive already. And I am also really looking forward to the checkerboard.

Maybe you could try to use flicker to simulate antialiasing? At least it would be interesting to see the result. :ponder:

#35  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Thu Sep 11, 2008 4:45 AM

Quote

This is very nice; well done!
thanx!

Quote

If it were me, the next thing I'd do would be put a bit of inertia on the movement, so when you move in a direction, it takes a little while to accelerate, and when you let go, it takes a little while to stop. I think this would really accentuate the effect.
You're right. that would look cool. I've downloaded the Atari 5200 version of Ballblazer see what's really going on.

Quote

Also, I'm wondering how much better it will look with the squares done -- that is, alternating the colours and making it a real chequerboard.
Yep, it's about time :) I will work something out.

#36  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Thu Sep 11, 2008 4:51 AM

View PostThomas Jentzsch, on Thu Sep 11, 2008 4:42 AM, said:

Maybe you could try to use flicker to simulate antialiasing? At least it would be interesting to see the result. :ponder:
mmmh... interesting. by increasing/decreasing horizontal movement by a pixel every other frame. Maybe that looks nice.

I've seen in the atari 5200 version that there is a sort of antialiassing in the vertical direction, the 2600 should be able to do that too.

#37  

    Thrust, Jammed, SWOOPS!

  • 16,625 posts
  • Joined: 25-April 01
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Thu Sep 11, 2008 5:02 AM

View Postroland p, on Thu Sep 11, 2008 12:51 PM, said:

mmmh... interesting. by increasing/decreasing horizontal movement by a pixel every other frame. Maybe that looks nice.
Interesting idea. Didn't think about this.

My idea is to use a different vertical offset for the "line" drawing. E.g. when you more one pixel of center, the pixel "jump" now is visible around the lower third. Which is probably the correct position when there is more than 50% of the pixel on the other side. With vertical antialiasing, you could do the pixel jump for the even frame a bit above and for the odd frame a bit below (e.g. after 25 and 75%) the current position.

Anyway, do whatever looks better. :)

Quote

I've seen in the atari 5200 version that there is a sort of antialiassing in the vertical direction, the 2600 should be able to do that too.
Yup, we would have vertical antialiasing here too.

#38  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Thu Sep 11, 2008 5:22 AM

Quote

Interesting idea. Didn't think about this.

My idea is to use a different vertical offset for the "line" drawing. E.g. when you more one pixel of center, the pixel "jump" now is visible around the lower third. Which is probably the correct position when there is more than 50% of the pixel on the other side. With vertical antialiasing, you could do the pixel jump for the even frame a bit above and for the odd frame a bit below (e.g. after 25 and 75%) the current position.

Anyway, do whatever looks better.

I've now used a 2 pixel offset every other frame. It looks not bad. I've to change my tables a bit to make it look even better, but now you have REAL antialiassing!

Attached Files



#39  

    Stargunner

  • 1,274 posts
  • Joined: 22-June 01
  • Location:Tasmania

Posted Thu Sep 11, 2008 5:35 AM

View Postroland p, on Thu Sep 11, 2008 9:22 PM, said:

Quote

Interesting idea. Didn't think about this.

My idea is to use a different vertical offset for the "line" drawing. E.g. when you more one pixel of center, the pixel "jump" now is visible around the lower third. Which is probably the correct position when there is more than 50% of the pixel on the other side. With vertical antialiasing, you could do the pixel jump for the even frame a bit above and for the odd frame a bit below (e.g. after 25 and 75%) the current position.

Anyway, do whatever looks better.

I've now used a 2 pixel offset every other frame. It looks not bad. I've to change my tables a bit to make it look even better, but now you have REAL antialiassing!


Noooo! This is a bad bad idea! It was so very clean, without any flickering. You're spoiling it with this totally unnecessary stuff. Stick to getting the checquerboard working, don't fix something that wasn't broken! Seriously, stay focused... don't get diverted!

Cheers
A

#40  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Thu Sep 11, 2008 5:48 AM

Ok, I'll stick to the useful stuff :D

#41  

    Thrust, Jammed, SWOOPS!

  • 16,625 posts
  • Joined: 25-April 01
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Thu Sep 11, 2008 11:21 AM

View PostAndrew Davie, on Thu Sep 11, 2008 1:35 PM, said:

Noooo! This is a bad bad idea! It was so very clean, without any flickering.
It doesn't look good on emulators and due to syncing problems most likely never will. But it might look good on a real TV if done right. Maybe as a switchable option.

But I agree, for now other stuff is more important.

#42  

    Visual batari Basic User

  • 20,535 posts
  • Joined: 23-April 01
  • Controlled Randomness

    Replay Value

    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Sep 11, 2008 12:07 PM

View PostAndrew Davie, on Thu Sep 11, 2008 7:35 AM, said:

Noooo! This is a bad bad idea! It was so very clean, without any flickering. You're spoiling it with this totally unnecessary stuff. Stick to getting the checquerboard working, don't fix something that wasn't broken! Seriously, stay focused... don't get diverted!
Yeah, it looked better the old way. I bet this will look pretty darn good when it's done.

#43  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Fri Sep 12, 2008 3:19 AM

Hi there,

My 4K is reaching its limits. The code for drawing the lines is a bit big because it's completely based on processor cycles. And besides the code, I use some tables for the horizontal movement wich occupies 207 bytes. The sinus table for vertical movement (which is needed to complete the tiles) is another 69 bytes. This results in >4K of ROM.

Now I've tried to calculate the vector in real time to save those 207 bytes. This is possible and takes now about 700 cycles. That's cool, but I'll get into memory problems anway. So what I want to do is:

1. Ditch the vector routine, nothing beats LDA OFFSET_DATA_0_7,X. Don't fix anything that's not broken ;)
2. Add some bankswitching

Is this the way to go? When I do bankswitching, I would want to go for the full 32K. What's the best way to do that?


Btw. I've downloaded a 6502 simulator to test small parts of code: http://home.pacbell....hal_k/6502.html You can exactly see what is going on. Really nice!

#44  

    Quadrunner

  • 5,831 posts
  • Joined: 24-November 04
  • Boom bam.
  • Location:Seattle, WA

Posted Fri Sep 12, 2008 9:21 AM

View Postroland p, on Fri Sep 12, 2008 1:19 AM, said:

1. Ditch the vector routine, nothing beats LDA OFFSET_DATA_0_7,X. Don't fix anything that's not broken ;)
2. Add some bankswitching

Is this the way to go? When I do bankswitching, I would want to go for the full 32K. What's the best way to do that?
Yes, add bankswitching. You'll never get a decent (or even playable :ponder:) Ballblazer clone in 4K.

Bankswitching is pretty easy, you just have to organize your code and data carefully. To set up your source code, just ORG each 4K block to wherever (make sure the 32K is consecutive) and RORG it to $Fxxx. You can search the forums for more information.

Or you can get crazy and use the wacky 32K bankswitching scheme I came up with. :ponder: No one else seems to think it's that cool, but I love it. :)

#45  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Wed Sep 17, 2008 7:23 AM

@vdub_bobby,
I get to the backswitching later. I have fixed the issue now by altering some 'org' declarations.

Due to extremely short spare time in the checkerboard edges, I've not enough time/memory to update all sprites every line. Therefore I thought of the following: update everyline one sprite, giving a vertical resolution of 4 pixels per sprite, and change the update pattern every frame to get a interlaced like effect.
Unfortunatly, it does not work.

Can anyone tell me why the following code does not work?
	LDA GRP1
	STA SPRITE_POINTERA
	
	LDX #0
	LDA #%10101010
	STA (SPRITE_POINTERA,X)
And why the following code DOES work?
	LDA GRP0
	STA SPRITE_POINTERA
	
	LDX #0
	LDA #%10101010
	STA (SPRITE_POINTERA,X)

Maybe I'm doing something very stupid and it is not possible at all...

#46  

    Quadrunner

  • 8,107 posts
  • Joined: 14-May 01
  • This is Sparta!
  • Location:Bavaria

Posted Wed Sep 17, 2008 7:29 AM

They actually both shouldn't work reliably without a # before the GRPs.

The code looks pretty weird anyway, what are you trying to do there? I have yet to see some useful code using ($$,X) indexing ;)

#47  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Wed Sep 17, 2008 7:34 AM

View PostCybergoth, on Wed Sep 17, 2008 3:29 PM, said:

They actually both shouldn't work without a # before the GRP.

Crap! That solved the problem! Thanks!
Funny that 'GRP0' does work. Probably the value $1B is stored at that adres? :D

#48  

    Stargunner

  • 1,274 posts
  • Joined: 22-June 01
  • Location:Tasmania

Posted Wed Sep 17, 2008 7:38 AM

View Postroland p, on Wed Sep 17, 2008 11:23 PM, said:

@vdub_bobby,
I get to the backswitching later. I have fixed the issue now by altering some 'org' declarations.

Due to extremely short spare time in the checkerboard edges, I've not enough time/memory to update all sprites every line. Therefore I thought of the following: update everyline one sprite, giving a vertical resolution of 4 pixels per sprite, and change the update pattern every frame to get a interlaced like effect.
Unfortunatly, it does not work.

Can anyone tell me why the following code does not work?
	LDA GRP1
	STA SPRITE_POINTERA
	
	LDX #0
	LDA #%10101010
	STA (SPRITE_POINTERA,X)
And why the following code DOES work?
	LDA GRP0
	STA SPRITE_POINTERA
	
	LDX #0
	LDA #%10101010
	STA (SPRITE_POINTERA,X)

Maybe I'm doing something very stupid and it is not possible at all...

I never once found the need to use indexed indirect (addr,x) addressing. Not once!
Why can't this code be written...

	ldx #0
	lda #%10101010
	sta GRP0,x

Or even just drop the indexing and use absolute writes. It's quicker!

Anyway, to answer your question... read this...

Indexed Indirect Addressing
---------------------------

Find the 16-bit address starting at the given location plus the
current X register. The value is the contents of that address. For
example,

LDA ($B4,X) where X contains 6

gives an address of $B4 + 6 = $BA. If $BA and $BB contain $12 and
$EE respectively, then the final address is $EE12. The value at
location $EE12 is put in the accumulator.




So, looks like you're retrieving a 16 bit address from the location SPRITE_POINTERA, SPRITE_POINTERA+1 (which is uninitialised) and then you're adding the X register to that, and writing to that resulting address. Could be anything. Pure chance either of your examples works at all, I'd say. Um, well actually since we have mirrored memory, in theory you are still writing to zero page. This code will work OK with the # as Manuel said, but it will fail on some bankswitching schemes when you switch later. It's broken, so fix it :)

Cheers
A

#49  

    Quadrunner

  • 8,107 posts
  • Joined: 14-May 01
  • This is Sparta!
  • Location:Bavaria

Posted Wed Sep 17, 2008 7:39 AM

View Postroland p, on Wed Sep 17, 2008 2:34 PM, said:

Funny that 'GRP0' does work. Probably the value $1B is stored at that adres? :D

Chances are usually good that the you get the last value returned from the bus, which indeed was GRP0. The exact behaviour may depend on the machine model and certain race conditions though I think. I'm sure somewhere on this board you'll find an essay from supercat detailling what exactly happens ;)

#50  

    Stargunner

  • 1,361 posts
  • Joined: 14-September 07
  • RLA
  • Location:The Netherlands

Posted Wed Sep 17, 2008 7:53 AM

View PostCybergoth, on Wed Sep 17, 2008 3:29 PM, said:

The code looks pretty weird anyway, what are you trying to do there? I have yet to see some useful code using ($$,X) indexing ;)

I've (hope) just enough time to update 1 sprite/line. And I have 4 sprites to draw. so the kernel could look like this:

at line 1 update sprite 1 with data1
at line 2 update sprite 2 with data2
at line 3 update missle with data3
at line 4 update ball with data4
...
...
at line 37 update sprite 1 with data37
at line 38 update sprite 2 with data38
at line 39 update missle with data39
at line 40 update ball with data40

etc. (data1..40 is memory)

That could work, but will look funny. because every sprite is drawn on another line.
By using pointers, I could change on wich line wich sprite is updated, that would look like this:

at line 1 update @pointerA with data1
at line 2 update @pointerB with data2
at line 3 update @pointerC with data3
at line 4 update @pointerD with data4

PointerA would point to sprite 1 at frame 1, and to sprite 2 at frame 2 etc.

I hope I'm clear.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users