Allegro.cc - Online Community

Allegro.cc Forums » The Depot » Please have a look at my latest effort (Purple Martians)

This thread is locked; no one can reply to it. rss feed Print
Please have a look at my latest effort (Purple Martians)
Michael Weiss
Member #223
April 2000

Hi all,

I have just finished porting my game "Purple Martians" from Allegro 4.4 to Allegro 5.2.

https://www.allegro.cc/depot/PurpleMartians

I would love any comments, reviews, new levels created with the level editor or anything.

Of particular note, I am really proud of how the display works.
Dynamic resizing while the game is playing!
Full screen on and off with F12 and resizing and moving a windowed display.

Also while the game is playing the entire level can be zoomed in and out with
F5 and F6.

I made my own multiplayer using libnet to send packets, and zlib to compress them.
I spent so many hours of my life, working all the kinks out of that..

The in-game help file uses a markup language I created to display formatted text
as well as static and animated images, it looks really cool.

I used the spline routines to make a cool animated logo of my initials for the splash screen.

All of this works identically across XP, 7, 10, and linux.

I have not include the sources with this release, but I will email them to anyone who asks...

<humor>
All you have to do is sign a waiver promising not to make fun of my horrible kludges!
<\humor>

So if anyone can spare the time to have a look at my project, it would be greatly appreciated.

I was away in the real world for many years, and it saddens me to see how allegro.cc is not as active as it used to be :'(

Eric Johnson
Member #14,841
January 2013
avatar

I played the first level on Windows 10. When I first launched the game, I got an error that said, "failed to initialize audio". I tried again and it worked without issue though.

Things I liked:

  • The animation as your name came into view.

  • The particle effect that is displayed hen defeating enemies.

  • The music and sound effects ("bonus").

  • The "in" and "out" things; it's fun to watch the player travel through the lines.

  • The general creativity and puzzles.

Some things I thought were odd:

  • The FPS defaults to 40 in the options menu. Why not 30 or 60?

  • The default key bindings were bizarre; I had to bind them to something else.

I had a lot of fun playing the first level. I'll definitely be playing more of this in my spare time. It'll be interesting to try making my own levels, too! Well done and thanks for sharing! :D

Michael Weiss
Member #223
April 2000

Thanks for the comments Eric, I really appreciate it.

The animation of my name is done with Allegro splines..

The particle effect is very simple.
I have a few animation frames I hand drew (just like every sprite I use!)
that I use for the death sequence. They are the same size, but I stretch draw them.

The music was gifted to me by a poster called Russel Hoy in 2000. He asked for a
copy of the sources, (which I would have given for nothing), and he wrote a small
.xm file that he said I could use as a sound track for the game.
I really like the music too, it goes great with the game.
I have no idea how to get a hold of Russel anymore...

Why 40 FPS? That was a design decision made many years ago.
All the players, items, and enemys speeds are based on that.
Also the netgame needs to send and receive packets based on that speed.
40 is a nice round number, it means each frame takes 25ms.

The key bindings are a favorite of mine. That's just where my fingers naturally
seem to fall on the keys. IJKL has then same layout as the arrow keys, its just
in the middle of the keyboard. My left hand uses the first 2 fingers for jump
and fire and SPACE and C. Of course you can change them to anything you like.
Just out of curiosity what key bindings did you choose?

Thanks for your comments, I hope you make some levels.
PM me if you have any questions..

Mark Oates
Member #1,146
March 2001
avatar

Could you attach the source to a post? I'm on OSX and can't play it but would like to take a look. :)

Michael Weiss
Member #223
April 2000

Ok, I've attached the sources to this post.
Its not pretty, but it it works.
Lots of things might not be obvious.
Ask me anything, like where certain features are, how I set
up my development environment on windows and linux, etc.
You can pm me or ask me here...

Eric Johnson
Member #14,841
January 2013
avatar

40 is a nice round number, it means each frame takes 25ms.

Fair enough. My only gripe with that is that the frame timing might be inconsistent. If using a 60 Hz monitor, you should strive for each frame to be displayed for the same amount of time within 1 second. 60 FPS would be best, but 30 FPS works as well. 40 FPS doesn't allow for each frame to have the same amount of time spent on the screen when running at 60 Hz. But your game allows for it to be changed, so it's not really a problem.

Quote:

Just out of curiosity what key bindings did you choose?

I changed it such that Z is jump, X is fire, and the arrow keys are for movement and looking around.

Michael Weiss
Member #223
April 2000

Thanks for your comments Eric,

As far as the FPS thing goes, I agree with you in principle.
If the screen refreshes at 60 fps it would make sense to refresh
at either 60 or a multiple of that, like 30.

I think that just about every system I've tested on probably had a
screen refresh rate of 60.

The thing is, I have have never noticed any problems running my game at 40.
The graphics seem to run very smoothly.

The only time they seem to be choppy is if frame skipping is going on.

In my game I have a timer running at the fps that I want.
If the game can't keep up to the internal timer, I will skip drawing
for that frame. When that happens the game seems a little choppy.
Not unplayable, but not something you'd want to live with for long.

You can literally set the FPS to 1000 or more and the game will run.
Its almost impossible to control at that speed, and lots of frames
will be skipped, but it will run.

In the normal running of the game, every frame I wait for the timer
before drawing.

I have a speed test mode, where I disable this and run the game as fast
as it can go, while still drawing every frame.

This allows me to test:
- how fast the hardware I'm running on can go
- what effect different screen sizes and zoom levels have
- what effect different drawing methods in my code have

When I use open_gl, it was automatically capping my maximum fps
to the refresh rate of the monitor. D3D did not.

That made sense to me, as it didn't seem to make sense to refresh the screen
faster than the monitor was capable of displaying.

I found a way to disable that limit though, just for testing.
(export vblank_mode=0)

But still I never noticed any stuttering, or weird screen effects or anything.

The game seems to run smoothly at any fps (unless skipping)

Maybe, I just can't see it...8-)

Did you notice anything like that?

Thanks again, for your comments and feedback, I really appreciate it.

Eric Johnson
Member #14,841
January 2013
avatar

The thing is, I have have never noticed any problems running my game at 40.

I didn't notice any issues either. I just thought it was a strange choice was all. :)

GullRaDriel
Member #3,861
September 2003
avatar

Nice to have a new entry with A5 and even networking support !

Keep going, it's good job :-)

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Edgar Reynaldo
Member #8,592
May 2007
avatar

Okay, I tried running it. Loved the animation. Sat still too long on the menu screen and then it went into the demo and I couldn't quit or stop or anything. Not very nice to have to kill your game with Task Manager, it also crashed when I pressed CTRL-ALT-DEL.

EDIT
Played through seven or eight levels, pretty fun, addictive little game. It's strange that 'save game' isn't on the main menu. Also, it crashed when I pressed ESC from the main menu.

Michael Weiss
Member #223
April 2000

OMG Edgar played my game!

Sorry to sound like a giddy schoolgirl, but I've read many of your posts and I might be a little starstruck here! (I'm not worthy!)

I really admire you (based on the posts I've read) and value your opinion.

OK enough fawning...

The demo mode is supposed to cancel when any key is pressed.

I'm sorry the game crashes on you, can I ask what OS?
(I'm guessing windows because of the task manager comment)
But what version of windows and is it 32 or 64 bit, etc..
I really want to get to the bottom of this and fix it.
First step, as always is to figure out how to reproduce it.

I did all of the windows development on windows 7 64bit and the linux development on ubuntu 16.04
For testing I have a roomful of 12 computers with a mixture of windows xp, windows 7, windows 10, and ubuntu 16.04
I didn't experience the freezing or having to kill with task manager.
I did have some random linux bugs where exiting the game would freeze the system so
hard I would have to restart the session.

What version of my game did you try?
In between 7.02 and 7.03 I fixed some bugs in my exit routines that were trying to destroy some non existing bitmaps...duh

By the way I tried to find some examples of the proper way to shut down Allegro.

I thought I read somewhere that you do not have to manually destroy bitmaps at exit, because when they are created, they get registered somehow to automatically get destroyed on exit.
I tried to look this up in the documentation, but could not find where I read it the first time.

Also, what is the proper order to destroy display and event queue?

Does any of this matter, or will al_uninstall_system() just take care of all that?

Right now my exit code is:
// destroy all the bitmaps
al_destroy_event_queue(event_queue);
al_destroy_display(display);
al_uninstall_system();

The save game thing.
I should probably rename that, as it probably does not do what you would expect.
It saves an array of every control change, indexed by the frame the change occurred on.

The purpose of this is to play back a previously played game. (that's what the demos are)

But most people would probably assume "Save Game" is more like a save state thing.

Thanks for playing my game and giving me feedback. Its the best reward possible.

The game is free, what other reward could I possibly get other than someone playing it and sending feedback?

If you could help me with information on your setup so I can try to reproduce the crashing bug, that would be greatly appreciated.

Thanks again

Edgar Reynaldo
Member #8,592
May 2007
avatar

I really admire you (based on the posts I've read) and value your opinion.

Well, thank you. I appreciate that. Perhaps you haven't read all my posts though. ;) Ha, I jest. (Sometimes I get a little argumentative but I've tried to chill out). ;)

I downloaded 7.03 and I'm on Windows 10.

It consistently crashes on exit when pressing ESC from the menu.

Here's the best backtrace I could get you :

Thread 1 received signal SIGSEGV, Segmentation fault.
0x775799d7 in wcstok_s () from C:\WINDOWS\System32\msvcrt.dll
(gdb) bt
#0  0x775799d7 in wcstok_s () from C:\WINDOWS\System32\msvcrt.dll
#1  0x77579913 in wcstok_s () from C:\WINDOWS\System32\msvcrt.dll
#2  0x00473678 in al_clone_bitmap ()
#3  0x0047c14f in al_convert_bitmap ()
#4  0x0047c688 in _al_convert_to_memory_bitmap ()
#5  0x004efcd2 in d3d_destroy_display_internals(ALLEGRO_DISPLAY_D3D*) ()
#6  0x004efd84 in d3d_destroy_display(ALLEGRO_DISPLAY*) ()
#7  0x0045e8b6 in final_wrapup() ()
#8  0x0064a2a6 in main ()

Also, where did my game go? I was on like level 10 or something when I quit and it crashed last time. Oh, I see, a 'save' game is not a save game at all but a replay of your game. Not quite sure how that works I tried to run my save game but it only lasted a couple seconds.

I can't get the Demo screen to lock me out again. Pressing a key seems to work fine to stop the demo now. Don't know what that was.

Anyway, quite a fun game. Currently stuck on level 9. Keep getting shot down by all the weird flying grey circles. ;P

If you're interested in what memory allegro tracks behind the scenes, here's a quick glimpse :

e:\LIBS\LIBS72Build\allegrogit\src>grep -r -E -I -n "_al_register_destructor" .*.*
.\bitmap.c:191:      bitmap->dtor_item = _al_register_destructor(_al_dtor_list, "bitmap", bitmap,
.\bitmap.c:477:   bitmap->dtor_item = _al_register_destructor(_al_dtor_list, "sub_bitmap", bitmap,
.\dtor.c:72: *  zero, _al_register_destructor will do nothing.
.\dtor.c:153:/* Internal function: _al_register_destructor
.\dtor.c:162:_AL_LIST_ITEM *_al_register_destructor(_AL_DTOR_LIST *dtors, char const *name,
.\events.c:109:      queue->dtor_item = _al_register_destructor(_al_dtor_list, "queue", queue,
.\shader.c:72:      shader->dtor_item = _al_register_destructor(_al_dtor_list, "shader", shader,
.\timernu.c:259:         timer->dtor_item = _al_register_destructor(_al_dtor_list, "timer", timer,

e:\LIBS\LIBS72Build\allegrogit\src>

So, it keeps track of timers, shaders, queues, and bitmaps. Essentially, all you need to do is hit atexit. BUT, atexit has its problems too. Allegro won't always shut down correctly for some reason or another, so it's best to just call al_uninstall_system() manually at the end of your game.

Warning - if you register 'atexit' inside a dll, it will be THAT dll's atexit that will call allegro's shutdown routine! NOT main's!

Michael Weiss
Member #223
April 2000

I was able to consistently reproduce the bug on window 10.

I removed everything from my 'final_wrapup' function except the call to al_uninstall_system();

I also turned off compiler optimizations that I only used on release versions of my game.

The bug seems to be fixed, with the small amount of testing that I have done,
I haven't been able to make it crash again.

I guess I didn't need to worry about destroying all those things.
I've just had that in my code for so long, I assumed I needed it.

Thanks again Edgar for helping me with that.

I released version 7.04 (now with less crashing!)

Edgar Reynaldo
Member #8,592
May 2007
avatar

Michael Weiss
Member #223
April 2000

Glad you liked the animated logo!

It doesn't use transforms, its all done with splines.

My array of points to draw the splines, has its center at 0,0 and ranges from -200, -200 to +200, +200

It is then trivial to scale x and y independently by multiplying all the x or y values by a scaler.

I have a routine to draw scaled text (x and y independently) and if the scale is negative, to h_flip or v_flip. This is how the small letters are done.

I was even thinking of taking that part of my code and making something for examples...

Also btw, I love your spiraloid art. One of the very first things I did as a programmer, when I was about 12 or so, on the Apple II, once I got past text programming, was to make string art drawings by drawing lines. I loved the moire patterns created by aliasing. Your drawings are very beautiful, in a cold mathematical kind of way.

---------------

The levels in the game are not as well arranged as I would like, but I seem unable to do any better...

I have re-arranged them so many times, but have never been satisfied.

I tried to put the simpler levels first 1-20 then the harder ones 20-40.

I find myself getting tired of having to kill all the enemies on some levels
and would like to make that easier, or less boring and grindy somehow.
The solution is probably just to create a less boring level!

My favorite levels are ones where its like a kind of puzzle. I also really like ones where there are multiple way to do it.

You know you can start playing any level? Just use right and left on "Start Level" in the menu. Also if you press enter on "Start Level" you get my nice little 'visual level select'.

I wanted to include all the levels, but I also want a way to highlight what I think are the best ones. Still thinking about that.

If you don't play all the levels, at least try some from this list of my favorites:
26
30
20
23
21 (for multiplayer)

some quite long levels:
25
36
31
32

I'm afraid there are some not so great levels between 11 and 20
if you get bored, don't give up on the game, just skip the level!

Thanks for playing!!

Edgar Reynaldo
Member #8,592
May 2007
avatar

Also btw, I love your spiraloid art. One of the very first things I did as a programmer, when I was about 12 or so, on the Apple II, once I got past text programming, was to make string art drawings by drawing lines. I loved the moire patterns created by aliasing. Your drawings are very beautiful, in a cold mathematical kind of way.

My first programming experience was with GW-BASIC on a Leading Edge back in the early 80's when I was a young kid. I also drew lines, like around the edge of the screen in color - I thought that was the coolest thing ever. OMG gosub FTW. And line numbers and execution tracing. Try that with a program from today and the dumb will be GigaBytes large.

I'm glad and grateful that you appreciate my Spiraloid art. Math IS Beautiful. I love visualizing math in colorful ways. Moire patterns ARE awesome. (EDIT : http://members.allegro.cc/EdgarReynaldo/previews/Spiraloid/Moire1a.html )

Michael Weiss said:

If you don't play all the levels, at least try some from this list of my favorites:

Haha, ok, I'll try to play more when I get time. Have you had a chance to try Skyline (my latest version) ?

Rage, rage against the dying of the light (Dylan Thomas)

E.

bamccaig
Member #7,536
July 2006
avatar

Nice job. It's very impressive. I jumped straight to level 26 and played through that. It took some trial and error, but I guess I figured it out. I even beat the level I think!

Eric Johnson
Member #14,841
January 2013
avatar

I'm going to see if I can get my brother to play multiplayer with me. I haven't looked into it yet, but how does that work exactly? If I host a game, do I need to open a port through my router and give him my public IP address?

EDIT

I get an error when selecting "Join Network Game": "Error: Client initialization failed". Any ideas?

Michael Weiss
Member #223
April 2000

As far as I know the netgame will not work over the internet. I have never tried.

The way its set up, its a very tight loop.

A client sends its moves to the server, the server consolidates all moves and syncs them back to the clients.

I always imagined that the latency of the internet would make that impossible, so I never even tried.

I call my method LAN networked multiplayer, to highlight that its not internet.

Anyway, to make it work is very simple:

- Both machines must be able to ping each other.
- The server does not need to know anything about the clients.
- All the clients need to know is the server's IP or hostname.

On the client you can set the server hostname from options->netgame option

Then just choose 'Host Netgame' on the server and 'Join Netgame' on the clients.

It works great on a LAN, I have spent many hours playing and testing it.

Netgames can span all versions of Windows (XP, 7, 10) and linux!

If you want you can even start a netgame from the command line like this:

pm -s (host netgame on current start level specified in config file)
pm -s 10 (host netgame on level 10)

pm -c (join netgame and use server name from config file)
pm -c ip (join netgame and use supplied server name)

You might have to open a firewall exception for the server (some systems need this, some don't)

The error you are getting: "Error: Client initialization failed"
means that the client attempted to connect to the server (whatever has been set)
and failed to get the proper response.

Basically make sure both machines can ping each other.
Make sure the client has the server's ip or hostname.
Set this from the menu or in pm.cfg or from the command line.

The error is probably related to one of those things not being right.

Hope you get it working and have fun in a netgame!

Its lots of fun to ride rockets and have another player grab onto it also.
Then you can both steer and crash!!

Its also lots of fun to shoot each other! Or even, god forbid, cooperate!

In netgame options you can turn off deathmatch bullets, and then players bullets
will not hurt other players.

You can also set the amount of damage that player's bullets do to each other.
100 = instant kill!

As an added bonus you can also set the amount of damage to a negative number.
Then when you shoot another player you actually give them health!!

Let me know how it goes, or ask me any questions....

Michael

Frank Drebin
Member #2,987
December 2002
avatar

Tested on Win10. This is a really polished game! I noticed that my fans speed up when running the game and that it seems to use 100% of one CPU-core. In allegro 4 I added rest(1) to the game loop to avoid that, I don't know the Allegro 5 equivalent (yet). Also the game crashed when I wanted to alt-tab to check CPU-usage but then I noticed that F12 helps to switch to windowed mode.

Michael Weiss
Member #223
April 2000

Thanks for checking out the game Frank Drebin! (if that really is your name..!)
As far as the CPU usage, the game is doing a lot of drawing every frame.
I'll have a look and see what I can find...

-----------------------------------------------------------

I have just released a newer version (7.05) with a few minor updates...

The default key bindings have been changed to something less 'bizarre' as suggested by Eric Johnson.

The names of 'Save Game' and 'Run Game' have been changed to 'Save Demo' and 'Run Demo' to cause less confusion. (Thanks Edgar)

I re-arranged all the levels again!
- 'A' levels are from 2-24
- segregated 'B' levels to 50+
- made three training levels from 90-92 that can be warped to, or skipped

I made the transitions from menu to game a bit slower so you can actually see them.

I did some clean up of the sources.
- removed lots of duplicated and deprecated variables and functions
- straightened out all the function prototypes and global variables
- removed a couple of source files that were no longer needed

Some minor bug fixes.

------------------------------------------------------

I have said in the past that I wanted people to pm me for the sources.
This was not about restricting access at all, it was more that I wanted a
personal contact with anyone that was interested in my game.

I have decided to release that requirement, and just give a link to the github repository:

https://github.com/mweiss001/purple_martians

I would still like to strongly encourage anyone that checks out the sources or the game to pm me or comment here on allegro.cc

mweiss001@gmail.com

Thanks all..

Michael Weiss

Edgar Reynaldo
Member #8,592
May 2007
avatar

Okay, I cloned pm and took a brief look at pm.h . Thanks for the .cbp by the way, I appreciate being able to see the whole project at a glance inside my favorite IDE.

I will say this first. Congratulations on managing the complexity of a full sized game like that. Good work.

Although, I'm a little frightened to look through the source code. I opened pm.h and it's full of dragons. Why so many globals? It shows a lack of consideration to organization on your part. Something else I saw right away, you're using char arrays in C++. Why not use std::string? You eliminate a giant source of array overruns with one swipe.

Where is main? Can you give me a small overview or outline of what is what in your project?

Michael Weiss
Member #223
April 2000

Did you miss the part where I said don't make fun of the horrible kludges?
I'm just kidding! I know that I have broken many good programming practices.
And I welcome any comments and suggestions.

In my defense, I came from a BASIC, and assembler background.

When I started this project 20 years ago, I did not know any C.

This was my learning project. I find it much easier to learn if I am making something at the same time.

I have gutted and re-written parts of the code base so many times, but there are still lots of artifacts, and older design decisions hanging around.

If I had to start all over again, there are many things I would do differently.

I am slowly refactoring and making things better, but usually only when I am changing something or troubleshooting. If its working I tend to leave it alone.

At one point around 2000, I decided I was going to re-do the entire project in C++.
That did not go as well as I planned. That's why all the source files are .cpp, but I don't really do anything that's not straight C.

I will look into your suggestion on std::string....

The overall organization is:

Files that begin with e_ are for the level editor (which at one time was a separate exe)

Files that begin with z are for the main game.

Files that begin with n_ are for the netgame

The one file that starts with y (yfilecom) is the common loading of levels and sprites

zmain.cpp has
main
initial setup
config files read and write
commandline arg processing
menu processing

zloop.cpp has the main game loop

zcontrol.cpp has the event processing loop

My event processing is probably a little unorthodox.

I have a function called proc_controllers() that I use to process all input,
I modified what it used to do in A4 so that it now also processes the event_queue.

When the game is running I call it once per frame.
When the game is not running, (menu's, level editor, etc) I just call it in whatever loop I'm using at the time.

In A4 I used to have so many places in my code (especially the level editor) where I did things like:

if (key[KEY_E])
{
while (key[KEY_E]);
show_all_enemies();
}

I really missed the key array from A4 so I made my own, and set it like:

if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
int k = ev.keyboard.keycode;
key[k] = true;
ret = k;
}
if (ev.type == ALLEGRO_EVENT_KEY_UP)
{
int k = ev.keyboard.keycode;
key[k] = false;
}

and now I use it like this:

if (key[ALLEGRO_KEY_E])
{
while (key[ALLEGRO_KEY_E]) proc_controllers();
show_all_enemies();
}

-------------------------------------

The way I draw each frame when the game is running is like this:

All my levels are 2000x2000 pixels (or 100x100 blocks at 20x20 each)

I generate the background only once when loading the level (or when I get a screen change)

The background is called: l2000

Then every frame I:

- copy the entire background from l2000 to level_buffer (also 2000x2000)
- draw all of the items, enemies, lifts, players on level_buffer
- copy only the section that I want to display from level_buffer to the back buffer
and apply scaling at the same time
- then I draw any screen overlays on the backbuffer
- then flip display and repeat

For speed reasons I use ALLEGRO_NO_PRESERVE_TEXTURE on all of my bitmaps
The ones that are generated every frame don't matter, but the ones that are not,
I have code to re-generate them if the screen changes.

This is just a quick pointer to where some things are in the game.
Please ask if you want to know where anything else is.

Michael

Go to: