Jump to content
IGNORED

My 1st Homebrew - Mr. Yo-Yo, WIP


DaveM

Recommended Posts

On 12/21/2020 at 8:19 PM, DEBRO said:

Attached is a new mockup showing two missiles launching. This is a rough sketch but shows how it can be done. There should also be enough time in the kernel to read and store hardware collision registers. Hopefully this will get you moving.

Thanks!  I'll work with this over the next few days or so and try to implement it into the game.  I'll let you know if I have any questions.

Link to comment
Share on other sites

I got a bit sidetracked by work and the holidays, but still working on this.  Here's the first pass.  Some progress.  It's buggy, but I haven't yet gone back through to see what I screwed up.  If anyone wants to have a look and fix some bugs, you're more than welcome to it.  

 

Looks like there are 2 missiles drawn on the screen, so that's not a problem.  The rest of it though, a little buggy.  I've got an extra scanline popping in and out of there, the fine horizontal motion on the top enemy isn't working, the missiles move vertically with the player, and the horizontal positioning of the missiles is erratic.  

 

I think there were more changes to the VBLANK area of the the code than I thought at first glance.  I kinda just rushed through that part, trying to keep as much of the previous code as I could, assuming the setup would be quite similar.  I think I was wrong in that assessment, and I think that's what's causing the issues.

 

So I'll get back to this later in the week, and hope to make more progress.

 

I hope everyone is having a wonderful holiday season, and have a Happy New Year!

Mr_Yo-Yo_B20201230.a Mr_Yo-Yo_B20201230.bin

  • Like 1
Link to comment
Share on other sites

Hi David,

On 12/30/2020 at 6:02 PM, DaveM said:

I've got an extra scanline popping in and out of there, the fine horizontal motion on the top enemy isn't working...

The horizontal positioning routine in the kernel crosses a page boundary which adds an extra cycle for the branching. This is causing the extra scan line and affecting the horizontal positioning of the objects in the kernel. You might consider moving the display kernel to start at the page beginning or the beginning of your ROM bank to help with this in the future.

 

I didn't add it in my mockup but Thomas has a CHECKPAGE macro you could insert in the kernel as well. It would help find these branches and stop the assembly when they are found.

 

On 12/30/2020 at 6:02 PM, DaveM said:

the missiles move vertically with the player, and the horizontal positioning of the missiles is erratic.

The reason the missiles move vertically with the player is because you are not setting the tmpMissile1VertPos and tmpMissile2VertPos correctly. These variables now represent the missile offset for the kernel. I'll try to explain what I'm doing.

 

To draw Mr. Yo-Yo I'm using tmpYoYoGraphicIdx. This gets decremented and compared to the height of Mr. Yo-Yo to know if it time to draw him. This value is calculated outside the kernel in relation to Mr. Yo-Yo's vertical position. This same positioning is used to determine when to draw the missiles. So the missile kernel scan line position must be in relation to Mr. Yo-Yo's vertical position. I do this outside the kernel in the mockup like...

   sec
   lda yoyoVertPos                  ; get Mr. Yo-Yo vertical position
   sbc missile1VertPos              ; subtract missile vertical position
   sta tmpMissile1VertPos           ; set missile vertical position for kernel
   sec
   lda yoyoVertPos                  ; get Mr. Yo-Yo vertical position
   sbc missile2VertPos              ; subtract missile vertical position
   sta tmpMissile2VertPos           ; set missile vertical position for kernel

I hope that makes sense.

  • Thanks 1
Link to comment
Share on other sites

12 hours ago, DEBRO said:

The horizontal positioning routine in the kernel crosses a page boundary which adds an extra cycle for the branching. This is causing the extra scan line and affecting the horizontal positioning of the objects in the kernel. You might consider moving the display kernel to start at the page beginning or the beginning of your ROM bank to help with this in the future.

 

I didn't add it in my mockup but Thomas has a CHECKPAGE macro you could insert in the kernel as well. It would help find these branches and stop the assembly when they are found.

Thanks!  That's very good to know.  I knew about not wanting to cross page boundaries when reading data from an array, but I didn't know that could affect other parts of the code as well.  I'm going to try to take care of the other issues first, then I'll leave this one until last.  

12 hours ago, DEBRO said:

The reason the missiles move vertically with the player is because you are not setting the tmpMissile1VertPos and tmpMissile2VertPos correctly. These variables now represent the missile offset for the kernel. I'll try to explain what I'm doing.

Got it.  

 

Over the past few days, I've been slowly going through the kernel mock-up line by line and making corrections in my code.  So I've been able to resolve a number of issues.

 

I think I only have two left - one is the extra scanline, which I've yet to tackle, but will get to; and the other is the missiles are now firing from above the yo-yo instead of in the middle of it.  But... I haven't gone through everything yet, so I'm hoping that will take care of itself as I continue along.

 

I'm also pretty sure I now have extra useless code sitting above the kernel - old code that the new kernel code makes obsolete.  So once I get the other stuff working, I'll go back through and see what's no longer needed up there and get rid of it.  

 

So I think I'm making a lot of good progress, and I'm hoping to find enough time this week so that I can complete the kernel integration by the end of the weekend.  It's really just a matter of finding the time to take care of things at this point.  

 

Updates attached for those that are interested.

Mr_Yo-Yo_B20210105.a Mr_Yo-Yo_B20210105.bin

Link to comment
Share on other sites

So freakin' close.  Need a bit of help on a couple issues.

 

First is that scanline problem.  I'm at 262, occasionally jumps to 263.  As Dennis mentioned above, this is due to crossing a page boundary...

On 1/5/2021 at 6:54 AM, DEBRO said:

The horizontal positioning routine in the kernel crosses a page boundary which adds an extra cycle for the branching. This is causing the extra scan line and affecting the horizontal positioning of the objects in the kernel. You might consider moving the display kernel to start at the page beginning or the beginning of your ROM bank to help with this in the future.

...but I can't figure out how to fix that.  I tried using the align command to align the kernel to the start of the page, but that causes all sorts of problems.  So, I'm not sure what to do to fix this issue.

 

The second problem has to do with some missile "dead zones".  The enemies travel in one of four horizontal lanes.  In between those lanes are some scanlines where the kernel is setting up the calcs for the enemy in the next zone, so the missiles cannot appear in those scanlines.  Only the yo-yo and string can appear there, all other time is taken up setting up the next enemy lane.  So if the player fires a missile while passing through those zones, the missile needs to be relocated either to the enemy lane directly above or below the dead zone.  Instead, what's happening is that no missile appears.

 

The scanlines where no missile can appear are lines 54-56, 83-85, and 112-114.  If you look at the LoadMissile subroutine, you'll see this code:

Quote

 

LoadMissile subroutine
; Starts reload counter and returns missle vertical position in Y
    ldy #ReloadTime
        sty MReload        ; Set reload counter
        sec
        lda PVrtPos        ; Mr. Yo-Yo Vertical Position
        sbc #(H_YO_YO / 2)    ; subtract to get vertical center

;    sbc #H_CAVE_TOP + (H_YO_YO / 2) + 4
;        lda #139
        
        tay            ; A -> Y 

 

If you uncomment the highlighted line, and change the value to the scanline you want to test, you can see how no missile will show up in the lines I mentioned above.

 

So the question is this...  What's the most efficient way of testing for those values and relocating the missile 1-2 scanlines up or down?  I could easily do a series of compares, but it seems like it would take a lot of processing time to go through 9 compares each time a missile is fired.  Is there a better way to do this?

 

Thanks!
 

Mr_Yo-Yo_B20210109.bin Mr_Yo-Yo_B20210109.a

  • Like 1
Link to comment
Share on other sites

On 1/9/2021 at 2:14 PM, DaveM said:

First is that scanline problem.  I'm at 262, occasionally jumps to 263.  As Dennis mentioned above, this is due to crossing a page boundary...

On 1/5/2021 at 6:54 AM, DEBRO said:

The horizontal positioning routine in the kernel crosses a page boundary which adds an extra cycle for the branching. This is causing the extra scan line and affecting the horizontal positioning of the objects in the kernel. You might consider moving the display kernel to start at the page beginning or the beginning of your ROM bank to help with this in the future.

...but I can't figure out how to fix that.  I tried using the align command to align the kernel to the start of the page, but that causes all sorts of problems.  So, I'm not sure what to do to fix this issue.

Still stuck on this one.  I've tried using align before the kernel, before the vblank code, at various points during the vblank code, and none of that worked.  I tried moving parts of the vblank code off into a subroutine so that the display kernel could then move up in the code and line up with the start of a page, but that didn't work either.  Everything I've tried either fails to compile, or creates bigger scanline count problems.  So I'm at a complete loss with what to do next.

Link to comment
Share on other sites

I had to go hunting for xmacro.h and tia_contraints.h, so you might want to include those with your source when you are sharing it.

 

It doesn't look to me that it's a page-crossing issue, since it only happens when you press fire. At some point, you may be going over cycles when processing the fire button. I'll take a closer look tomorrow and see if I can figure anything out myself.

  • Thanks 1
Link to comment
Share on other sites

Well, I made a couple of small improvements, at least. You were waiting on the timer before the visible screen twice - once via the TIMER_WAIT macro, and the other manually right after by checking INTIM manually. I eliminated the latter, and added a WSYNC after for timing consistency.

 

On the second wave, the coins that go left don't wrap vanish soon enough, so they end up wrapping, and the scanlines jump when that happens. Fixing that will get rid of some of the other scanline jumps.

 

There are still cases where the scalines jump up that I wasn't able to figure out easily. I'm attaching the source with the dependency files zipped up with it in case anyone else wants to look at this and take a crack at it, too.

 

Mr_Yo-Yo_B20210113.zip

  • Thanks 1
Link to comment
Share on other sites

Hi there,

 

On 1/12/2021 at 11:38 PM, Karl G said:

It doesn't look to me that it's a page-crossing issue, since it only happens when you press fire.

You are correct Karl. It is not a page boundary issue. I'm sorry about that. The issue is my kernel time counts. I missed removing the HMCLR around line 1285. This is adding an extra 3 precious cycles and causing the extra line when the kernel draws Mr. Yo-Yo on the upper cave line.

 

David, you can remove that HMCLR because its now done outside the kernel.

  • Thanks 1
Link to comment
Share on other sites

Thanks guys!  It looks like a solid 262 lines now!

 

On 1/12/2021 at 9:38 PM, Karl G said:

I had to go hunting for xmacro.h and tia_contraints.h, so you might want to include those with your source when you are sharing it.

Will do.  The editor I'm using includes the xmacro by default, so I keep forgetting to attach those.  I'll just upload a zip with everything from now on.

6 hours ago, DEBRO said:

David, you can remove that HMCLR because its now done outside the kernel.

Done.  As best I can tell, it's a stable 262 now.

 

Next up is the dead zone missile issue.  We had that fixed under the "one missile" kernel you did, but it looks like that logic gets overwritten in the new kernel.  I went back to the most-recent mock up, and this logic is in there...

Quote

DetermineToActivateMissile
   lda yoyoVertPos                  ; get Yo-Yo vertical position
   sbc #H_CAVE_TOP + (H_YO_YO / 2) + 4
   bcc MoveActiveMissiles           ; branch if in top section...no missile
   ldx #NUM_KERNEL_SECTIONS - 1
.determineLane
   dex
   sbc #H_INNER_CAVE + 4            ; subtract height of cave zones
   bcs .determineLane
   adc #H_INNER_CAVE + 5            ; increment to get offset
   cmp #H_INNER_CAVE + 1            ; compare with cave zone height
   bcc .determineToMoveMissile      ; branch if within zone
   sbc #H_INNER_CAVE                ; Mr. Yo-Yo center in another zone
   dex
.determineToMoveMissile

 

That sets X to the zone the missile is in, and A to the missile position within the zone, and takes care of the whole "firing the missile when you're in between zones" thing.  But then a little further down in the code, the missile position gets set again...

Quote

.spawnNewMissile
   tax                              ; move new spawned index to x register
   ora missileAttributes            ; combine with missile attribute
   sta missileAttributes
   sec
   lda yoyoVertPos                  ; get Yo-Yo vertical position
   sbc #(H_YO_YO / 2)               ; subtract to get vertical center
   bit joystickDebounceValues       ; check joystick values
   bvs .launchMissileLeft           ; branch if joystick MOVE_LEFT
   bpl MoveActiveMissiles           ; branch if joytick not MOVE_RIGHT
.launchMissileRight
   sta missileVertPos - 1,x         ; set missile vertical position

And that overrides the earlier logic.  I figured out that the earlier logic isn't used, and left it out of the game code, but didn't realize at the time that it takes care of the dead zone missile issue as well.

 

So now I just have to figure out a new piece of logic that will work with the new missile positioning to take care of the issue.  I've got the new logic all worked out in Excel, now I just have to translate it to assembly. ??

Mr_Yo-Yo_B20210114.zip

Link to comment
Share on other sites

The dead zone missile issue has been resolved!

 

To quickly sum up, if a missile was fired in scanlines 54-56, 83-85, or 112-114, the missile wouldn't be drawn, as the kernel uses those scanlines to calculate stuff and position the next enemy, so there's no time to draw the missile.

 

I came up with the following code to fix that issue.  Now, if a missile is fired in one of these dead zones, it will be positioned to the lowest line in the section above the dead zone.  In other words, a missile fired in lines 54-56 will be moved to line 53.  Missiles in the other two dead zones will go to lines 82 and 111, respectively.

 

So here's the logic I came up with.  I tried to be as efficient as I could, but it still seems just a bit convoluted. Please take a look, and if you see where I could be more efficient or just plain write better code to accomplish the same thing, please let me know.  This appears in the LoadMissile subroutine, down on line 2950.  The #mRelocTop constant is equal to 86, which is the highest line available for missiles in the next-to-last horizontal zone.  The A register holds the missile's vertical position at the start of the code, and the result is transferred over to Y at the end of the code.

Quote

 

; This next bit of logic relocates the missile if
; it's fired while Yo-Yo is in a "dead zone"

        ldx #mRelocTop + 26    ; Set X = top of the next-to-bottom section + 26
        stx LaneNum        ; Store to this temp variable.
.mRelocLoop        
        cmp LaneNum        ; Compare missile position (A) to LaneNum
        bpl .RelocMissile    ; If result is +, branch
                  
        sta tmpMissile1VertPos     ; Move A to a temp variable
        txa            ; x -> A
        sec
        sbc #29            ; Subtract 29
        sta LaneNum        ; Set variable
        bpl .SetUpNextLoop    ; Is result positive?  If yes, branch

 

                                             ; Result is negative.
        lda tmpMissile1VertPos    ; Restore value from temp variable       
        jmp .SetMissileLoc     ; Exit loop, value is OK.        

.SetUpNextLoop        
        tax            ; A -> X
        lda tmpMissile1VertPos    ; Restore value from temp variable
        jmp .mRelocLoop           ; Back to top of loop
        
.RelocMissile        
        REPEAT 3
        inc LaneNum
        REPEND            ; Add 3 to LaneNum
        
    cmp LaneNum        ; Compare missile position (A) to LaneNum
        bpl .SetMissileLoc    ; If result is +, branch, position OK.
        txa            ; X -> A
        sec
        sbc #2            ; subtract 2 to set new position
                
.SetMissileLoc        
        tay            ; A -> Y. Sets final missile position in Y.

 

So it looks like all outstanding issues involving the new kernel have been resolved.  I've got (as far as I can tell) a stable 262 scanlines, and two missiles that can fire anywhere while Mr. Yo-Yo is passing through the cave.  Next up is adding collision detection back in, followed by restructuring the intermission to fit the new kernel, then a few gameplay tweaks, then I'll be ready to add the menu and various game options, and that should be it!

Mr_Yo-Yo_B20210115.zip

Link to comment
Share on other sites

Hi David,

8 hours ago, DaveM said:

The dead zone missile issue has been resolved!

Woohoo! So glad to see you making progress.

8 hours ago, DaveM said:

Next up is adding collision detection back in

I intentionally left the collision detection out of the kernel. I left it out as a potential exercise. There should be enough time in the drawing of the zones to check collisions and time outside to reset the register. You can ask for assistance if you find yourself stuck. I'll eventually get you an answer ;) And between me not logging in and answering another skilled developer may chime in as well.

8 hours ago, DaveM said:

followed by restructuring the intermission to fit the new kernel, then a few gameplay tweaks, then I'll be ready to add the menu and various game options, and that should be it!

Yes, the remaining 90% of tweaks and hopefully optimizations. You should feel proud.

 

While you work on the tweaks, I'd like to suggest considering PAL50 and fractional positioning. Your players will thank you...I know I would. I am indebted to @Andrew Davie for opening my eyes to fractional positioning. This will give you more control over your objects. Considering PAL50 could give you more vertical resolution for your player area and zones too. Since PAL50 allows 312 scan lines you could increase the size of the zones for PAL50 or maybe allow more zones if there is enough RAM to spare. An added benefit for your PAL players.

 

Also, I was thinking about the current implementation of the missiles. Currently, one will have to be the color of an obstacle. This is fine but there may be a better way. I may be adding more work for myself for this but had to get it out :)

 

Instead of using the BALL to draw the string we could use GRP1 for both the string and Mr. Yo-Yo. This could be done by setting the color and graphic of the string before launching the kernel then when time to draw Mr. Yo-Yo change the color and graphics. Then you could use the BALL and M1 for the missiles. In this configuration the worse case scenario (one missile is above Mr. Yo-Yo) would have one missile the color of the string and the other the color of Mr. Yo-Yo. The best case scenario (both missiles below Mr. Yo-Yo) would have both missiles the color of Mr. Yo-Yo. The collision routine would of course need work too since the string and Mr. Yo-Yo would share the same object. When a player collision occurred you would need to know the zone to know if the collision was with the string or Mr. Yo-Yo.

 

This is all theoretical at this point. I haven't done anything to prove or disprove it could work. What do you think?

 

  • Thanks 1
Link to comment
Share on other sites

16 hours ago, DEBRO said:

I intentionally left the collision detection out of the kernel. I left it out as a potential exercise. There should be enough time in the drawing of the zones to check collisions and time outside to reset the register. You can ask for assistance if you find yourself stuck. I'll eventually get you an answer ;) And between me not logging in and answering another skilled developer may chime in as well.

Thanks!  I'll have to re-learn how to use the collision detection registers.  I played around with them early in the game's development and felt comfortable using them, so I don't anticipate too many problems.  But if there's one thing this whole process has taught me is that just when you think you understand how this stuff works, some bizarre unforeseen problem is sure to come up.

16 hours ago, DEBRO said:

While you work on the tweaks, I'd like to suggest considering PAL50 and fractional positioning.

I'll have to go back and re-read the stuff on fractional positioning you directed me to a while back.  I'm not crazy about the idea of re-writing another major portion of the game though.  This project has taken much, much longer than I had planned, and I'm far behind on almost all of my non-Atari projects around the house, so I kinda got to finish off this game and get to some other stuff.  But I'll at least have a look at the fractional positioning before I finish it up, and I know I had planned on using that in my games going forward.

16 hours ago, DEBRO said:

Considering PAL50 could give you more vertical resolution for your player area and zones too. Since PAL50 allows 312 scan lines you could increase the size of the zones for PAL50 or maybe allow more zones if there is enough RAM to spare. An added benefit for your PAL players.

I haven't looked into anything PAL-related so far, so PAL50 works for me.  I don't want to create a completely different game for PAL though.  I think the PAL and NTSC versions should be as close to each other as possible.  If I've got extra scanlines to play with, I'll figure out something to do with them, maybe a little more room at the top, maybe some sort of logo at the bottom like Activision games have, but I'd like to keep the game pretty much the same.

16 hours ago, DEBRO said:

Also, I was thinking about the current implementation of the missiles. Currently, one will have to be the color of an obstacle. This is fine but there may be a better way. I may be adding more work for myself for this but had to get it out :)

 

Instead of using the BALL to draw the string we could use GRP1 for both the string and Mr. Yo-Yo....

 

...This is all theoretical at this point. I haven't done anything to prove or disprove it could work. What do you think?

Well, like I said, I'd really like to finish this off rather than re-write it again.  But if you want to have a crack at it, and it involves just a few minor changes to the current code, then go for it.  Like you said, we'd have to have an extra check with the P0-P1 collision detection to see if the obstacle collided with the string or yo-yo portion of P1.  Basically, if the obstacle's bottom scanline is at or below the yo-yo's top scanline, then it's a collision with the yo-yo, otherwise, it's a collision with the string.  Sounds simple enough, which probably means it's quite complicated. :)

 

I can't thank you enough for your help on this!  Without it, I probably would've settled for a game with lots of flicker.  I've learned a lot through this whole process, and I'm sure I'll use a lot of what I've learned going forward in future games.  

Link to comment
Share on other sites

On 1/16/2021 at 8:16 AM, DEBRO said:

I intentionally left the collision detection out of the kernel. I left it out as a potential exercise. There should be enough time in the drawing of the zones to check collisions and time outside to reset the register. You can ask for assistance if you find yourself stuck. I'll eventually get you an answer ;)

Well, so much for thinking I understood collisions.  Actually, it's not so much how to use the CX registers, it's a matter of where to place them in the kernel so as to not cause timing issues.  As best I can tell, there's only one place in the kernel where I can check collisions, and it's here:

Quote

 

;--------------------------------------   third line after cave
JmpIntoKernelLoop
    lda #0                     ; 2         assume we are not drawing Yo-Yo
    bcs .drawThirdCaveLineYoYo ; 2³        branch if not time to draw Yo-Yo
    sta ENABL                  ; 3 = @07   disable BALL (i.e. a = 0)
    lda (yoyoGraphicPtr),y     ; 5         get Mr. Yo-Yo graphic data
.drawThirdCaveLineYoYo
    sta GRP1                   ; 3 = @15
    lda HorizontalMoveTable - 241,x;4
    sta HMP0                   ; 3 = @22   set obstacle fine motion value
    dey                        ; 2         decrement Yo-Yo graphic index
    lda #0               ; 2           assume we are not drawing Yo-Yo
    cpy #H_YO_YO           ; 2
        bcs .drawYoYoForFourthCaveLine ;2³     branch of not time to draw Yo-Yo
        sta ENABL           ; 3 = @33   disable BALL (i.e. a = 0)
        lda (yoyoGraphicPtr),y       ; 5           get Mr. Yo-Yo graphic data
.drawYoYoForFourthCaveLine
    dey               ; 2
        sty tmpYoYoGraphicIdx       ; 3   
        ldx #<ENAM1           ; 2
        txs               ; 2
        cpy tmpMissile2VertPos     ; 3
;
; At most cycle time ends at cycle 50. 23 more cycle available without focusing
; on constant cycle time.
;

 

; **** CHECK COLLISIONS HERE ****

 

    sta WSYNC

 

Right before the last sta WSYNC.  

 

I'm running into two issues.  First, as soon as I add ANY instruction there, I get a series of yellow lines on the right side of the screen.

 

Second, I just don't see how I can check what I need to with the remaining cycles.  Even when I ignore the yellow lines (and ignore the other graphics glitches that show up as I continue to add code), I run out of cycles very quickly.

 

So here's what I need to do:  I need to check 4 registers, CXM0P, CXM1P, CXP0FB, and CXPPMM.  For each, I also need to know which of the horizontal zones the collision occurred.  So I'm assuming I need to check each register on each pass through the kernel loop, if a collision occurred, record the type of collision and which zone (tmpKernelSection) it occurred in (my plan is to use some equates to represent the collision type, and store those in the high 4 bits of a variable, and use the low 3 bits of the same variable to store the zone number), and then do a sta CXCLR before it loops through the next zone.  I figure this method would only record one collision per frame (as a collision higher up the screen would be overwritten by one lower on the screen), but that should be good enough.

 

There are other areas of the kernel where there's time to check collisions, but none of those seem to be part of the main loop through the four horizontal zones that make up the area where the collisions would occur.  So I'm assuming checking for a collision in one of the areas after the four zones have been drawn wouldn't do me any good.  I would then need logic in the overscan to figure out where a collision occurred, so I'd end up checking collisions manually anyway.

 

Any suggestions?

 

See the zip file a few posts up for the latest code.

Link to comment
Share on other sites

Hi David,

On 1/20/2021 at 3:57 PM, DaveM said:

Any suggestions?

You could check for collisions in the kernel and that is probably where I'd place them. The way your game is setup you should be able to determine the collisions outside the kernel.

 

On any given frame an obstacle could collide with Mr. Yo-Yo. Checking the CXPPMM register would give you this condition. Now that you know this collision occurred; you can determine the zone for Mr. Yo-Yo to know the type of obstacle that triggered the collision.

 

You can use a similar routine with the missiles and string (i.e. BALL). Once knowing a collision occurred, you can now determine the zone for the corresponding missile to know which obstacle triggered the collision. For the string, again you would look for the obstacle within the horizontal position of the string that triggered the collision.

 

If you didn't want to use the time to determine the obstacle that hit the string then you could use an array to hold these collisions to make it easier to find outside the kernel.

 

Link to comment
Share on other sites

On 1/22/2021 at 10:59 AM, DEBRO said:

You could check for collisions in the kernel and that is probably where I'd place them.

That's the plan.

 

On 1/22/2021 at 10:59 AM, DEBRO said:

On any given frame an obstacle could collide with Mr. Yo-Yo. Checking the CXPPMM register would give you this condition.

Yes, I'm ok as far as coding how to check the CX registers.  But here's the problem I'm running into.  And I apologize, as I should've included this example with my previous post.

 

Starting on line 1459 of the attached, I've added code to check for P0-P1 collisions.  It looks like that part of the kernel is the only part where I'd have time to check.  These lines bring me up to 61 cycles, as best I can tell.  I've highlighted the lines I've added:

Quote

 

        cpy tmpMissile2VertPos     ; 3
;
; At most cycle time ends at cycle 50. 23 more cycle available without focusing
; on constant cycle time.
;
    bit CXPPMM            ; 3    Player collision?
        bpl .NoPlayerCollision        ; 2    If not, branch
        ldx tmpKernelSection        ; 3    Load Zone #
        stx cxType            ; 3    Store in variable

.NoPlayerCollision
    sta WSYNC

 

Now when you run the binary, you'll see the issue.  As soon as I add that bit instruction, a bunch of yellow lines appear on the right side of the screen, and when I fire missiles, four missiles appear - one in each horizontal zone.  So why is that happening?  I'm not modifying the missile position as far as I can tell.

 

In addition, when any other line is added (for example, a sta CXCLR, just above the WSYNC), then it starts generating an extra scanline, even though I should be at 64 cycles, max.

 

I see that immediately above the lines I've added, there's a cpy instruction.  So that's telling me that maybe I'm adding these lines in the wrong spot.  Where in this kernel are the best spots to check for the collisions?  I'd really like the CXPPMM check to occur inside the kernel, and hopefully the CXP0FB check as well.  If I can fit those two in, then I'm relatively ok with checking the missile collisions outside the register, and running some code to determine the zone for each missile, although, ideally, I'd like all four checks to occur inside the kernel.

Mr_Yo-Yo_B20210123.zip

Link to comment
Share on other sites

28 minutes ago, DaveM said:

Now when you run the binary, you'll see the issue.  As soon as I add that bit instruction, a bunch of yellow lines appear on the right side of the screen, and when I fire missiles, four missiles appear - one in each horizontal zone.  So why is that happening?  I'm not modifying the missile position as far as I can tell.

Solved this problem.  I thought I tried this before and it didn't work, but it worked now.  So I moved those lines a little further up:

Quote

        bcs .drawYoYoForFourthCaveLine ;2³     branch of not time to draw Yo-Yo
        sta ENABL           ; 3 = @33   disable BALL (i.e. a = 0)
        lda (yoyoGraphicPtr),y       ; 5           get Mr. Yo-Yo graphic data
.drawYoYoForFourthCaveLine
        bit CXPPMM            ; 3    Player collision?
        bpl .NoPlayerCollision        ; 2    If not, branch
        ldx tmpKernelSection        ; 3    Load Zone #
        stx cxType            ; 3    Store in variable
    
.NoPlayerCollision
    dey               ; 2
        sty tmpYoYoGraphicIdx       ; 3   
        ldx #<ENAM1           ; 2
        txs               ; 2
        cpy tmpMissile2VertPos     ; 3
;
; At most cycle time ends at cycle 50. 23 more cycle available without focusing
; on constant cycle time.
;
    sta WSYNC

But I still can't find a place to add a sta CXCLR anywhere.  No matter where I add it, even if it appears that I have plenty of free cycles, it starts jumping to 263 scanlines.

 

So I'm still stuck as to where to add the CXCLR, and where I would have space within the kernel to check the other CX registers.

Mr_Yo-Yo_B20210123b.zip

Link to comment
Share on other sites

So it turns out that this isn't the place to check collisions after all.  Looks like I'm checking for a collision before the enemy is drawn, and as a result, the collisions aren't registering properly.  I just can't find anyplace in the kernel to put the collision detection.  So I think I'll have to check the registers after the kernel, then go through the manual check anyway of finding out what collided.  

 

Does anyone see any other way of doing this?

Link to comment
Share on other sites

Hi David,

18 hours ago, DaveM said:

Looks like I'm checking for a collision before the enemy is drawn, and as a result, the collisions aren't registering properly.

You can check the registers in the kernel. Checking in that spot would register the collision for the previous zone.

 

I've attached two mock ups for collisions. One checking collisions in the kernel...storing the BALL collisions in an array and 1 byte each for the player and missile collisions. The other checking all collisions after the kernel is done drawing. The code isn't pretty but should give an idea. Hopefully I have my cycle counts correct with these.

 

 

mr_yo_yo_kernel_mockup_INSIDE_KERNEL_COLLISION.asm mr_yo_yo_kernel_mockup_OUTSIDE_KERNEL_COLLISION.asm

Link to comment
Share on other sites

3 hours ago, DEBRO said:

You can check the registers in the kernel. Checking in that spot would register the collision for the previous zone.

Yes, that's exactly the problem I had.  Then I think I messed up the code to figure out the zone later on, and that got me frustrated.

3 hours ago, DEBRO said:

I've attached two mock ups for collisions.

Thanks!  I'll have a look at them over the weekend.

 

I actually had success earlier today with the missile collision detection outside the kernel.  This wiped out an enormous amount of lines of code I had in there from my earlier manual method of collision checking. Got rid of an entire subroutine.  So I'm pretty happy with how it turned out.  

 

Anyway, I'll check out your code over the weekend and see if I can't finish off the collisions.

Mr_Yo-Yo_B20210127.a Mr_Yo-Yo_B20210127.bin

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...