| |
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.... |
| |
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. |
| |
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
:
|
| |
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. |
| |
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. |
| |
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. |
| |
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. |
| |
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. |
| |
Krill
Registered: Apr 2002 Posts: 3098 |
Quoting Pex Mahoney TufvessonI 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 JackAsserI'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. |
| |
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. |
| |
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 |