From 78172175661c7a04ef494601fb6f1f080563c19a Mon Sep 17 00:00:00 2001
From: johns <>
Date: Sat, 27 May 2000 21:56:21 +0000
Subject: [PATCH] Added PudInfo and GetPudInfo for the menu loader.

---
 src/include/pud.h     |  23 +++
 src/stratagus/pud.cpp | 394 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 417 insertions(+)

diff --git a/src/include/pud.h b/src/include/pud.h
index 893fea5fd..c11d5c5a1 100644
--- a/src/include/pud.h
+++ b/src/include/pud.h
@@ -62,10 +62,33 @@
 #define MapActionRocks		0xFFFD	/// rocks on map
 #define MapActionForest		0xFFFE	/// forest on map
 
+/*----------------------------------------------------------------------------
+--	Declarations
+----------------------------------------------------------------------------*/
+
+/**
+**	Get info for a pud.
+*/
+typedef struct _pud_info_ {
+    char*	Description;		/// Map description
+    int		MapTerrain;		/// Map terrain
+    int		MapWidth;		/// Map width
+    int		MapHeight;		/// Map height
+    int		PlayerType[16];		/// Same player->Type
+    int		PlayerSide[16];		/// Same player->Side
+    int		PlayerGold[16];		/// Same player->Gold
+    int		PlayerWood[16];		/// Same player->Wood
+    int		PlayerOil[16];		/// Same player->Oil
+    int		PlayerAi[16];		/// Same player->Ai
+} PudInfo;
+
 /*----------------------------------------------------------------------------
 --	Functions
 ----------------------------------------------------------------------------*/
 
+    /// Return info for pud.
+extern PudInfo* GetPudInfo(const char*);
+
     /// Load a pud file.
 extern void LoadPud(const char* pud,WorldMap* map);
 
diff --git a/src/stratagus/pud.cpp b/src/stratagus/pud.cpp
index 5e5690adb..d376341ed 100644
--- a/src/stratagus/pud.cpp
+++ b/src/stratagus/pud.cpp
@@ -286,6 +286,400 @@ local int PudReadByte(CLFile* input)
     return temp_char;
 }
 
+/**
+**	Get the info for a pud.
+*/
+global PudInfo* GetPudInfo(const char* pud)
+{
+    CLFile* input;
+    long length;
+    char header[5];
+    char buf[1024];
+    PudInfo* info;
+
+    if( !(input=CLopen(pud)) ) {
+	sprintf(buf, "pud: CLopen(%s)", pud);
+	perror(buf);
+	exit(-1);
+    }
+    header[4]='\0';
+    if( !PudReadHeader(input,header,&length) ) {
+	fprintf(stderr,"%s: invalid pud\n", pud);
+	exit(-1);
+    }
+    if( memcmp(header,"TYPE",4) || length!=16 ) {
+	fprintf(stderr,"%s: invalid pud\n", pud);
+	exit(-1);
+    }
+    if( CLread(input,buf,16)!=16 ) {	// IGNORE TYPE
+	perror("CLread()");
+	exit(-1);
+    }
+    if( strcmp(buf,"WAR2 MAP") ) {	// ONLY CHECK STRING
+	fprintf(stderr,"%s: invalid pud\n", pud);
+	exit(-1);
+    }
+
+    info=malloc(sizeof(PudInfo));
+
+    //
+    //	Parse all sections.
+    //
+    while( PudReadHeader(input,header,&length) ) {
+	DebugLevel3("\tSection: %4.4s\n",header);
+
+	//
+	//	PUD version
+	//
+	if( !memcmp(header,"VER ",4) ) {
+	    if( length==2 ) {
+		int v;
+
+		v=PudReadWord(input);
+		DebugLevel1("\tVER: %d.%d\n",(v&0xF0)>>4,v&0xF);
+		continue;
+	    }
+	    DebugLevel1("Wrong version length\n");
+	}
+
+	//
+	//	Map description
+	//
+	if( !memcmp(header,"DESC",4) ) {
+	    if( CLread(input,buf,length)!=length ) {
+		perror("CLread()");
+		exit(-1);
+	    }
+	    info->Description=strdup(buf);
+	    continue;
+	}
+
+	//
+	//	Player definitons.
+	//
+	if( !memcmp(header,"OWNR",4) ) {
+	    if( length==16 ) {
+		int i;
+		int p;
+
+		for( i=0; i<16; ++i ) {
+		    p=PudReadByte(input);
+		    info->PlayerType[i]=p;
+		}
+		continue;
+	    } else {
+		DebugLevel1("Wrong player length\n");
+	    }
+	}
+
+	//
+	//	Terrain type or extended terrain type.
+	//
+	if( !memcmp(header,"ERA ",4) || !memcmp(header,"ERAX",4) ) {
+	    if( length==2 ) {
+		int t;
+
+		t=PudReadWord(input);
+		switch( t ) {
+		    case TilesetSummer:
+			DebugLevel3("\tTerrain: SUMMER\n");
+			break;
+		    case TilesetWinter:
+			break;
+		    case TilesetWasteland:
+			DebugLevel3("\tTerrain: WASTELAND\n");
+			break;
+		    case TilesetSwamp:
+			DebugLevel3("\tTerrain: SWAMP\n");
+			break;
+		    default:
+			DebugLevel1("Unknown terrain %d\n",t);
+			t=TilesetSummer;
+			break;
+		}
+		info->MapTerrain=t;
+		continue;
+	    } else {
+		DebugLevel1("Wrong terrain type length\n");
+	    }
+	}
+
+
+	//
+	//	Dimension
+	//
+	if( !memcmp(header,"DIM ",4) ) {
+
+	    info->MapWidth=PudReadWord(input);
+	    info->MapHeight=PudReadWord(input);
+	    continue;
+	}
+
+	//
+	//	Unit data (optional)
+	//
+	if( !memcmp(header,"UDTA",4) ) {
+	    char* bufp;
+
+	    length-=2;
+	    if( PudReadWord(input) ) {
+		DebugLevel3("\tUsing default data\n");
+		CLseek(input,length,SEEK_CUR);
+	    } else {
+		if( length<sizeof(buf) ) {
+		    bufp=buf;
+		} else if( !(bufp=alloca(length)) ) {
+		    perror("alloca()");
+		    exit(-1);
+		}
+		if( CLread(input,bufp,length)!=length ) {
+		    perror("CLread()");
+		    exit(-1);
+		}
+	    }
+	    continue;
+	}
+
+	//
+	//	Pud restrictions (optional)
+	//
+	if( !memcmp(header,"ALOW",4) ) {
+	    char* bufp;
+
+	    if( length<sizeof(buf) ) {
+		bufp=buf;
+	    } else if( !(bufp=alloca(length)) ) {
+		perror("alloca()");
+		exit(-1);
+	    }
+	    if( CLread(input,bufp,length)!=length ) {
+		perror("CLread()");
+		exit(-1);
+	    }
+	    continue;
+	}
+
+	//
+	//	Upgrade data (optional)
+	//
+	if( !memcmp(header,"UGRD",4) ) {
+	    char* bufp;
+
+	    length-=2;
+	    if( PudReadWord(input) ) {
+		DebugLevel3("\tUsing default data\n");
+		CLseek(input,length,SEEK_CUR);
+	    } else {
+		if( length<sizeof(buf) ) {
+		    bufp=buf;
+		} else if( !(bufp=alloca(length)) ) {
+		    perror("alloca()");
+		    exit(-1);
+		}
+		if( CLread(input,bufp,length)!=length ) {
+		    perror("CLread()");
+		    exit(-1);
+		}
+	    }
+	    continue;
+	}
+
+	//
+	//	Identifies race of each player
+	//
+	if( !memcmp(header,"SIDE",4) ) {
+	    if( length==16 ) {
+		int i;
+		int v;
+
+		for( i=0; i<16; ++i ) {
+		    v=PudReadByte(input);
+		    switch( v ) {
+			case PlayerRaceHuman:
+			case PlayerRaceOrc:
+			case PlayerRaceNeutral:
+			    break;
+			default:
+			    DebugLevel1("Unknown race %d\n",v);
+			    v=PlayerRaceNeutral;
+			    break;
+		    }
+		    info->PlayerSide[i]=v;
+		}
+		continue;
+	    } else {
+		DebugLevel1("Wrong side length\n");
+	    }
+	}
+
+	//
+	//	Starting gold
+	//
+	if( !memcmp(header,"SGLD",4) ) {
+	    if( length==32 ) {
+		int i;
+		int v;
+
+		for( i=0; i<16; ++i ) {
+		    v=PudReadWord(input);
+		    info->PlayerGold[i]=v;
+		}
+		continue;
+	    } else {
+		DebugLevel1("Wrong starting gold length\n");
+	    }
+	}
+
+	//
+	//	Starting lumber
+	//
+	if( !memcmp(header,"SLBR",4) ) {
+	    if( length==32 ) {
+		int i;
+		int v;
+
+		for( i=0; i<16; ++i ) {
+		    v=PudReadWord(input);
+		    info->PlayerWood[i]=v;
+		}
+		continue;
+	    } else {
+		DebugLevel1("Wrong starting lumber length\n");
+	    }
+	}
+
+	//
+	//	Starting oil
+	//
+	if( !memcmp(header,"SOIL",4) ) {
+	    if( length==32 ) {
+		int i;
+		int v;
+
+		for( i=0; i<16; ++i ) {
+		    v=PudReadWord(input);
+		    info->PlayerOil[i]=v;
+		}
+		continue;
+	    } else {
+		DebugLevel1("Wrong starting oil length\n");
+	    }
+	}
+
+	// FIXME: support the extended resources with puds?
+
+	//
+	//	AI for each player
+	//
+	if( !memcmp(header,"AIPL",4) ) {
+	    if( length==16 ) {
+		int i;
+		int v;
+
+		for( i=0; i<16; ++i ) {
+		    v=PudReadByte(input);
+		    info->PlayerAi[i]=v;
+		}
+		continue;
+	    } else {
+		DebugLevel1("Wrong AI player length\n");
+	    }
+	}
+
+	//
+	//	obsolete oil map
+	//
+	if( !memcmp(header,"OILM",4) ) {
+	    CLseek(input,length,SEEK_CUR);	// skip section
+	    continue;
+	}
+
+	//
+	//	Tiles MAP
+	//
+	if( !memcmp(header,"MTXM",4) ) {
+	    unsigned short* mtxm;
+
+	    if( !(mtxm=alloca(length)) ) {
+		perror("alloca()");
+		exit(-1);
+	    }
+	    if( CLread(input,mtxm,length)!=length ) {
+		perror("CLread()");
+		exit(-1);
+	    }
+
+	    continue;
+	}
+
+	//
+	//	Movement MAP
+	//
+	if( !memcmp(header,"SQM ",4) ) {
+	    unsigned short* sqm;
+
+	    if( !(sqm=alloca(length)) ) {
+		perror("alloca()");
+		exit(-1);
+	    }
+	    if( CLread(input,sqm,length)!=length ) {
+		perror("CLread()");
+		exit(-1);
+	    }
+
+	    continue;
+	}
+
+	//
+	//	Action MAP
+	//
+	if( !memcmp(header,"REGM",4) ) {
+	    unsigned short* regm;
+
+	    if( !(regm=alloca(length)) ) {
+		perror("alloca()");
+		exit(-1);
+	    }
+	    if( CLread(input,regm,length)!=length ) {
+		perror("CLread()");
+		exit(-1);
+	    }
+
+	    continue;
+	}
+
+	//
+	//	Units
+	//
+	if( !memcmp(header,"UNIT",4) ) {
+	    int x;
+	    int y;
+	    int t;
+	    int o;
+	    int v;
+
+	    while( length>=8 ) {
+		x=PudReadWord(input);
+		y=PudReadWord(input);
+		t=PudReadByte(input);
+		o=PudReadByte(input);
+		v=PudReadWord(input);
+
+		length-=8;
+	    }
+	    continue;
+	}
+
+	DebugLevel2("Unsupported Section: %4.4s\n",header);
+
+	CLseek(input,length,SEEK_CUR);
+    }
+
+    CLclose(input);
+
+    return info;
+}
+
 /**
 **	Load pud.
 **