Jump to content
Sign in to follow this  
jum

Clearing collision buffer

Recommended Posts

Quick question for advanced Lynx programmers - is it possible to clear the collision buffer AND write non-zero collision numbers to it using just one "background" sprite?

 

At the moment I am drawing a 1-pixel background sprite with collision number 0, stretched to fill the screen. This clears the screen buffer AND the collision buffer.

Then I am drawing my "playfield" sprite, which has collision number 1.

 

Is there some trick where I can just draw my playfield sprite, and the transparent pixels write collision number 0, while the opaque pixels write collision number 1?

 

Or am I dreaming?

Share this post


Link to post
Share on other sites

I believe that you could set the collision buffer to your write page buffer and draw it in one go by setting it as a background sprite so that all pixels are drawn.

Share this post


Link to post
Share on other sites

Thats maybe not the way the collision buffer should be used. But yes you can initialize with other numbers. but why would you want to?

Any sprite will fill the collition buffer with its "collision number", if the sprite has correct type and collision is on.

Transparent pixel <!=> uncollidable pixel -> read the docs.

Share this post


Link to post
Share on other sites

Thanks Karri and Sage.

 

Karri - drawing sprite to the collision buffer directly is an interesting idea. Problem is that it does not save me any sprite draws, I still need to draw to the display buffer too. (Edit: actually I might try this, as it should be faster than a sprite writing to display buffer and collision buffer). Is there any source code out there that does this?

 

Sage - true, however what I want is to write 0 to collision buffer for transparent pixels, and 1 to the collision buffer for opaque pixels. (ie: "clear" the collision buffer where no playfield is, and write 1 to collision buffer where there is playfield)

 

My current collision code is correct and work properly, I was just wondering if there was a faster way to do it.

Edited by jum

Share this post


Link to post
Share on other sites

You could create a small asm file for drawing the sprite to the collision buffer. Just replace DRAWPAGE with the address of the collision buffer.

draw_collision_sprite:                    ; Draw it in collision buffer
        sta     SCBNEXTL
        stx     SCBNEXTH
        lda     DRAWPAGEL
        ldx     DRAWPAGEH
        sta     VIDBASL
        stx     VIDBASH
        lda     #1
        sta     SPRGO
        stz     SDONEACK
@L0:    stz     CPUSLEEP
        lda     SPRSYS
        lsr
        bcs     @L0
        stz     SDONEACK
        lda     #TGI_ERR_OK
        sta     ERROR
        rts
  • Like 1

Share this post


Link to post
Share on other sites

No, I dont thing this is possible in one step.

 

True. Drawing to collision buffer won't display anything on the screen. So you have to do this in two operations.

  • Like 1

Share this post


Link to post
Share on other sites

So a quick test:

 

1. Draw "clear" sprite to clear draw buffer and collision buffer, followed by a "playfield" sprite with collision enabled (1 call to Suzy) :

snap_clearSCB.bmp

 

2. Draw playfield sprite directly to collision buffer, then draw it to the draw buffer (2 calls to Suzy):

snap_directCollClear.bmp

 

The green area shows how many hcounts it took to draw. If you can believe Handy, then method 2 is way faster.

 

(If you don't want to download/look at the images, then method 1 takes almost a whole frame, and method 2 takes about 60% of a frame = 60 hcounts).

 

Results can be predicted from:

Method 1:

- Draw clear sprite = 75% of "normal" sprite draw time (NSDT), as it does not have to read pixels (write only)

- Draw playfield sprite = 100% of NSDT

- Total = 175% of NDST

 

Method 2:

- Draw background non-collideable sprite to collision buffer = 66% of NDST

- Draw background non-collideable sprite to draw buffer = 66% of NDST

- Total = 134% of NDST

 

So you would expect method 2 to be about 30% faster, even before implementing it.

 

(Also, why does it take almost a whole frame just to clear the draw buffer and collision buffer?)

Edited by jum

Share this post


Link to post
Share on other sites

While I was writing "Always winter, never Christmas" I found out that at least Mednafen is so much faster than a real Lynx. So I would prefer to get these test results from a real Lynx if possible.

 

The result sounds reasonable. The collision buffer is probably a great idea when dealing with random areas. But when you have a large, full-screen rectangle then drawing the whole area twice is faster than trying to draw into two buffers at once.

Share this post


Link to post
Share on other sites

While I was writing "Always winter, never Christmas" I found out that at least Mednafen is so much faster than a real Lynx. So I would prefer to get these test results from a real Lynx if possible.

 

The result sounds reasonable. The collision buffer is probably a great idea when dealing with random areas. But when you have a large, full-screen rectangle then drawing the whole area twice is faster than trying to draw into two buffers at once.

 

I will test on real Lynx (using SD card adapter) and get some screenshots.

Share this post


Link to post
Share on other sites

 

 

While I was writing "Always winter, never Christmas" I found out that at least Mednafen is so much faster than a real Lynx.

 

Well that's probably not true with Handy ;)

But I agree, testing on real hardware makes sense when you're benching/profiling stuff.

Share this post


Link to post
Share on other sites

Comparison of the 2 screen clear methods, using Handy and using a real Lynx (note: real Lynx seems to be faster than Handy).

 

Lynx clear screen method comparison

Note: I think the frame rate is set to 75fps. If so I will do another comparision with 60 fps version.
Edit: No difference when frame rate is changed to 60 using tgi_setframerate(60). Possibly tgi_setframerate() is broken?
Edited by jum

Share this post


Link to post
Share on other sites

Thank you! There is a small difference. But even a small difference can be a game changer in fast games. You may be able to get one frame time less for every draw cycle.

 

With Reiko's Robot Run the speed difference is the opposite. Emulation is faster. The same is true for sending sound samples directly to the speakers.

Edited by karri
  • Like 1

Share this post


Link to post
Share on other sites

 

Comparison of the 2 screen clear methods, using Handy and using a real Lynx (note: real Lynx seems to be faster than Handy).

 

Note: I think the frame rate is set to 75fps. If so I will do another comparision with 60 fps version.
Edit: No difference when frame rate is changed to 60 using tgi_setframerate(60). Possibly tgi_setframerate() is broken?

 

 

Strange. I have to check the framerate stuff. It is also used for the clock() function. And abcmusic.

FD93 = PBKUP. Magic 'P' count, (W)
reset = x,x,x,x,x,x,x,x
INT((((line time - .5us) / 15) * 4) -1)
At 60 Hz, 'PBKUP' = 41. (0x29)

HTIMBKUP    = $FD00             ; horizontal line timer (timer 0)
rate50: lda     #$bd        ; 50 Hz
        ldx     #$31
        bra     setRate
rate60: lda     #$9e        ; 60 Hz
        ldx     #$29
        bra     setRate
rate75: lda     #$7e        ; 75 Hz
        ldx     #$20
setRate:
        sta     HTIMBKUP
        stx     PBKUP

Share this post


Link to post
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.

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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...