News for hackers. Stuff that matters.
Re:Game Programming Patterns: Double Buffer (2014) by aidenn0 on Monday August 27, 2018 @12:05AM (#17849371)
Interestingly enough, there were many games in the 8 bit era that you could watch the scene render from back to front (golf games were notorious for this), and going back even further, early video game systems lacked a frame buffer at all.
Re:Game Programming Patterns: Double Buffer (2014) by mikekchar on Monday August 27, 2018 @12:41AM (#17849473)
Though on the Apple II, I suspect that most games were essentially double buffered (although there is no video hardware to speak of). I wrote an arcade game when I was in high school (probably around 1985???) and the advice I got was to draw into a separate piece of memory and then copy that memory into the video memory -- otherwise you'd always have trouble with video artefacts (especially because the colour it output was dependent upon the bit patterns in memory).

It was actually important from another aspect: the video memory was not contiguous. IIRC, it was divided in 3. So the first row was the first scan line, the second row was 1/3 the way down the page and the third row was 2/3 down the page. In order to compose graphics on the screen, you'd have to have this weird algorithm for drawing into memory. Compositing right in the video memory would have resulted in lots of timing problems.

Re:Game Programming Patterns: Double Buffer (2014) by mpweiher on Monday August 27, 2018 @09:56AM (#17851487)
> draw into a separate piece of memory and then copy that memory into the video memory

While the Apple ][ had no graphics hardware to speak of, it did have two graphics buffers that you could switch between.

So you would draw into the non-displayed buffer and switch to that.

If you had installed the vertical-blank mod, you could even do that without tearing. (I think the //e came with that).

Re:Game Programming Patterns: Double Buffer (2014) by Steve44 on Monday August 27, 2018 @08:09AM (#17850917)
One extreme example I remember very well is The Hobbit on the ZX Spectrum. It was an illustrated text adventure using graphics to add atmosphere and interest. I suspect they used a drawing programme with scripted commands to minimise memory usage at the expense of time and sometimes fine detail to draw them.

There are a couple of good examples at 4:57 onwards. Link at https://www.youtube.com/watch?v=3f3PFfK-9Gk

Edited to add there is a video here https://www.youtube.com/watch?v=D9qrZC7WUio of the 128k Spectrum version. Looking at the speed I suspect they pre-rendered the images in the background and used the extra memory to store them and then copy the completed image to display when needed.

Re:Game Programming Patterns: Double Buffer (2014) by kayamon on Monday August 27, 2018 @09:02PM (#17855833)
Hi, I’m the guy who did the 128K port.

The images are all hand-drawn art, stored as compressed data and simply decompressed when needed. We don’t render (or prerender) anything.

Re:Game Programming Patterns: Double Buffer (2014) by Steve44 on Tuesday August 28, 2018 @03:51AM (#17857207)
Ah OK, I hadn't appreciated that video was a remake and had assumed that they were still looking to keep a limit on loading times.

Nice work, good to see these old systems still being played with and experimented on.

Re:Game Programming Patterns: Double Buffer (2014) by Sharlin on Monday August 27, 2018 @05:08AM (#17850299)
As ddingus implied, in the C64 era you'd actually have state-change logic executed as the beam moved across the screen. For instance, the VIC graphics chip only had support for eight hardware sprites at a time. But by using the hsync interrupt you could reuse those sprites and draw each at different coordinates as long as they were in different regions of the screen, vertically.

[1] https://en.wikipedia.org/wiki/Raster_interrupt

Re:Game Programming Patterns: Double Buffer (2014) by rusk on Monday August 27, 2018 @05:25AM (#17850361)
This also enabled more colours, as you were limited to something like 8 colours (2 per sprite and 1 background) in multicolour mode. At different vertial positions you could swop out the banks between scans and this worked particularly well for horizontal scrollers ...
Re:Game Programming Patterns: Double Buffer (2014) by yason on Monday August 27, 2018 @05:24AM (#17850357)
The golf games (Leaderboard Golf comes to mind: https://www.youtube.com/watch?v=4jA5eKk10Wo&t=803) had to do this because it took incredibly long time to render a 3D map on the screen. No chance those machines could've rendered the whole scene within a few frames.

The games just made it a visual gimmick for the player to watch the drawing instead of offering a waiting screen, rendering to a backbuffer and then copying the image over.

Frankly, I wouldn't be surprised if the rendering was even made a bit slower so that the player can see the areas fill up in human-scale time. For example, a C64 with 6502 can fill polygons faster than what you see on the screen.

Re:Game Programming Patterns: Double Buffer (2014) by rusk on Monday August 27, 2018 @05:29AM (#17850372)
I don't know ... I remember using a paint program where something like a flood fill, actually ran before your very eyes... at something like 4-5MHz there isn't a lot of CPU to do your bidding so game logic, music, graphical rendering all takes a slice and you don't even have any kind of preemptive scheduler to make sure everyone stays in time. I'd say with this kind of game the developers were more focused on the game mechanics. The graphics were just "good enough" for what they were trying to do.
Re:Game Programming Patterns: Double Buffer (2014) by Narishma on Monday August 27, 2018 @09:44AM (#17851439)
The C64 ran at 1Mhz. Other contemporary CPUs that were clocked faster tended to take multiple clock cycles per instruction so it came down to the same.
Re:Game Programming Patterns: Double Buffer (2014) by rusk on Tuesday August 28, 2018 @04:20AM (#17857323)
Was it the spectrum that ran at 4MHz? Thanks for the correction!
Re:Game Programming Patterns: Double Buffer (2014) by Steve44 on Wednesday August 29, 2018 @03:58AM (#17866530)
Not the poster but yes, the Spectrum was at about 3.5Mhz.
Re:Game Programming Patterns: Double Buffer (2014) by Steve44 on Monday August 27, 2018 @12:43PM (#17852521)
> I wouldn't be surprised if the rendering was even made a bit slower

Trust me, everything was flat out then. I posted a link in another reply about something similar. Have a look at this flood fill, this was zipping along at full speed.

> There are a couple of good examples at 4:57 onwards. Link at https://www.youtube.com/watch?v=3f3PFfK-9Gk

Re:Game Programming Patterns: Double Buffer (2014) by yason on Tuesday August 28, 2018 @04:13AM (#17857294)
That looks like a traditional flood fill which is a different case but I might be wrong.

Leaderboard had vector graphics so the program knew analytically where the polygon edges are and it could simply write bytes in the bitmap, in most cases without reading back pixels.

Let's say C64 had roughly, in practise, about 15k cycles per frame. Quick calculation shows that filling the entire 320x200 screen in a trivial loop is 7-8k cycles for instructions alone, plus any delays should the graphics chip read the memory at the same time. Add to that vector math and the fact that not the whole screen will be filled and we should be able to count filling the scene in terms of frames, not several seconds.

Leaderboard might have sloppy routines to make it 'watchable' but I suspect C64 can fill faster than that if made to.

Filled vectors were notoriously hard on C64 as both the bandwidth usage and cpu cycles spent on math rack up. Yet games like Rescue in Fractalus had simpler but still filled vectors in real time.

Re:Game Programming Patterns: Double Buffer (2014) by veebat on Tuesday August 28, 2018 @08:08AM (#17858152)
Early 3D games are primarily limited on how they handle occlusion. If your scene is designed favorably(e.g. wireframe spaceships), you can ignore occlusion, but that doesn't describe most interesting scenes.

Leaderboard is using a kind of painter's algorithm to do everything, which is flexible but requires using overdraw, and by itself, will produce rendering errors in many scenes because the depth will be sorted per object or per triangle, versus per pixel. Filled triangle rasterization is particularly expensive to compute and requires a fair amount of numeric precision, both of which compound the issue of using overdraw.

Fractalus does not use these techniques for terrain - although the exact implementation is idiosyncratic[1], it's ultimately filling an outline that defines the horizon, and then adds texture to the landscape with dot patterns. Bear in mind, it doesn't render to the full screen either, it's mostly HUD, while Leaderboard is a little more expansive.

[1] A similar technique is described for Captain Blood: http://bringerp.free.fr/RE/CaptainBlood/main.php5

Re:Game Programming Patterns: Double Buffer (2014) by criminalpatto on Tuesday August 28, 2018 @02:15AM (#17856880)
A similar technique was used in Last Ninja 2, where the 3d isometric screens would be visibly redrawn, with the objects drawn one over another. It was actually a very cool effect. Don't know if the underlying technical reasons were similar though.
Re:Game Programming Patterns: Double Buffer (2014) by ptero on Monday August 27, 2018 @09:07AM (#17851221)
Another problem with double buffering is the need to perform the copy of the buffer. This is trivial now, but not quite so in the early years. I grew up way behind the tech curve -- we had a few 1MHz computers in our non-US university lab and a single 4 MHz machine (with a color monitor, wow) which seemed super fast.

As frames are often similar (only a small portion really changes), on those slow machines many folks preferred to update a small portion of the single buffer at the right time instead of copying the whole thing.

Re:Game Programming Patterns: Double Buffer (2014) by kd5bjo on Monday August 27, 2018 @11:08AM (#17851926)
Often, the buffer was never copied. Instead, the video card is told to read from the old back buffer (which is the new front buffer), and the old front buffer (which the video card was drawing from last frame) becomes the new back buffer. This only requires a few instructions, so can easily be done during the monitor's vertical blank.
Re:Game Programming Patterns: Double Buffer (2014) by Steve44 on Monday August 27, 2018 @12:36PM (#17852474)
That is entirely dependant on the hardware. Some machines could, some couldn't, and some could but mucked it up.

The Spectrum couldn't so you either wrote to the live video display or used some method of copying.

The QL could in theory switch video display between two buffers but they put a section of IO/System memory (I can't remember the details) in the middle of one of the buffers so it was useless.

Some systems also had hardware sprites which weren't part of the main video ram, they were overlaid by hardware. You could also do some fun stuff with those such as rewriting them as the scanline progressed down the screen to fudge a lot more hardware sprites.

I'm out of the industry now but one of the major parts of games programming was pushing the hardware way beyond what it was designed to do. Now, as far as I understand, you write for an API.

Re:Game Programming Patterns: Double Buffer (2014) by ddingus on Monday August 27, 2018 @12:34AM (#17849447)
Race that beam!

For simpler things, not 3D, sorting objects and a single buffer render still work just fine.

Re:Game Programming Patterns: Double Buffer (2014) by wiz21c on Monday August 27, 2018 @02:44AM (#17849822)
Well, except that to prevent tearing, you have to draw just behind the monitor's refresh line (well, at least when we had cathodic monitors). And that required an awful lot of super accurate timing (on PC at least)
Re:Game Programming Patterns: Double Buffer (2014) by ddingus on Monday August 27, 2018 @12:50PM (#17852581)
Or, draw just ahead of it. I think that is a matter of perspective.

The idea being to have the graphics there for the display device to render them. Once it has done that, they are no longer needed, until next frame.

Doing that actually needs only a small buffer, but is timing intense, also compute and write demanding.

If one has a sprite capability, and or a larger, or full frame buffer, just write from the top down, starting at the beginning of blank from the previous frame.

Drawing behind works simplest assuming a full frame buffer, so the new follows the old once the display has pushed those pixels to eyeballs.

Another scheme, used in DEFENDER and ROBOTRON, among many others, is to divide the screen into top and bottom regions. Or more, depending.

Render into the one the display is not using. This is more coarse, but can be less complex to arrange.

The timing depends. If one is working scanline by scanline, yeah. Need accurate timing.

When working with screen regions, or just a blanking period, the requirement is relaxed. Really, all you need is to understand the speed of the object draw engine and a quick sort to insure the initial part of the frame is drawn in time for the display.

Screen regions also work well when the renderer cannot get a full frame drawn every display frame. There, a priority system will draw what is needed, delay that which is not.

I enjoy doing ths kind of programming. A full double buffer is a luxury :D

Re:Game Programming Patterns: Double Buffer (2014) by sasaf5 on Monday August 27, 2018 @01:24AM (#17849601)
Cool stuff! Perhaps one could have even written some routines to kinda abstract that?
Re:Game Programming Patterns: Double Buffer (2014) by HelloNurse on Monday August 27, 2018 @03:36AM (#17849996)
An "engine" could take care of synchronizing rendering with reading, but the difficult part is application specific: ensuring that rendering fits in the specified number of CPU cycles.
Re:Game Programming Patterns: Double Buffer (2014) by ddingus on Monday August 27, 2018 @01:05PM (#17852700)
For many cases, one ends up writing a little kernel that manages the display.

Break the display into whatever elements make sense, and insure timing is all sorted. Run tests to get maximums.

Once it is running, the rest feeds it with pointers to objects, and lists or the objects get generated dynamically at display time.

Various schemes apply to overtime requirements. In old Williams arcade games, one method was to just move baddies to a non displayed region. Aggresive players would fire off a ton of shots to trigger this.

Another is to delay animation or movement.

The kernel can do that, but it gets more complex and slow. Dumber kernels are faster. Higher level code can manage what the kernel has to do.

One thing is smart to do though, and that is to have the display kernel fail gracefully. Use hardware timers, or loop counters to prevent overdraw and the loss of display sync normally associated with that condition.

Re:Game Programming Patterns: Double Buffer (2014) by shoo on Monday August 27, 2018 @04:56AM (#17850261)
there's a bit of discussion about isometric tile rendering nonsense, although not specific to vsync, in David Brevik's diablo postmortem https://www.youtube.com/watch?v=VscdPA6sUkc

along with a whole lot of other fascinating stuff

Re:Game Programming Patterns: Double Buffer (2014) by ddingus on Tuesday August 28, 2018 @02:12AM (#17856875)
That was a great video. Enjoyable talk.

At one point, they were drawing tiles, the walls associated with them, objects, etc...

Moving objects would end up between tiles and the sprite would be cut off by a different tile draw. Worse, there was no sort order that worked for all cases. They ended up creating, what the speaker called "an ai" to move the object away from the draw conflict, get it all drawn, then move the player back, just ahead of the actual motion...

In hindsight, they could have just decoupled the walls from the tiles and it all could have been a lot simpler!

Re:Game Programming Patterns: Double Buffer (2014) by bartread on Monday August 27, 2018 @03:39AM (#17850004)
The 16-bit era meant that machines had a bit more memory to play with so double-buffering became a common technique on platforms like the Amiga.
Re:Game Programming Patterns: Double Buffer (2014) by unwind on Monday August 27, 2018 @05:11AM (#17850310)
True, and on the Amiga it was especially nice since the location of the frame buffer was under software control, so no need to copy a full screen's worth of pixels anywhere.

To swap, just tell write the new frame buffer base address to the appropriate custom chip registers, and you're done.

Since the swap should be synchronized to the beam, the actual write typically happened in a copper list anyway, so that's what you really write to in order to do the swap.

It all brings me back to being a teenager and discovering these things. :) Amiga <3.