• Please review our updated Terms and Rules here

Here is a game I wrote (unfinished)

PgrAm

Experienced Member
Joined
Sep 28, 2011
Messages
276
Location
Toronto, Canada
As a follow up to a promise I made here

I'll post the game I made on this forum later so anyone can download it.

This is a game for dos that I wrote on a 386.

Some parts of this game such as the keyboard driver were shamelessly copied from "The Black Art of 3D Game Programming" (LaMothe, 1995)

I'm posting the game and the c++ source code all under Zlib license: http://zlib.net/zlib_license.html.
There is also a Turbo C++ project file included too.

WARNING: This game is completely unfinished. I'ts almost unplayable. It suffers from severe flickering on a 25Mhz 386 and runs too fast on a 486.

I welcome any programmers on this forum to offer patches to my code or advice on improvement.

Everything is in a zip file that I made on a modern computer so extract it before copying onto a retro pc.

View attachment vgagm.zip

EDIT:

I completely forgot to tell people what the game was about.

It's a pretty standard spaceship vs aliens kinda game where you scroll through space and shoot as many enemies as possible.
 
Last edited:
I've noticed that a couple people have downloaded it. Just wondering if anyone had gotten it to run? How do you like it? Any suggestions on how to improve it such as how to avoid the flickering?
 
I've noticed that a couple people have downloaded it. Just wondering if anyone had gotten it to run? How do you like it? Any suggestions on how to improve it such as how to avoid the flickering?

Well, you have NO buffering going on... you seem to set up a back buffer, but you're not using it for anything near as i can tell, at least, not as a real backbuffer.

The method I used in Paku Paku might work well for you here -- my back-buffer I clear just where all the sprites are, render the sprites new locations to the backbuffer, then copy the old locations and new locations from the backbuffer as my frame update. This way you aren't actually erasing it on the front-buffer until you are rendering it's new location. Since you know how big everything is and how far it moves, an 'overcopy' restore, where you copy the old position and new position in one slice from the backbuffer would eliminate all of your woes.

Something I'm noticing is that while you're in 320x200 256 color mode, you're really only using the base 16 vga colors - you may actually be better off dropping to 320x200 in 4 bit/16 color mode if that's all you're going to use -- the lower memory requirements means you'd have enough pages to have hardware buffering instead of doing it 'the hard way', single color items like text could be blitted far, far faster (since you can write all four color planes in one pass), even clearing the display would be faster since in planar mode you can hit 8 pixels in 16 colors with just a one byte write... though I'm a big fan of oddball 4 bit color modes, so that idea might just be me.

That would also mean porting all your sprites to 4 bit planar... still your 22x22 could be upped to using a 24x24 (3 byte across) area, but it would take only 288 bytes to write, far less than the 484 bytes of writing your current incarnation has to deal with.

Another option that could gain you some ground would be to switch to the so called 'mode x' -- unchained mode -- which I'd do if I really needed the full 256 color palette. In unchained mode it's planar by column, allowing you to access up to 256k of memory if you need it.... assuming that much video RAM is available.

When I first made Paku Paku I faced a lot of flickering issues due to being so concerned about blitting to the screen as fast as possible... learned a lot about manual and hardware double buffering from it.

Your blits could also be sped up a good deal.... take your enemy::draw method. If you calculated the and remainder per line FIRST, and put the X axis (sequential memory locations) as the inside loop instead of outer.... well.. (excuse this code, my C is pretty rusty) -- this should be way faster.

Code:
void enemy::draw() {

	int	pixelOffset=ix+(iy<<6)+(iy<<8);
	int rowIncrement=298;

	for (int iy=0; iy<11; iy++) {
		for (int ix=0; ix<22; ix++) {
			if (alien[iy][ix]!=CYAN) {
				videomem[pixelOffset]=alien [iy] [ix];
			}
			pixelOffset++;
		}
		pixelOffset+=rowIncrement;
	}
}

Far, FAR faster. Another speedup might be to use a mask filter instead of an if statement inside the loop, or to use what's called 'row count compression' on your sprites.... code sprites, while rather large in terms of code size, could also be much faster than going to the array. It's a method I'd forgotten about and another member mentioned to me here.

For example, let's take your 'starz'... I'm doing this in pascal+ASM because it's what I'm more comfortable with, but you should be able to get the idea.
Code:
procedure drawStar(x,y:word); assembler;
asm
	mov  di,x
	mov  ax,y
	xchg ah,al { faster than a shift 8 }
	add  di,ax
	shr  ax,2  { 2 is faster than 6 }
	add  di,ax
	mov  ax,$A000
	mov  es,ax
	mov  dx,$0007
	add  ax,2
	mov  es:[di],dh // 00
	add  ax,318
	mov  es:[di],dx // 0007
	add  ax,2
	mov  es:[di],dh // 00
	add  ax,316
	mov  es:[di],dx // 0007
	add  ax,2
	mov  es:[di],$0F07 
	add  ax,2
	mov  es:[di],dh // 00
	add  ax,316
	mov  es:[di],dx // 0007
	add  ax,2
	mov  es:[di],dh // 00
end;

It's a bit of work, but it's blazingly fast -- faster you can blit them, less likely you are to have flicker during the retrace... though again the true solution is to double-buffer.
 
Thanks so much for the help. I will definitely modify my blitting functions, I've made some modifications to my code since posting this but I will work in your suggestions too. For coded sprites I think I could probably write another C++ program just to generate some ASM code out of a bmp image, sort of a bitmap compiler. As for the onscreen buffer I had tried to implement one but things went bad real fast, such as the computer restarting when a certain pixel was written to (why I have no idea). I also tried entering mode X but for some reason that failed to. Double buffering however seems like my best bet.
 
Sorry for the bump, but I thought I would drop by and say that this is excellent. Good work! :)
 
Last edited:
Back
Top