|
game saves in allegro? |
relay01
Member #6,988
March 2006
|
Now this is WAY ahead in my scope of programming and even if this is possible I don't believe I'd be able to do it yet but I figured I'd throw it out there just because... I'm bored and seek conversation... _____________________________________ |
Inphernic
Member #1,111
March 2001
|
No, Allegro doesn't offer game saving (although one could use config files for it, that would be exceedingly ghetto). That doesn't mean it's not possible. -- |
spellcaster
Member #1,493
September 2001
|
Allegro packfile functions are exactly what you want. So, define your game data, and then save it. It's as easy as that. -- |
Inphernic
Member #1,111
March 2001
|
Quote: Allegro packfile functions are exactly what you want. More like "Allegro packfile functions are exactly what you need", considering that if he would know anything about file saving/loading in Whatever++^2, he wouldn't be asking it like this (leading one to assume that what he basically wants are save_game() and load_game()). -- |
relay01
Member #6,988
March 2006
|
I'm not entirely familiar with packfiles yet. I'm working in C++ (which i'm new to) and allegro (which i'm also new to) I've been learning as much allegro and c++ as I could at every moment of free time... Which has left me with headaches and sleepless nights for a fortnight. I actually welcome going to calculus class because it's less confusing. _____________________________________ |
Thomas Fjellstrom
Member #476
June 2000
|
allegro's PACKFILE is almost identical to C's FILE. -- |
spellcaster
Member #1,493
September 2001
|
See, we'd really like to help you, but right now what you're saying is basically: "I want to do stuff. Can allegro do stuff?" So, giving you an answer that actually helps you is kinda hard. But, let's say you're using something like this: typedef struct { int level; int score; int lifes; } GameData; for your game data, what you'd do to save the data is to simply open a file, store the data and then close the file. if you're only targeting a single platform, something like:
will do the trick. if you don't know the fopen / fwrite / fclose methods - google for them. They are the basic C file IO functions, and you'll see them a lot. Also, allegro's packfile functions are modelled after them, so once you know how to use the std c routines, the allegros fuznctsions will be less intimidating. -- |
Jonny Cook
Member #4,055
November 2003
|
Is there any reason why you would want to use Allegro's file IO routines instead of the standard C++ ones? The face of a child can say it all, especially the mouth part of the face. |
BAF
Member #2,981
December 2002
|
It's supposed to be more portable, endian safe, supports compression and encryption, and you can chunk it (pack_fopen_chunk). |
relay01
Member #6,988
March 2006
|
Well that is what I asked... exactly... I wanted to know if allegro could do such saving features and apparently they can with packfiles... now if somebody could explain to me what a packfile is and does and how to use them... that would be awesome squared... _____________________________________ |
Matthew Leverton
Supreme Loser
January 1999
|
Have you read the manual yet and tried? If you cannot do that, you cannot do anything at all. |
miran
Member #2,407
June 2002
|
Quote: now if somebody could explain to me what a packfile is and does and how to use them Spellcaster already did that. Read his post again, but replace FILE with PACKFILE and all the fsomething() functions with pack_fsomething(). Everything else is the same or at least very similar. The manual explains most things that need explaining in detail. -- |
m c
Member #5,337
December 2004
|
I'm away from my dev pc now (and will be for hours yet) but packfiles != grabber datafiles do they? (\ /) |
miran
Member #2,407
June 2002
|
packfiles != datafiles -- |
Tobias Dammers
Member #2,604
August 2002
|
datafiles == subset_of(packfiles) --- |
Shawn Hargreaves
The Progenitor
April 2000
|
At the risk of confusing things further, I have to say that fwrite (or pack_fwrite) are horrible API's. Totally untypesafe, error prone, and not portable across different endianess or processor word sizes. I'd strongly recommend using individual component write functions (putw, putf, etc) instead. |
Tobias Dammers
Member #2,604
August 2002
|
pack_mputXXX() is what you're looking for. --- |
relay01
Member #6,988
March 2006
|
Tobias... you changed your avatar so for a second I couldn't recognize you (I'm a visual learner) but luckily you have a funny name so I could quickly catch on... _____________________________________ |
Jonny Cook
Member #4,055
November 2003
|
Quote: At the risk of confusing things further, I have to say that fwrite (or pack_fwrite) are horrible API's. Totally untypesafe, error prone, and not portable across different endianess or processor word sizes. I'd strongly recommend using individual component write functions (putw, putf, etc) instead. But isn't pack_frwite just essentially pack_putc, except for an array of characters instead of an individual character? I thought pack_fwrite would look similar to this: void pack_fwrite(void *data, int size, PACKFILE *pf) { for (int i = 0; i < size; ++ i) { pack_putc(data<i>, pf); } } So what's so unsafe about that? I'm sorry, but my knowledge endianess is pretty limited. Is this something I need to consider whenever I read/write to/from files? The face of a child can say it all, especially the mouth part of the face. |
Shawn Hargreaves
The Progenitor
April 2000
|
Yes, that's exactly how pack_fwrite is implemented. The problem is, this is taking the address of some other type (eg. an integer), treating that as a void *, then casting the void * to a byte pointer and reading the data as individual bytes. This is not a safe thing to do. For one thing, it is very error prone. How does it know how many bytes to process? You have to tell it. If you tell it wrong, it does the wrong thing. And also, how many bytes there are in an int can be different on other machines. And which order those bytes are in can be different (that is called endianess). So a file you write on one computer will not be able to be read on a different one. Solution: don't use API's that take void * parameters (or at least, not unless you absolutely have to). They're evil and not typesafe. In this case you can easily just call the strongly typed methods for bytes, ints, floats, etc. Your code becomes portable, less error prone, and also shorter and more readable: what's not to like about that? |
Tobias Dammers
Member #2,604
August 2002
|
Quote: but luckily you have a funny name so I could quickly catch on... I take this as an offence. Quote: So what's so unsafe about that? I'm sorry, but my knowledge endianess is pretty limited.
What Shawn said. Or, to rephrase: Quote: Is this something I need to consider whenever I read/write to/from files? Yes, unless you store everything as single bytes or strings (which are arrays of bytes). --- |
CursedTyrant
Member #7,080
April 2006
|
Something like this perhaps?
--------- |
Shawn Hargreaves
The Progenitor
April 2000
|
That's the bad way to save things. It is just blindly dumping out whatever order of bytes happen to be in your PLAYER struct, which depends on what processor you happen to be running on today, and also how the compiler happened to lay out the struct in memory. The resulting files are fragile, non portable, and not future proof. The only safe way to do this is to write your fields one at a time through some kind of interface that has well defined endianess rules: output.WriteInt(p1->x); output.WriteInt(p1->y); Yes, it's a bit more typing for structures with lots of fields, but there are no shortcuts that don't lose safety. And this extra typing is often actually a good thing because it provides a clear reference about exactly what the format of your file is: very handy if you need to extend it in the future, or if your types grow to include some fields that shouldn't be saved to disk, or if you add things that can't be saved at all by a simple binary dump (for instance pointers to other objects). Actually I lied when I said there are no shortcuts: in languages with dynamic reflection capabilities (Python, C#, Java) you can use an automatic serializer to locate all the members for you and figure out the appropriate types. That's not possible in C++ though. |
Tobias Dammers
Member #2,604
August 2002
|
...and in fact, automatic serialization has its downsides. --- |
Shawn Hargreaves
The Progenitor
April 2000
|
It's true, the simple "just dump every single field" type serialization is pretty limited. But there are smarter ways, especially if your language allows you to add reflection metadata on a per-field basis. For instance in C# you could write a serializer that understood things like: class MyType { public int ThisWillBeSerialized; public OtherType AndSoWillThis; [NoSerialize] public int ButThisOneWillNot; [SerializeOptional(Default="Hello World")] public string ThisMayNotBeThereInOldFileVersions; } ie. most stuff just works automatically, but you can decorate the type to indicate where you want other things to happen. I'm a huge fan of reflection and attributes. It's a real shame that C++ doesn't support anything like that! |
|