• Hey Guest. Check out your NeoGAF Wrapped 2025 results here!

How "oldschool" graphics worked

I would imagine that the early Nintendo developed NES games from 1983 used the graph paper method, but a lot of the later games from the mid 80's onwards were created with much better tools and proper paint programs.

From about 1986 onward, an Amiga with Deluxe Paint was basically industry standard. So many game companies -- including Sega -- used it.

otyUDRI.gif


The manual for the version of Deluxe Paint I own (can't be bothered to go grab it at the moment) includes examples from Desert Strike in the manual when introducing you to the tools. Desert Strike was unreleased at the time. EA made both Deluxe Paint and Desert Strike.

Here's an example of sprite development for Super Mario Bros 3:

tumblr_nqviop7XSD1rpku4no9_r1_500.jpg


Most people were not drawing sprites by hand using binary calculations. That was basically limited to extremely tiny eastern european developers contracted out by US Gold to do shit ports of arcade titles to microcomputers in the span of weeks for dirt cheap, lol.
 
The drawing method of having multiple sprites to form one character is properly the reason for the flicking problems the NES had.
 
The drawing method of having multiple sprites to form one character is properly the reason for the flicking problems the NES had.

It's a form of error correction for displaying more than 8 sprites (or however many hardware sprites your system has available) per raster. Different hardware had different solutions. If your hardware (or software sprite multiplexer) doesn't have a way to handle this error, it'll simply stop drawing after the 8th sprite per raster. This means any sprites to the right of the 8th sprite per raster won't be drawn at all.

Modern-ish machines from about 1985 onward would implement object attribute cycling routines, which basically watched for this error and would adjust the display between frames such that, if, say, you had 10 sprites per raster like so, and our hardware only had 8 physical sprites per raster:

frame 1: [A, B, C, D, E, F, G, H, i, j]

and the bolded capital letters are displayed, and the italicized lower case letters are not then on the next frame, it would purposefully cycle through non displayed sprites such that, eventually, every sprite would appear over a set number of frames, like so:

frame 2: [a, B, C, D, E, F, G, H, I, j]

frame 3: [a, b, C, D, E, F, G, H, I, J]

frame 4: [A, b, c, D, E, F, G, H, I, J]

frame 5: [A, B, c, d, E, F, G, H, I, J]

etc...

This is actually built into most VDP and PPU's in their hardware multiplexer, but smart developers could write their own object attribute cycling routines to more intelligently figure out this display limit and sometimes eliminate flickering all together depending on circumstance.

When you'd hear about old developers "coding to the metal" this is the type of stuff they were doing. This is the sort of things Manfred Trenz or Treasure became really well known for, what made those types of developers really notable and distinguishable. An example - Treasure had a very advanced object attribute cycling method designed for 2 player mode of Gunstar Heroes when both players would fire bullets. Every other bullet, depending on frame and player, would display according to their cycling routine in order to push the insane number of bullet sprites they could display on the screen at once.
 
We had some commodore 64 code books when I was a kid, was too lazy to ever build one, I only wanted to play summer olympics and strip poker
 
We have some commodore 64 code books when I was a kid, was too lazy to ever build one, I only wanted to play summer olympics and strip poker

Most of these concepts I first stumbled upon myself as logical conclusions when I would spend my early days writing graphics subrountines in qbasic, and then eventually C++. I would begin by doing the simplest task possible - drawing a mere pixel to the screen - then evolve that into sprites, which I would store in managed parts of memory myself. Blit to and from that memory, just like I was using a hardware register. From there, I would encounter problems like described above - I need to display more "sprites" but my defined memory size only allows for X number of sprites, and I need to display X + Y sprites. That would lead to experimentation, which would lead to stumbling upon methods, which I would implement, then see done elsewhere in demoscene which would clue me in that this process was the "correct" process. And then that would form a feedback loop.

I suspect most people who have worked in graphics have similar stories of independent yet similar invention. These methods are logical if you understand the underlying mechanics and reasons behind them. That's not to say they are obvious, but the "correct" solutions sort of come naturally to those who are deep into this stuff.

I had a problem when I was younger where I would come up with my own method of doing things, then I'd get embarrassed and think I wasn't doing these things "correctly" and wouldn't show them off, only to eventually come to understand that my method was how most people did things in the first place.
 
If you think coding graphics for 8-bit systems was insane, check out how they had to do it for the Atari 2600 - this is from Ian Bogost's fascinating book Racing the Beam, well worth a read if this stuff interests you.

From this Wired article, more details at the link: http://www.wired.com/2009/03/racing-the-beam/

In the book, Montfort and Bogost explain that the primary difference between the VCS and most every other game console is the machineÂ’s lack of a "frame buffer." This is the section of a systemÂ’s RAM that saves the image data for each successive screen that the game displays. The programmer writes each image to RAM, and they are flashed up onto the television screen in succession.

The Atari VCS had a miniscule 128 bytes (thatÂ’s bytes) of RAM, not nearly enough for a frame buffer. So programmers had to generate graphics literally in real time, drawing on the screen as the television screenÂ’s electron gun was passing over the tube.



As illustrated in this image from Racing the Beam, the electron gunÂ’s movement included three large spaces where it was not drawing on the screen: the vertical and horizontal "blanks" on the top and left, and the "overscan" on the bottom. These blind spots were crucial for Atari programmers, as these were the only times they could do anything that didnÂ’t involve drawing graphics on the screen, such as computing joystick inputs, player movements, scoring, etc.

If you’ve ever seen little black lines appear at the left edge of the screen while you’re playing a VCS game, those are bits of the game’s code where the program is taking too much time doing other calculations, and it can’t draw on the screen, leaving it blank. The black bar on the left-hand side of the Pitfall! screen at top was Activision designers’ solution — they cut out part of the gameplay field in exchange for more processing time.
 
When I started out dabbling with programming on the Amiga, I was massibpvely jealous of the SNES and how it practically handed you scrolling play fields on a plate. You could create maps out of tiles and the hardware would practically do the rest for you. Although the Amiga was really powerful, it had to do things like that manually - so you'd have to move data around with the blitter to add tile stripes to the edges of the playfield and then as your playfield reached the edge of your reserved memory, you had to blit the whole thing back to the start point. I think the Atari ST was even worse because it didn't have a blitter to back it up, so everyone was moved by the CPU. So you'd have amazing polygon games like star glider, but then crappy scrolling games because it was all software scrolling.

I wish I still had my Amiga hardware reference manual.

And I love all the tricks for getting more colours or detail in sprites on old machines. Thinking how slow they all were, and how limited the CPUs were - yet you could still mess around with Hblank interrupts which are tiny little time slices. Amazing.
 
If you think coding graphics for 8-bit systems was insane, check out how they had to do it for the Atari 2600 - this is from Ian Bogost's fascinating book Racing the Beam, well worth a read if this stuff interests you.

From this Wired article, more details at the link: http://www.wired.com/2009/03/racing-the-beam/




The Atari 2600 is an 8-bit machine. Further, working in vblank and hblank is how all the other contemporary systems - NES, SMS, C64, SNES, Genesis, etc - all worked. The sprite multiplexing I described last page for the C64, as an example, occurs in HBlank.
 
When I started out dabbling with programming on the Amiga, I was massibpvely jealous of the SNES and how it practically handed you scrolling play fields on a plate. You could create maps out of tiles and the hardware would practically do the rest for you. Although the Amiga was really powerful, it had to do things like that manually - so you'd have to move data around with the blitter to add tile stripes to the edges of the playfield and then as your playfield reached the edge of your reserved memory, you had to blit the whole thing back to the start point. I think the Atari ST was even worse because it didn't have a blitter to back it up, so everyone was moved by the CPU. So you'd have amazing polygon games like star glider, but then crappy scrolling games because it was all software scrolling.

I wish I still had my Amiga hardware reference manual.

And I love all the tricks for getting more colours or detail in sprites on old machines. Thinking how slow they all were, and how limited the CPUs were - yet you could still mess around with Hblank interrupts which are tiny little time slices. Amazing.

MSX2 games like Space Manbow do the same thing in order to smoothly scroll at less than character-width (8 pixels) per frame.

Also, with the NES, you can only smoothly scroll in 1 direction at once, either horizontally or vertically. Games like Mario 3 use the same method you're describing to (usually) scroll horizontally, as the two play-fields are arranged vertically in just about every level so you can fly.

Speaking of smooth scrolling - you can use bank switching in retro consoles, or blit updated tile information, to "pre-calculate" the process you describe across arbitrary bits of the background, storing every "frame" of scroll as an independent tile. If you had a background pattern that repeated, you could alter the scroll of these tiles to create faked parallax scrolling, like the kind seen in turrican 2:

xTRb9si.gif
 
It's been a while, but I *think* Nintendo DS even had a palette-limited tile mode, and I wouldn't be surprised if PS1 did too.

Correct, the PS1 has support for CLUT-based 4 / 8-bit textures.

The Atari 2600 is an 8-bit machine. Further, working in vblank and hblank is how all the other contemporary systems - NES, SMS, C64, SNES, Genesis, etc - all worked.

Working with the 2600 is radically different from NES / SMS / SNES / Genesis though. The 2600 basically only has a 20x1 pixel-buffer for graphics ( aside from the 5 sprites ), whereas the other mentioned systems have tile-buffers that cover at least the size of their output resolution.
 
Working with the 2600 is radically different from NES / SMS / SNES / Genesis though. The 2600 basically only has a 20x1 pixel-buffer for graphics ( aside from the 5 sprites ), whereas the other mentioned systems have tile-buffers that cover at least the size of their output resolution.

I've actually worked with a 2600 :)

Missiles and balls, lol

I'm just saying the thing he's pointing to as an example of "you think these machines had it rough" are things that virtually every machine until the mid 90's had to deal with. Race the beam style tricks aren't inherent to the 2600.

The biggest change in 2600 style programming is color selection, which is quite unlike most modern-ish machines. Many aren't familiar with intensity flags and things of that sort.
 
Race the beam style tricks aren't inherent to the 2600.

But they're not tricks on 2600, it's mandatory, that's how you get shit done, you race the beam. It's not like tricking the hardware into doing more than it should by super-finely timing certain special moves like busting borders on the ST or whatever.
 
Race the beam style tricks aren't inherent to the 2600.

But they're not tricks on 2600, it's mandatory, that's how you get shit done, you race the beam. It's not like tricking the hardware into doing more than it should by super-finely timing certain special moves like busting borders on the ST or whatever.

Yes, it's mandatory on other systems too. It's how you do everything. Everything is updated in vblank or hblank. What you are describing isn't inherent to the 2600.
 
From about 1986 onward, an Amiga with Deluxe Paint was basically industry standard. So many game companies -- including Sega -- used it.

otyUDRI.gif


The manual for the version of Deluxe Paint I own (can't be bothered to go grab it at the moment) includes examples from Desert Strike in the manual when introducing you to the tools. Desert Strike was unreleased at the time. EA made both Deluxe Paint and Desert Strike.

I haven't seen or thought about Deluxe Paint in 20 years.


Spent countless hours playing around with it when I was young
 
From about 1986 onward, an Amiga with Deluxe Paint was basically industry standard. So many game companies -- including Sega -- used it.

otyUDRI.gif
What an lovely program.

Well, outside it's tendency to interpolate color values for gradients for palette in HSV?, so basically we had to create them by hand or get some very weird results.
 
Nice little video, though I'm not sure where he got the idea that tiles were called "color cells", they were (and still are) called tiles, both in magazines of the time (Compute!) and in official SDK documentation (at least for the Gameboy Color). BTW, the colors that can be displayed in one tile are known as a "palette" - the NES could display 4 colors per background tile (mostly...), so those 4 colors are a single palette, and it can display four palettes per screen (meaning, each tile can choose from premade color palette 0, 1, 2, or 3).
Also check the NESDev forums.

Plus a lot of these systems don't actually hold a screen in memory at all, just the tile map and tile properties, but maybe he'll get to that...
 
Yes, it's mandatory on other systems too. It's how you do everything. Everything is updated in vblank or hblank. What you are describing isn't inherent to the 2600.
I disagree. On Atari 2600 it literally is how you do everything - right before each scanline is drawn during the small space of time between scanlines known as the horizontal blank or hblank, you tell it what to draw on the next scanline, and often you have to time things as the scanline is drawn and interrupt it in the middle to tell it to change what's it was about to draw. These aren't tricks but the basic way the system is controlled, you are telling the system how to draw the screen while it is being drawn, it requires exact timing and extreme code optimization, if your timing is off one bit the entire rest of the screen will be messed up. And you have to constantly do it, every time the screen is drawn your code has to be there telling it how to draw itself.

On systems like NES, though, all you have to worry about is "is the screen being drawn, if so don't update graphics". Most of what games had to do was "Wait for the screen to finish being drawn, then update any sprite data or background tiles that changed that frame, maybe update color palettes, and set scroll values", then you had plenty of time to update everything that didn't care whether the screen was being drawn or not, like music or game logic. Whenever the screen starts being drawn again, it will automatically be drawn with the changes you made, and you can ignore it and keep running any code that doesn't alter the screen. You *can* do special hblank or scanline effects to do tricky things while the screen is being drawn, but it's all optional (and is considered advanced tricks pushing the system).

Atari development is entirely different from any of the later systems, requires a different coding style and mindset.
 
Atari development is entirely different from any of the later systems, requires a different coding style and mindset.

Yes it does. "Using hblank," however, is not the reason the coding style and mindset need to be different. Any programmer - literally anybody who has ever worked with these types of machines - is familiar with racing the beam. They are not "tricks." They are essential - if you want to write an NES program that does anything beyond merely displaying an image to the screen, you will race the beam. Because Hblank and VBlank are where the entirety of any "live" computation occurs.

As an example - want to poll your joystick? Plex the input? You better be racing the beam, then.

"Racing the beam" isn't exotic in the realm of old school programming. It was expected and mandatory.
 
Yes it does. "Using hblank," however, is not the reason the coding style and mindset need to be different. Any programmer - literally anybody who has ever worked with these types of machines - is familiar with racing the beam. They are not "tricks." They are essential - if you want to write an NES program that does anything beyond merely displaying an image to the screen, you will race the beam. Because Hblank and VBlank are where the entirety of any "live" computation occurs.

As an example - want to poll your joystick? Plex the input? You better be racing the beam, then.

"Racing the beam" isn't exotic in the realm of old school programming. It was expected and mandatory.
But that's not correct. Want to poll the joystick on NES? Just do it any time you want, there is no timing involved. You can do it while the screen is being drawn, doesn't matter. You *never* have to worry about hblank on NES, in fact the system doesn't even have an easy way to detect if it's in hblank unless your cartridge has special mapper chips in it that adds that functionality. All developers *had* to worry about, is "is the screen being drawn, then don't update graphics", meaning you update graphics after the current frame is done. You aren't "racing the beam", you don't even really have to "race the frame" ;)
 
But that's not correct. Want to poll the joystick on NES? Just do it any time you want, there is no timing involved. You can do it while the screen is being drawn, doesn't matter.

This isn't true. While the screen is being drawn, the CPU is in use and you can't do any other computation, period. These aren't multitasking machines, they perform one action at a time, period. This is WHY you race the beam - to give the illusion of doing simultaneous actions. You perform things in hblank that you want to give the appearance of happening simultaneously with drawing to the screen.

You *never* have to worry about hblank on NES, in fact the system doesn't even have an easy way to detect if it's in hblank unless your cartridge has special mapper chips in it that adds that functionality. All developers *had* to worry about, is "is the screen being drawn, then don't update graphics", meaning you update graphics after the current frame is done.

And the vast majority of NES games used mappers because "racing the beam" is essential to creating games of the complexity one would expect.

The vast, vast, vast majority of C64 games used sprite multiplexers like I described on the last page. If you were a professional C64 game developer, you were expected to race the beam. It was just part of the territory. Everybody used the technique.
 
This isn't true. While the screen is being drawn, the CPU is in use and you can't do any other computation, period. These aren't multitasking machines, they perform one action at a time, period. This is WHY you race the beam - to give the illusion of doing simultaneous actions. You perform things in hblank that you want to give the appearance of happening simultaneously with drawing to the screen.
But that's where you are incorrect. The NES (and pretty much all other systems) have two chips, a CPU and PPU (known these days as GPU). While the PPU is drawing the screen, your game code is still running on the CPU, doing whatever you want. You don't have direct control over the PPU, it spends its time automatically drawing the screen for you. No matter what you do, it will draw the screen using data that you set up, so all you have to worry about is not altering data that the PPU is currently accessing (unless you *do* want to do special tricks).
 
But that's where you are incorrect. The NES (and pretty much all other systems) have two chips, a CPU and PPU (known these days as GPU). While the PPU is drawing the screen, your game code is still running on the CPU, doing whatever you want. You don't have direct control over the PPU, it spends its time automatically drawing the screen for you.

This is simply incorrect. Retro VDPs and PPUs are not the functional equivalent of a GPU. They don't work in parallel like you are describing. They are more like interfaces to television hardware than independent graphics processing units. When they are drawing to the screen, the CPU is in use.

No matter what you do, it will draw the screen using data that you set up, so all you have to worry about is not altering data that the PPU is currently accessing (unless you *do* want to do special tricks).

Yes, it'll draw in fixed intervals automatically. And while it's drawing, to ensure this timing dependence, the CPU is in use preparing the next raster line.
 
This is simply incorrect. Retro VDPs and PPUs are not the functional equivalent of a GPU. They don't work in parallel like you are describing. They are more like interfaces to television hardware than independent graphics processing units. When they are drawing to the screen, the CPU is in use.
But, um, they do. I know what I am talking about - here is the NES game I am currently programming:

3n7ZlTc.jpg


The NES CPU and PPU are entirely separate and do their own things. You can set an interrupt to be called when the PPU enters VBlank (when it's done drawing the screen) called NMI, so that you know when that happens so you can update graphics without having to worry about what the PPU is doing. But other than that, you can do whatever in the CPU, whenever you want; most game logic is done while the screen is being drawn.
 
I'm probably more impressed with the techniques used for 8/16 bit games than I am for modern games. Not to discount modern developer's hard work, but NES developers had so little frame of reference or options, yet managed to pull off some really incredible things that people still utilize in games today.
 
But, um, they do. I know what I am talking about - here is the NES game I am currently programming:

3n7ZlTc.jpg

And you're telling me, in this application, you poll while drawing to the screen? That, while the PPU is in use, you execute commands on the CPU independent of preparing the next raster line?

Because that's not how these systems work. This is the entire reason hblank exists in the first place. And, while nintendo hardware is not my expertise by a long shot, I have more than a passing knowledge of Sega VDP hardware:

cydoLHa.png


Here I am emulating the VDP back in 2007.
 
This is simply incorrect. Retro VDPs and PPUs are not the functional equivalent of a GPU. They don't work in parallel like you are describing. They are more like interfaces to television hardware than independent graphics processing units. When they are drawing to the screen, the CPU is in use.

Unless there's some terminology misunderstanding here, Dreamwriter is correct. On the NES you can absolutely do calculations and make changes in memory as the screen is being drawn.

You have to wait for VBLANK to be able to make any changes to the PPU data, because if you mess with it while the screen is being drawn all kinds of weird things can happen, since you don't know where you're at on the screen without extremely precise timing.

While the screen is being drawn is the perfect time to do non-graphics calculations, and then as soon as VBLANK hits you quickly switch gears and make any graphical changes you need to do.

In fact a technique I learned from others that I've used in my own demos is to turn on the greyscale effect bit as the screen starts being drawn, do all your calculations, and then turn the bit back off. This results in some amount of the top of the screen to be drawn in greyscale, as sort of a percentage meter for how much time you have left to do calculations before the next VBLANK.

My demo (really old by now):

reN8ZNR.png


Actually I forgot, that's a bit different from what I described...the start of the white stripe is when I was done with calculations, then I just spun on a loop for a while and turned greyscale back off, so it just leaves a stripe instead of turning a huge chunk of the screen greyscale.

So it shows that I've used ~10% of my CPU time on the basic engine. It dips lower when you move around due to physics calculations.
 
Unless there's some terminology misunderstanding here, Dreamwriter is correct. On the NES you can absolutely do calculations and make changes in memory as the screen is being drawn.

You have to wait for VBLANK to be able to make any changes to the PPU data, because if you mess with it while the screen is being drawn all kinds of weird things can happen, since you don't know where you're at on the screen without extremely precise timing.

While the screen is being drawn is the perfect time to do non-graphics calculations, and then as soon as VBLANK hits you quickly switch gears and make any graphical changes you need to do.

In fact a technique I learned from others that I've used in my own demos is to turn on the greyscale effect bit as the screen starts being drawn, do all your calculations, and then turn the bit back off. This results in some amount of the top of the screen to be drawn in greyscale, as sort of a percentage meter for how much time you have left to do calculations before the next VBLANK.

My demo (really old by now):

reN8ZNR.png


Actually I forgot, that's a bit different from what I described...the start of the white stripe is when I was done with calculations, then I just spun on a loop for a while and turned greyscale back off, so it just leaves a stripe instead of turning a huge chunk of the screen greyscale.

So it shows that I've used ~10% of my CPU time on the basic engine. It dips lower when you move around due to physics calculations.

If this is indeed the case, then Nintendo's PPU works drastically different from Sega's VDP - because the hblank driven style I am speaking about is how all of Sega's VDP driven hardware works, from the master system upward.
 
Some NES games even dared to mess with the PPU while the screen was being drawn, though again it required really precise timing. For example, bank switching to show different graphics in a lower section of the screen, so you could have a more complex status bar.

Noah's Ark uses the same method I showed above to simulate the effect of rising water, just flipping an "effect" bit that changes all the colors.

https://www.youtube.com/watch?v=43pmwBwBoHs

gi2QqKS.jpg
 
Some NES games even dared to mess with the PPU while the screen was being drawn, though again it required really precise timing. For example, bank switching to show different graphics in a lower section of the screen, so you could have a more complex status bar.

Noah's Ark uses the same method I showed above to simulate the effect of rising water, just flipping an "effect" bit that changes all the colors.

https://www.youtube.com/watch?v=43pmwBwBoHs

gi2QqKS.jpg

Why wouldn't this effect work during hblank? Why would it need to occur during drawing (The noah's ark example, specifically).
 
In fact a technique I learned from others that I've used in my own demos is to turn on the greyscale effect bit as the screen starts being drawn, do all your calculations, and then turn the bit back off. This results in some amount of the top of the screen to be drawn in greyscale, as sort of a percentage meter for how much time you have left to do calculations before the next VBLANK.

My demo (really old by now):

reN8ZNR.png


Actually I forgot, that's a bit different from what I described...the start of the white stripe is when I was done with calculations, then I just spun on a loop for a while and turned greyscale back off, so it just leaves a stripe instead of turning a huge chunk of the screen greyscale.

So it shows that I've used ~10% of my CPU time on the basic engine. It dips lower when you move around due to physics calculations.

Heh, I just to do pretty much the same thing on GBA; switch the bg color when my processing was done for a basic profiling tool.

And yes that's how it works on all nintendo 2D hardware as far as I know. Unless you want to do some special effects during hblank, such as raster scrolling, palette changes, perspective scaling with mode 7 etc, the CPU was free to do whatever while the screen was drawing.

And if Sega hardware couldn't just sounds odd to me; there's got to be some misunderstanding
 
Why wouldn't this effect work during hblank? Why would it need to occur during drawing (The noah's ark example, specifically).

If you're going to mess with the PPU "live" it's certainly best to wait for HBLANK so you don't get glitchy lines in the middle of the screen at the point where you make changes. In most cases they probably did, so maybe these examples aren't the most convincing. My own demo doesn't wait for HBLANK because you have to keep precise timing from the start of VBLANK and I couldn't be arsed, it's just a meter for my own use that would be taken out of a finished game.

The NES doesn't have any built in timers for this sort of thing, all you get is a VBLANK interrupt so that's the only instant you can be sure of what the PPU is doing at that moment. If you want to do anything on a specific HBLANK you have to count cycles from there, run CPU commands with precise cycle use etc.

That's how NES games did parallax as well. You might notice that NES parallax games often seem to have simpler engines, because you have to be so meticulous counting cycles down the screen to do a split during HBLANK that you don't have time for anything else. Either that, or you could use timers introduced in later cartridge configurations/mappers. Some games like Return of the Joker use their parallax really high on the screen so it doesn't intrude so much on their CPU time.

Homebrewers have made a few demos doing a vertical screen split, timing their scroll changes to happen in the middle of a horizontal line draw, but that takes such precision that it's not really practical for anything.
 
If you're going to mess with the PPU "live" it's certainly best to wait for HBLANK so you don't get glitchy lines in the middle of the screen at the point where you make changes. In most cases they probably did, so maybe these examples aren't the most convincing. My own demo doesn't wait for HBLANK because you have to keep precise timing from the start of VBLANK and I couldn't be arsed, it's just a meter for my own use that would be taken out of a finished game.

The NES doesn't have any built in timers for this sort of thing, all you get is a VBLANK interrupt so that's the only instant you can be sure of what the PPU is doing at that moment. If you want to do anything on a specific HBLANK you have to count cycles from there, run CPU commands with precise cycle use etc.

That's how NES games did parallax as well. You might notice that NES parallax games often seem to have simpler engines, because you have to be so meticulous counting cycles down the screen to do a split during HBLANK that you don't have time for anything else. Games like Return of the Joker use their parallax really high on the screen so it doesn't intrude so much on their CPU time.

Homebrewers have made a few demos doing a vertical screen split, timing their scroll changes to happen in the middle of a horizontal line draw, but that takes such precision that it's not really practical for anything.

later NES games used an on cart memory mappers which had a raster counter, so you didn't have to waste cpu resources. and the first scene in the batman video is done by bank switching rather than raster scrolling
 
later NES games used an on cart memory mappers which had a raster counter, so you didn't have to waste cpu resources. and the first scene in the batman video is done by bank switching rather than raster scrolling

Yeah, I edited in about the timers. And you got me on Batman, I always forget that. :P They bankswitch it as an animation so that buildings can appear to overlap it.
 
Come to think of it, the infamous C64 loading routine of randomized colored bands:

ycwkJRF.gif


Was done mid-draw because it could be done in a single command, and programmers would place the call at the ends of block loading subroutines to let them indicate that they were still loading from tape, which could freeze.

So now I'm wondering if the quirks I'm describing and heavy reliance on hblank is something just common with Sega machines. Sega's VDP has evolutionary roots back to the colecovision, so perhaps this is just a vestigial leftover from the very old days.

Regardless, I do lots of race the beam style programming, and every other retro programmer I know is versed in the practice.
 
And you're telling me, in this application, you poll while drawing to the screen? That, while the PPU is in use, you execute commands on the CPU independent of preparing the next raster line?
Exactly - the NES vblank period (the time between frames) isn't actually very long at all, so your game logic ends up doing stuff while the screen is being drawn pretty quickly. If it had to do everything during hblank between scanlines, that'd be horrible, because there's just a tiny, tiny amount of time to do anything there. In fact, a common way to do scanline effects is to have a loop running on the CPU just waiting for the screen to get to where you want it to be (usually waiting for a sprite to set a flag saying it was on top of a particular background pixel).

Admittedly, quite a lot of NES games *do* use some basic scanline effects - for example, The Legend of Zelda changes scrolling values while the screen is being drawn so that it can have a HUD at the top of the screen that stays still while the screen scrolls vertically. And my NES game is doing that too now. But the system is setup for that to be the exception, not the rule - the NES in fact makes it darn hard to do scanline effects.
 
Homebrewers have made a few demos doing a vertical screen split, timing their scroll changes to happen in the middle of a horizontal line draw, but that takes such precision that it's not really practical for anything.

This was just about the only reason I could think one would want to mess with something like that mid scanout. It's neat to hear someone has actually pulled it off. Do you have any links to such an example?

I saw a topic recently about "retro style games" or whatever, and someone posted a gif of a game that featured some train segments separating, and people were complaining that something of that sort couldn't be accomplished on actual NES hardware. Well, the dev was a demoscene coder in the NES hacking scene, and he cryptically said it could have been done "with a large cartridge." Assuming the CPU/drawing limitation I mentioned before, I thought he just meant relying on bankswitching the entire background like a huge flip book, with one half of the background being devoted to each train segment (hence the huge cart part), but now I'm wondering if someone could pull it off with vertical screen splitting...
 
Definitely possible, but freaking hard because of how NES scrolling works - if you are updating scrolling mid-scanline, you have to set four bytes to change the scroll position (rather than just X and Y like you do normally), and some of the scroll changes start to happen as you write the bytes. So there would probably be a bit of corruption. You'd probably want the scroll values pre-calculated and stored in RAM before the screen got to the lines where the split happens.
 
Top Bottom