Oh, the link is here.
http://www.execpc.com/~halkun/ff7/index.html
I think you should seriously consider using SDL instead. I haven't used Allegro but SDL has to be the greatest thing out there:
- All in open source, standard C (no C++)
- Supports Windows (DirectX), Unix (X, SVGAlib, framebuffer), MacOS, BeOS, with easy extensions to new platforms
- Is made to be as thin as possible and consume as little CPU as at all possible, while still giving you device independent features (can emulate color depth, but won't if you pick the right one)
- Contains 2D graphics support (blits), GLUT replacement for OpenGL (initializes the buffer but you must do drawing directly with the GL library), threads, timers, input, etc.
- The authors is Loki, the famous Linux game creators (ported Unreal Tournament, Descent, Quake, Railroad Tycoon 2 etc. to Linux).
- A very extensive support of addon libraries supporting it, such as MPEG2 decoders, music and sound, etc etc.
You can find SDL at www.libsdl.org
Also remember the Legacy project (www.legacy-ovwp.org), cooperation would be great epsecially in the music field, where you will need MIDI support. Legacy is strictly C++ but can it hurt that bad? At least we can share our discoveries.
It looks like a great project, too bad I have my hands full with Legacy. I'll help out as much as I can from there though, see if we come up with anything that can help you (or vice versa).
It also uses C, but don't worry. You can download C++ wrappers for it to make the function calls a little more sane for you OO people. Even though SDL is cool, Allegro offers many built in higher level functions too.
In other news, I think I've figured out how to play the movies. There is a animation player for *NIX called "Xanim" that works by loading win32 DLLs and executing the code inside. (This is the only way to get quicktime running in linux) This may be an option for x86 systems, but I have no idea what to do for Macs and Sparcs. Allegro only has native support for FLI. Hmm
Halkun: About C++ wrappers...hehe, you think I use C++ for the syntax? I have been using SDL for half a year now, and I never ever even tried searching for a C++ wrapper. What would be the point of such a wrapper? Isn't...
surface2->BlitTo(surface1, rect1, rect2);
...just the same as:
SDL_BlitSurface(surface1, rect1, surface2, rect2);
...they say exactly the same thing! There's no drawback with the C syntax, C++ wrappers are the most pointless thing ever made in most cases, only in a few cases where they extend a lot of the original functionality (like GTK-- does with it's signal system) it makes any sense.
If you think I like C++ for object.do(); rather than do(object);, then you are very mistaken. I *only* use C++ because of:
a) strong typing, constness, exceptions
b) templates
c) most importantly, polymorphism
If there was a better way doing that last point, polymorphism, in C, I would have used C, I don't care about syntax. Polymorphism in C can be extremely tedious though, so I stay with C++.
(Polymorphism is "virtual member functions", if you don't know what they can do then you should find out, because they are the only reason C++ exist, though C zealots like to think otherwise (like if having the a.b() rather than b(a) syntax has anything to say))
You see, I've had my roots in x86 machine code. That was the first thing I ever coded. I find C more of a machine code short hand. Over the years I've created a way that I do C. Unfortunitly, with the advent of C++ makes my particular coding style difficult to use and take advantge of what C++ has to offer at the same time. For example;
1) I enjoy and embrase the use of globals for all major varibles. I even keep them in thir own .c file. Because of this, the need to keep varibles "public" and "privite" is drasticly reduced.
2) I'd like to call any fuction from anywhere. You will never know when you will need it. If I want a function not callable, I wont extern it. for example I have foobar.c and in it I have foo() and bar(). foo() is the main function and bar() helps foo(). Because foo() is the function I'll only be calling in foobar.c I'll extern foo() and make is seeable by all. bar() is my privite function.
3) As opposed to using classes as objects, I use whole .c files as objects. Everything public is global and everything privite is not externed.
4) almost always my structs are global.
5) I happen to like what +,-,/,* do already. As oppsed to overloading * to square as opposed to just mutiply, I'll write a fuction to do it instead.
6) It took me almost twice as long to figure out what a class was then it did for me to correctly use a pointer. when I realized that it was just a struct with a function in it, I became bitter and decided not to use such an animal.
7) I >> don't >> like >> streams
8) You can call C code fom C++ code. So I'm not breaking compatibility.
9) I obsess about little things like my C coding style.
that's why.
Example: A while ago I was coding an OpenGL graphics display. It could draw particles. So I had a TParticle class. Descending from that were TGlowParticle, TLightParticle, etc. If I had a particle of *any* type - even if I didn't know what it was - I just called particle.Render() and it drew itself. That's the beauty of OOP. Doing that in C would not be nice.
Plus it makes code a helluva lot easier to reuse safely!
Take Cosmo as an example; I reused the LGP code from LGP Editor. The code looks something like:
LGP := TLGPFile.CreateFromFile('d:...whatever.lgp'); Obviously, this looks nicer than the C++ equivalent because it's written in Delphi :) If you don't like streams ... then it must be the way C++ does them. Streams in Delphi are a lifesaver for me ... means I can have dynamically allocated memory without worrying about pointers. Plus I can write my code to work on a generic TStream and not care about where the stream actually came from. Example: My TFF7Level object (that Cosmo uses) has a LoadFromStream method. If I'm loading a level from disk, I pass it a TFileStream object. If I'm loading it from memory, I pass it a TMemoryStream object. If I really wanted to be clever, I'd define a new type TLGPStream that read data from an LGP and pass it that when I loaded a level from an LGP. I could go on ... OOP isn't the best solution to every problem but it sure simplifies a lot of them...
For I := 0 to LGP.NumEntries-1 do
lstNames.Add(LGP.Entries.Filename);
...