Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / Game Design & Programming / Platformisis - A new 2D sidescroller but different. Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
juhnu

December 02, 2004, 12:59 AM

the code is pretty readable and that's a very good thing. Although its also true that its way too over-abstractized without getting much benefits of such abstraction. even lots of abstraction layers, things like a bit depth is hard-coded in. anyway I would like to try out the game, anyone know where to get the binaries? I did find nothing but a source from the webpage and am too lazy to try and compile it.



juhani



 
tussukka

December 02, 2004, 07:56 AM

/*
If you can do a better reimplementation of the drawing primitives I would like to see it.
*/

I looked at your implementation, you have a switch() statement inside PutPixel() to figure out how to compute the color. You might want to do the decision just once for each primitive (like quad) you are drawing.

You obviously have go through some trouble writing the sourcecode so I refuse to believe that anyone would do that just for laughs therefore I hope you are serious about this.

If you want a good quality and reasonable performance look up "alpha blending", you can do it just fine with software renderer like yours. Basicly it means that for each 'sprite' you store you have four components (red,green,blue and alpha) instead of three you store now (red, green and blue).

Their meanins is as follows:

red,green,blue = pixel color
alpha = pixel translucency

If you use 32 bit picture this means you can easily have 8 bit per channel, and can use following struct to abstract what you are doing:

typedef unsigned char uint8;

struct pixel
{
uint8 b,g,r,a;
};

Now when you are drawing, you mix the color already in the buffer with the color you are drawing using the alpha, this way you can have smooth edges for sprites and translucency controlled per pixel that gives better image quality overall (YMMV). This technique is generally refered as "alpha blending" now you know how to find more information on the topic if you get interested.

A general rule-of-thumb in software rendering is to minimize the work you do per pixel, now you call functions, do switch statements you could do just once and so on. You have tens of times slower code that could get the job done that is not a very good thing.

Okay your code works on 2 Ghz processor if that is only thing you care about then indeed there is no point 'wasting time' on improving the architechture of your software. Premature optimization and all that. But when you start doing things against common wisdom from the start on purpose and even spend a lot of time and energy in *designing* application to be inefficient that is not something you might want to learn permanently. It's harder to unlearn bad habits than learn good habits.. I recommend that you try to think your design one more time from more pragmatic point of view but what you do is up to you and not my problem if you decide to get cranky instead. :)

But if the purpose is to LEARN by doing, you usually tend to learn much better when your goal is perfection rather than mediocricity (no offence intended, if you are smart you think very hard what I been saying and try to spot places in your code to improve it).

And I don't mean rewriting a function to be 2x faster but to think if you could avoid calling this function at all. Look at your putpixel for example, you compute the address individually for each pixel you write. Why? When you draw a box you surely see that in horizontal span next pixel is next addreses in memory and computing those is simple addition or incrementing, computing the address shouldn't be more expensive than that). Think about stuff like that and you will soon learn a lot about writing *efficient* software rendering from programming point of view and have easily 3-6 times faster code (it could be even faster but that kind of improvement goes without saying :)

Processors are fast, sure, but what if you want to draw 1600x1200 one day? You will notice that is _30_ times more pixels to draw than you do now.. will you wait for 30 times faster processors to be invented or what you do? If you don't have the skills NOR DESIRE TO ACQUIRE THEM to write fast enough code that's it: game over.

Programmable Graphics Processors have reduced the incentive and necessity to concern yourself with software rendering in this manner (to a degree, say, on a desktop) but the skills you acquire are universally useful in software writing. Some write good code and some write bad code that's just a fact of life it's up to you which group you _want_ to belong to. And in my opinion it is very hard to find a person for whom the problem is the capacity rather than the willingness to learn new things. Have fun!

 
Scoot

December 02, 2004, 08:52 AM

Went to the site, liked your title screen - though if you WILL accept one piece of constructive criticism: I think that it would be preferable if your title screen wasn't spelt incorrectly (or maybe that "crazy" font doesn't ship with an 'm') - just so that people know *exactly* which 2D side-scrolling game involving a giant fly they are playing :o)

-Scoot

 
FrancoisSoft

December 02, 2004, 09:11 AM

Thanks a lot! I'll look into the alpha blending like you said. :)

 
FrancoisSoft

December 02, 2004, 09:22 AM

Hmm... but I did the exact implementation you did and the results were not much better than PutPixel(). I'll try to improve the alpha blending but I have trouble visualizing scanlines. That's why I'm working at the pixel level otherwise I would probably be doing the scanline method. I did take some of the advice given here and converted some of my box drawing methods to the scanline method like what you're doing but when it comes to flipping images and rotating them I still have trouble visualizing that without pixels. Perhaps someday I will develop those skills. I am not an expert at gaming. I have been programming for 6 years but I never really developed gaming skills. I have developed enough programming skills to implement a game with no problem but when it comes down to it I really released the code for this project to see what other people could do with it. I really expected people to reimplement some of the methods within the code and send me the results so I could compare what they're doing and what I'm doing. You wouldn't mind helping me out in that way, would you? That's what I call constructive criticism. I want to see the implementation itself.

 
FrancoisSoft

December 02, 2004, 09:23 AM

Why not help me with the project?

 
tussukka

December 02, 2004, 09:37 PM

I'm not going to write you so much code since I have my own projects to work on, but here'st he generic idea of 'scanline' rendering:

First, you abstract the drawing canvas (or call it surface if you like), something along these lines:

struct surface
{
int width;
int height;
uint8* image;
int pitch;
};

The three first members are self-explatonary. The last one, pitch, is width of a scanline in BYTES (the difference to width is that width is in *pixels*). If you allocate the surface yourself, you can guarantee that:

width * sizeof(pixel) == pitch

But when you abstracting a 'surface' in graphics card memory this is not always the case, gfx hardware sometimes uses power-of-two pitch for the surfaces even if visible area (width) is something else. For example 640x480 screen might have pitch of 1024*bpp, where bpp is either 1, 2 or 4.

Sometimes the requirement is less strict and the pitch only has to be multiple of 32 bits, still if you have 3 bpp graphics mode (read: 24 bit color) there still might be need for padding bytes after each visible pixel in memory so that next scanline begins from address that is multiple of 4 bytes (32 bits).

That aside, now you know what the "pitch" is used for. Now how we compute address of a pixel, assuming we use the 32 bit graphics mode:

surface s = ...;
pixel* scan = reinterpret_cast(s.image + y * pitch);

Now scan points to start of the scanline the pixel is at, notice that we compute this address as uint8 pointer (char pointer), THEN convert it to 32 bit pointer (pixel*). The reinterpret_cast might look ugly but it is functional equivalent to (pixel*) typecasting with C-style cast. I use C++ casts because they carry a little bit more information about the intended cast and are easier to find from the sourcecode with 'search' functionality in text editors. ;)

OK, so now we have the scan address... to write a pixel with some specific color:

scan[x] = color;

That's it! ;)

Now how to draw a bit using scan method, what you want to do is to compute the address for top-left corner of the box.. you do it like above:

uint8* scan = s.image + box.y * s.pitch + box.x * sizeof(pixel);

Notice how I multiply the x by sizeof(pixel) so that correct address is computed horizontally, this is because the "pitch" is already scaled (since it is width of scanline in BYTES). Hope all still makes sense.

Next we will draw the box..

for ( int y=0; y

 
juhnu

December 02, 2004, 10:29 PM

I would really like to try out the game. where can I find the .exe and required files?


juhani

 
FrancoisSoft

December 03, 2004, 12:31 PM

The game is not finished yet so you will not see the binaries for another few weeks or so unless someone beats me to it.

 
FrancoisSoft

December 03, 2004, 12:32 PM

Fixed it. I was just being dumb that day.

 
FrancoisSoft

December 03, 2004, 12:33 PM

You can't compile the actual game yet but you can compile the toolkit and the testing suite. Just read the "How To" in the programmer's manual.

 
FrancoisSoft

December 03, 2004, 12:34 PM

The bit dept is not a problem and will never be. One of the backends makes sure that this dept is converted to the right dept for output. I am not willing to work with anything less than true color for the sake of speed.

 
FrancoisSoft

December 03, 2004, 12:36 PM

No, it gets this speed on a 300 megahertz. You will find the speed to be the same on a 400 megahertz pentium II. I wasn't even aware 2 gigahertz existed.

 
FrancoisSoft

December 03, 2004, 12:41 PM

The purpose of this thread is not to prove anything. I just want to share my code with other programmers but I don't just want people to tell me what's wrong. I want to see a reimplementation for some of all of the packages. I am a beginner at gaming and I learn by doing not by what others tell me. I have to see something to believe it. This project might be fun for you if you have nothing to do. The code is readable and highly portable. There is a testing suite to debug the already made packages and a toolkit for programmers. I have yet to write a hacker's manual explaining the internals of Platformisis. Just give it a try. Right now I'm implementing a font system. Next I'll brush up the utilities package and then work on a artificial intelligence library. So I might interest you to work on the project as well. You might even find that it get's interesting!

 
Chris

December 03, 2004, 12:44 PM

2GHz was my own assumption, I thought he was talking about a reasonably new CPU.

10M pixels/second on a 300MHz I don't believe. That'd be 30 clocks per call, and the code is faaar too loaded to achive that. He's even got a switch within his PutPixel.
Not that 30 clocks per call would be exceptionally good, of course not.

But then again he's been shouting numbers before, maybe the 10M is guesswork too. I'd like to see real profiling results.

And yes, that's one of the reasons I liked the 80286 days. Even as a noob you were immediately forced into THINKING about what you programmed, because you didn't have that many clock cycles to waste. For example, things like he shows us have been done on a 16 MHz machine using a larger frame buffer than his.

 
FrancoisSoft

December 03, 2004, 12:49 PM

I have no idea where you get 2GH from. My machine only runs at 400 megahertz. Sometimes I use one that runs at 900 megahertz. The scene backend can only process a little more than 65000 pixels at a time. This can be draw in less than a millisecond on a 300 megahertz machine. Transparent pixels don't even get processed and the average sprite size is 30x30 pixels. In the future when my visualization skills improve I will probably do away with the pixels but if you compiled any part of the testing suite you would find out that the method that you are talking about is not much faster than the pixel method. On average the scanline method is only 1/5 faster than the pixel method. So with a small screen and bad visualization skills I would gladly sacrifice this small fracition of speed for better visualization. Not everything is drawn using pixels. Backdrops are drawn using scanlines and call not other routines except memcpy(). In the future I might just do away with C++ for drawing and just go strait to assembly because that's much faster than C++.

 
FrancoisSoft

December 03, 2004, 02:06 PM

Compile the testing suite and then run it.

 
This thread contains 47 messages.
First Previous ( To view more messages, select a page: 0 1 ... out of 1) Next Last
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.