Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Sprite multiplexer question
2007-10-14 17:27
Barbarossa

Registered: May 2007
Posts: 31
Sprite multiplexer question

Hi guys,

I am making a simple spritemultiplexer. And I have some timing problems.

There are two x-adjacent physical sprites (sprite 2-3) which are also y-adjacent and repeated 2 times (for a total of 2 by 3 sprites). Sprites 0-1 are also active but can be anywhere on the screen (not being multiplexed but they steal cycles).

I set the new Y-coordinate 1 or 2 rasterlines before the new sprite should be displayed. This is not a problem. But I have a problem with the spritepointers. My reasoning is that I should change the two spritepointers on rasterline Y-1 and before cycle 57 (when the new spritepointers are fetched by VIC). When I do this the last line of the previous sprite displays the data of the next sprite (too early).
When I add a couple of NOPs and wait until line Y (after the spritepointers are fetched) it seems to work. I don't understand why, because I think I am too late with the change. Or I am missing something?

One other problem. The sprites should scroll with the background graphics. The screens are doublebuffered. When the multiplexer works and I start to scroll, the sprites start to flicker as if I am missing frames. I am talking about an x-scroll here (so the badlines remain where they are), so I don't see any difference for the multiplexer whether the screen is static or scrolling. I am updating spritepointers for both screens.

It seems to me that timing is very critical even for my rather simple multiplexer. But when I read some of the multiplexers on codebase64 I never see any discussion regaring timing (only sorting). Just as if it's not that important.

This is my first go with a multiplexer so maybe you guys can point me in the right direction.

Thanks.

John
2007-10-14 18:12
cadaver

Registered: Feb 2002
Posts: 1160
Those articles probably discuss a multiplexer which re-uses all physical sprites in "round-robin" fashion, and in those timing isn't an issue until all sprites are in constant use caused by tightly packed sprite groups.

Remember that you can write the new Y-coordinate much earlier, as soon as the "old" sprite has started displaying. Though judging from what you tell about flickering when scrolling, you may well have some weird bugs in your code :)
2007-10-14 18:16
ChristopherJam

Registered: Aug 2004
Posts: 1409
I tend to avoid needing such tight timing, either by staggering the sprite positions and using an extra sprite, eg:

0
01
01
21
20
20
10
12
12
_2

or by using slightly more definitions so I can duplicate the data from the last few pixel rows of each sprite in the last few pixel rows of the next sprite, then I can change sprite pointers every (eg) 19 lines instead of every 21, and it doesn't matter if I'm a little late switching. Note that the transition gets earlier in each row of sprites, so your sprite definitions will look a little shuffled with the muxer disabled.

Oh, and I agree with everything @cadaver wrote :)
2007-10-14 19:57
Oswald

Registered: Apr 2002
Posts: 5094
sprite data fetch is done across 2 rasterlines. the 'right' side of the 'previous' and 'left' side of 'the current'. so you're wrong with assuming that all sprite data has been fetched in y-1.

sprites 0,1 are fetched on the right side, sprite 2 is present on both, and sprites 3,4,5,6,7 are fetched on the left side of a rasterline.


see the timings here:

https://sh.scs-trc.net/vic/vic_article_3.6.htm#3.6.3.

edit: well I'm wrong with where the sprite fetches are done, but no diagram for all 8 sprites in there.

edit2: your sprite flicker may be that you miss to update the sprite pointers in _both_ of your screens.
2007-10-14 21:22
WVL

Registered: Mar 2002
Posts: 902
For adjacent sprites, i'd always use the half-sprite method.

So for every switch of sprite, you have an extra sprite. This gives you 10 rasters of max delay you can stand, very easy.

Your extra sprite, would have the bottom part of the topmost sprite, and the top-part of your lowest sprite.

So if sprite 0 looks like

A
B

And the next like

C
D

you have an inbetween spritedefinition that looks like

C
B

Disadvantage : 50 (2 sprites) up to 100% (unlimited sprites) waste of extra memory :(
2007-10-14 21:28
Oswald

Registered: Apr 2002
Posts: 5094
its funny how nobody notices, that the problem is not how to make the switch between the sprites bugfree ;)
2007-10-15 07:30
Barbarossa

Registered: May 2007
Posts: 31
Quote: Those articles probably discuss a multiplexer which re-uses all physical sprites in "round-robin" fashion, and in those timing isn't an issue until all sprites are in constant use caused by tightly packed sprite groups.

Remember that you can write the new Y-coordinate much earlier, as soon as the "old" sprite has started displaying. Though judging from what you tell about flickering when scrolling, you may well have some weird bugs in your code :)


Ok, so the physical sprites are always as far apart as possible. I understand now why timing is not an issue here.
2007-10-15 07:51
Barbarossa

Registered: May 2007
Posts: 31
Quote: sprite data fetch is done across 2 rasterlines. the 'right' side of the 'previous' and 'left' side of 'the current'. so you're wrong with assuming that all sprite data has been fetched in y-1.

sprites 0,1 are fetched on the right side, sprite 2 is present on both, and sprites 3,4,5,6,7 are fetched on the left side of a rasterline.


see the timings here:

https://sh.scs-trc.net/vic/vic_article_3.6.htm#3.6.3.

edit: well I'm wrong with where the sprite fetches are done, but no diagram for all 8 sprites in there.

edit2: your sprite flicker may be that you miss to update the sprite pointers in _both_ of your screens.


I understand how the sprite fetches work. And I am not assuming sprites fetches are done in Y-1. What I say is that I assume I have to FINISH updating the spritepointers BEFORE the VIC starts fetching them with starts in the right border on line Y-1 (with sprites 0-2).

+-----------------------------------+
| 1 2 6 |
|123456789012345678901..234567890123|Cycles
+---------[------(----..----)---]---+Borders
|3-4-5-6-7-rrrrrgggggg..gggg-N0s1s2s|Phi-1 VIC
|ss ssssss|Phi-2 VIC
|==xxxxxxxxxxxxxxxxxxx..xxxXXX======|Phi-2 CPU
+-----------------------------------+
// IRQevent - 7 cycles
// last instruction - 2-6 cycles
// sprite 3 - 2 cycles
// total - 10-15 cycles
multiplexer: sta STOREA // 13-18
stx STOREX // 16-21
sty STOREY // 19-24
preloadacc: lda #$00 // 21-26
sta $d005 // 25-30
sta $d007 // 29-34
ldy $01 // 32-37
ldx #$30 // 34-39
stx $01 // 37-42
(insert NOPs)
inc $07fa // 43-48
inc $07fb // 49-54
inc $dffa // 55-60
inc $dffb // 61-66 (next line)

The above version doesn't work. Even when not scrolling (only use one screen). Spritepointers Screen 1 ($0400) are updated in time. There are issues with screen 2 but I can always update the Y-coordinate one line earlier (which I already tried btw). But screen 1 should work and it doesn't. It does work when I insert enough NOPs so that the inc starts at the next line around cycle 4. This is the line the new sprite image starts.
I think this is strange because the VIC already read the spritepointers (and spritedata) at that point. This is what I don't understand.

edit: sorry about that mess. I did not realize that spaces were going to be trimmed.
2007-10-15 08:01
Barbarossa

Registered: May 2007
Posts: 31
Quote: For adjacent sprites, i'd always use the half-sprite method.

So for every switch of sprite, you have an extra sprite. This gives you 10 rasters of max delay you can stand, very easy.

Your extra sprite, would have the bottom part of the topmost sprite, and the top-part of your lowest sprite.

So if sprite 0 looks like

A
B

And the next like

C
D

you have an inbetween spritedefinition that looks like

C
B

Disadvantage : 50 (2 sprites) up to 100% (unlimited sprites) waste of extra memory :(


This really is a nice idea. But I am afraid I don't have enough memory for that. I think I need a total of 170 sprite images. And to double that.... ouch :-(

But I like the idea.
2007-10-15 08:11
Barbarossa

Registered: May 2007
Posts: 31
Quote: its funny how nobody notices, that the problem is not how to make the switch between the sprites bugfree ;)

Yes. The problem is how to understand why it is bugfree :-)

For my other problem. Scrolling of the background is done in the bottomborder, so there is no flicker and the scrolling goes at a constant speed of 1 pixel per frame.

The user can scroll the screen one charactier at a time. If the scrolling finishes after one character screen 2 is displayed. What happens is that when the screen is moved 7 pixels with $d016 everything is fine (sprites still on screen 1). Then the screen switches to screen 2 (in lower border). The sprites flicker but when the screen is static again the sprite images are ok. So updating the SP on screen 2 seems not to be a problem.

I am not ruling out any bugs at this point, but they seem rather unlikely so I was thinking maybe I am forgetting something obvious or doing something wrong. when I know that my thinking is ok I can hunt this baby to death for bugs. :-)
2007-10-15 09:02
WVL

Registered: Mar 2002
Posts: 902
Oh!

now I see :D

well, if you set your sprite pointers to Y, the sprites will be displayed at position Y+1!! And not at position Y!! So naturally, when you expect that you need to update the spritepointers at Y-1, actually you have top update at Y (Y+1-1)!
2007-10-15 10:54
Barbarossa

Registered: May 2007
Posts: 31
Quote: Oh!

now I see :D

well, if you set your sprite pointers to Y, the sprites will be displayed at position Y+1!! And not at position Y!! So naturally, when you expect that you need to update the spritepointers at Y-1, actually you have top update at Y (Y+1-1)!


I update the spritepointers on position Y and the updated sprite starts to draw at Y also (not at Y+1). That's what I find strange.
2007-10-15 16:32
Oswald

Registered: Apr 2002
Posts: 5094
your 'other' problem will be a badly synchronized doublebuffering of d018 writes & changing of spr ptr writes. your first problem may be an emulator bug, vic article bug, or you are not on the cycle you think you are :D btw if you will only scroll horizontally, you should use the HW horizontal scrolling trick, the only disadvantage of it is that you loose 1 screen line at the bottom (sprite pointers weill become visible).

search for vsp and horizontal scrolling / agsp:

http://codebase64.org/
2007-10-15 19:07
Barbarossa

Registered: May 2007
Posts: 31
Well I use a rasterinterrupt at the appropiate rasterline and I walked through the VIC x-positions step by step via the emulator so I think I know where I am.

As far as the synchronizing I will have to look into it some more. If the flicker is not something obvious I must be doing something wrong.

As for the scrolling, it is in all directions, not only horizontal. But after I added the sprites I was first trying to get it to work horizontally. Don't need any more timing problems due to unpredictable bad lines. :-)

Well thanks for all the input, although I am not much wiser. Back to the drawing board.
2007-10-16 07:00
Barbarossa

Registered: May 2007
Posts: 31
I figured it out by myself.

Problem one:
I thought the raster Y is always the same as the sprite Y. But in fact raster Y = sprite Y + 1. I think WVL was trying to tell me that. It didn't come across though. :-)

Problem two:
On closer examination I noticed that the flickering also happened when modifying $d016 (not only on screen swaps). Since the main loop is copying the screen at that point, the instructions are more cycle insentive than when the screen is static and the main program is in a polling loop waiting for user input. Conclusion my interrupt arrives late and I miss a frame. I probably will need a stable raster for that to work.

After that I probably will need to find a solution how to change the spritepointers on a badline with all the sprites active :-(
2007-10-16 07:16
WVL

Registered: Mar 2002
Posts: 902
Yes, that was what I was trying to say ;)
2007-10-16 07:17
ChristopherJam

Registered: Aug 2004
Posts: 1409
You could always use a variant of WVL's half sprite technique that just uses 1-2 pixel rows of overlap in definitions instead of 10. Then your overhead would only be 5-10% instead of 50%.

I tried to explain that above but may have failed.
2007-10-16 07:36
WVL

Registered: Mar 2002
Posts: 902
Quote: You could always use a variant of WVL's half sprite technique that just uses 1-2 pixel rows of overlap in definitions instead of 10. Then your overhead would only be 5-10% instead of 50%.

I tried to explain that above but may have failed.


AH! now i understand your point :)

Ofcourse you only save sprite defs if you need >2 sprites vertically.. nice :)
2007-10-16 09:02
Barbarossa

Registered: May 2007
Posts: 31
Quote: AH! now i understand your point :)

Ofcourse you only save sprite defs if you need >2 sprites vertically.. nice :)


Chris,

I did read your post. It is something that would work very nicely. I will keep it in mind when I run in more problems (eg bad lines). The only problem I see with it is that I need more sprite images which consume more memory. And I predict that I need around 170 images in total

But I can see now that in the end I probably have no other choice. :-)
2007-10-16 09:21
doynax
Account closed

Registered: Oct 2004
Posts: 212
Quote: Chris,

I did read your post. It is something that would work very nicely. I will keep it in mind when I run in more problems (eg bad lines). The only problem I see with it is that I need more sprite images which consume more memory. And I predict that I need around 170 images in total

But I can see now that in the end I probably have no other choice. :-)


Well.. You could "cheat" by simply not allowing sprites to be placed on badlines (or, say, odd line to even things out). It depends on your game whether this is acceptable of course but I managed to multiplex all four sprites (with underlays) on the same line this way. I had to generate the interrupt code dynamically to manage it though.
Or I suppose you could swap all eight sprites simultaneously, even on a badline, by swapping between a pair of video matrices. Scrolling would be a mess though..
2007-10-16 14:06
ChristopherJam

Registered: Aug 2004
Posts: 1409
Shorter overlaps also require nastier shuffling, and for maximal space use they also need the sprites to be triggered at different y positions depending on which frame is being displayed, and brought onscreen by changing their x-position or changing from a blank definition at the top and bottom of the area to be shown.

All quite unpleasant really, so not necessarily any less work than getting your interrupts stable. It's only a definite win if you have some memory up your sleeve.

Christopher.
2007-10-16 17:05
TNT
Account closed

Registered: Oct 2004
Posts: 189
If you have more cycles than memory, you can cheat by copying first two or three rows from lower sprite to the one above it when you update the y coordinate. That way the sprite repeats with the new y position and new graphics, and you have couple of lines to change the sprite pointer before display reaches non-copied gfx rows. You need to restore those lines later, of course.
2007-10-16 21:55
Barbarossa

Registered: May 2007
Posts: 31
I finally got it to work. :-)

It was a bug after all (isn't it always). My color memory in the bufferscreen is located at $dc00 under the i/o. Normally i/o is up and roms are down. When my mainloop was copying the colorram it took the i/o down of course. My multiplexer then wrote Y-coordinates to ram therefore missing a frame.

And as a bonus the vertical scroll also works perfectly despite of the repositioning of the bad lines.

Thanks for all your help.

John
2007-10-17 13:28
Oswald

Registered: Apr 2002
Posts: 5094
"And as a bonus the vertical scroll also works perfectly despite of the repositioning of the bad lines."

huh? :)
2007-10-17 16:56
Barbarossa

Registered: May 2007
Posts: 31
Well I think I can explain that. The sprites also move together with the background. So the position of the bad lines in relation to the sprite positions never change.

I was just anticipating some problems with that, but hey sometimes things aren't as bad as they seem to be :-)
2007-10-17 17:02
Oswald

Registered: Apr 2002
Posts: 5094
ok, now I get it :)
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
apprentix
Sychamis
iceout/Avatar/HF
Guests online: 93
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 X-Mas Demo 2024  (9.5)
7 Dawnfall V1.1  (9.5)
8 Rainbow Connection  (9.5)
9 Onscreen 5k  (9.5)
10 Morph  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top Swappers
1 Derbyshire Ram  (10)
2 Jerry  (9.8)
3 Violator  (9.7)
4 Acidchild  (9.7)
5 Cash  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.062 sec.