Space Invaders Emulator Blitz3D
Not strictly speaking a 3D project as such, but GFX are stored in Space Invaders ram area as a 1 bit bitmap so the output interface I wrote reads the bits and draws white rectangles when the bit is 1. Doing this in Blitz3D 2D graphics mode is slow compared to doing it onto a texture and then putting the texture onto a sprite.
Current version runs Space Invaders, Space Invaders Colour, Super Earth Invasion and Space Invaders Pt 2/Deluxe romsets at full speed (and probably is capable of running a lot of others).
Uses only partial Intel 8080a / 8080b emulation. The games above don't use the Aux. carry flag so not implemented. Space Invaders variants also don't use parity flag, but Super Earth invasion does so had to impement that. Around 200 of 256 Opcodes implemented as the others aren't used by the games.
A lot of getting this running at a good speed was writing routines in multiple different ways using different instructions and then speed testing them to see which executed fastest. I got over a 100 fold increase in speed by not using BIN$/HEX$/MID$/LEFT$/RIGHT$ and instead using simple mathematical loops to deal with binary calculations.
Added optional scanlines option for realistic old skool display effect.
Can be downloaded from here.
Awesome! ..and those backgrounds are a nice touch!
Thanks for sharing Randall and Welcome to the Forums!
Congratulations! I love emulators.
Interesting to hear about your optimizations. You didn't mention if it play sounds. If yes how did you handle that?
Hi. Many thanks for the welcomes and approvals, and great forum. To answer the questions:
"Awesome! ..and those backgrounds are a nice touch!" - Bloody typical... I removed them on the final release. Whilst they look nice, they weren't really part of the emulator and reduced the game-play size significantly.
Also this is just a technical demo to see if 1) I was capable of writing an emulator and 2) Blitz3D was capable of running one, so I decided to stick to the technical aspects.
"You didn't mention if it play sounds. If yes how did you handle that?" - Yes plays sound... I erm "borrowed" the MAME sound samples.
I did try and integrate them into the main program, and then write "temp" .wav files out of the program whilst the program was executing, but I couldn't get the output files to write correctly so that they were playable.
Now they are the regular MAME Invaders sound samples, and now the only part of the program external to the main program.
"Interesting to hear about your optimizations." - It sounds daft to say it now, but it took writing an emulator to realise how quick some Blitz3D commands would be compared to others.
Once you have the basics of what a processor can do quickly, and whats likely to take it a long time to do, it changes the way your programing goes.
I found lots of ways to save bits of time here and there, mostly swapping out complicated instructions for simple math loops.
An example is:
a single condition select true/case is faster than a single condition If/then.
A double condition IF/And/Then is faster than a double condition select true/case.
If you have two conditions to check for though, the fastest way is to use a single condition select true/case and then a single condition If/Then.
Writing routines in 5 or 6 different ways, and then running them 10000 times each and timing how long it took each of them also helped greatly.
The display routine was optimised numerous times. 7 kB of bits (57344) to go through and see if they are 1 or 0.
Optimisation 1 - Black background and only draw the white ones.
Optimisation 2 - No GFX on rows 0 to 7 (bottom of screen) or rows 248 to 255 so skip them.
Optimisation 3 - As the bits are stored in bytes, and as 80% of the screen is 0's, check byte value first before splitting into bits and skip if byte value is 0.
Optimisation 4 - Dont use 2D Graphics mode as its slow. Use Graphics3D and draw to a texture and then add texture to a sprite the size of the viewable screen. 60 FPS without breaking sweat.
Interesting project to do, but now need to push it a step further. Looking at doing a 6502 based emulation project now, possibly Asteroids. Will be interesting to see how translating vector coordinates th screen works.
really interesting project you got here using Blitz3D for emulation. Are you also familiar with x86 assembly?
Dont use 2D Graphics mode as its slow. Use Graphics3D and draw to a texture and then add texture to a sprite the size of the viewable screen.
that is always the case, but then again mixing 2D and 3D particulary on game engines is still common up to now. I'm also looking into doing full 3D when doing 2D stuff.
Looking at doing a 6502 based emulation project now, possibly Asteroids. Will be interesting to see how translating vector coordinates th screen works.
cool, looking forward to this!
thanks for the explanation, yes I've tried a bit of writing wave files and it's bit tricky but not as hard as emulating.
I tried the invader games and they played really smoothly on Windows 7 and 10 and the emulator seems to be very stable. The only time I noticed a slowdown was in the main menu on Windows 10, moving the selected menu item with Arrow keys went down from a delay of about 1 second to about 3 seconds.
Can I request if it isn't that much work, could you provide at least one smaller resolution, something no more than 720 pixels, as it was unplayable on my laptops with maximum heights of 720 or 800.
Also, I'm wondering how you handled the drawing, did you draw it all really small and then scale up the texture or did you draw it at full size (1080 pixels)? Just wondering if it would be scalable to any size.
I found an unimplemented Opcode 0xBB while playing Super Earth Invasion, I was just about to shoot the UFO and a little error message came up.
Thanks for the comments / feedback.
@markcwm - I started by just implementing the Opcodes that the games used, however I kept finding ones half way through a game that were needed (as you did) so have now implemented all of the Intel 8080 Opcodes so shouldn't happen again now. Have also implemented the Auxiliary Carry bit (which was a bitch!) so that the credits decrement correctly. Had an issue where if the lower digit of the credits was greater that 6, games cost 7 credits a go...and over 66 credits, games cost about 40 credits a go.... Turns out that despite being told otherwise, the Auxiliary carry bit is used by Space Invaders. I thought I'd fixed this, but then I noticed that when the score got to 100, it reset back to zero... Finally got it nailed on about fifth attempt.
Apologies about the slowdown on the menu screen. I haven't noticed any this end (running on an I5 7th gen so not cutting edge), but to be fair, the menu probably isn't written brilliantly so may simplify it. Have run speed checks all the way through this and all parts should be running at 60 FPS.
Have added an editable config file so that you can define the size of the window before you start. Its all drawn onto a texture and then put onto a sprite. Its not drawn tiny as textures look bad if they are pixel for pixel so I drew it scaled up by 4 onto the texture, but as its a texture on sprite, the window is scalable to any size (Scanline option looks bad on anything less that 500x500).
I'm a bit confused about Space Invaders Pt II at the moment. According to MAME, it should run off of a 2 MHz Intel 8080, but if I run it like that, I get all sorts of issues, however if I run it at 3.125 MHz (Intel 8080b), It works fine.... I'm not even sure where to start debugging that, and as it works, I'm just tempted to leave it.
wow great stuff, I was wondering if you had moved on from this. Can't wait to try it out! Thank you.
Reply To Topic (minimum 10 characters)
Please log in to reply