Jump to content



2

Lightgun homebrew


41 replies to this topic

Poll: Lightgun homebrew (26 member(s) have cast votes)

Would you like to see an xe lightgun homebrew made?

  1. Yes (22 votes [84.62%])

    Percentage of vote: 84.62%

  2. No (0 votes [0.00%])

    Percentage of vote: 0.00%

  3. Unsure (2 votes [7.69%])

    Percentage of vote: 7.69%

  4. Don't Care (2 votes [7.69%])

    Percentage of vote: 7.69%

Vote Guests cannot vote

#26 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Wed Dec 7, 2011 2:36 PM

So how would i implement Cathode Ray Timing in 6508 assembly language? A simple example should be enough to get started, but i'll let you know as soon as i add it to my game code.

Sincerely,

Primordial Ooze

#27 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 882 posts
  • Location:Germany

Posted Wed Dec 7, 2011 2:38 PM

View PostPrimordial Ooze, on Tue Dec 6, 2011 3:31 PM, said:

Say what????? So what i would need to do is create 2 variables. One would hold the x position of the electron beam. The other one would replace the y register for the y position of the electron beam. Is this correct or am i totally off? Also how many x and y positions are there in a CRT television screen?
The 2600 can display 160 pixels in about 200 scanlines, but unfortunately you can't poll the light sensor that often. Also the Atari lightgun isn't that acurate to begin with. So a lightgun resolution of 53 x 40 seems realistic.

A couple of years ago I took the lightgun routine from Sentinel, changed the values a bit to work better on my TV and made a lightgun test program out of it. It displays a grid with a resolution of 53 x 38 squares. If you pull the trigger of the lightgun in the left controller port, a hit marker should appear in one of the squares. I adjusted to position values so that, if you press the gun directly against the screen of your CRT and position it over one of the squares, the hit marker should appear in that square when you pull the trigger. It works fine on my multi-standard TV. If the marker is off on your TV, you need to adjust the position values accordingly.

Attached File  guntest.zip   3.58K   19 downloads

#28 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Wed Dec 7, 2011 3:07 PM

View PostEckhard Stolberg, on Wed Dec 7, 2011 2:38 PM, said:

View PostPrimordial Ooze, on Tue Dec 6, 2011 3:31 PM, said:

Say what????? So what i would need to do is create 2 variables. One would hold the x position of the electron beam. The other one would replace the y register for the y position of the electron beam. Is this correct or am i totally off? Also how many x and y positions are there in a CRT television screen?
The 2600 can display 160 pixels in about 200 scanlines, but unfortunately you can't poll the light sensor that often. Also the Atari lightgun isn't that acurate to begin with. So a lightgun resolution of 53 x 40 seems realistic.

A couple of years ago I took the lightgun routine from Sentinel, changed the values a bit to work better on my TV and made a lightgun test program out of it. It displays a grid with a resolution of 53 x 38 squares. If you pull the trigger of the lightgun in the left controller port, a hit marker should appear in one of the squares. I adjusted to position values so that, if you press the gun directly against the screen of your CRT and position it over one of the squares, the hit marker should appear in that square when you pull the trigger. It works fine on my multi-standard TV. If the marker is off on your TV, you need to adjust the position values accordingly.

Attached File  guntest.zip   3.58K   19 downloads
Thanks, i found this very useful. Question though, is this:
CoarseTest:	 dex
			    beq	 CEndRelay	   ; test is over with no hit detected
			    nop   
			    nop
			    nop
			    nop
			    nop
			    nop
			    nop
			    bit	 INPT4		   ; test lightgun sensor
			    bpl	 HitX01to03	  ; did we hit within the last 5 cycles
			    bit	 INPT4
			    bpl	 HitX04to08
			    bit	 INPT4
			    bpl	 HitX09to13
			    bit	 INPT4
			    bpl	 HitX14to18
			    bit	 INPT4
			    bpl	 HitX19to23
			    bit	 INPT4
			    bpl	 HitX24to28
			    bit	 INPT4
			    bpl	 HitX29to33
			    bit	 INPT4
			    bpl	 HitX34to38
			    bit	 INPT4
			    bpl	 HitX39to43
			    bit	 INPT4
			    bpl	 HitX44to48
			    bit	 INPT4
			    bpl	 HitX49to53
			    jmp	 CoarseTest
CEndRelay:	  jmp	 CEndFrame	   ; test is over with no hit detected

HitX49to53:	 lda	 #158		    ; hit was at pixel 158 or before
			    bne	 AdjustHpos
HitX44to48:	 lda	 #143
			    bne	 AdjustHpos
HitX39to43:	 lda	 #128
			    bne	 AdjustHpos
HitX34to38:	 lda	 #113
			    bne	 AdjustHpos
HitX29to33:	 lda	 #98
			    bne	 AdjustHpos
HitX24to28:	 lda	 #83
			    bne	 AdjustHpos
HitX19to23:	 lda	 #68
			    bne	 AdjustHpos
HitX14to18:	 lda	 #53
			    bne	 AdjustHpos
HitX09to13:	 lda	 #38
			    bne	 AdjustHpos
HitX04to08:	 lda	 #23
			    bne	 AdjustHpos
HitX01to03:	 lda	 #8
			    bit	 INPT4
The only way to do it cause it seems to be a very messy way of doing it. Sorry if i sound rude but, i just want to know before i end up adding code that i will need to refix latter.

Sincerely,

Primordial Ooze

#29 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 882 posts
  • Location:Germany

Posted Thu Dec 8, 2011 7:31 AM

View PostPrimordial Ooze, on Wed Dec 7, 2011 3:07 PM, said:

Thanks, i found this very useful. Question though, is this:
The only way to do it cause it seems to be a very messy way of doing it. Sorry if i sound rude but, i just want to know before i end up adding code that i will need to refix latter.
No need to apologize as this part of the code was borrowed from Sentinel. ;) Of course you could do it differently. But in oder to get a reasonably high horizontal resolution you need to be able to check the lightgun sensor as often as possible during a scanline. And if you try to avoid all unnecessary loops and checks to be able to fit in more reads of the lightsensor, the code can get a little messy.

Also you might have noticed that the AdjustHpos subroutine only is 75 cycles long. That way the reads in the scanlines following the first hit detection always happen one processor cycle before the check in the last scanline. Since the lightgun sensor would register a hit for several scanlines, you can increase the resolution of the check to single cycle precision, which is the best you can achieve on the VCS. And since you have to make sure that the reads of the lightgun sensor always happen after the same number of cycles after the last read no matter which of the branches was takes, the code gets a little more messy.

#30 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Thu Dec 8, 2011 2:43 PM

View PostEckhard Stolberg, on Thu Dec 8, 2011 7:31 AM, said:

View PostPrimordial Ooze, on Wed Dec 7, 2011 3:07 PM, said:

Thanks, i found this very useful. Question though, is this:
The only way to do it cause it seems to be a very messy way of doing it. Sorry if i sound rude but, i just want to know before i end up adding code that i will need to refix latter.
No need to apologize as this part of the code was borrowed from Sentinel. ;) Of course you could do it differently. But in oder to get a reasonably high horizontal resolution you need to be able to check the lightgun sensor as often as possible during a scanline. And if you try to avoid all unnecessary loops and checks to be able to fit in more reads of the lightsensor, the code can get a little messy.

Also you might have noticed that the AdjustHpos subroutine only is 75 cycles long. That way the reads in the scanlines following the first hit detection always happen one processor cycle before the check in the last scanline. Since the lightgun sensor would register a hit for several scanlines, you can increase the resolution of the check to single cycle precision, which is the best you can achieve on the VCS. And since you have to make sure that the reads of the lightgun sensor always happen after the same number of cycles after the last read no matter which of the branches was takes, the code gets a little more messy.
I just finished adding your light checking routine to my lightgun game and am having a bit of trouble. When the lightgun's trigger isn't pressed in the right port, the screen is displayed correctly. However when i press the trigger well......
ScreenFlash.jpg
As you can see something funky is going on. :grin: I have attached the latest version of my source code for your enjoyment. ;) Any assistance in this matter would be greatly appreciated.

Sincerely,

Primordial Ooze

Edited by Primordial Ooze, Mon Dec 12, 2011 1:03 PM.


#31 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 882 posts
  • Location:Germany

Posted Fri Dec 9, 2011 7:44 AM

View PostPrimordial Ooze, on Thu Dec 8, 2011 2:43 PM, said:

I just finished adding your light checking routine to my lightgun game and am having a bit of trouble. When the lightgun's trigger isn't pressed in the right port, the screen is displayed correctly. However when i press the trigger well......

As you can see something funky is going on. :grin: I have attached the latest version of my source code for your enjoyment. ;) Any assistance in this matter would be greatly appreciated.
The lightgun test routine exits once it has detected the lightgun position. If you are pointing the gun at the top of the screen, that might be after 50 scanlines or something. This is not enough for a full frame and therefore the screen starts to roll. To compensate for that my program sets a timer before executing the lightgun test routine and waits for that timer to expire afterwards. After having a quick look at your code, it seems that you moved the timer handling code and forgot to set the timer to a proper value before calling the lightgun test subroutine.

#32 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Fri Dec 9, 2011 3:24 PM

View PostEckhard Stolberg, on Fri Dec 9, 2011 7:44 AM, said:

View PostPrimordial Ooze, on Thu Dec 8, 2011 2:43 PM, said:

I just finished adding your light checking routine to my lightgun game and am having a bit of trouble. When the lightgun's trigger isn't pressed in the right port, the screen is displayed correctly. However when i press the trigger well......

As you can see something funky is going on. :grin: I have attached the latest version of my source code for your enjoyment. ;) Any assistance in this matter would be greatly appreciated.
The lightgun test routine exits once it has detected the lightgun position. If you are pointing the gun at the top of the screen, that might be after 50 scanlines or something. This is not enough for a full frame and therefore the screen starts to roll. To compensate for that my program sets a timer before executing the lightgun test routine and waits for that timer to expire afterwards. After having a quick look at your code, it seems that you moved the timer handling code and forgot to set the timer to a proper value before calling the lightgun test subroutine.
Are you talking about these lines:
			    lda	 INTIM		   ; wait for VBLANK period to end
			    bne	 Check
			    sta	 WSYNC

			    lda	 #236		    ; timer for 199 scanlines
			    sta	 TIM64T  
			    lda	 #$00    
			    sta	 WSYNC   
			    sta	 VBLANK
Cause that is the only thing that resembles a timer for me. Please let me know if this is the timer you are talking about.

Sincerely,

Primordial Ooze

#33 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 882 posts
  • Location:Germany

Posted Sat Dec 10, 2011 8:02 AM

View PostPrimordial Ooze, on Fri Dec 9, 2011 3:24 PM, said:

Are you talking about these lines:
				lda	 INTIM		   ; wait for VBLANK period to end
				bne	 Check
				sta	 WSYNC

				lda	 #236			; timer for 199 scanlines
				sta	 TIM64T  
				lda	 #$00	
				sta	 WSYNC  
				sta	 VBLANK
Cause that is the only thing that resembles a timer for me. Please let me know if this is the timer you are talking about.
Yes, that code waits for the timer that I set up for the VBLANK period to expire and then sets up a new timer for the 199 scanlines of the lightgun position check. You also need the code after the CEndFrame label, because it waits for this timer to expire and discharges the capacitors for the lightgun sensor, which is needed, so that you can do another test later.

#34 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Mon Dec 12, 2011 9:06 AM

Hi guys, I've managed to attached Eckhard Stolberg's and it seems to be working. The next step is going to be how should i detect collisions? There are 2 possibilities for this. One is using the bounding box method:
lda DuckX
cp BulletX ; if the duck's x position is greater then then bullet's x position
bcc SkipNoCollision
lda BulletX
cp DuckX ; if the bullet's x position is less then the duck's x position
bcs SkipNoCollision
lda DuckX
cp BulletX ; if the duck's y position is greater then then bullet's y position
bcc SkipNoCollision
lda BulletX
cp DuckX ;if the bullet's x position is less then the duck's x position
bcs SkipNoCollision
The other way is the "Atari 2600 way" which is done by making a crosshair sprite, setting it's position to where the gun was fired and test for a collision. My only problem with that is that it's not gonna be faithful to the original Qwak! and Duck Hunt games. Any input would be greatly appreciated.

Sincerely,

Primordial Ooze

#35 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • 5,990 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Dec 12, 2011 9:56 AM

Duck = Player 0

Crosshair = Player 1, color same as background

The crosshair wouldn't be visible unless you're using the playfield to draw clouds or something.

#36 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Mon Dec 12, 2011 11:40 AM

View PostSpiceWare, on Mon Dec 12, 2011 9:56 AM, said:

Duck = Player 0

Crosshair = Player 1, color same as background

The crosshair wouldn't be visible unless you're using the playfield to draw clouds or something.
This was my original idea, except then i can't use player 1 for the dog sprite :_(

Sincerely,

Quacker Blaster

#37 GroovyBee OFFLINE  

GroovyBee

    7800 Developer

  • 5,781 posts
  • Busy bee!
  • Location:North, England

Posted Mon Dec 12, 2011 12:01 PM

Just use the ball. It'll be the same colour as the playfield but your player sprite will be in front of it.

#38 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Mon Dec 12, 2011 12:46 PM

Does player1/ ball have to be drawn in order for collisions to register or can i just position the ball and check for a collision? The reason i ask is because i plan on extending the playfield so it uses multicolors, though it's just an idea at the moment. :)

Sincerely,

Primordial Ooze

#39 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • 5,990 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Dec 12, 2011 1:37 PM

View PostPrimordial Ooze, on Mon Dec 12, 2011 11:40 AM, said:

This was my original idea, except then i can't use player 1 for the dog sprite :_(
You only need to draw the cross hairs for 1 frame after the player pulls the trigger - so just for that single frame skip drawing the dog.

Or can you also shoot the dog? If so you could reuse Player 0 to draw the dog (assuming the duck is always in the air and the dog on the ground).

#40 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Mon Dec 12, 2011 1:46 PM

View PostSpiceWare, on Mon Dec 12, 2011 1:37 PM, said:

View PostPrimordial Ooze, on Mon Dec 12, 2011 11:40 AM, said:

This was my original idea, except then i can't use player 1 for the dog sprite :_(
You only need to draw the cross hairs for 1 frame after the player pulls the trigger - so just for that single frame skip drawing the dog.

Or can you also shoot the dog? If so you could reuse Player 0 to draw the dog (assuming the duck is always in the air and the dog on the ground).
The dog will most likely only appear after the duck is shot or gets away so most likely they will never appear at the same time. How to get the dog to show the duck being held in his hand after it drops is another question. Most kernals draw the sprites for a full frame, so how would i make it only draw for a single frame?

Sincerely,

Primordial Ooze

#41 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • 5,990 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Dec 12, 2011 1:58 PM

psuedo code
if trigger just pulled
  sprite1 = cross hairs
  X1 = lightgun X location
  Y1 = lightgun Y location
else if dog onscreen
  sprite1 = dog image
  X1 = dog X position
  Y1 = dog Y position
else
  Y1 = 230 (offscreen location)
endif


#42 Primordial Ooze OFFLINE  

Primordial Ooze

    Dragonstomper

  • 504 posts
  • Quacker Blaster Lead Programmer
  • Location:United States of America

Posted Mon Dec 12, 2011 3:42 PM

Update: Post has been moved to the 2600 programming section to keep the thread less cluttered and on topic.

Sincerely,

Primordial Ooze

Edited by Primordial Ooze, Tue Dec 13, 2011 1:39 PM.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users