Like many older computers the C64's graphic capabilites are a little more complex then the simple random-access framebuffer you get today, so just saying it has 320x200 at 16 color doesn't quite capture it, as there are numerous limits one has to deal with and tricks one can use to get around some of those limitations.
Resolution and Colors
At its core the screen of the C64 has a resolution of 384x272, however only the central 320x200 pixels of that area are usable in the normal sense, the rest is a colored border, which color one can change, but that otherwise remains fixed. The central 320x200 area is where the action happens. This area can be switched to five modes:
* Standard Character Mode
* Multicolor Character Mode
* Extended Background Color Mode
* Hires Bitmap Mode
* Multicolor Bitmap Mode
The first three are character modes, that are used for either the regular text output or tile based games. Each of the 256 characters in those modes is either a single color 1-bit 8x8 bitmap or a four 2-bit 4x8 bitmap (which gets scaled to 8x8 for display). The color of the character isn't determined by the character bitmap itself, but by a separate color map that allows to assign a different color to each 8x8 area of the screen. In the 1-bit hires mode one unique color is allowed and an additional one that is shared across the screen. In the multicolor mode one unique colors and three shared ones are allowed, as an additional complication that unique color is limited to only the first 7 of the C64's 16 colors, the remaining bit is used to decide if the character is in hires or multicolor mode. This little trick allows mixing hires tiles with multicolored ones on the same screen, which many games make use of. In Extended Background Color Mode the individual colors disappear and instead one can set four colors that are shared across the whole screen.
As one can see, the limitations of the character mode essentially break the 320x200 screen with 16 colors down to a 160x200 screen with four colors, in reality things aren't quite that bad, as some trickery and clever use of the palette can be used to overcome some of those limitations.
The bitmap modes of the C64 gets rid of the character based display and instead allow to address each pixel individually. Similar limitations as in character mode apply, i.e. only four colors in each 8x8 block are allowed or only two colors in hires mode. Unlike character mode however one has free choice of three colors per 8x8 block, instead of just one, and there is only one color remaining that has to be shared across the screen. Unlike a regular linear framebuffer, the memory layout of the C64 however is a little more complicated, as it doesn't store all pixel one after each other, but instead stores them in 8x8 blocks, so the math to find where exactly a pixel is stored becomes a bit more complicated.
The C64 also has the ability to handle eight hardware sprites. The sprites work independed of the graphics mode chosen for the main screen and are 24x21 pixels large. They again provide hires and multicolor modes, selectable for each sprite individually, and as with the regular screen the horizontal resolution goes in half when choosing multicolor mode. Sprites have one unique color each, two shared across all sprites and the final color acts as transparency.
Sprites can be scaled in horizontal or vertical direction by a factor of two. Ordering can also be adjusted via a priority bit, which can also be used to put them behind portions of the background screen.
The C64 also comes with build in sprite collision detection that will inform you when two sprites have collided.
Build in Palette
The C64 provides a set of 16 colors, these colors are fixed and can't be altered and as mentioned you only can chose o few of those for your image. While this looks quite limited at first, the palette is cleverly choosen so that so that one can build numerous color gradients out of a combination of a light color, a dark color and an intermediate grey value. This image demonstrates some of the possibilities.
Pixel by pixel smooth scrolling is possible on the C64 when using character mode. With the help of a scroll offset the screen can be moved by up to 7x7 pixels away from its regular position without touching the screen data itself, once that position is reached, the actual screen content has to be updated manually. Which in characte mode means copying 40x25 (1000) bytes around.
In bitmap mode that offset is available as well, but not really useful for scrolling, as the C64 isn't fast enough to copy the 10.000 bytes around that form the framebuffer and the color maps.
Parallax scrolling isn't possible on the C64 by normal means, as it can only do a single layer of graphics. Tricks with sprites or animated character graphics can however be used to get a bit of a parallax effect.
Sprites are not influenced by the scrolling registers, they have to be moved along manually.
So far all the capabilities presented still have some problematic limits. If you wanna display a HUD along with a scrolling playfield, you can't really do that, as the HUD would move along with your playfield. Sprites also wouldn't be of much use, as you'd want to use those for the game itself, not waste them on the interface. The raster interrupt comes to the rescue, it allows to execute code on essentially each scanline. This can be used for a multitude of clever tricks, such as switching the screen mode or scroll offset while the screen is getting drawing to the TV. This thus allows to have a HUD that stays fixed at the bottom of the screen, while the playfield above scrolls around, you simply change the scroll offset at a scanline. That interrupt can also be used to allow two player split screen or to change the color palette on the fly to make more use of the limited amount of color the C64 provides. It can of course also be used by simple special effects, such as a water effect.
And here a little example of a multicolor bitmap mode image running on the emulator Vice (example code and explanation how that image was created might follow later):