Doom?
Re: Doom?
For the 256 colour palette mapping, the best I could find was (basically an octree) to find the "longest" (or most populous) axis through the colour space, then the longest perpendicular to that giving the third. Then split the longest axis (doubling its partitions), repeat another three times and "average" for each of the 16 volumes. Quicker and dirtier would be to just use the RGB axes.
-
- Posts: 510
- Joined: Wed Feb 07, 2018 3:35 pm
- Contact:
Re: Doom?
If this gets to stage of looking really playable, which it isn't far off.
I think I may have a look at designing levels for doom and maybe looking at using textures and colours that work well for nula hardware. Maybe turn it into a larger beeb game with more levels.
I think I may have a look at designing levels for doom and maybe looking at using textures and colours that work well for nula hardware. Maybe turn it into a larger beeb game with more levels.
Last edited by mr-macrisc on Sun Mar 17, 2019 1:37 pm, edited 1 time in total.
Re: Doom?
This is awesome Rob.
Your dynamic palette idea sounds like an interesting challenge! It's quite a colourful game unfortunately (and colours in use vary depending on level locations) so 16-colours is a pretty tricky constraint.
As has already been mentioned, there's a few well known ways to get fast best fit palettes, but I'd be curious if they'd be performant enough for real time use? I'd also imagine dynamic palettes would need some tricks to stop colours 'popping' in and out per frame. Perhaps some sort of interpolation could smooth any artefacts over time? Maybe even only allow a few dynamic colours in the palette of 16.
Perhaps a custom fixed palette could be another compromise approach. A general doom palette might work well with say 6 greys (black-white), 2 shades red, 2 shades blue, 2 shades green, 2 shades yellow, 2 shades brown. Then maybe some ordered dither would bridge some colour gaps - although mode2 pixels are quite big, so it might be too distracting.... hmm. Ruff example:
So many options! Really looking forward to following how you get on with this anyway!
Your dynamic palette idea sounds like an interesting challenge! It's quite a colourful game unfortunately (and colours in use vary depending on level locations) so 16-colours is a pretty tricky constraint.
As has already been mentioned, there's a few well known ways to get fast best fit palettes, but I'd be curious if they'd be performant enough for real time use? I'd also imagine dynamic palettes would need some tricks to stop colours 'popping' in and out per frame. Perhaps some sort of interpolation could smooth any artefacts over time? Maybe even only allow a few dynamic colours in the palette of 16.
Perhaps a custom fixed palette could be another compromise approach. A general doom palette might work well with say 6 greys (black-white), 2 shades red, 2 shades blue, 2 shades green, 2 shades yellow, 2 shades brown. Then maybe some ordered dither would bridge some colour gaps - although mode2 pixels are quite big, so it might be too distracting.... hmm. Ruff example:
So many options! Really looking forward to following how you get on with this anyway!
Re: Doom?
Thanks Simon. Trying other 16 colour palettes should be very simple as the NuLA palette is generated from the PLAYPAL lump in the wad. I did originally try to optimise the palette (by using GIMP to find finding the best 16 colours to fit Doom's standard 256 colours) but this all got sidelined by the wall texture bug and so I haven't tried it again since.
I'll have a go with your palette and see what it looks like. Agree about the issues with using a dynamic palette - I'm not really sure if it's going to be worth it and you definitely wouldn't want dramatic colour changes from frame to frame.
One thing I haven't put in yet but definitely should is proper support for multiple palettes. Doom adds progressively red tints as you get hurt but I'm currently just mapping more of the colours to red as that's what the EGA palette mod does. However, with NuLA, it's possible to gradually increase the red components of all colours as is done with the original 256 colour palette.
I'm also going to do some profiling as I currently don't know how much time is spent generating each frame and how much time is spent sending it across the TUBE. I'm currently updating all of the status bar every frame but the host rom has code to just send blocks of differences which should be more efficient. There's some more unrolling I can do in the frame transfer routine too. They probably won't make a lot of difference but will speed things up a bit.
I'll have a go with your palette and see what it looks like. Agree about the issues with using a dynamic palette - I'm not really sure if it's going to be worth it and you definitely wouldn't want dramatic colour changes from frame to frame.
One thing I haven't put in yet but definitely should is proper support for multiple palettes. Doom adds progressively red tints as you get hurt but I'm currently just mapping more of the colours to red as that's what the EGA palette mod does. However, with NuLA, it's possible to gradually increase the red components of all colours as is done with the original 256 colour palette.
I'm also going to do some profiling as I currently don't know how much time is spent generating each frame and how much time is spent sending it across the TUBE. I'm currently updating all of the status bar every frame but the host rom has code to just send blocks of differences which should be more efficient. There's some more unrolling I can do in the frame transfer routine too. They probably won't make a lot of difference but will speed things up a bit.
Re: Doom?
Another really exciting development, Rob!
Look forward to seeing how far you take this, and the surely inevitable interview in Retrogamer magazine...
As someone who, with this and your Spectrum and Amstrad CPC emulators, has pushed the delivery of graphics from a co-pro to the host, would you consider perhaps documenting your approach and/or opening your source for others to build on?
Look forward to seeing how far you take this, and the surely inevitable interview in Retrogamer magazine...
As someone who, with this and your Spectrum and Amstrad CPC emulators, has pushed the delivery of graphics from a co-pro to the host, would you consider perhaps documenting your approach and/or opening your source for others to build on?
BBC Master Turbo, Retroclinic External Datacentre, VideoNuLA, PiTubeDirect with Pi Zero, Gotek USB Floppy Emulator
Re: Doom?
Absolutely happy to share what I've done with anyone who wants to do the same thing. It would be great to see other people do stuff for the Pi.
For the C on the Pi side of things, I've got some newlib stubs for the standard library functions and code that allows access to SWIs etc. I use Ubuntu on Windows and the arm-none-eabi gcc compiler.
On the host side, I hook into OSWRCH and use the VDU queue (&FEE1). I send a control code for each of the different transfer types and get the data lined up on the Pi side so that the host doesn't need to check that data has arrived before reading. Sending blocks of differences works well in the emulators as there's generally not much change from frame to frame as the 8-bit machines can only do so much.
For Doom I just use an unrolled loop like: LDA &FEE1:STA &4000,X:LDA &FEE1:STA &4100,X...LDA &FEE1:STA &7F00,X and then increment X once for every 64 writes. It should be possible to unroll some parts even more and use STA &abs but there's a limit to the amount of code space in ROM.
Re: Doom?
Thanks Rob.
If that's the case, is it true that your code is "just" extending the MOS to ensure that the data reaches your ROM routines, as opposed to a custom-written program that is running on the host and actively polling for incoming data?
Also, please could you expand on what you mean by the "control code for each of the different transfer types"?
Thanks!
So am I understanding correctly, that the Pi is writing to the Tube registers to &FEF9, which (automatically?) appears on the host at &FEE1. The host (MOS?) picks up the transferred data as an OSWRCH call, passes this to the host's VDU driver, which is then indirected to routines in your ROM image that executes, takes the data and writes to the screen memory?RobC wrote: ↑Sun Mar 17, 2019 9:34 pm Absolutely happy to share what I've done with anyone who wants to do the same thing. It would be great to see other people do stuff for the Pi.
For the C on the Pi side of things, I've got some newlib stubs for the standard library functions and code that allows access to SWIs etc. I use Ubuntu on Windows and the arm-none-eabi gcc compiler.
On the host side, I hook into OSWRCH and use the VDU queue (&FEE1). I send a control code for each of the different transfer types and get the data lined up on the Pi side so that the host doesn't need to check that data has arrived before reading. Sending blocks of differences works well in the emulators as there's generally not much change from frame to frame as the 8-bit machines can only do so much.
If that's the case, is it true that your code is "just" extending the MOS to ensure that the data reaches your ROM routines, as opposed to a custom-written program that is running on the host and actively polling for incoming data?
Also, please could you expand on what you mean by the "control code for each of the different transfer types"?
Presumably Doom is doing a lot more in terms of changes to the screen than a more traditional (e.g., static screen platform) game, as turning the character could mean that potentially every pixel on the main view window is going to need updating. If the main window is 160x200, what sort of frame rate are you looking at, and how fast do you think you'll be able to get it?RobC wrote: ↑Sun Mar 17, 2019 9:34 pm For Doom I just use an unrolled loop like: LDA &FEE1:STA &4000,X:LDA &FEE1:STA &4100,X...LDA &FEE1:STA &7F00,X and then increment X once for every 64 writes. It should be possible to unroll some parts even more and use STA &abs but there's a limit to the amount of code space in ROM.
Thanks!
BBC Master Turbo, Retroclinic External Datacentre, VideoNuLA, PiTubeDirect with Pi Zero, Gotek USB Floppy Emulator
Re: Doom?
Absolutely superb, and definitely worth posting to https://www.reddit.com/r/itrunsdoom RobC!
Re: Doom?
Yes - you've got it spot on. For simplicity, I have a function called _VDU on the Pi side to write a byte to the VDU queue (&FEF9) but it's just a wrapper to the OS_WriteC SWI call.jregel wrote: ↑Mon Mar 18, 2019 8:26 pm So am I understanding correctly, that the Pi is writing to the Tube registers to &FEF9, which (automatically?) appears on the host at &FEE1. The host (MOS?) picks up the transferred data as an OSWRCH call, passes this to the host's VDU driver, which is then indirected to routines in your ROM image that executes, takes the data and writes to the screen memory?
Yes. I extend OSWRCH to send data (sound and graphics) via the VDU queue and OSBYTE to get one or two bytes back from the host (e.g. keyboard reading, joystick and vsync polling).jregel wrote: ↑Mon Mar 18, 2019 8:26 pm If that's the case, is it true that your code is "just" extending the MOS to ensure that the data reaches your ROM routines, as opposed to a custom-written program that is running on the host and actively polling for incoming data?
Also, please could you expand on what you mean by the "control code for each of the different transfer types"?
The control codes are sent by the _VDU function and tell the host what sort of data is being sent and which ROM routine to jump to. I use the characters above the ASCII codes so that things like printf still work (sort of with odd screen sizes!). So, in Doom, sending 0xFF indicates a full screen update and is followed by 16,000 bytes of screen data. Other codes indicate things like sound data or the transfer of a block of screen data (where I indicate the length and screen address in subsequent bytes).
It's possible to adapt the approach to suit what you're trying to do - if you were writing a game with lots of sprites, you could have different control codes for different sprite sizes etc.
Yes and that's why I decided to update the whole screen every frame rather than going for the "send the differences" approach I use for the emulators. What I should do is just update the whole of the play area and send differences for the status bar - I'll look at putting this in next as the ROM code is already there to support this.jregel wrote: ↑Mon Mar 18, 2019 8:26 pm Presumably Doom is doing a lot more in terms of changes to the screen than a more traditional (e.g., static screen platform) game, as turning the character could mean that potentially every pixel on the main view window is going to need updating. If the main window is 160x200, what sort of frame rate are you looking at, and how fast do you think you'll be able to get it?
I haven't measured the frame rate but am in the process of looking at the Pi uS timer so that I can profile the code. I don't know how long the Pi is taking to generate each frame yet so can't say whether it's significant.
The theoretical limit for the TUBE transfer is about 9 cycles per byte using LDA &abs, STA &abs,X although I might be able to fit in STA &abs for some of it. A faster way of doing this would be to use Chris Morley's Bad Apple technique and then you can use LDA imm followed by multiple STA &abs but I guess you'd need a PC rather than a Pi co-pro at the other end.
Thanks - I'll look into it. May wait until I've seen how much I can improve things first!dom wrote: ↑Mon Mar 18, 2019 9:02 pm Absolutely superb, and definitely worth posting to https://www.reddit.com/r/itrunsdoom RobC!
Last edited by RobC on Mon Mar 18, 2019 9:56 pm, edited 1 time in total.
Re: Doom?
Impressive is an understatement .
In Case it slept your attention there are already ports that may be helpfull
https://www.youtube.com/watch?v=WFMM3F_-bx0
the impressive Vicdoom by Kweepa
(based to a small degree on the Linux Doom 1.10 source code)
http://sleepingelephant.com/ipw-web/bul ... &start=315
from 6502 based humble Vic20
https://github.com/Kweepa/vicdoom
mr-macrisc wrote: ↑Sat Feb 16, 2019 4:42 pm No planned ports, little ambitious for me but thought would be interesting to see what could be done with modern tube processors. Either very fast 6502 or ARM. Wonder if just updated pixels coming back may even be able to use a 16 colour mode.
also
https://www.youtube.com/watch?v=7ZzivzuDOls
the C64 Doom by Amidog witch runs on an expanded C64(65c816/16MB)
https://scpu.amidog.se/doku.php?id=scpu:doom
(who has also ported Wolf3d
https://www.youtube.com/watch?v=Pa9cC6HcgrE
https://www.youtube.com/watch?v=shA0CHaQF-U
to the same C64 configuration with even better results)
and Amidog has his MIPS recompiler avaiable
https://scpu.amidog.se/doku.php?id=scpu:mipsrecompiler
Last edited by Titus on Wed Mar 20, 2019 3:20 am, edited 6 times in total.
Re: Doom?
Thanks Rob.
It's incredibly impressive that you have been able to build on top of the routines provided by the MOS and extend them in such an elegant way. It really does show how well the original API was designed.
It's incredibly impressive that you have been able to build on top of the routines provided by the MOS and extend them in such an elegant way. It really does show how well the original API was designed.
BBC Master Turbo, Retroclinic External Datacentre, VideoNuLA, PiTubeDirect with Pi Zero, Gotek USB Floppy Emulator
- vanpeebles
- Posts: 763
- Joined: Wed Nov 28, 2012 10:01 am
- Location: UK
- Contact:
Re: Doom?
Quake??mr-macrisc wrote: ↑Sun Mar 17, 2019 11:45 am Let's make everyone laugh...
Here, RobC? What could we do with a master, nula and Dual PI co-processor?
Re: Doom?
A few shots of 8 colour (so none-videonula) BeebDoom
-
- Posts: 510
- Joined: Wed Feb 07, 2018 3:35 pm
- Contact:
Re: Doom?
Looks great again.
I think we have makings of a useful game here and I am defo planning designing some levels better suited to 8 and 16 colour and make it something a little bigger than doom.
Or maybe to start see what is out there in 8/16 already and maybe try them and use them to help my ideas.
I think we have makings of a useful game here and I am defo planning designing some levels better suited to 8 and 16 colour and make it something a little bigger than doom.
Or maybe to start see what is out there in 8/16 already and maybe try them and use them to help my ideas.
Last edited by mr-macrisc on Wed Mar 20, 2019 12:40 pm, edited 1 time in total.
Re: Doom?
That Beeb palette version is surprisingly effective! Yet again I'm lamenting the fact that Acorn didn't give us half-bright RGBs with the other 8 colours.
Re: Doom?
Is there any chance at all that dithering can be brought into play?
Re: Doom?
Maybe the textures could be dithered when read by the pi (or just preprocess them so they are stored processed) in order to add more nuance?
e.g. https://www.youtube.com/watch?v=-Nz_QB26Clw
e.g. https://www.youtube.com/watch?v=-Nz_QB26Clw
BBC Master 128, BBC Model B i7, PMS B2P-6502 2nd proc., PiTubeDirect (both internal and external), RetroClinic Multi-OS Selector, Sundby 256k RAM/ROM card, MMFS, Gotek, Music 500, Hoglet RGBtoHDMI, ...
Re: Doom?
I got a phone call before hitting submit and see that BigEd had the same question
BBC Master 128, BBC Model B i7, PMS B2P-6502 2nd proc., PiTubeDirect (both internal and external), RetroClinic Multi-OS Selector, Sundby 256k RAM/ROM card, MMFS, Gotek, Music 500, Hoglet RGBtoHDMI, ...
Re: Doom?
Frameskip is enabled ?, it look like it goes in slowmo
Re: Doom?
Yes - I did a bit of reading up on algorithms earlier in the week but haven't coded anything up yet. As you'd expect, the frame time is dominated by the Tube transfer so getting the Pi to work out the dithering shouldn't slow things down much.
Also, the palettes for both the NuLA and non-NuLA versions are generated from the PLAYPAL lump in the wad. So, it's entirely possible to come up with your own palettes by using a wad editor like Slade.
I wanted to put some code in to calculate the actual frame rate before setting Doom's internal TICRATE parameter. I'll hopefully get it running at the correct speed shortly.
It's currently running at 12.5fps but it's always updating the whole screen rather than just the play area. There's also scope to speed up the screen transfer code a little bit.
Last edited by RobC on Wed Mar 20, 2019 3:42 pm, edited 1 time in total.
-
- Posts: 510
- Joined: Wed Feb 07, 2018 3:35 pm
- Contact:
Re: Doom?
Still seriously impressed...
1980-ish that tube bus was designed along with rest of hardware and connected to a modern 2nd processor it really is impressive. That bus is nearly 40yr old.
Yeah you could make it better now but who would have thought something remotely like this could come down the tube and be displayed by the bbc.
1980-ish that tube bus was designed along with rest of hardware and connected to a modern 2nd processor it really is impressive. That bus is nearly 40yr old.
Yeah you could make it better now but who would have thought something remotely like this could come down the tube and be displayed by the bbc.
Re: Doom?
Yes, it’s remarkable. That’s probably why we all like the BBC so much, it’s an amazing machine!
Re: Doom?
There's a very handy forum post here looking at how best to dither on a moving image:
https://forums.tigsource.com/index.php? ... msg1363742
https://forums.tigsource.com/index.php? ... msg1363742
Re: Doom?
This is probably the only 8 bit computer that have a true full doom port running.
Even is in 8 colors, very impressive.
Even is in 8 colors, very impressive.
Re: Doom?
Here's another good dithering reference: https://bisqwit.iki.fi/story/howto/dither/jy/
PS. Awesome work Rob! What does this look like in MODE 8 out of interest? Low resolution but twice the framerate maybe?!
PS. Awesome work Rob! What does this look like in MODE 8 out of interest? Low resolution but twice the framerate maybe?!
Bitshifters Collective | Retro Code & Demos for BBC Micro & Acorn computers | https://bitshifters.github.io/
Re: Doom?
Great link, thanks!kieranhj wrote: ↑Thu Mar 21, 2019 12:47 am Here's another good dithering reference: https://bisqwit.iki.fi/story/howto/dither/jy/
Re: Doom?
The idea of using the VDU queue came from BigEd and hoglet's 6502 Life demo. Once the ROM routines were working, they made writing the code on the Pi much simpler as it just sits there waiting to send the data as quickly as it can and, if you get the data lined up before sending, you know it's going to be fast enough to keep up with the host
Thanks for that. I'll have a good read through it later.kieranhj wrote: ↑Thu Mar 21, 2019 12:47 am Here's another good dithering reference: https://bisqwit.iki.fi/story/howto/dither/jy/
PS. Awesome work Rob! What does this look like in MODE 8 out of interest? Low resolution but twice the framerate maybe?!
I haven't tried mode 8 yet but could easily get it running and it would be even easier to knock up a screenshot within the existing mode 2 framework.
I guess it would look really bad though - if we got 256 colours in exchange for the reduction in resolution it wouldn't be so bad!