Hacker News new | past | comments | ask | show | jobs | submit login

Yes. It was hard for Commander Keen because DOS used a screen buffer that was written to first before rendering the pixels to screen, which was quite slow back then.

In comparison, game consoles used blitting, and would directly send the lines to the CRT to draw. I assume C64 is the same.




That’s true, but this is from the readme

> VSP (VARIABLE SCREEN POSITIONING)

> This port relies on the VSP-technique for scrolling. If you experience crashes while playing the game, this is most likely the issue. You may find out if your computer is prone to crashing by running VSP Lab.

I don’t know anything about the C64, but it sounds like scrolling the screen in this case wasn’t easy at all, if it required a technique that outright crashes on some C64s.


Best explanation of vsp (or, vsp-induced crashing) I'm aware of: https://www.linusakesson.net/scene/safevsp/index.php


Interesting. So is VSP something that was officially documented, or was it an undocumented hack that was discovered?

The blast processing trick on the Genesis would be something similar then. There's a syncing issue with that one too: https://www.youtube.com/watch?v=rvvL6S5Buiw


It's an undocumented hack. The C64 officially does support vertically and horizontally shifting the display one whole character position pixel by pixel by changing a register, but VSP is a hack that allows scrolling much more without copying memory.

It's odd to use for such a simple game as Mario, as I can't see how it's possibly complex enough that they couldn't afford to scroll "normally".


The CPU isn't really fast enough to fine-scroll large sections of the screen.

It runs at about 1mhz, and which means there are about 16,000 CPU cycles per frame. The CPU typically takes 3-7 cycles per instruction, so you have a maximum of 5600 instructions per frame.

The there is a useful "rotate memory left/right" instruction which takes 7 cycles. An unrolled loop of these could shift about 2000 bytes of memory left/right per frame. A 160x200 2bit color bitmap mode screen takes up 8000 bytes, so at the very least you can shift ¼ of the screen.

That might be enough for super Mario Bros, if you can be smart about empty areas.

Except, I skipped over a few things. To scroll 2bit graphics, you have to rotate twice. 14 cycles per byte, so we are down to ⅛ of the screen.

And such scrolling only works if each line uses the same 4 colors. To have more than 4 colors per line you have to shift the attribute bytes too, and deal with attribute clashes when a tile is halfway between two vic2 tiles.

You would be lucky to shift a sixteenth of the screen per frame, with zero time left over for processing gameplay and sprites.


> The CPU isn't really fast enough to fine-scroll large sections of the screen.

That's fine; it is not how you'd do it on the C64. Nor was VSP very common.

> The there is a useful "rotate memory left/right" instruction which takes 7 cycles. An unrolled loop of these could shift about 2000 bytes of memory left/right per frame. A 160x200 2bit color bitmap mode screen takes up 8000 bytes, so at the very least you can shift ¼ of the screen.

Nobody used bitmaps to for scrollers on the C64 (or indeed for most games). A game screen using character mode takes at most 2000 byes if you need to scroll the entire screen, including color RAM, which you wouldn't be doing as you'd spend some space on other things, like score displays etc., and putting more static decorations was indeed a common way of cutting down on the amount actually scrolled. Another way was to do level designs so that you did not have to scroll everything every time. E.g. by keeping some lines using the same colour, or fill part of the screen with sprites instead of characters.

To scroll the first 7 pixels in any direction then only requires updating a single register to shift the screen. This applies for bitmaps too, so there really are no circumstances where you'd bit-shift bitmaps to scroll.

For the 8th pixel you need to copy, but you don't need to complete the copy in one frame; you just need to outpace the raster-beam. So the moment it has rendered the first full line of text, you can scroll it; as long as you take care to not speed past the rendering, then you can continue following past. If you do this you have nearly two full frames to complete the copy, for about 1000 byes per frame.


True, The Great Gianna Sisters scrolls just fine, and I am assuming it does not use this hack.


It probably saves a CPU cycle or two.


More like thousands.


C64 games mostly use the character mode in which the screen has a resolution of 40x25 characters of 8x8 ("hires") or 4x8 ("lores"; lores was most common as it allowed 2 colours plus the background colour per 4x8 character). There were exceptions, like e.g. Elite, or slow games (e.g. strategy or adventure games - the Lord of the Rings text adventure used a split screen setup using the raster interrupt to show a bitmap image on the top that was painfully slowly rendered with a tiny polygon count).

To do scrolling with the character mode you'd normally use a register to tell the graphics chip to hide 8/4 pixels on each side. You can then set the x-position and/or y-position of the viewport within that slightly reduced "window". When you've scrolled the maximum amount in one direction, the simplest approach is to wait for the vertical blank interrupt and then you copy just the 2K or less that makes up the characters on screen and whatever portion of the color attributes you need to copy. If you don't use the full height of the screen, or keep colours the same on parts of the screen, you can drastically cut the amount you copy. (Though apparently this Mario port uses VSP, which avoids the copying, but has stability problems)

Add to this that you could very precisely time things on the C64 as you can set the raster interrupt to a specific line, and the cycle count of everything on the C64 was painstakingly documented (EDIT: Though certainly not by Commodore, other than relatively high level details), and if you wanted to you could start processing the game loop while the screen was still being updated as long as you took care to ensure any rendering did not outpace the graphics rendering (if in doubt, you can check and optionally reset the raster interrupt to trigger again later on screen).

For the characters you'd use hardware sprites (most common) or you certainly could use characters "blitted" onto the screen, with the risk of making things jerky and requiring careful design as there's no way to blend against anything but the screen background colour. This was rarely done, but it happened. Barbarian II [1] at least uses that technique for at least some characters in-game, allowing bigger entities on screen (another common technique to get bigger objects is to use multiple sprites for a single in-game character). I found that out to my surprise as a child while stopping the game (which unusually for Barbarian II worked without clearing the screen) which left characters on screen representing players, not just sprites and background. Another notable one is Skyfox [2] - a 3D game where the "3D" consists of character blobs existing in multiple different sizes.

If you needed more than 8 sprites, you could use the raster interrupt to render more by resetting sprite registers after a sprite was rendered (with the caveat you could never have more than 8 on a given raster line).

[1] https://www.youtube.com/watch?v=fdEZuK8PqLg

[2] https://www.youtube.com/watch?v=SurusNWvDmw


The EGA also had hardware scrolling though, and it was what Keen used.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: