Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » Creating an Old School Game Lib

This thread is locked; no one can reply to it. rss feed Print
Creating an Old School Game Lib
Goalie Ca
Member #2,579
July 2002
avatar

I Don't really have a lot of free time so it'll be curious as to how far i go. I plan to do it really slowly over a long period of time (scale = months).

I first learned the basic of programming on hypercard when i was in elementary school but forgot it by the time i was in high school. In high school i took it upon myself to learn QBasic. I didn't have a modern computer and it was all i had. I really ended up learning quite a bit of the ins and out and produced some pretty polished games fairly easily.

my first gaming experiences were on the C64 (and my neighbours atari) and an old school arcade at the mall back in the 80's (when they still had arcades). Then i learned to play nintendo, snes, n64, and now a nintendo DS.

Even though the published games at that time weren't multi-media experiences, they were well polished, could be done by a small team rather quickly, and were fun. Plus there's that nostalgic and "futuristic" feel of playing galaxian and robotron.

I'm not an artist (very creative just can never realize my ideas) and i simply don't have time to even pretend to be one. That is where most of my games have fallen apart in the past few years.

I've decided that i would once again love to make these old school games. I'm busy deciding on which QBasic functions to port over to allegro/openlayer/whatever. The idea is that i'm gonna "fake" a 320x200 screen on a modern surface. It'll have the following functions. It'll mimic the Qbasic state machine needless to say.

1COLOR( int num ); // sets the color, will be palleted using the 16 colors
2LOCATE( int row, int col); //locates the cursor for printing text
3std::string INPUT(std::string text) // prints string then asks for input
4SLEEP(); //waits for key to be pressed
5void DRAW(std::string command); //logo command string (possibly delay this one)
6void PRINT(std::string str); //prints starting at cursor
7float RND(); // generates random number between 0 and 1
8void LINE(int x, int y, int x2, int y2, SDL_Color& color, int flag) //flag NULL will draw line, "B" box, "BF" filled box
9void SOUND(float freq, float duration) //aah, pc speaker days ;D
10void PLAY(std::string input) //(possibly delay this one) input is a string of notes, commands, etc. this is basically midi interface that qbasic had
11void CIRCLE(int x, int y, int radius, int color); //draws outline
12void PAINT( int x, int y, int color, int border) // fills with color, stops at border
13void VSYNC(); //wait &H3DA in Qbasic waited for vertical sync
14void CLS() //clears the screen
15void PUT(int x, int y, bitmap* sprite, int FLAG) //puts the sprite at location, flag is either PSET (pixel set), xor, or, and etc.
16void GET(int x, int y, int x2, int y2, bitmap* dest) //grabs the screen and stores it in dest
17void PSET(int x, int y, int color); //sets the pixel
18//DATA 10, 24, 31, 15, 67, 34, 87, 92, 14
19DATA(std::string input) // parse the ints and put them onto a queue
20READ(int &a) //pops the data off the queue into a.
21void flip() //to copies the drawing buffer to the screen
22void DELAY(int milliseconds) //will try and sleep for amount of time

It may seem silly to try and cripple myself to use these functions but i'll constrain me to a certain art style and hopefully allow me to make something cool and retro by design rather than by skill :P I will hope to make it as authentic as possible without being stupid. There's no reason to have the screen flicker and the keyboard buffer fill up now is there? Keyboard input is one which i will not mimic. Qbasic had such awful handling that everyone resorted to peek and poke the keyboard buffer for scancodes etc. silly hack but had to be done.

I'm still working on how to deal with timing and drawing. I think a hard limit to 60fps will be good enough. I'll program it with that in mind. (or 30fps mode as well). Not gonna do threading. will use DELAY instead of a timer based event, process will sleep. If not vsync'd by user it will cause potential flickering (vsync cannot be reliably used as delay() as it was in the past because each monitor is different). But this potential minor tear shouldn't be nearly the same as drawing directly to the screen (in case it didn't have multiple pages as many didn't).

My first goal is to port my tetris and breakout games from Qbasic to this as part of testing.

-------------
Bah weep granah weep nini bong!

A J
Member #3,025
December 2002
avatar

this is daft.

___________________________
The more you talk, the more AJ is right. - ML

Simon Parzer
Member #3,330
March 2003
avatar

If you want to use QBASIC then use QBASIC.

kdevil
Member #1,075
March 2001
avatar

Limiting yourself to 320x200 and 16 colors is interesting, but...QBASIC? Ew.

-----
"I am the Black Mage! I casts the spells that makes the peoples fall down!"

Goalie Ca
Member #2,579
July 2002
avatar

Quote:

If you want to use QBASIC then use QBASIC.

well, the Basic language sucks to program in. I like using STL and and the rest. Plus being limited to dos really sucks (esp considering i use a mac and linux machine).

The whole point of using the Qbasic functions is to present myself with an old-school way of doing things. The tools you use gives the style of the art. Plus these constraints will make it easier for me to produce something polished (in the style of the 80's).

Maybe there's a better way of going about it or a better library/interface. I don't suppose any of you guys have any ideas?

-------------
Bah weep granah weep nini bong!

nonnus29
Member #2,606
August 2002
avatar

I think it sounds like your looking for a magic bullet to make game programming easier. I don't think that's possible. Games represent alot of complexity no matter what language; c, qbasic, assembler whatever. For example GDR is running a coding challenge right now to write a dig dug clone. Sounds easy right? Not until you really analyze how that old game works.

It looks like your list of proposed functions merely wrap existing allegro functionality. Why not just use allegro as is and limit your design? That's just my .02....

Paul Pridham
Member #250
April 2000
avatar

Matthew should just rename this website to "Nayllegro.cc".

Mordredd
Member #5,291
December 2004
avatar

I think you cannot limit a game to the screen resolution it runs with.

X-G
Member #856
December 2000
avatar

Today on Reinventing The Wheel: Square wheels!

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Goalie Ca
Member #2,579
July 2002
avatar

Now that you've all had your laugh on something i didn't quite think through that night... i've decided to modify things.

1) Square wheels. Well.. more like hexagonal ;)

2) I am gonna keep the text printing system as a state machine with rows, columns, etc. it may be worthwhile to have ncurses style for some types of games. That is where a window is a region, and print causes it to eventually scroll up. Those of you who've used ncurses before would get it. Would make a good console.

3) A new input class. It will be one of those "highscore" style inputs that arcade machines used to have.

4) I will include all of the classic modes like 320x200x16 and 640x480x255. Since computers like my mac can only run modern resolutions, I will stretch blit the draw surface to the screen (which can be whatever) when the user calls FLIP(). The blit doesn't distort, it will center vertically for example, if the game has a widescreen ratio (like 320x200). The draw surface itself will be 32-bit. When color number is passed into the drawing functions it is converted into the 32-bit and draws on draw surface automatically. Palette system basically. Idea is to create a super-thin wrapper on the allegro primitive and blitting functions.

5) sound? well never really used sound in allegro before. Will have to figure out that one still

6) Pixel Perfect collision detection. Will look to see what others have provided or write it my self.

edit:
I've decided to make a "window" class. It's not a gui window, just an area of the screen where i can do things to sprites or clear text or whatever. The idea is that there's a tree with the root node being the background. Then there may be a game window, or two game windows, a status window, a game stats window (level, points, highscore, lives, etc), or other windows that become active during certain parts of the game like game over or intro screen. I'm gonna have some pre-made and ready-to-inherit classes of common things to slap into my game as needed. Each window has a draw surface and wrapped allegro functions to it, basically the primitives and blitting.

-------------
Bah weep granah weep nini bong!

Neil Walker
Member #210
April 2000
avatar

Apart from a few classic remakes, you'll find 320x200 16 colour games are crap and defeat the object of bringing old ways to new platforms. What works best I think is old-style games utilising new-style ideas.

The quickest and easiest thing to do is make it 640x480, double your sprites in size and re-colour them.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Tobias Dammers
Member #2,604
August 2002
avatar

The stretch idea works nice for me; what my buffering code does is this: In fullscreen, if a native low-res (I'm using 400x300 now) mode is available, it uses that, otherwise it falls back on twice the size (800x600) and stretches; if that is not available, it uses 640x480 and creates ugly (but playable) graphics.
In windowed mode, it uses 800x600 for any desktop resolution that can hold it, otherwise 400x300.
Big advantage is that it runs super-fast on older machines (which can usually do low-res natively), but also works on newer ones that don't have native low-res anymore. It also look nice in windowed mode, when 400x300 would be too small.

BTW, I had quite some fun coding for the BackHack virtual machine; limiting yourself to a platform like that forces you to keep it small and not go overboard with ideas that require way too much manpower and produce nothing but abandonware.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Jonny Cook
Member #4,055
November 2003

I guess it's an interesting idea... but the only thing I could really see coming from it is a headache.

The stretching thing is I what I'm doing for my current project. I create a buffer bitmap that's 320x240, and just stretch it to the window size.

The face of a child can say it all, especially the mouth part of the face.

Niunio
Member #1,975
March 2002
avatar

Hey! That idea was mine ;).

May be you want to colaborate (just tell me what do you think about it). Anyway, a bit of healthy receipt would be nice. :)

-----------------
Current projects: Allegro.pas | MinGRo

Thomas Harte
Member #33
April 2000
avatar

I don't expect you care, but if you're going to limit yourself to 320x200 resolution then don't expect an easy Mac port. Macs have never had a 320x200 resolution and nowadays don't go below 640x480. Even Mac versions of games from the "classic DOS period" such as Chuck Yeager, Prince of Persia, Flashback, etc, run at 640x480. I also don't think they have anything that would allow an integer scale from 320x200.

Anyway, enough of that - I've been seriously thinking about challenging myself to finish a title for an old machine. I've done simple hardware manipulation before - a Mode 7 floor for the Atari Lynx, a few sprites floating around for the ZX Spectrum - but never really finished anything. The Lynx is actually a really cool hardware platform, which essentially works in the same was as DirectDraw with page flipping of frame buffers and hardware performed sprite draws therein.

Quote:

BTW, I had quite some fun coding for the BackHack virtual machine;

You didn't happen to keep the source code did you?

EDIT: I've found the library code at least...

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

You didn't happen to keep the source code did you?

I certainly have it somewhere, but I'd really have to dig deep into my zipped back-ups.

Quote:

I don't expect you care, but if you're going to limit yourself to 320x200 resolution then don't expect an easy Mac port. Macs have never had a 320x200 resolution and nowadays don't go below 640x480. Even Mac versions of games from the "classic DOS period" such as Chuck Yeager, Prince of Persia, Flashback, etc, run at 640x480. I also don't think they have anything that would allow an integer scale from 320x200.

A few thoughts:
a) Scale to 640x400, draw onto a 640x480 screen, leaving two black stripes. Cons: Skews the aspect ratio. Pros: Cheap (integral stretch), low-tech, no extra libs except allegro.
b) Anti-aliased stretch. No idea if this is feasible in real-time. Maybe through OpenGL; render to a memory buffer, upload as texture, draw a quad filling the while screen. Not very efficient in terms of bus usage etc, but since there will only ever be one texture per frame, it might work.
c) OpenLayer. Use it and be done with it. Gives you the benefits of b, but since you upload each sprite only once, and leave most of the rendering to the gpu, you'll achieve superior performance.
d) Run windowed if the desired res is unavailable. This way, you're not tied to screen resolution, but can use whatever makes sense (320x200 or 640x400 with 2x stretch or 960x600 with 3x stretch).

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Simon Parzer
Member #3,330
March 2003
avatar

Quote:

b) Anti-aliased stretch. No idea if this is feasible in real-time. Maybe through OpenGL; render to a memory buffer, upload as texture, draw a quad filling the while screen. Not very efficient in terms of bus usage etc, but since there will only ever be one texture per frame, it might work.
c) OpenLayer. Use it and be done with it. Gives you the benefits of b, but since you upload each sprite only once, and leave most of the rendering to the gpu, you'll achieve superior performance.

What's the difference? You can use b and render directly to a texture. That way it would have at least the same performance as c, I think.
Also, I wouldn't call it Anti-aliased, but filtered. The bilinear filter (OpenGL standard filter) would make things a bit blurry, though.

Tobias Dammers
Member #2,604
August 2002
avatar

There are quite some differences. For a start; b) renders everything to a RAM surface using allegro, then uploads that as a texture to OpenGL hardware and finally uses some gl calls to render a quad. c) uses openlayer to render everything using opengl; this means that all graphics are uploaded as gl textures; sprites are then drawn as opengl primitives. The cpu has little to do with this; most work is done by the gpu. The performance is very likely to skyrocket, although the potential is a gazillion times larger than any oldschool game will ever need.
Apart from that; b) uses opengl directly, and doesn't require openlayer. c) does, but you can use it without knowing much opengl.

Quote:

Also, I wouldn't call it Anti-aliased, but filtered. The bilinear filter (OpenGL standard filter) would make things a bit blurry, though.

Anti-aliasing refers to any algorithm that reduces or eliminates "aliasing" effects, which result from a single pixel value used as an "alias" for a subpixel position (upsampling) or a group of pixels (downsampling).
Bilinear filtering is the anti-aliasing algorithm usually used when upsampling. For downsampling, a weighted sum is a good algorithm. Both are anti-aliasing techniques. Multi-sampling is another one; it involves rendering the same scene, aliased, but with slightly different sub-pixel offsets, then averaging the resulting images.
Yet another approach for primitive edges is to calculate appropriate alpha values for each pixel, to mix it with the destination color.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Chris Katko
Member #1,881
January 2002
avatar

As for QBASIC functions: I think it's a great idea. It was fun making games with QBASIC. I made a Chopper Commando clone once. It ran slow, but then again, it was QBASIC.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Thomas Harte
Member #33
April 2000
avatar

I've always thought QBASIC was the worst BASIC. It's a slightly rubbish BASIC on a platform where much better languages are available and just as convenient. That said, as it's a nostalgia and deliberate limitation exercise that isn't really a valid complaint concerning the main project goal.

My only other interesting comment is that this topic has inspired me to dust off my Atari Lynx development tools and have a bash at a complete game. I'll probably fail miserably, but there you go. I've dusted off my old Mode 7 code, maybe I'll do something with that...

Goalie Ca
Member #2,579
July 2002
avatar

Heh, found this thought it was interesting. It's SDL based but check out the function list. It does a lot of the things i was talking about.

http://www.student.kuleuven.ac.be/~m0216922/CG/codebase.html

-------------
Bah weep granah weep nini bong!

Go to: