I have been working for the past 15 hrs trying to figure this out, but I can't! I have pasted the code below, please tell me where I am wrong,
I have made a sub-routine "poll" which stores a 1 in "whitevar' variable whenever a white color is detected. Then the subroutine "change_white" would make all the sprites black except 1 in one NMI, it then polls it in the same NMI trying to detect a white. Then in the next NMI a second object is turned white and rest all are made black, then poll is called to detect white and so on
The whole code is here:
http://www.sendspace.com/file/zqtlqa
/* here I keep sprite zero at bottom right of the screen so that the subroutine knows when to stop polling */
poll:
jsr update_sprites
poll1:
lda $4017
and #%00001000
beq white
lda $2002 ; detecting sprite 0
and #%01000000
bne nothing
JMP poll1
white:
lda #1
sta whitevar
rts
/*this is executed every NMI
in first NMI, the first object becomes white, then the second in second NMI and so on till 4 objects (and hence 4 NMI's)*/
change_white:
lda trig ; trig is set in the code which detects the pulling of trigger
cmp #17
bne sex
lda white_var
cmp #0
bne check1
lda #1
sta $512
sta $50e
sta $50a
lda #0
sta $506
inc white_var
jsr poll
lda whitevar
cmp #1
bne doo1
INC $507 ; simply just to see if it works
INC $507
INC $507
INC $507
INC $507
INC $507
INC $507
rts
check1:
cmp #1
bne check2
lda #1
sta $50e
sta $506
sta $512
lda #0
sta $50a
inc white_var
jsr poll
lda whitevar
cmp #1
bne doo1
INC $50b
INC $50b
INC $50b
INC $50b
INC $50b
rts
check2:
cmp #2
bne check3
lda #1
sta $512
sta $506
sta $50a
lda #0
sta $50e
inc white_var
jsr poll
lda whitevar
cmp #1
bne doo1
INC $50f
INC $50f
INC $50f
INC $50f
INC $50f
doo1:
rts
check3:
cmp #3
bne comp1
lda #1
sta $50e
sta $506
sta $50a
lda #0
sta $512
sta white_var
jsr poll
lda whitevar
cmp #1
bne comp11
INC $513
INC $513
INC $513
INC $513
INC $513
comp1:
rts
comp11:
lda #0
sta trig
jsr backs ; this subroutine bring backs the original screen
rts
Zapper Problem!!! Please help..
Moderator: Moderators
From what I can see so far, it looks like everything is happening in NMI (during vblank) and the main loop is an infinite JMP.
With the Zapper, a photo-diode is connected directly to the NES port (it's not buffered). I haven't tried to calculate the exact timing for how long it stays active. In practice, you have to use a timed polling loop (or a timer of some sort) so you know which vertical screen position the hit occurred on. Then you narrow down the horizontal position, by iterating through all the targets that are (still) in range on the next frame (by making the hitboxes white or not). The more targets, the longer it will take since you can only iterate once per frame.
You almost need a sprite-0 hit or something, so you can start the polling at a predetermined time. I guess your code does, but with it being called from the NMI at first glance it doesn't look like it's running during the appropriate screen-rendering time (let me know if I got it wrong).
With the Zapper, a photo-diode is connected directly to the NES port (it's not buffered). I haven't tried to calculate the exact timing for how long it stays active. In practice, you have to use a timed polling loop (or a timer of some sort) so you know which vertical screen position the hit occurred on. Then you narrow down the horizontal position, by iterating through all the targets that are (still) in range on the next frame (by making the hitboxes white or not). The more targets, the longer it will take since you can only iterate once per frame.
You almost need a sprite-0 hit or something, so you can start the polling at a predetermined time. I guess your code does, but with it being called from the NMI at first glance it doesn't look like it's running during the appropriate screen-rendering time (let me know if I got it wrong).
Isn't that too hardcore for a newbie though? I mean, an experienced coder might make use of timed code to find the target faster, but AFAIK you can just make each target white during the course of several frames until you find the one that was hit, which is the simplest way to do it. Of course is only good if you have few possible targets, like 6 or so.Memblers wrote:In practice, you have to use a timed polling loop (or a timer of some sort) so you know which vertical screen position the hit occurred on.
vishu_supreme, can you tell us what happens when you run your current code? Do the white hit boxes show up fine? You have to tell us what exactly is going wrong.
EDIT: Oh, I see you posted a copy of the whole program. I'll see if I can find what the problem is.
EDIT: Oh, I see you posted a copy of the whole program. I'll see if I can find what the problem is.
Last edited by tokumaru on Sun Sep 19, 2010 7:22 pm, edited 1 time in total.
Yeah, that works OK too, for less targets. But you still have to poll it the same way, during the frame rendering and during all the scanlines you want to check (it won't "remember" hitting it if you wait too long to read it). So there really is no way to avoid using some sort of timed code. From there it's pretty easy to increment a timer in that loop, and use it if it's useful (even if it's not exactly scanline-timed).
1- Why do you need timed code? Don't you just need a way to shutdown the main loop for one vrefresh while you spin on the output from the zapper?
2- Once you're timing the Y position, why not time the X position? I admit I'm only getting sextiles of the screen with my not particularly good loop (assuming that FCEU's zapper handling is correct)...
2- Once you're timing the Y position, why not time the X position? I admit I'm only getting sextiles of the screen with my not particularly good loop (assuming that FCEU's zapper handling is correct)...
1. Mostly because you typically wouldn't want to overflow the frame time - you're gonna have to know how long you'll be polling it for. So it doesn't have to be 100% exact, but you will want to know (at least roughly) how much CPU time, and how many scanlines, are being spent.
2. I wondered about that, I didn't try it though. But on the zapper test I did, it seemed like moving the gun horizontally was having no effect (but my code wasn't made to test H movement specifically). Not sure I trust the emulators on stuff like this (stuff that no game probably ever did).
2. I wondered about that, I didn't try it though. But on the zapper test I did, it seemed like moving the gun horizontally was having no effect (but my code wasn't made to test H movement specifically). Not sure I trust the emulators on stuff like this (stuff that no game probably ever did).
For #2.
I found that emulators do not seem to handle X location. ie: they set the diode at the same point of every scanline.
For my half completed lightgun game, I used multiple blank screens. Typically 3 or 4 in a row. That still works out to 4 out of 60 frames (1/15 of a second) which I personally didnt have a problem with.
The biggest killer for me was that not all emulators treat sprite DMA the same way. Nintendulator does it right. What worked for me in FCEUX would not work on real hardware or Nintendulator. Since reading the diode happens in screen draw, all my manipulation was being done in NMI. My sprite manipulation code took too long so I didnt have time in NMI to actually do the DMA.
Al
I found that emulators do not seem to handle X location. ie: they set the diode at the same point of every scanline.
For my half completed lightgun game, I used multiple blank screens. Typically 3 or 4 in a row. That still works out to 4 out of 60 frames (1/15 of a second) which I personally didnt have a problem with.
The biggest killer for me was that not all emulators treat sprite DMA the same way. Nintendulator does it right. What worked for me in FCEUX would not work on real hardware or Nintendulator. Since reading the diode happens in screen draw, all my manipulation was being done in NMI. My sprite manipulation code took too long so I didnt have time in NMI to actually do the DMA.
Al
Have you updated Nintendulator? It had bugs in the OAM DMA in some earlier versions. When I was doing Chu Chu Rocket and turning off the screen at the end, Nintendulator was corrupting the sprites, not matching any other emulator or hardware.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!