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 > Freely moving sprites over a triggered VSP?
2025-02-16 22:59
JackAsser

Registered: Jun 2002
Posts: 2038
Freely moving sprites over a triggered VSP?

The clock slide itself is not a problem since it's outside the sprite DMA area anywas, but we need to kick it off at a well known cycle, regardless of sprite DMA. Is it even possible?

Currently I do a hack by detecting if sprite 0 interfere and adjust appropriately. Double timer won't cut it since the first timer will trigger in the middle of the sprite fetches.

Only idea I have so far is to stabalize before the sprite fetches and the via sprite y-positions perform a series of compares to get a delay value via some table. I did something similar in The Wild Bunch for the sprite multiplexer balls over 4x4-fli, but there I knew the sprites always came in pairs, so the combinations were only 16.
 
... 34 posts hidden. Click here to view all posts....
 
2025-02-17 08:49
Pex Mahoney Tufvesson

Registered: Sep 2003
Posts: 54
I would go for static sprite y-positions and static D015 at your counter-VSP-scroller rasterline, and manually copy sprite data into your sprites at the height you want. I'm not a fan of fiddling with timing-dependent VIC tricks, so I would simplify it this way.
2025-02-17 08:50
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: here is a way that seems to work for me:

* stabilize the raster so that you always end up at cycle 50 (i think - just before the sprites start to steal cycles anyway) of rasterline $2f. (for me, i use a cia timer for this, a 63 cycle countdown that i fire off at cycle 16 sometime during initialization, then do a lda #62 / sec / sbc $dd04 / (wait for 30 cycles max) thingy at the middle of line $2f, this gets me to cycle 50).
* use a variable timing mechanism of maximum 19 cycles (a traditional mechanism with a branch instruction that jumps into a series of 2-cycle instructions and a 3-cycle one at the end)
* compute the number of cycles that the sprites will steal (0-19) by computing the number of sprites that will be on line $30:

    lda #0
    sta spritescover
    /* Figure out how many sprites cover the rasterline $30 */
    .for (var i = 0; i < 8; i++) {
        lda $d001 + i * 2
        cmp #$30 - 21 * 2 // y expanded sprites
        bcc next
        cmp #$30
        bcs next
        lda spritescover
        ora #1 << i
        sta spritescover
    next:
    }


then use a table of cycle values that each sprite combination will steal and index into this table:

    ldx spritescover
    lda spritecyclestab,x
    sta bplcycles + 1


that table is generated like this:

spritecyclestab:
    .for (var i = 0; i < $100; i++) {
        .byte vic_sprcycles(i)
    }


where the magic is done by this function:

.function vic_sprcycles(d015value) {
    /*
        from https://bumbershootsoft.wordpress.com/2016/02/05/sprites-and-ra..

        def sprdelay(active):
            return sum(map(int, list((bin(active)[2:] + '00').replace('100', '5').replace('10', '4').replace('1','2'))))
    */

    .var d015 = toBinaryString(d015value) + "00"
    .eval d015 = str_replace(d015, "100", "5")
    .eval d015 = str_replace(d015, "10", "4")
    .eval d015 = str_replace(d015, "1", "2")
    .var cycles = 0
    .for (var i = 0; i < d015.size(); i++) {
        .eval cycles += (d015.charAt(i) - '0')
    }
    .return cycles
}


after this, the code is cycle stable and allows to write into $d011 at the start of the visible screen. (but have only tested this quickly, so i may have missed some quirk.)


Yep, this was my original idea. Thanks for testing it in practice. I'll test it. Currently the compensation is hard coded for sprite 0 only like:

		lda $d001
		cmp #$33+18*8-20+21
		.assert >* = >(:+), error, "Cycle penatly introduced 4"
		bcc :+
			nop
			nop
			nop
		:
		cmp #$33+18*8-20
		.assert >* = >(:+), error, "Cycle penatly introduced 5"
		bcs :+
			nop
			nop
			nop
		:
2025-02-17 08:51
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: I would go for static sprite y-positions and static D015 at your counter-VSP-scroller rasterline, and manually copy sprite data into your sprites at the height you want. I'm not a fan of fiddling with timing-dependent VIC tricks, so I would simplify it this way.

I've also considered that. It might be more elegant in the end anyway because the sprites are rendered and masked anyway. Render to a different y pos in a sprite should be no extra overhead.
2025-02-17 08:58
Oswald

Registered: Apr 2002
Posts: 5127
how about doing it like Maniac Mansion ? it treats the sprites as the atari 8 bit, where each sprite is a screen high column - like on amiga.

So if you multiplex from each sprite a full high column, then all timing will be static, the con is that to move objects in Y you have to copy them up and down in the sprite columns with the cpu. also animation is copy.

also ofcourse you can have only 8 objects max, but each at any height.


reading back Mahoney suggested this already I guess.
2025-02-17 09:00
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: how about doing it like Maniac Mansion ? it treats the sprites as the atari 8 bit, where each sprite is a screen high column - like on amiga.

So if you multiplex from each sprite a full high column, then all timing will be static, the con is that to move objects in Y you have to copy them up and down in the sprite columns with the cpu. also animation is copy.

also ofcourse you can have only 8 objects max, but each at any height.


reading back Mahoney suggested this already I guess.


That would limit the renderer way too much.
2025-02-17 09:02
oziphantom

Registered: Oct 2014
Posts: 502
if you disable sprites does any active one still DMA steal? Or do they stop dead? because if they stop dead just set d015 to 0 before the restore VSP and done.
2025-02-17 09:11
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: if you disable sprites does any active one still DMA steal? Or do they stop dead? because if they stop dead just set d015 to 0 before the restore VSP and done.

Sprite DMA continues until offset 62 has been fetched in a sprite, regardless of $d015-state.
2025-02-17 11:22
Krill

Registered: Apr 2002
Posts: 3098
Quoting Pex Mahoney Tufvesson
I would go for static sprite y-positions and static D015 at your counter-VSP-scroller rasterline, and manually copy sprite data into your sprites at the height you want. I'm not a fan of fiddling with timing-dependent VIC tricks, so I would simplify it this way.
Quoting JackAsser
I've also considered that. It might be more elegant in the end anyway because the sprites are rendered and masked anyway. Render to a different y pos in a sprite should be no extra overhead.
The Y-positions may still be dynamic there, no?
Just need to make sure that all sprites are enabled and active across the critical section.

In other words, may keep the Y positions of sprites that are enabled and active already, but Y-multiplex those that will be finished displaying within (or just before) the critical section.
2025-02-17 12:52
Oswald

Registered: Apr 2002
Posts: 5127
btw sprite DMA is only on the borders, whats stopping you from timer stabilizing on the screen in a non badline ? 40 cycles should be enough, then jump to a routine thats selected based on the nr of active sprites to pass the border cycles.
2025-02-17 12:57
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: btw sprite DMA is only on the borders, whats stopping you from timer stabilizing on the screen in a non badline ? 40 cycles should be enough, then jump to a routine thats selected based on the nr of active sprites to pass the border cycles.

Nothing. See OP. This was my initial idea and what Trident tested. Just wanted more input if there are ”smarter” ideas.
Previous - 1 | 2 | 3 | 4 | 5 - Next
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
Guests online: 265
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Codeboys & Endians  (9.7)
4 Mojo  (9.6)
5 Coma Light 13  (9.6)
6 Edge of Disgrace  (9.6)
7 Signal Carnival  (9.6)
8 Wonderland XIV  (9.5)
9 Uncensored  (9.5)
10 Comaland 100%  (9.5)
Top onefile Demos
1 Nine  (9.7)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.5)
6 Scan and Spin  (9.5)
7 Onscreen 5k  (9.5)
8 Grey  (9.5)
9 Dawnfall V1.1  (9.5)
10 Rainbow Connection  (9.5)
Top Groups
1 Artline Designs  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Performers  (9.3)
5 Censor Design  (9.3)
Top Webmasters
1 Slaygon  (9.7)
2 Perff  (9.6)
3 Sabbi  (9.5)
4 Morpheus  (9.4)
5 CreaMD  (9.1)

Home - Disclaimer
Copyright © No Name 2001-2025
Page generated in: 0.074 sec.