Fire effect
Moderator: Moderators
Fire effect
After two months of "serious" programming for the FE3 RAM Disk, I needed a break and had a go at implementing the fire effect from C-64 version on the VIC-20.
It uses custom characters to display dithered colours, so it was not too difficult to adopt it for the VIC-20. And it runs on the unexpanded Vic.
Then I put some bloat in by adding a (slow) scroller and playback of a digitized sound sample. (needs 24K RAM)
Have fun with my first "intro"!
Source code
It uses custom characters to display dithered colours, so it was not too difficult to adopt it for the VIC-20. And it runs on the unexpanded Vic.
Then I put some bloat in by adding a (slow) scroller and playback of a digitized sound sample. (needs 24K RAM)
Have fun with my first "intro"!
Source code
Buy the new Bug-Wizard, the first 100 bugs are free!
Hmmm.... Where is the .prg?
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Cool
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
- joshuadenmark
- Big Mover
- Posts: 1218
- Joined: Sat Oct 23, 2010 11:32 am
- Location: Fr-Havn, Denmark
- Occupation: Service engineer
Thank you all, but I did not do much.
Just took this fire demo for C-64, Jeff's font and put it together.
BTW, if anybody got an idea how to make computing the fire faster, I'd really appreciate to read it
It takes way more time than a screen refresh and therefore I did not bother to sync it with vertical retrace in the unexpanded version. The principle is quite easy:
seed the bottom line with new (pseudo-random) characters
for each screen position do (starting from top)
add the character value and the three characters below it
subtract 3 and divide by 4
write the value to the current position
custom characters are filled with patterns for increasing heat,
i.e. 0 is black/empty, 1 has a few red dots, ... more yellow added ... up to character 63 (so the sum of 4 characters is less than 256)
Simple but nice to watch.
Just took this fire demo for C-64, Jeff's font and put it together.
BTW, if anybody got an idea how to make computing the fire faster, I'd really appreciate to read it
It takes way more time than a screen refresh and therefore I did not bother to sync it with vertical retrace in the unexpanded version. The principle is quite easy:
seed the bottom line with new (pseudo-random) characters
for each screen position do (starting from top)
add the character value and the three characters below it
subtract 3 and divide by 4
write the value to the current position
custom characters are filled with patterns for increasing heat,
i.e. 0 is black/empty, 1 has a few red dots, ... more yellow added ... up to character 63 (so the sum of 4 characters is less than 256)
Simple but nice to watch.
Buy the new Bug-Wizard, the first 100 bugs are free!
- Mike
- Herr VC
- Posts: 4841
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
This table based routine takes 34 cycles (+ some extra ones, when a page is crossed) for each character:Kananga wrote:BTW, if anybody got an idea how to make computing the fire faster, I'd really appreciate to read it
Code: Select all
.loop
CLC ; 2
LDA base,Y ; 4
ADC base+offset-1,Y ; 4
ADC base+offset ,Y ; 4
ADC base+offset+1,Y ; 4
TAX ; 2
LDA table,X ; 4
STA base,Y ; 5
INY ; 2
BNE loop ; 3
-----------------------------------
34 cycles
Michael
Thanks!Mike wrote: This table based routine takes 34 cycles (+ some extra ones, when a page is crossed) for each character:Code: Select all
.loop CLC ; 2 LDA base,Y ; 4 ADC base+offset-1,Y ; 4 ADC base+offset ,Y ; 4 ADC base+offset+1,Y ; 4 TAX ; 2 LDA table,X ; 4 STA base,Y ; 5 INY ; 2 BNE loop ; 3 ----------------------------------- 34 cycles
In order to get rid of the cycles for indirect ZP-based addressing, you need this routine four times (Screen memory spreads over 4 pages), giving ~34000 cycles. Screen refresh happens approx. every 22000 cycles (PAL). For the version with the scroll text, I have left out one page of video RAM, which still results in ~26000 cycles.
It is perhaps not doable in under 22K cycles without reducing the screen size.
Buy the new Bug-Wizard, the first 100 bugs are free!
- Kweepa
- Vic 20 Scientist
- Posts: 1315
- Joined: Fri Jan 04, 2008 5:11 pm
- Location: Austin, Texas
- Occupation: Game maker
You can move the CLC out of the loop since the ADCs are guaranteed not to overflow.
You can use LSR/LSR instead of TAX/LDA tab,X which is 2 cycles less, if you can put up with some noise (!) in the fire from not clearing the carry. Might actually be preferable.
You could also put all four updates inside the same loop with different base values, to save 15*256 cycles on loop checking. There might be an obvious artifact at each page boundary though, I'm not sure.
I make that 256*(3*25 + 30) = 26880 full screen.
Leaving out one page makes it 256*(2*25 + 30) = 20480.
[EDIT: ah, I misunderstood the algorithm. Still, some of these ideas are valid... just not the LSR/LSR...
256*(2*27 + 32) = 22016. So close! Unrolling again...
128*(5*27 + 32) = 21376. Phew! Unrolling again...
64*(11*27 + 32) = 21056.
A full unroll would be 20736, so this is a good balance.]
[EDIT 2: I tested this, and didn't see any obvious artifacts. Whee!]
You can use LSR/LSR instead of TAX/LDA tab,X which is 2 cycles less, if you can put up with some noise (!) in the fire from not clearing the carry. Might actually be preferable.
You could also put all four updates inside the same loop with different base values, to save 15*256 cycles on loop checking. There might be an obvious artifact at each page boundary though, I'm not sure.
I make that 256*(3*25 + 30) = 26880 full screen.
Leaving out one page makes it 256*(2*25 + 30) = 20480.
[EDIT: ah, I misunderstood the algorithm. Still, some of these ideas are valid... just not the LSR/LSR...
256*(2*27 + 32) = 22016. So close! Unrolling again...
128*(5*27 + 32) = 21376. Phew! Unrolling again...
64*(11*27 + 32) = 21056.
A full unroll would be 20736, so this is a good balance.]
[EDIT 2: I tested this, and didn't see any obvious artifacts. Whee!]
Great!Kweepa wrote: 256*(2*27 + 32) = 22016. So close! Unrolling again...
128*(5*27 + 32) = 21376. Phew! Unrolling again...
64*(11*27 + 32) = 21056.
A full unroll would be 20736, so this is a good balance.]
[EDIT 2: I tested this, and didn't see any obvious artifacts. Whee!]
Buy the new Bug-Wizard, the first 100 bugs are free!