BBC Bomberman
BBC Bomberman
Just wanted to start a thread on stardot about my progress in porting NES Bomberman to the BBC.
I found somebody had done an almost complete disassembly of the 6502 code on GitHub 9 years ago. The comments were lacking and in Russian, but it was a great starting point.
I've ripped the tiles, sprites, font and music so far as assets converted where appropriate for the BBC. I've also implemented the password system to allow continues from specific levels with certain power-ups retained. I've done all the menus and game over / game completed screens.
I'm using MS vscode with extensions by Simon.M, beebasm, and a mixture of BBC Micro emulators such as jsbeeb / beebem / b2 and beebjit.
I'm uploading progress to my GitHub project page periodically.
It can be played online with jsbeeb here. https://bbc.godbolt.org/?disc1=https:// ... d&autoboot
I found somebody had done an almost complete disassembly of the 6502 code on GitHub 9 years ago. The comments were lacking and in Russian, but it was a great starting point.
I've ripped the tiles, sprites, font and music so far as assets converted where appropriate for the BBC. I've also implemented the password system to allow continues from specific levels with certain power-ups retained. I've done all the menus and game over / game completed screens.
I'm using MS vscode with extensions by Simon.M, beebasm, and a mixture of BBC Micro emulators such as jsbeeb / beebem / b2 and beebjit.
I'm uploading progress to my GitHub project page periodically.
It can be played online with jsbeeb here. https://bbc.godbolt.org/?disc1=https:// ... d&autoboot
Re: BBC Bomberman
That is very impressive so far! How difficult was it... ? I imagine there's a lot of work in adding software sprite plotting routines, because I'd expect a console like the NES has hardware sprites.
Re: BBC Bomberman
Thanks.
Quite difficult hence the slow progress I’m making. I have to keep switching between Beeb manuals and the NES dev wiki to translate what’s going on.
Yes I’ve been coding sprite and tile plotting routines to closely match what the NES is doing, which does have hardware sprites. My biggest problem is going to be running out of RAM.
- cardboardguru
- Posts: 239
- Joined: Fri Mar 09, 2018 10:26 pm
- Contact:
Re: BBC Bomberman
Looking good picosonic.
Re: BBC Bomberman
Indeed - looking really good. I put this on those mini arcade machines for my kids and they love it.
Presentation looks excellent. Can't wait to see the end result.
Re: BBC Bomberman
Thanks. I’m 6 months in so far. It’s been slow as I haven’t had much time to work on it.
Next on my todo list is making the bombs explode, then power ups.
-
- Posts: 563
- Joined: Sat Dec 23, 2000 5:56 pm
- Contact:
Re: BBC Bomberman
It's not necessarily a helpful observation given the route you're coming from, but Eric and the Floaters — the western retitling of the 1983 Bomber Man upon which the 1985 NES port was based — runs on a 16kb Spectrum, i.e. has at most 9.25kb of code and data once you subtract the screen.
I don't recall it having scrolling mazes though, and total variety is probably a lot less elsewhere; I don't really know the NES title. Also I had a quick skim through the other micros that hosted the 1983 release and they're all Z80s except for one 6809, so nothing directly to learn there in terms of a direct port.
Re: BBC Bomberman
The sprites and tiles come to 8k alone, plus there are 10 tunes and one PCM explosion sound effect. There’s also a demo mode with a playthrough (which I probably won’t keep). There are 50 “randomly” generated levels.ThomasHarte wrote: ↑Mon Mar 01, 2021 9:39 pm It's not necessarily a helpful observation given the route you're coming from, but Eric and the Floaters — the western retitling of the 1983 Bomber Man upon which the 1985 NES port was based — runs on a 16kb Spectrum, i.e. has at most 9.25kb of code and data once you subtract the screen.
I don't recall it having scrolling mazes though, and total variety is probably a lot less elsewhere; I don't really know the NES title. Also I had a quick skim through the other micros that hosted the 1983 release and they're all Z80s except for one 6809, so nothing directly to learn there in terms of a direct port.
I doubt the sideways scrolling will work well as I’m using a custom 256 pixel wide screen mode (to match the NES) so hardware scrolling won’t really work. Meaning I’ll probably have to restrict it to one screen.
Re: BBC Bomberman
Hardware scrolling works for 8, 10, 16 and 20KB, so will work for 256x256, or at least it will wrap around to &4000. You don't need to display all of it, but it is a bit wasteful otherwise.
Re: BBC Bomberman
I was using 256x240 to save an extra 2k.
But hardware scrolling would be nice and closer to the NES version.
I’m currently moving the sprites by multiples of 4 in X and multiples of 8 in Y as this is quite trivial and gives a slightly smoother result than jumping a 16x16 tile at a time. But pixel by pixel motion would also be a nice to have.
I’ve already added your suggested code for reading the keyboard into a bit field which is working well, so thanks for the help on that.
Last edited by picosonic on Tue Mar 02, 2021 3:24 pm, edited 1 time in total.
Re: BBC Bomberman
Yep, hardware scrolling can be wasteful, but I guess Acorn weren't expecting much game support requirements for their expect 10K sales!
Horizontal hardware scrolling is 4 MODE 1 pixels, vertical can be 1 at a time.
Horizontal hardware scrolling is 4 MODE 1 pixels, vertical can be 1 at a time.
- cardboardguru
- Posts: 239
- Joined: Fri Mar 09, 2018 10:26 pm
- Contact:
Re: BBC Bomberman
I took a look at the keyboard handling code, because I was intrigued about what reading it into a bitfeld meant. I haven't done that. Looks neat.
But I think as it stands there's a small potential for an interrupt to happen whilst you're programming the System VIA. Which might break the keyboard code for one frame. I think interrupts should be disabled. An SEI at the start of the routine and a CLI at the end.
But I think as it stands there's a small potential for an interrupt to happen whilst you're programming the System VIA. Which might break the keyboard code for one frame. I think interrupts should be disabled. An SEI at the start of the routine and a CLI at the end.
Last edited by cardboardguru on Tue Mar 02, 2021 3:46 pm, edited 1 time in total.
Re: BBC Bomberman
On the keyboard handling code I had help from tricky, it's quicker than loads of INKEY calls and packs the inputs into a single byte to match the NES joypad read.cardboardguru wrote: ↑Tue Mar 02, 2021 3:10 pm I took a look at the keyboard handling code, because I was intrigued about what reading it into a bitfield meant. I haven't done that. Looks neat.
But I think as it stands there's a small potential for an interrupt to happen whilst you're programming the System VIA. Which might break the keyboard code for one frame. I think interrupts should be disabled. An SEI at the start of the routine and a CLI at the end.
Yes I've got it wrapped in SEI / CLI, just not committed that change yet.
Re: BBC Bomberman
Sorry, yes, I usually call it from the interrupt that enables the game logic, so the keys are as lower latency as possible and interrupts are already disabled or for something like my Pac Man where the whole game is run with interrupts disabled
I usually store it in a byte to make it easy to EOR #&FF to store as "was not pressed" and then AND with to give "was just pressed".
Depending on the game I will have left/right in the top two bits so that I can BIT then BMI, BVS etc to quickly choose or cancel if both pressed.
If it is 8 directions, I may put the directions in the low bits and AND #&0F to get a direction index.
I usually store it in a byte to make it easy to EOR #&FF to store as "was not pressed" and then AND with to give "was just pressed".
Depending on the game I will have left/right in the top two bits so that I can BIT then BMI, BVS etc to quickly choose or cancel if both pressed.
If it is 8 directions, I may put the directions in the low bits and AND #&0F to get a direction index.
Last edited by tricky on Tue Mar 02, 2021 3:49 pm, edited 1 time in total.
- cardboardguru
- Posts: 239
- Joined: Fri Mar 09, 2018 10:26 pm
- Contact:
Re: BBC Bomberman
Ah right, I hadn't put 2 and 2 together. Yes NES gamepads do have that funny serial reading system.
Re: BBC Bomberman
I implemented horizontal sprite flipping last night and it takes a considerable amount of clock cycles to do.
Here's an example of processor time taken, I switch the palette at the start of vsync, then back again once I've completed the raster.
For walking left (no flip) the sprites draw reasonably quickly.
However when walking right (flip) it takes over twice as long to draw.
There isn't much room in RAM to store flipped copies of all the sprites, so I was doing it on the fly.
Perhaps I need to suck it up and copy the facing right sprites to RAM (4 fit per memory page).
Bomberman has 3 walking left sprites, but there are 8 enemies (with 3 facing left sprites each) all would require flipped versions, there are some levels with multiple enemy types displayed simultaneously. Perhaps I need to limit it to 1 enemy type per level (although I think they change when you run out of time).
Here are al the sprites and tiles from the original game, as displayed on a Beeb.
The joys of 8bit dev
Here's an example of processor time taken, I switch the palette at the start of vsync, then back again once I've completed the raster.
For walking left (no flip) the sprites draw reasonably quickly.
However when walking right (flip) it takes over twice as long to draw.
There isn't much room in RAM to store flipped copies of all the sprites, so I was doing it on the fly.
Perhaps I need to suck it up and copy the facing right sprites to RAM (4 fit per memory page).
Bomberman has 3 walking left sprites, but there are 8 enemies (with 3 facing left sprites each) all would require flipped versions, there are some levels with multiple enemy types displayed simultaneously. Perhaps I need to limit it to 1 enemy type per level (although I think they change when you run out of time).
Here are al the sprites and tiles from the original game, as displayed on a Beeb.
The joys of 8bit dev
Re: BBC Bomberman
How are you implementing the flipping? If you're using rotates or masks and shifts, it may be worth considering some form of look-up table. It'll cost you some memory (at most a page) but it sounds like that'll be less than having flipped copies of all the sprites...
Re: BBC Bomberman
Like Rob said, use a 256 byte fliptable and plot the sprite column bytes in the opposite order for speed .....
Greetings
Kees
Greetings
Kees
Re: BBC Bomberman
I’m using a modified mode 1, so all 4 colours. Flipping with ANDs and shifts.RobC wrote: ↑Thu Mar 04, 2021 2:35 pm How are you implementing the flipping? If you're using rotates or masks and shifts, it may be worth considering some form of look-up table. It'll cost you some memory (at most a page) but it sounds like that'll be less than having flipped copies of all the sprites...
So 256 operations per sprite. Having a single page lookup table would greatly speed this up.
- cardboardguru
- Posts: 239
- Joined: Fri Mar 09, 2018 10:26 pm
- Contact:
Re: BBC Bomberman
Yeah, I was going to go with having both orientations as separate sprites on Tazz. But might try the 256 entry lookup table approach as memory is tight.
Re: BBC Bomberman
As mine are 16x16 pixels they are 64 bytes each, so I copy flipped bytes from offsets 0..7 to 24..31, 8..15 to 16..23 and 24..31 to 0..7. Then the same again for the bottom half of the spritecardboardguru wrote: ↑Thu Mar 04, 2021 3:38 pm Yeah, I was going to go with having both orientations as separate sprites on Tazz. But might try the 256 entry lookup table approach as memory is tight.
Re: BBC Bomberman
You might also consider flipping half the sprite and not the other half to reduce the worse case if it gets too much with explosions.
-
- Posts: 563
- Joined: Sat Dec 23, 2000 5:56 pm
- Contact:
Re: BBC Bomberman
If this is single-player Bomberman, as I think the NES version is (?), why not just flip statically when the player changes direction and keep in memory in that form?
Re: BBC Bomberman
I did consider doing that with a flag for each sprite set to indicate flip status.ThomasHarte wrote: ↑Thu Mar 04, 2021 8:14 pm If this is single-player Bomberman, as I think the NES version is (?), why not just flip statically when the player changes direction and keep in memory in that form?
I’ll run some experiments
- cardboardguru
- Posts: 239
- Joined: Fri Mar 09, 2018 10:26 pm
- Contact:
Re: BBC Bomberman
That's an absolutely great idea that I've never considered. Even out the work so it's the same either way. I think I'll use that.
Re: BBC Bomberman
I've done some experiments, no surprises with the results really, shown in order of CPU load
For a baseline, this is walking left (as before, no flips) ~ 46 scanlines
Then walking right with half the sprite already flipped (so it's at worse only flipping half the sprite) ~ 103 scanlines
Then walking right using a look up table for flipping, but sprites encoded normally ~ 88 scanlines
Finally, walking right when half sprite already flipped and other half using look up table ~ 73 scanlines
So ultimately the look up table makes the biggest difference going from ~ 140 scanlines to ~ 88 scanlines.
Having half the sprite already flipped combined with the lookup table saves a further ~ 15 scanlines
For a baseline, this is walking left (as before, no flips) ~ 46 scanlines
Then walking right with half the sprite already flipped (so it's at worse only flipping half the sprite) ~ 103 scanlines
Then walking right using a look up table for flipping, but sprites encoded normally ~ 88 scanlines
Finally, walking right when half sprite already flipped and other half using look up table ~ 73 scanlines
So ultimately the look up table makes the biggest difference going from ~ 140 scanlines to ~ 88 scanlines.
Having half the sprite already flipped combined with the lookup table saves a further ~ 15 scanlines
Re: BBC Bomberman
As I was beginning to get to the point where I'd have to start thinking about RAM usage I came across the BBC Micro source for Kevin Edwards game Crazee Rider on GitHub which has a method for using memory starting at &0E00 and up to screen memory.
Since I was previously loading at &1900 this results in a further 2,816 (&B00) of RAM which I can now use.
The trick is to load at &1900, then disable DFS (by switching to TAPE fs) and finally relocate (or as Kevin puts it "download") to &0E00 then jump to the moved code.
The "downloader" is a separate piece of code with a known origin within screen RAM (as it doesn't matter if this gets lost after the download).
Realising this gave me a lightbulb moment as to what the screen corruption you see at the top of so many BBC Micro games right at the end of their loading sequence.
Like this example from Repton 3, Around the World in 40 Screens :
Often games will also tag on code to be relocated to the language workspace at &0400 .. &07FF, but I found it easier to have this in a separate file.
For my use of the technique I load a 14,957 (&3A6D) byte file at &1900, this includes a downloader at the end of the file which ends up at &5300 (in screen RAM), which is the exec address and the origin for the downloader code.
The downloader also contains all the one time init code which will end up being discarded once the screen starts being written to.
Once downloaded the block of code/data resides at &0E00 to &4800, with &4800 being the base of screen memory in my 256x224 pixel (NES equivalent) mode.
Since I was previously loading at &1900 this results in a further 2,816 (&B00) of RAM which I can now use.
The trick is to load at &1900, then disable DFS (by switching to TAPE fs) and finally relocate (or as Kevin puts it "download") to &0E00 then jump to the moved code.
The "downloader" is a separate piece of code with a known origin within screen RAM (as it doesn't matter if this gets lost after the download).
Realising this gave me a lightbulb moment as to what the screen corruption you see at the top of so many BBC Micro games right at the end of their loading sequence.
Like this example from Repton 3, Around the World in 40 Screens :
Often games will also tag on code to be relocated to the language workspace at &0400 .. &07FF, but I found it easier to have this in a separate file.
For my use of the technique I load a 14,957 (&3A6D) byte file at &1900, this includes a downloader at the end of the file which ends up at &5300 (in screen RAM), which is the exec address and the origin for the downloader code.
The downloader also contains all the one time init code which will end up being discarded once the screen starts being written to.
Once downloaded the block of code/data resides at &0E00 to &4800, with &4800 being the base of screen memory in my 256x224 pixel (NES equivalent) mode.
Re: BBC Bomberman
Well known technique indeed. I do it slightly differently. My SETUP binary is loaded first at the very end of screen memory. It then does some one time init code and then loads the main binary at &1F00. Then relocates the whole thing down to 0. And the binary is max size &5800 if you are in MODE 4 or 5.
0xC0DE
"I program my home computer / Beam myself into the future"
Follow me on Twitter
Visit my YouTube channel featuring my games and demos for Acorn Electron and BBC Micro
"I program my home computer / Beam myself into the future"
Follow me on Twitter
Visit my YouTube channel featuring my games and demos for Acorn Electron and BBC Micro
Re: BBC Bomberman
I’d never seen it documented before in any guides, but assumed that’s what they must be doing. Seeing Kevin Edwards source confirmed it for me and allowed me to loosely follow the method.0xC0DE wrote: ↑Wed Mar 31, 2021 4:18 pm Well known technique indeed. I do it slightly differently. My SETUP binary is loaded first at the very end of screen memory. It then does some one time init code and then loads the main binary at &1F00. Then relocates the whole thing down to 0. And the binary is max size &5800 if you are in MODE 4 or 5.
I don’t think I can load at zero page as I use sound and other OS routines.
Last edited by picosonic on Thu Apr 01, 2021 9:21 am, edited 1 time in total.