[HN Gopher] Nine - seemingly impossible C64 demo
___________________________________________________________________
Nine - seemingly impossible C64 demo
Author : appleorchard46
Score : 244 points
Date : 2025-02-04 23:11 UTC (23 hours ago)
(HTM) web link (linusakesson.net)
(TXT) w3m dump (linusakesson.net)
| kbelder wrote:
| Neat. Having more than 8 sprites on screen is not hard, it just
| requires some well-timed interrupts to move a sprite from above
| the current raster location to below it, so that the same sprite
| is drawn multiple times.
|
| But I'm not sure about the end of the demo where they are all
| rotating on the same line. I guess it could be done with
| interrupts occurring partway through the horizontal scanline, but
| I didn't think they could be that precise?
| o11c wrote:
| Youtube comments said something about "multiple apparent
| sprites per actual sprite, with stretching"?
| pwrrr wrote:
| Yeah, you can x and/or y expand a sprite, then change it to
| make it look like it contains more data by cleverly drawing
| the sprite because 1 pixel becomes 2 pixels wide in expanded
| mode.
| egypturnash wrote:
| Nope, that's not it. There's a video out there already that
| dissects it and figures out the trick.
| peterleiser wrote:
| I don't know the trick, but take a look at the "7". It looks
| like it's made from the vertical line in "4" and a portion of
| another number.
| badc0ffee wrote:
| This is true, but not relevant to the trick.
| boltzmann-brain wrote:
| you can't multiplex sprites so that more than 8 appear on the
| same line.
|
| the secret is to pretend you have a 9th sprite by emulating it
| with characters that look exactly like one of the sprites
| would.
| egypturnash wrote:
| That stops working when you open the borders and put sprites
| outside the area the video chip will render
| characters/bitmaps.
| eru wrote:
| Yes, but the demo is really cheeky about that.
|
| The borders are open when you can still do the normal
| multiplexing, because there's lots of vertical separation
| between the sprites.
|
| Later, when they put the sprites together on the same line,
| the borders are closed.
| jchw wrote:
| But in this case, that (alone) can't be it because all 9
| sprites clip (smoothly) in and out of the border. So they've
| really gotten cheeky with this one.
| Dylan16807 wrote:
| I don't like how you worded this post. You know the demo's
| point is having all 9 go at the same time, so it's quite
| misleading to start off describing something that _sounds_ like
| the demo 's point, but is _not_ the demo 's point, and saying
| it's "not hard". Your second paragraph mostly corrects that
| false impression, but I dislike that you gave a false
| impression to start with.
| Underphil wrote:
| This is an extremely common type of comment on articles like
| this. The commenter has to ensure everyone knows their
| credentials before offering any sort of praise to the
| creator. I also despise this type of self-serving comment.
| flohofwoe wrote:
| 9 sprites on screen at the same time is trivial (this is
| known as sprite multiplexing), 9 sprites on the same raster
| line is the actual 'aha effect' because the C64 can only do 8
| sprites per line.
| Dylan16807 wrote:
| I'm not sure why you replied to me? Are you nitpicking that
| I said "go at the same time" because I think it's clear
| enough in context.
| pinoy420 wrote:
| All you need is a little "Just"(TM) and everything is possible.
|
| Typical HN comment minimising the immense effort required to do
| %thing% due to their own arrogance.
| flohofwoe wrote:
| The VIC-II reads the data for each sprite at hardwired
| horizontal positions outside the visible area, so this sort of
| 'horizontal multiplexing' shouldn't work.
| aappleby wrote:
| Eight hardware sprites and one blitted to the background every
| frame?
| erik wrote:
| That works until you see what appears to be 9 sprites on the
| same scan line in the border region.
| boltzmann-brain wrote:
| VIC II doesn't have that functionality. the first commodore
| that could do this was the Amiga series.
| badc0ffee wrote:
| Not quite. Drawing a full sprite-sized bitmap would not be so
| smooth on the C64.
| pwrrr wrote:
| They are in the border, Only sprites, ghostbyte (a repeating
| byte only shown in black. It is the last byte of the chosen
| videobank) and background color can be displayed there.
| siltcakes wrote:
| As soon as I saw who made this, I cranked my speakers and wasn't
| disappointed! Linus is amazing. I recommend his cover of The Moon
| from DuckTales:
|
| https://linusakesson.net/chipophone/ducktalesmoon.php
| jetbalsa wrote:
| I'm a huge fan of his A Mind is born demo 256 byte demo he did
| awhile back, freaking amazing
|
| https://linusakesson.net/scene/a-mind-is-born/index.php
| userbinator wrote:
| Discussion of it showed up on HN too:
| https://news.ycombinator.com/item?id=26511266
|
| I like how the title really invites you to pun it as "a mind
| is blown", because mine sure was when I first watched it.
| nonane wrote:
| Here is a video where Martin Piper uses a C64 debug tools to
| figure out how Nine was created:
| https://m.youtube.com/watch?v=Ik1vsMM2EuY .
| pimlottc wrote:
| Just guessing here, but does it have anything to do with the fact
| that 9 is the same as 6 rotated?
| boltzmann-brain wrote:
| no. there are 9 separately moving objects and them being
| visually similar or even the same doesn't mean much
| TheRealPomax wrote:
| Can we take a moment to appreciate that the music starts in 10/8,
| too? Because that's just the cherry on top.
| donohoe wrote:
| I assume it is 8 sprites but the "6" is also used to represent
| the "9" and jumped (and rotated) from position to position?
| JKCalhoun wrote:
| That was my guess -- but I'm not familiar with the C-64 and its
| sprite limitations.
| badc0ffee wrote:
| The limit on the C64 is, nominally, 8 sprites. Widely known
| tricks exist to increase that to 8 per raster line, by IIRC
| repositioning them during horizontal retrace.
|
| This demo actually shows 9 "sprites" on the same raster line
| using some clever tricks like low-res stretched sprites
| combined with custom characters. It all makes sense once you
| know the tricks, but the really impressive thing is how smooth
| it is. Which I guess is why it features a magician.
| pwrrr wrote:
| You can't change the sprites every rasterline. Sprites are 21
| pixels in height in unexpanded mode. So you can only change
| the sprite after displaying all 21 lines, unless you use
| sprite-crunching, where the limit is still several lines.
| Linus has an article on sprite-crunching (mind-blowingly
| complex).
| Luc wrote:
| > Linus has an article on sprite-crunching (mind-blowingly
| complex).
|
| https://www.linusakesson.net/scene/lunatico/misc.php
|
| Great article.
| pwrrr wrote:
| Indeed :)
| jll29 wrote:
| The video demonstrates a second common trick: making use of
| the black frame "outside" the screen buffer. Once the first
| demos showed it was possible it quickly spread and nearly
| everyone used it.
|
| It's been a while, but I recall that you had to do some fancy
| interrupt timing stuff for that. To find where that was in
| the code, the same procedure applied that we used to find the
| handler for background in the code of games: search for 0x78
| (SEI), which temporarily blocked interrupts so background
| stuff could be installed ("pseudo-multitasking").
|
| We used to purchase a tape or 5 1/4" floppy disk with a game
| per month and instead of playing the game, we competed who
| could remove the music from the game the fastest (so that it
| could play in the background alone, e.g. while writing code).
| In the end that was a matter of just seconds for previously
| unseen machine code using a hex monitor/disassembler. The
| advantage of such a "teenage sports" is you will never forget
| that "169 = A9 = load accumulator" and the rest of the MOS
| 6510 opcode table, even after not using it for 40 years.
|
| I wonder what today's kids will remember? (They seem to have
| to Google each Python keyword, and they can't do anything if
| WiFi is down for an hour, which worries me.)
| badc0ffee wrote:
| > they can't do anything if WiFi is down for an hour, which
| worries me.
|
| I worked with a younger guy on a pre-existing, large
| project written in C. He saw me use the man command and
| asked why I would do that - was I expecting to be offline?
| But I don't think of man pages that way, I still think of
| them as primary documentation. They're also specific to the
| software versions on the system I'm logged into, unlike
| whatever comes up when I Google `man 2 unshare`.
| aqueueaqueue wrote:
| Rabbit holed to this https://linusakesson.net/music/withering-
| bytes/index.php
|
| Thia is .... Something else!
| noman-land wrote:
| This dude's work is incredible. His entire YouTube channel is
| amazing. My personal recent favorite, The Commodordion: "A
| fully functional 8-bit accordion with bellows made out of
| floppy disks." Legend.
|
| https://www.youtube.com/watch?v=EBCYvoC4muc
| junon wrote:
| I want a Savant remix of that tune. It was so good.
| relistan wrote:
| Wow
| neuroelectron wrote:
| I probably don't understand it completely but from what I
| gathered from Martin Piper's video is that the spite locations
| and data are updated during the scan lines allowing the renderer
| to reuse the same hardware sprites before the scanline is
| complete.
| yumraj wrote:
| I didn't get. Can someone please explain what's impossible about
| it?
| themadturk wrote:
| The problem is presented in the intro screen: The Commodore 64
| only has eight independent sprites, yet this demo showed what
| appear to be nine sprites.
| yumraj wrote:
| Thanks!!
| panic wrote:
| By putting all the sprites on one horizontal line in the top
| "border", the demo also proves it's not using any of the
| standard tricks to fake extra sprites. The only thing that
| the C64 will draw up there are real sprites (not
| character/bitmap graphics), and you can't multiplex sprites
| in the same horizontal line of pixels.
| mdp2021 wrote:
| Not really the point: that is a tongue-in-cheeck trick, as we
| know how to solve that problem - but it takes using different
| stripes of the screen, whereas in the demo they are before
| 2:00 all put in the same stripe...
|
| At that point we go "Ah."
|
| (It's very normal in illusionism: the practitioner states
| something that puts you in the relaxed mood of participation
| to a game you know - then actually surprises you.)
| thih9 wrote:
| Is there a text explanation of the trick - for those that cannot
| watch a video?
| exitb wrote:
| The demo shows nine separate sprites, even though C64 supports
| showing only eight. It starts off by separating them
| vertically, which is a common trick, but then moves them all to
| the same raster lines and overlapping locations, which is much
| more surprising.
| nottorp wrote:
| By "cannot" i assume you mean you watched the demo video but
| your life is too short to waste it on video explanations of
| assembly tricks that are much better done in text? :)
| account42 wrote:
| Or he's somewhere where enabling audio is not an option.
| human3047628272 wrote:
| Some people have sight problems, or are even totally blind.
| But they still use the Internet.
| nottorp wrote:
| Yeah but the OP sounds like they saw the demo and are
| wondering how it's done now.
| stavros wrote:
| I don't know about the GP, but for me it meant "I have ten
| seconds to understand this curiosity, but not 32 minutes. If
| someone wanted to spend ten seconds explaining to the rest of
| us, I'd be grateful".
| masswerk wrote:
| There are some basic debugging notes by Martin Piper:
| https://github.com/martinpiper/DebuggingDetails/blob/main/Ni...
|
| For better understanding: The demo starts with a magician
| character drawn in the center of the screen, announcing the
| trick in text (some of this is big text achieved by overlaying
| sprites). Then, 9 sprites, each in the form of a colored number
| from 1 to 9, exit the magician's hat to rotate around him (in
| the notes screen #1), then, the screen gradually widens
| horizontally beyond the usual borders and the circle of the 9
| apparent sprites spreads out over the entire screen (screen
| #2). (At this point, the display of the magician, which was
| clearly drawn by PETSCII characters, before, shouldn't be
| viable anymore.) The swirling numbers transition to a narrow
| ellipse near the top of the screen (screen #3), which then
| transition to the very top of the screen, above the normal
| display area, a zone, which is available for sprites only,
| showing the sprites in a linear rotation (screen #4). Meaning,
| these must be sprites and these 9 apparent sprites are drawn at
| the same scan-lines. (So there is no way this could have been
| achieved by conventional, vertical multiplexing. This is the
| highlight, the big trick of the magician's show.) At the end,
| the sprites return to their initial circling motion and vanish,
| one by one, into the magician's hat.
|
| The demo is a combination of various tricks and artful timing,
| which enables perfect transitions between them.
| isoprophlex wrote:
| The music is very, very good too.
| thih9 wrote:
| Video of the explanation, at the timestamp showing 8 sprites
| that look like 9 sprites: https://youtu.be/Ik1vsMM2EuY?t=1509
|
| > the last two Sprites there are multicolored mode; (...) we
| have a different number of of high res mode Sprites and
| multicolored Sprites and expanded Sprites; and those high res
| and multicolor and some horizontally expanded Sprites are all
| munged together and then the apparent view with animation of
| the Sprite data as well the Sprite frames (...) gives an
| apparent view of having nine independent Sprites; but we know
| it's not, we know that it's a great big blob of eight Sprites
| all grouped together horizontally (...)
|
| via youtubetranscript:
| https://youtubetranscript.com/?v=Ik1vsMM2EuY
| yuchi wrote:
| Posted it few days ago but didn't get any traction. All Linus'
| work on retro computing is fenomenal. Please have a look at its
| channel, a lot of awesome content there.
| nerdralph wrote:
| My guess is it is chasing the beam. Change the border color from
| black to your sprite color, then back to black again. The change
| takes a minimum of 4 cycles (store absolute), which I think
| explains the thickness of the numbers. Some calculations
| involving the PAL scan line frequency could confirm if 4 cycles
| is quick enough.
|
| edit for further detail: This would be used for one of the
| numbers, with the other 8 using sprites.
| nerdralph wrote:
| As mentioned in other posts, the trick is using multi-color
| sprites to look like multiple single-color sprites.
|
| I did the scan line frequency calculations, and my though of
| changing the border color would not work. In one cycle the
| scanline advances 8 pixels, so toggling the border color would
| be a minimum of 32 pixels in width.
___________________________________________________________________
(page generated 2025-02-05 23:02 UTC)