[AD] compressed demo level |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
After having to download the level.txt over SVN, I made it so it is
loaded from a .dat file instead, to save some space. Result is this:
> l level.*
-rw-r--r-- 1 elias elias 45231 2006-01-02 21:29 level.dat
-rw-r--r-- 1 elias elias 193245 2006-01-02 21:00 level.txt
Patch is attached.
--
Elias Pschernig
Index: src/tkeniser.c
===================================================================
--- src/tkeniser.c (revision 5645)
+++ src/tkeniser.c (working copy)
@@ -7,8 +7,10 @@
int Error, Lines;
char ErrorText[1024];
struct Tok Token;
-FILE *input = NULL;
+PACKFILE *input = NULL;
+static int my_ungetc_c = -1;
+
/*
OVERARCHING NOTES ON THE LEVEL PARSER
@@ -83,12 +85,19 @@
\r\r - 2 line endings
*/
-int my_fgetc(FILE * f)
+int my_fgetc(PACKFILE * f)
{
static int LastChar = '\0';
- int r = fgetc(f);
+ int r;
char TestChar;
+ if (my_ungetc_c != -1) {
+ r = my_ungetc_c;
+ my_ungetc_c = -1;
+ }
+ else
+ r = pack_getc(f);
+
if (r == '\n' || r == '\r') {
TestChar = (r == '\n') ? '\r' : '\n';
@@ -104,7 +113,15 @@
}
/*
+ Hackish way to ungetc a single character.
+*/
+void my_ungetc(int c)
+{
+ my_ungetc_c = c;
+}
+/*
+
GetTokenInner is the guts of GetToken - it reads characters from the input
file and tokenises them
@@ -144,10 +161,10 @@
Tok struct an extra potential error condition is invoked */
do {
*Ptr++ = my_fgetc(input);
- } while (Ptr[-1] != '\"' && !feof(input)
+ } while (Ptr[-1] != '\"' && !pack_feof(input)
&& (Ptr - Token.Text) < 256);
Ptr[-1] = '\0';
- if (feof(input) || (strlen(Token.Text) == 255))
+ if (pack_feof(input) || (strlen(Token.Text) == 255))
Error = 1;
return;
}
@@ -172,12 +189,12 @@
/* check if this is a terminator or we have hit end of file as in either
circumstance we should check if what we have makes a valid number */
- if (breaker(newc) || feof(input)) {
+ if (breaker(newc) || pack_feof(input)) {
/* check first if we have a valid integer quantity. If so fill
IQuantity with that and cast to float for FQuantity */
char *eptr;
- ungetc(newc, input);
+ my_ungetc(newc);
Token.IQuantity = strtol(Token.Text, &eptr, 0);
if (!*eptr) {
Token.Type = TK_NUMBER;
Index: src/level.c
===================================================================
--- src/level.c (revision 5645)
+++ src/level.c (working copy)
@@ -446,7 +446,8 @@
*/
struct Level *LoadLevel(char *name, int radius)
{
- struct Level *NewLev;
+ PACKFILE *file;
+ struct Level *NewLev = NULL;
ErrorText[0] = '\0'; /* set ErrorText to be a zero length string
so that it will be obvious later if anything has set the error flag
@@ -454,11 +455,41 @@
Error = 0; /* reset error flag as no error has occurred yet */
Lines = 1; /* first line is line 1 */
- /* attempt to open named level file, report an error if that fails */
- input = fopen(name, "rt");
+ /* attempt to open named level file */
+ file = pack_fopen(name, "rp");
+
+ /* Find the data of the first object in the datafile. */
+ input = NULL;
+ {
+ /* is it a datafile? */
+ long magic = pack_mgetl(file);
+ if (magic == DAT_MAGIC) {
+ long i, n = pack_mgetl(file);
+ /* check all objects in it */
+ for (i = 0; i < n; ) {
+ long type = pack_mgetl(file);
+ /* skip properties of this object */
+ if (type == DAT_PROPERTY) {
+ pack_mgetl(file); /* type */
+ long size = pack_mgetl(file);
+ pack_fseek(file, size);
+ continue;
+ }
+ i++;
+ file = pack_fopen_chunk(file, FALSE);
+ /* use the very first DATA object found */
+ if (type == DAT_DATA) {
+ input = file;
+ break;
+ }
+ file = pack_fclose_chunk(file);
+ }
+ }
+ }
+
if (!input) {
uszprintf(ErrorText, sizeof(ErrorText), "Unable to load level.txt");
- return NULL;
+ goto error;
}
/* allocate and initially set up new level structure */
@@ -467,18 +498,15 @@
/* load materials, vertices & triangles in that order */
LoadMaterials(NewLev);
if (Error) {
- FreeLevel(NewLev);
- return NULL;
+ goto error;
}
LoadVertices(NewLev);
if (Error) {
- FreeLevel(NewLev);
- return NULL;
+ goto error;
}
LoadTriangles(NewLev, radius);
if (Error) {
- FreeLevel(NewLev);
- return NULL;
+ goto error;
}
/* do a repeat 'fix' of vertices and fix of edges until we have
@@ -494,22 +522,19 @@
/* load ordinary object types */
LoadObjectTypes(NewLev, radius);
if (Error) {
- FreeLevel(NewLev);
- return NULL;
+ goto error;
}
/* load special case object: door */
if (!(NewLev->DoorOpen = ObtainBitmap("dooropen"))) {
- FreeLevel(NewLev);
uszprintf(ErrorText, sizeof(ErrorText),
"Unable to obtain dooropen sprite");
- return NULL;
+ goto error;
}
if (!(NewLev->DoorShut = ObtainBitmap("doorshut"))) {
- FreeLevel(NewLev);
uszprintf(ErrorText, sizeof(ErrorText),
"Unable to obtain doorshut sprite");
- return NULL;
+ goto error;
}
NewLev->Door.Image = NewLev->DoorShut;
NewLev->Door.CollectNoise = NULL;
@@ -519,8 +544,7 @@
NewLev->TotalObjects = 0;
LoadObjects(NewLev);
if (Error) {
- FreeLevel(NewLev);
- return NULL;
+ goto error;
}
/* scale graphics according to current screen resolution. Note
@@ -541,16 +565,24 @@
/* load static level stuff - player start pos, etc */
LoadStats(NewLev);
if (Error) {
- FreeLevel(NewLev);
- return NULL;
+ goto error;
}
- /* close input file */
- fclose(input);
-
/* make a copy of the initial state */
NewLev->InitialState = BorrowState(NewLev);
/* return level */
return NewLev;
+
+error:
+ /* close input file */
+ if (input)
+ file = pack_fclose_chunk(input);
+ if (file)
+ pack_fclose(file);
+
+ if (NewLev)
+ FreeLevel(NewLev);
+
+ return NULL;
}
Index: src/game.c
===================================================================
--- src/game.c (revision 5645)
+++ src/game.c (working copy)
@@ -79,7 +79,7 @@
game_audio = load_datafile(AudioPath);
Scale = itofix(SCREEN_H) / 480;
- Lvl = LoadLevel("level.txt", 15);
+ Lvl = LoadLevel("level.dat", 15);
if (!Lvl)
return GetLevelError();
Index: include/tkeniser.h
===================================================================
--- include/tkeniser.h (revision 5645)
+++ include/tkeniser.h (working copy)
@@ -79,7 +79,7 @@
};
extern struct Tok Token;
-extern FILE *input; /* the file from which level input is read */
+extern PACKFILE *input; /* the file from which level input is read */
extern void GetToken();
extern void ExpectToken(enum TokenTypes Type);