This will be for a video I'm making so I need to explain in simple terms for the average person to understand, but I'm curious anyway to learn how Graham Stafford and David Fish (coders of) "The Living Daylights" game pulled off getting more than the standard 4 colours of Mode 1 - in fact 8 colours ALSO along with parallax scrolling. Despite the gameplay not being that good, I think it's actually really very impressive! And deserves more recognition and praise.
(https://www.cpc-power.com/extra_lire_fichier.php?extra=fiches&fiche=1307&slot=1&part=1307_mode1plus2.png)
CPC-Power website (https://www.cpc-power.com/index.php?page=detail&num=1307) says it's by the use of "rasters" that it's gone beyond the use of 4 colours, but reading the CPC Wiki page (https://www.cpcwiki.eu/index.php/Rasters) I can sort of understand a bit how it may be done in demos for nice coloured bars maybe... but I'm struggling to understand or see how that would apply to more complex scrolling background objects in a game such as this one.
If you look at a video of the game or attached screenshot - the main game window looks like it's "split" but it has 3 different layers scrolling, eg the top mountains which include enemy sprites popping up and down shooting, the middle area with Bond running, and the smaller bottom area with green bushes moving past quickly - giving a very nice parallax effect overall.
Are these 'screen splits'? You've then got the HUD below with the score, lives, energy, etc so that would mean even more splits.
How is this all done to give more colours in Mode 1 and why didn't more coders do this in their games? :)
In simple terms so non-coders can understand! Thanks in advance!
Yeah, they're "rasters", i.e. carefully timed changes of the colour palette so that different sections of the screen appear to be different colours. It's not a particularly advanced technique, but there are some limitations:
- There are only a few fixed positions you can wait for (except on a Plus) so you have to either carefully design the changes around those points or wait for one and then burn a lot of CPU cycles to get the change to happen where you want.
- Because the rasters scans left to right, top to bottom, you can really only achieve horizontal bands of colours so you have to design things around that. This tends to restrict how things can move on the screen to avoid them crossing the boundaries which would cause them to change colour. The very limited movement in Living Daylights (probably because it was designed to be a light gun game on other platforms) makes this easier.
It's possible that it's also doing "screen splits" aka "ruptures". That's about changing the screen address for certain (again horizontal) portions of the screen. That lets you do things like hardware scroll different sections while keeping some bits static. It's quite an advanced technique though and was often shied away from by commercial teams for fear it might cause issues on some displays (since it's basically abusing the CRTC timing)
You can change the colours at any time by simply setting a new colour value. The effect is immediate. If you're midway through the frame, the colour will change midway through the frame. If you keep doing this every frame at the same time, you have a colour split.
The trick is with the timing. The CPC won't actually tell you what scanline is currently being drawn. However, it does have an interrupt that goes off every 300th of a second - 6 times per frame, or every 52 scanlines - which you can sync to. It's fairly easy to write some code that changes the colours at any one of these interrupt points, giving you up to six colour splits. You can leave this code running on the interrupt and once it's initialised you can pretty much ignore it. That's the easiest way. A lot of games do this to put a split between the play area and the score panel.
You can change colours at other times besides the interrupt points, if you have some code that always takes exactly the same amount of time each frame so that you know exactly where you are. Because again, the CPC annoyingly won't tell you. If you don't keep the timing the same every frame, the location of your split will jitter around.
The scrolling here is probably an ordinary software scroll, so no complicated rupture effect is needed.
The colour does look particularly nice in The Living Daylights. IIRC the title screen also uses some line-by-line colour changes.
From the colour point of view, it might help to look at the video memory for understanding. It is all in normal mode 1's 4 colours, so you can see from the video memory that it's just the 4 colours being changed at points in the screen.
I've also added a screen of the display with Winape having interupts highlighted in blue. You can see from those the 6 interrupts per frame haven't fallen exactly where they want the colour changes, so they have extended them (paused or other code) to be able to make the colour changes where they want. The 1st colour set will most likely be on the first interrupt, which is above the frame. I've added the numbers 2-4 where during those interrupts they will have changed the colours.
Also from the video memory image, you can see a large gap between the player sprite and the bushes below, along with the level name text that is no longer visible on the screen, so it does appear they are using screen splits. Though I had assumed they were because the game has had trouble with some emulators in the past, I think the split hasn't got the timing quite right. Scratch that, I just checked it in AceDL, and it is showing the screen is 304 lines high instead of the 312 it should be.
Update: I scrolled along and you can see the images in video memory have now offset from the base in the extra image I just added. It appears to be using that large amount of space that was initially there to allow it to scroll a number of screens without worrying about screen address reset (guessing, not checking code). I think it is probably doing something different with the bushes part at the bottom. But it does appear each scrolled section is in hardware.
And there's a smaller gap between the bushes and the score panel in the memory map... so I am guessing that they are using a hardware scroll just on that foreground layer of bushes.
Oop, I see in your updated picture it is indeed all layers.
Quote from: Anthony Flack on 09:11, 02 April 25You can change colours at other times besides the interrupt points, if you have some code that always takes exactly the same amount of time each frame so that you know exactly where you are. Because again, the CPC annoyingly won't tell you. If you don't keep the timing the same every frame, the location of your split will jitter around.
The scrolling here is probably an ordinary software scroll, so no complicated rupture effect is needed.
Interestingly there is some 'jitter' between the top background layer, and the middle 'Bond' layer... (if you look closely)
Quote from: Axelay on 09:14, 02 April 25From the colour point of view, it might help to look at the video memory for understanding. It is all in normal mode 1's 4 colours, so you can see from the video memory that it's just the 4 colours being changed at points in the screen.
I've also added a screen of the display with Winape having interupts highlighted in blue. You can see from those the 6 interrupts per frame haven't fallen exactly where they want the colour changes, so they have extended them (paused or other code) to be able to make the colour changes where they want. The 1st colour set will most likely be on the first interrupt, which is above the frame. I've added the numbers 2-4 where during those interrupts they will have changed the colours.
Thanks Axelay! So for my understanding, the top game screen area between interrupt 1 and 2 ("interrupt" is the same as "screen split" or "rupture" as Andy described above right?) is doing the following ->
(1) Initially in purple, white and orange (ignoring black here) like the rest of the main screen (in Mode 1)
(2) They have carefully timed 'raster' code that scans down and...
(3) Where it finds 'white' flips it to 'yellow' (for the mountain)
(4) Where it finds 'orange' flips it to 'grey/green'
etc
Am I on the right track here?
So it IS using ruptures, which is more complicated than just changing colours.
This is how you trick the CRTC into hardware scrolling only part of the screen (which it believes it can't do):
Basically, instead of setting the CRTC registers to output a regular PAL video frame at 50hz and leaving it alone to do its job (as you normally would), you disable vsync, then tell it to output a much smaller screen fragment. Then when it gets to the end of that you send it updated values to draw a second one, or a third, and so on, and providing you get all the timing right the whole thing will add up to something that resembles the timing for a complete PAL frame at the end. Then you trigger vsync and hope your monitor doesn't notice any difference.
This involves a bit of doing things manually that the CRTC would ordinarily handle automatically for you, like maintaining vsync.
Pardon my interjection, but interrupts are not the same thing as screen splits... however the interrupt is useful for timing.
Interrupt is just a trigger that goes off every 300th of a second but it's the fastest clock you can sync to on the CPC, and you can also tell the Z80 to stop whatever it's doing and run a particular bit of code - automatically - every time the interrupt goes off. So it's handy to put your screen split code on the interrupt. It will run independently of your main game code and maintain the correct timing.
...more or less; there are some complicating factors but that's the general idea.
I think the best way to think of rasters is that they are changes to the *palette* that can occur anywhere as the electron beam scans across the screen. You can change the background colour or any of the inks (just as the border and ink commands do in BASIC for the whole screen). It takes a little time to select which you want to update and a little time to change the colour so that limits the number of changes you can make to about one every inch or two. If you make no further changes the palette remains until the beginning of the next frame when you must provide them all over again (unlike in BASIC where the firmware handles this for you).
Interrupts are a way to temporarily suspend your code at a regular point to allow you to change the palette. Without them you must carefully time your code to a precise number of clock cycles to hit the exact point in time that the electron beam that you need. It is hard to write code that way so those effects are mostly done in demos.
I keep imagining that I will make some explainer videos on this stuff as part of my demo channel but having started trying to make one on displaying graphics I'm not enjoying the process of making explainer so far and it's a bit of a drag :-(
Thank you Anthony and Interrupt! (Quite an apt name for this topic! :D )
So "The Living Daylights" is basically using a mixture of rasters, interrupts and rupture/screen splits then! All 3?
I'm hoping someone could give a simple breakdown/overview of what's happening there and what Graham/David have done.
So far from my understanding it seems like ->
(1) They've started by using several rupture/screen splits (4? 3 in the main game area and 1 for the HUD at the bottom), then...
(2) They can use that for the hardware scroll for the 3 areas in the game window using the CRTC chip. I believe you use the registers in the CRTC chip - R3 isn't it for horizontal sync? And R12 and R13 to define the start address (checking old notes)
(3) They've then used 'interrupts' to help with timing roughly around the areas of the ruptures/screen splits to do the rasters/colour changes...
(4) And as Interrupt described above, using rasters they done palette colour changes on each rupture/screen split area to give up to 8 colours in game
Am I roughly right there / on the right lines?
I would say it starts with interrupts, as these are what are being used to implement the multiple screens (ruptures, and it does look like 4 screens) and the colour changes.
They wont be using R3 for the scrolling though, only R12/13. R3 is for scrolling in half character steps, but I am not aware of a way you can use different R3 settings on directly adjacent screens. Also, looking closely at the slowest scrolling section at the top of screen, it appears to be scrolling in character steps which only needs R12/13, so it looks like it would be scrolling slower by moving half as often rather than half the step as the section below.
Quote from: Xyphoe on 12:00, 02 April 25Thank you Anthony and Interrupt! (Quite an apt name for this topic! :D )
So "The Living Daylights" is basically using a mixture of rasters, interrupts and rupture/screen splits then! All 3?
I'm hoping someone could give a simple breakdown/overview of what's happening there and what Graham/David have done.
So far from my understanding it seems like ->
(1) They've started by using several rupture/screen splits (4? 3 in the main game area and 1 for the HUD at the bottom), then...
(2) They can use that for the hardware scroll for the 3 areas in the game window using the CRTC chip. I believe you use the registers in the CRTC chip - R3 isn't it for horizontal sync? And R12 and R13 to define the start address (checking old notes)
(3) They've then used 'interrupts' to help with timing roughly around the areas of the ruptures/screen splits to do the rasters/colour changes...
(4) And as Interrupt described above, using rasters they done palette colour changes on each rupture/screen split area to give up to 8 colours in game
Am I roughly right there / on the right lines?
Yes.
I will call out the rupture part as the cleverest bit as this is something most coders at the time didn't do.
Colour changing was common, R12/R13 for hardware scroll was done in quite a few games, but rupture very very few.
I would love to know why they chose this and where they found out about it.
One coder I asked who used rupture in a game did it 'to save memory' and didn't remember where they had heard of it from.
Also to add to this, changing colours and doing rupture must be done every frame (50Hz) to maintain the display regardless of the speed the actual gameplay is running at.
This is my basic understanding and as I haven't yet coded any ruptures I'm going on what is written above and my background reading over the years. The CRTC and palette information has to be updated every frame (50hz) for stable "ruptures". Everything is being updated as the electron beam is in motion.
There are six interrupts available per frame (see Axelay's screenshot). When an interrupt happens an interrupt handler is called. On each call to the interrupt handler you do something different. Once you return from the handler your game code continues as before.
On some of the interrupt handler calls that involves telling the CRTC to believe it is starting an entirely new screen that is a smaller height than a full screen. This is a "rupture" in what would otherwise be a standard continuous screen. At that time you also change the palette.
They will have needed to do this 4 times (I think) - interrupt 1 for the sky, interrupt 2 for the ground, interrupt 3 for the bushes and interrupt 4 for the status panel. See Axelays images.
The interrupt timings are fixed so if the interrupt doesn't occur at the right place on the screen for your need (Axelay shows they don't for this game) you have to either execute enough "no operation (NOP)" instructions to wait until the electron beam is in the right place or you have to do something else that takes the same amount of time. This code is hard to write as both paths for optional conditions (if A then do X else do Y) must take the same amount of time or your timing will be unstable. Without disassembling we won't know which choice they are making where. The gap to get from interrupt 3 to the right place for the bushes seems like a long time to just sit doing nothing.
Does that help?
There is a lot production with this trick:
https://www.cpc-power.com/index.php?page=database&lemot=MODE1_special
If I had to do this, for me the easier way would be this:
- Try to make fixed duration (or relatively fixed) code blocks, like for painting sprites, detect collisions, painting UI, etc
- Not using the interrupt handler (that adds a lot of uncertainty).
- Run some code blocks that I know won't take more than 3328 us (the time between interrupts)
- Wait for raster to be in next screen block with HALT
- Set the palette for that new block
- Start over again
That's what I do, for instance, to have a lot of colours in mode 1 in the Acon 2020 menu screen. The drawback is that it waste some CPU time waiting but it may be enough for some games.
That's the other way to do it... put the splits inline with your main code, which you can do if you know your code will take the same amount of time each frame. Examples in demos using many more ruptures by doing them inline and writing code with exact timing.
As Abalore says you also have the option to HALT at any time and just wait for the next interrupt to come along, but we hate to waste CPU time doing nothing. But this is actually what you have to do to get your timing 100% perfect.
The way interrupts work, the interrupt call only happens AFTER the CPU finishes its current instruction, and instructions don't all take the same amount of time. So the interrupt can end up being delayed by a small amount, depending on what exactly it is doing when being interrupted... causing a small timing jitter.
However with a HALT instruction, you always know exactly what you're doing - halting - so when the interrupt hits and your code resumes, you know you are exactly synced with the interrupt, therefore no jitter.
Trouble is, when it's inline you have to keep this loop going all the time, no matter what your code is doing, and it has to be at 50hz. If your code fails to complete before the interrupt it's supposed to halt for, it will wait for the next one instead, and all the timing will break. Losing the colour changes for a frame or two might not be a complete disaster, but if you mess up the timings for a rupture, your image will lose vsync and the picture will roll...
This is all because there is no way for the CPC to check what the exact time is. The CRTC knows, but those values are internal and hidden from the CPU. The only thing you can do to check the time is to wait for the next interrupt pulse to occur, and then count cycles from there.
You can see where the interrupts are occurring in WinAPE - when you tell it to display interrupts, it turns the border blue every time the interrupt is called, and then back to normal once the interrupt is returned from - making those blue stripes in the border of the images above. If you read the screen like a graph, with the top of the screen being the start of the frame and the bottom of the screen being the end, all the blue sections represent the times when the main code has been interrupted. So we can see that the splits in this case are happening on the interrupt.
Since I know Xyphoe is a Plus man like myself, it's also just worth mentioning that two of the most useful additions to the Plus were the Programmable Raster Interrupt (PRI) and Split registers. The PRI lets you do away with all the "six interrupts at fixed position" nonsense and just let you tell the hardware "I want the next interrupt to occur on line X" - which makes many of the timing issues with colour changes go away. The Split register is even more powerful, since it lets you do roughly the same thing as a rupture split automatically, by just telling the hardware what line you want it in and what address to start fetching screen data from. Whilst the code for Living Daylights probably took days, if not weeks, of skilled coding to get right you could probably knock up the equivalent on a Plus in half an hour, even if you were only a mediocre developer.
And yet people just think it was just some extra colours and some hardware sprites...
Quote from: Anthony Flack on 02:40, 03 April 25That's the other way to do it... put the splits inline with your main code, which you can do if you know your code will take the same amount of time each frame. Examples in demos using many more ruptures by doing them inline and writing code with exact timing.
As Abalore says you also have the option to HALT at any time and just wait for the next interrupt to come along, but we hate to waste CPU time doing nothing. But this is actually what you have to do to get your timing 100% perfect.
The way interrupts work, the interrupt call only happens AFTER the CPU finishes its current instruction, and instructions don't all take the same amount of time. So the interrupt can end up being delayed by a small amount, depending on what exactly it is doing when being interrupted... causing a small timing jitter.
However with a HALT instruction, you always know exactly what you're doing - halting - so when the interrupt hits and your code resumes, you know you are exactly synced with the interrupt, therefore no jitter.
Trouble is, when it's inline you have to keep this loop going all the time, no matter what your code is doing, and it has to be at 50hz. If your code fails to complete before the interrupt it's supposed to halt for, it will wait for the next one instead, and all the timing will break. Losing the colour changes for a frame or two might not be a complete disaster, but if you mess up the timings for a rupture, your image will lose vsync and the picture will roll...
This is all because there is no way for the CPC to check what the exact time is. The CRTC knows, but those values are internal and hidden from the CPU. The only thing you can do to check the time is to wait for the next interrupt pulse to occur, and then count cycles from there.
You can see where the interrupts are occurring in WinAPE - when you tell it to display interrupts, it turns the border blue every time the interrupt is called, and then back to normal once the interrupt is returned from - making those blue stripes in the border of the images above. If you read the screen like a graph, with the top of the screen being the start of the frame and the bottom of the screen being the end, all the blue sections represent the times when the main code has been interrupted. So we can see that the splits in this case are happening on the interrupt.
Just one clarification, if you use double buffer the game doesn't need to run at 50 fps. You just need to set the inks in the proper places but you can switch the buffers after several passes.
Quote from: abalore on 11:23, 03 April 25Just one clarification, if you use double buffer the game doesn't need to run at 50 fps. You just need to set the inks in the proper places but you can switch the buffers after several passes.
Not if you're using Ruptures or colour rasters. They need to happen on every frame (regardless of whether you redraw anything) or the display will corrupt. Double buffering doesn't change this.
Quote from: andycadley on 15:16, 03 April 25Quote from: abalore on 11:23, 03 April 25Just one clarification, if you use double buffer the game doesn't need to run at 50 fps. You just need to set the inks in the proper places but you can switch the buffers after several passes.
Not if you're using Ruptures or colour rasters. They need to happen on every frame (regardless of whether you redraw anything) or the display will corrupt. Double buffering doesn't change this.
I think you didn't understand a single word of what I said, because I said the same than you. You need to respect the timings for ink changes and ruptures, but you don't need to draw the whole screen in a single frame, can take all the frames you want
We all know how it works so we're not in disagreement, but everybody loves the opportunity to explain. It's rare to find somebody who doesn't know how to code already, who isn't bored to hear about it.
I should say that the game can update at whatever speed you like, but all all that raster malarky has to run on a 50hz loop without fail. So if your game loop is locked to 25hz, all the raster stuff will turn up twice in each game loop.
In this case TLD appears to have all the raster stuff running on the interrupt, so the main game code can ignore it and is free to drop frames whenever it cares to.
Also, this makes way more sense as a light gun game. I didn't know that was the idea.
Quote from: Anthony Flack on 01:46, 04 April 25Also, this makes way more sense as a light gun game. I didn't know that was the idea.
We don't know for sure.
The ZX Spectrum version of The Living Daylights which also came out in 1987 looks and plays very similar, it was coded by the same guys (Graham Stafford & David Fish) and likely co-developed at the same time.
The ZX Spectrum also later got a light gun version of the game which was bundled with Amstrad's new +2A versions of the Speccy for Xmas '89... (and it was rubbish) was it Amstrad's intentions all along and they had a word with Domark to make sure they could turn their Bond game into something that would be 'light gun compatible' down the line? In time for a relaunch/refresh of Amstrad/Spectrum computers seeing as Amstrad had just bought out Sinclair? But which took 2 years to happen? But never on the CPC?
Speccy light gun version ->
https://www.youtube.com/watch?v=-0XFJQQaDJ0
(Although the Speccy, to the best of my knowledge, doesn't have an internal video chip like the Amstrad's CRTC - it has 16K of RAM that the CPU can access, which means quickly porting would be an issue, especially when the CPC version utilised the CRTC chip...)
Here's a timeline...
1986 -> Amstrad bought out Sinclair
1987 -> Amstrad and ZX Spectrum versions of The Living Daylights Released
ALSO Magnum Light Phaser Released - Maybe Amstrad knew they could do something with this and the game?
Xmas 1989 -> The James Bond 007 Action Pack for the Spectrum +2A with the light gun modified The Living Daylights (as "Mission Zero") released
https://www.mi6-hq.com/sections/games/james-bond-007-action-pack
Who knows. A lot of speculation on my part.
Quote from: andycadley on 08:49, 02 April 25That lets you do things like hardware scroll different sections while keeping some bits static. It's quite an advanced technique though and was often shied away from by commercial teams for fear it might cause issues on some displays (since it's basically abusing the CRTC timing)
Absolutely.
Besides, "The Living DayLights" suffers from a compatibility issue related to its rupture on CRTC 1.
It works as expected on other CRTCs.
This can be seen in two screenshots presented in this article about the Compendium (sorry, in French).
On the screenshot (CRTC 1) we can see that the HUD appears prematurely, and therefore when the palette has not yet been modified.
https://blog.logonsystem.eu/compendium/
The technical explanation is in the compendium (V1.8 page 235)
https://shaker.logonsystem.eu/ACCC1.8-EN.pdf
Another game "3D STARSTRIKE", published by "Realtime Games Software" in 1985, was developed on CRTC 0.
The developers did not modify the programmed value in ROM for the length of the VSYNC.
This causes a bug during the game on CRTC 1 and 2, because the firing cursor is not in phase with the display and flashes, while this is not the case on CRTC 0, 3 and 4.
Quote from: Interrupt on 13:12, 02 April 25The interrupt timings are fixed so if the interrupt doesn't occur at the right place on the screen for your need (Axelay shows they don't for this game) you have to either execute enough "no operation (NOP)" instructions to wait until the electron beam is in the right place or you have to do something else that takes the same amount of time
As an exception, if interrupts have been disabled for more than 52 lines, an interrupt is pending and occurs when the Z80A allows it.
If this interrupt occurs during the counter areas between 32 and 51, then the next interrupt is delayed by 32 lines.(e.g. bit 5 of R52 is cleared)
Finally, all this is true if we don't play with Hsync frequency.
At the fastest, we can force the Gate Array to issue one interrupt every 104 nops (with one Hsync every 2 µseconds)
(a test in Shaker shows this).
Also playing with the CRTC which generates the HSYNC signal allows you to "manage" an interruption on a given screen line by creating "small lines" during one or two displayed lines.
Quote from: Anthony Flack on 10:00, 02 April 25Basically, instead of setting the CRTC registers to output a regular PAL video frame at 50hz and leaving it alone to do its job (as you normally would), you disable vsync, then tell it to output a much smaller screen fragment. Then when it gets to the end of that you send it updated values to draw a second one, or a third, and so on, and providing you get all the timing right the whole thing will add up to something that resembles the timing for a complete PAL frame at the end. Then you trigger vsync and hope your monitor doesn't notice any difference.
With the RFD (Rupture For Dummies ;D ) technique (see Compendium chapter 11.6), there's no need to build frames or worry about vsync (This requires 4 outs for the entire frame. See 11.6.3).
This technique "force" and "keep" the CRTC's internal state true, allowing R12/R13 to be updated during the whole frame.
But this only works on CRTC 1...
Hi again everyone. So I posted this originally because this was for a video project and to describe what is going on in simple terms for the average person watching - so they could understand too, and maybe learn a little bit themselves as well.
So I've written up a summary, a basis of a script of sorts. How does this sound? Feel free to correct or add anything, some of this I have used some of your words and phrases. Thanks in advance and also thanks everyone so far! It's been a very interesting topic!
The Living Daylights is unusual and fairly unique in that it uses a mixture of clever screen coding techniques to achieve how it looks and moves, very rarely seen combined together in other games. It's setup in Amstrad's "Mode 1" screen mode which is normally limited to a maximum of 4 colours, but here we can see they have actually 8 colours on screen. And also some very nice fast and smooth moving scrolling, with layers of parallax in the background to go with it too! What have they done here to achieve it?
Without access to the original source code we can't know for definite, but with debugging tools and knowledge learned within the community over many years we can make some very accurate guesses.
Firstly it starts with 'interupts'. The Amstrad has an interrupt that goes off every 300th of a second - 6 times per frame, or every 52 scanlines - which you can sync to with it being the fastest clock you can do on the CPC. Interrupts are a way to temporarily suspend the Z80 CPU at regular points and do things with some code. We can see it happening on this screenshot [insert Axelay's screenshot with the blue borders] and they have setup and used 6 interrupts. And it's these interrupts that the coders Graham Stafford and David Fish have used to both place their screen splits (called 'ruptures') and then also change the palette colours within them to give us the 8 colours on screen.
With the palette changes you can see originally this was the usual 4 colours [insert Axelay's video memory screenshot] then rasters were used in each of the screen splits to change the palette within them. More on that shortly.
As for the scrolling this is very difficult to achieve because there's essentially 3 different areas being scrolled here within the ruptures and screen splits - in level 1 the first is the mountains being the slowest, secondly the middle area where Bond is running slightly faster, and lastly the 3rd area at the bottom with bushes scrolling the fastest - for a nicely layered parallax effect.
And it must be using a hardware scroll for this, utilising the Amstrad CRTC video chip. So you first disable vsync (vertical synchronisation) which normally would result in chaos! But with careful coding and timing, you're going to tell the chip (because you've done a rupture or screen split) to output a much smaller screen on one of your interrupts (and of course you've changed the palette colours too just to make things more complex!). Then you move onto the next screen split, and so on - including the HUD (heads up display where the score, lives, etc are) at the bottom. When all that's completed - and fingers crossed you got all your timings correct, you re-enable the vsync and pray the monitor likes it!
For those interested in terms of the hardware scrolling technique being used here, the CRTC chip has registers you can change to define the start address of the screen which are registers 12 and 13, known as R12 and R13 - and it looks like this is what the coders are using here.
So why wasn't all the above used more in other games?
Possibly because it was discovered that it was hard to ensure it worked on all Amstrad CPC models due to different revisions of the CRTC chip. On what is known as CRTC 1 model "The Living Daylights" actually glitches and becomes unstable, and some of the HUD appears in the middle of the game area. It's likely the coders didn't know about this revision and were coding on a CRTC 0, the most common model. By the late 80's this 'bug' or known difference was probably more well known about and coders didn't want to deal with the headache.
Additionally their usage of rasters to change the palette colours in game caused additional complexities on top of the screen splits and ruptures, it meant their game loop code had to run at 50Hz without fail or it would simply fall apart.
Coders under severe time pressure from publishers and their bosses to turnaround games, especially conversions or licenced properties simply wouldn't have time to go to these lengths for their games and would have taken easier routes to complete their projects for a deadline.
Quote from: Xyphoe on 10:19, 07 April 25Additionally their usage of rasters to change the palette colours in game caused additional complexities on top of the screen splits and ruptures, it meant their game loop code had to run at 50Hz without fail or it would simply fall apart.
Seems mostly accurate from a quick read, but this stood out as incorrect. If you are using interrupts to perform the palette changes and ruptures, your game loop can take as many screen refreshes as it likes, even vary between game frames, the interrupts will handle it at 50hz because that is their purpose.
It is only if you choose to do a rupture or palette change without using interrupts, making them part of your 'main code loop' that you need to maintain them 'manually' at a 50hz rate. Even then, your game loop does not need to run at 50hz as such, you could have a 25hz game loop that executes the required colour changes or rupture code at the correct time twice per game loop.
Chibi Akumas has some great pix on the interrupts and Z80 examples on changing screen mode per interrupt(simple to just change the colours using same interrupt code)
https://www.chibiakumas.com/z80/platform5.php#LessonP41
Quote from: Axelay on 11:05, 07 April 25Quote from: Xyphoe on 10:19, 07 April 25Additionally their usage of rasters to change the palette colours in game caused additional complexities on top of the screen splits and ruptures, it meant their game loop code had to run at 50Hz without fail or it would simply fall apart.
Seems mostly accurate from a quick read, but this stood out as incorrect. If you are using interrupts to perform the palette changes and ruptures, your game loop can take as many screen refreshes as it likes, even vary between game frames, the interrupts will handle it at 50hz because that is their purpose.
It is only if you choose to do a rupture or palette change without using interrupts, making them part of your 'main code loop' that you need to maintain them 'manually' at a 50hz rate. Even then, your game loop does not need to run at 50hz as such, you could have a 25hz game loop that executes the required colour changes or rupture code at the correct time twice per game loop.
I think this may have come from my comment. I was coming at it from the perspective that you have to solve the problem of setting the CRTC configuration and palette at exactly the right moment every frame. You can't simply set some registers to configure a permanent split. Interrupts are an easier way to do that but I think that the fact you can't "fire and forget" some settings goes some way to explain the relatively infrequent use of these techniques in games.
I agree with Axelay that the penultimate paragraph isn't quite right - I'd probably just remove it as I think that by the time it is corrected it won't add much.
In my opinion, the text looks good now (with the suggested change).
One additional observation about the game, an idea that was new to me and that is quite interesting: In the screenshot of the video memory we see a big gap between the mid scrolling layer and the lower scrolling layer. In this gap still the level name is visible. The upper scrolling layer moves slow, the mid scrolling layer moves faster. So the slower layer will never catch up with the faster layer. But the faster layer eventually will arrive at the status/HUD. The gap gives it some space so that it can scroll for some time (until the end of the level) without collision.
A similar trick could have been done to the mid scrolling layer and the lower scrolling layer. The problem here is that the lower scrolling layer moves so fast that it would consume the whole gap in half of the time. Then the levels would be quite short. So it seems here another trick has been used (but I'm not sure about which one).
What was new to me: My first idea would be to distribute each scrolling layer to its own 16K memory page. Then there wont be any collision (because of the wiring of the CRTC). But with three scrolling layers also three out of four memory pages would be in use, and the last one would be needed for the non-scrolling status/HUD and all the program, sprite data, music, and sound effects. This would not be an effective use of memory, because in the three memory pages for the scrolling layers most of the available memory would be unused (but never the same part, so it cannot be used for anything else but for temporary data). The trick described above solves this problem. It only cannot scroll forever, but only for a limited time. If the game is split into several levels, this is perfectly ok.
Thank you everyone!
I think then, it would be fine to just end and leave it with ....
"Additionally their usage of rasters to change the palette colours in game caused additional complexities on top of the screen splits and ruptures.
Coders under severe time pressure from publishers...."
Just chop off the "it meant their game loop code had to run at 50Hz" bit which was incorrect. Yea?
Cheers!
Yeah, I think some of the wider conversation complicated things more than they needed to be. The rupture/colour change code does need to run at 50hz, and synced to the monitor. But putting it on the interrupt already takes care of that.
The interrupt is handy for triggering anything you want to happen at a regular interval, somewhat independently of your main code. Most games that use a colour split will do it on the interrupt and that was something coders used right from the early days (eg Sorcery, Jet Set Willy). In Frank N Stein you can very clearly see colour changes happening at each interrupt, with visible timing glitches as they change colour mid-line.
What is most remarkable about The Living Daylights for the time is the parallax hardware scrolling using ruptures, which was much less well understood.
Quote from: Xyphoe on 10:19, 07 April 25It's likely the coders didn't know about this revision and were coding on a CRTC 0, the most common model. By the late 80's this 'bug' or known difference was probably more well known about and coders didn't want to deal with the headache.
At the end of the 1980s, the various CRTC models were just beginning to be identified.
I think it was difficult to be exhaustive on this subject without knowing the components ordered by Amstrad.
We had to investigate numerous CPCs (our own and those of the A100% editorial team) to get a clearer idea.
From memory, the most notable difference experienced by some game programmers was the loss of monitor Vsync with the CRTC 2.
The first fullscreen displays (demos, games) involved centering the screen (via R2), which could cause this problem.
Rémi Herbulot also experienced the problem in his game "Get Dexter" with scrolling using R2.
More recently, the Compendium allows these differences to be detailed and described precisely.
For your article, you can also add this image, which is quite clear about the HUD.
(https://blog.logonsystem.eu/content/images/2024/02/2024-02-19_16h24_40.jpg)
Maybe this emulator doesn't work properly because I had a CPC with CRTC 2 and this game was displayed normally and not like on picture above.
Quote from: ZorrO on 19:03, 08 April 25Maybe this emulator doesn't work properly because I had a CPC with CRTC 2 and this game was displayed normally and not like on picture above.
You misread. This problem only occurs on CRTC 1.
Amspirit is the most accurate CPC emulator currently available. ;)
I confirm! 8)
Tested now on real hardware with a CPC CRTC Type 1 :
(https://cpcrulez.fr/im4/7/poulette73-IMG339.jpg)
(https://cpcrulez.fr/im4/7/poulette73-IMG340.jpg)