TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Massively Interleaved Sprite Crunch – C64 Demo Effect (2016)

152 点作者 sleazy_b大约 8 年前

9 条评论

dzdt大约 8 年前
This reminds me of a quote by a master magician, which I unfortunately can&#x27;t locate right now. The gist was that one way that magic tricks work is that the audience would never believe the sheer amount of work that goes into developing the skill to pull of the trick.<p>The C64 demoscene is at this point a pure case of magicians developing tricks for other magicians. Compare to 20 years ago, when the tricks were made to wow users familiar with the platform and its limitations.<p>Now someone without intimate knowledge of the C64 would not understand what is the hard part of this demo part. Letters scroll up and sometimes expand or shrink a bit. We&#x27;ve seen lots of different scroll text parts. Is this hard?<p>Consider the brute force approach. The text scroll area is 192 pixels by 200 pixels. If this was just a bitmap, that is 4800 bytes to update. Pure unrolled code to move bytes would do<p><pre><code> LDA src,x STA dest,x </code></pre> for a minimum of 8 cycles per byte (extra if 256-byte page boundaries are crossed, and to update the x index, and do the logic to pick out which letter to draw) or 38,400 cycles to update that bitmap. But there are just 19,656 cycles free per frame! The best a brute force approach would get then is one update per 3 frames, or 17fps.<p>So all the cleverness is getting the machine to do something at 50fps that naively it could do at best at 17fps. This is by racing the display raster and playing tricks with the hardware bugs in the cpu&#x2F;video chip interface.
评论 #13862546 未加载
camtarn大约 8 年前
Totally worth watching the entire video of the demo, too - with headphones on, as the music is great :)<p><a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=XcAUlEkU05A" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=XcAUlEkU05A</a>
评论 #13860080 未加载
Pxtl大约 8 年前
Having watched the video of what he accomplished on the C64 I am now retroactively furious at every drop of framerate I have experienced on every platform ever.
评论 #13861860 未加载
评论 #13860246 未加载
评论 #13860460 未加载
jepler大约 8 年前
I particularly like Linus A&#x27;s contributions to the C64 demoscene, because more than likely he&#x27;ll do an excellent writeup like this about a newly discovered or perfected technique that was central to it.
评论 #13860270 未加载
mvindahl大约 8 年前
I used to program demos for the C64 back in my teens. A lot of the learning was simply reverse engineering the code from other demos, sometimes verbatim copying snippets, always trying to understand. At age 16 I was pretty confident that I had achieved the skille level of a wizard but in reality my understanding was pretty sketchy.<p>An example: Rendering graphics (i.e. sprites) at the far horizontal edges of the screen would require the CPU to perform some shenanigans to trick the video circuits; this would need to be done on every scanline and required the timing of the CPU to be in close sync with the video hardware. I understood that. I had also experienced how sprites and every eight scanline (aka &quot;badline&quot;) would mess up the carefully planned timings. Eventually, I kinda understood that concept. I had also seen, from code that I copied, how triggering a badline could be used to force the CPU in sync with the raster beam but it was akin to black magic for me. Wasn&#x27;t until years later, programming on the Amiga, that the penny dropped for me.<p>And of course, grasping the concept and implications of DMA was pretty basic stuff compared to what&#x27;s going on in this article. I don&#x27;t think that I&#x27;ll ever devote the time to understand it in detail but I find it fascinating how people keep discovering new unintended features in the old C64 architecture.
Zitrax大约 8 年前
The Lunatico demo got 2nd place at X&#x27;2016. Here you can find videos of the winner and the rest: <a href="http:&#x2F;&#x2F;www.indieretronews.com&#x2F;2016&#x2F;11&#x2F;x2016-c64-had-one-hell-of-demoparty.html" rel="nofollow">http:&#x2F;&#x2F;www.indieretronews.com&#x2F;2016&#x2F;11&#x2F;x2016-c64-had-one-hell...</a>
the_cat_kittles大约 8 年前
linus if you are reading, i just discovered your website via this post, and have really enjoyed checking out all the stuff on it. lots of great fun on there, and also lots of very thought provoking ideas about music and the compositional process. thank you!
sehugg大约 8 年前
This looks like a pretty nutty technique, essentially exploiting an undocumented state (or bug?) in the VIC chip.<p>The Atari 2600&#x27;s TIA had lots of sharp corners caused by the reliance on polynomial counters, which saved silicon but made for lots of seemingly-random edge cases (after all, polynomial counters are also used to generate pseudo-random noise!)
评论 #13860223 未加载
EdSharkey大约 8 年前
So, let me see if I can sum this wild gem up.<p>1. On each raster scan line, at precisely cycle 15, you need to clear the Y-expand register (vertical pixel size doubler thingy that sprites can do). This throws the hardware into confusion, the internal registers keeping track of where in memory a sprite is being drawn from is scrambulated and you wind up with the interesting graph presented on the right as to how the indexes progress from scanline to scanline. Y-expand is a single byte register where each bit belongs to one of the eight sprites. Simply clearing a sprite&#x27;s Y-expand bit on clock 15 every scan line is sufficient to introducing glitch pandemonium.<p>2. On some rows you want your sprite&#x27;s Y-expand to be cleared to trigger the glitch and sometimes not to have the next row be read in sequence, so before the scanline ends, we need to toggle Y-expand for a sprite to 1 on a per-sprite basis. How did the author do this efficiently? ...<p>3. ... by using sprite-to-playfield character collision detection! He put the sprites in the background, behind the character graphics and placed a single pixel vertical bar using redefined characters or bitmap graphics to cover the right-most pixel of the sprite. In the sprite definition&#x27;s right-most pixel for the current row, he would encode either a 0 or 1 to decide if the next row&#x27;s Y-expand should be 0 or 1. The natural collision detection of the sprite hardware would transcribe a 0 or 1 into the sprite-to-playfield collision register for all 8 sprites when both the sprite and the playfield had a filled bit. You&#x27;d wind up with a byte that is ready-made for the Y-expand setting for the NEXT scanline for all 8 sprites. (I assume before the end of the scanline, the idea is to read the collision register and write its value to Y-expand.) What a clever way to save a memory fetch! Also by reading from the collision register before the end of the scanline, it resets the VIC chip&#x27;s readiness to test collisions and collisions will be tested again on the next scan line, so the whole process can repeat.<p>I find this hack to be really beautiful. That use of collision to dynamically build the next scanline&#x27;s Y-expand values kindof reminds me how modern 3D games may encode all kinds of different scene information into various layer buffers and color channels as a game frame is rendered over many passes.<p>As a kid I reused the 64 sprite hardware over and over to fill the screen with sprites. As I recall, I lost a lot of CPU time because the VIC chip was hogging access to the memory more than it normally would. This trick would have let me fill the screen with more sprites than ever. One of my dream goals as a kid was to reuse the sprite hardware faster, to change their colors and be able to get more colors on the screen.<p>I recall trying to find a way to get the sprites to be only one scanline high and spend all my time simply changing colors and memory locations on the sprites. It never worked, it was like the VIC chip was locked in on the settings for a sprite until it was done drawing. And that in fact is the trick with this Y-expand thing - you can trick the sprite hardware to finish a sprite in fewer scanlines than should be possible (apparently as few as 4, according to the author!) Once the hardware thinks the sprite is finished, the hardware is relinquished and can be commanded to reuse that sprite on subsequent scanlines to paint more pictures.<p>It seems the demoscene may achieve my dream someday - perhaps my fancy super-color-1-pixel-high-sprite bitmap display mode hack may one day become a reality!