Map file parser and linked lists

Started by
4 comments, last by Mephs 21 years, 10 months ago
Hi, I''m currently trying to design a map file parser for worldcraft .map files looking something like shown below
  
{
"classname" "worldspawn"
"sounds" "1"
"MaxRange" "4096"
"mapversion" "220"
"wad" "\halflife\valve\halflife.wad;\halflife\valve\xeno.wad;\halflife\valve\decals.wad;\halflife\valve\gfx.wad;\halflife\valve\liquids.wad;\halflife\valve\spraypaint.wad;\halflife\valve\cached.wad;\halflife\valve\de_aztec.wad;\halflife\valve\as_tundra.wad;\halflife\valve\cs_747.wad;\halflife\valve\cs_assault.wad;\halflife\valve\cs_bdog.wad;\halflife\valve\cs_cbble.wad;\halflife\valve\cs_dust.wad;\halflife\valve\cstrike.wad;\halflife\valve\ajawad.wad;\halflife\valve\mephs.wad"
{
( -528 178 -208 ) ( -528 178 -304 ) ( -528 246 -304 ) -1CSSANDWALL [ 0 1 0 -22 ] [ 0 0 -1 0 ] 0 1 1 
( -528 246 -208 ) ( -528 246 -304 ) ( -512 246 -304 ) -1CSSANDWALL [ 1 0 0 -112 ] [ 0 0 -1 0 ] 0 1 1 
( -512 178 -304 ) ( -528 178 -304 ) ( -528 178 -208 ) -1CSSANDWALL [ 1 0 0 -112 ] [ 0 0 -1 0 ] 0 1 1 
( -512 178 -208 ) ( -528 178 -208 ) ( -528 246 -208 ) -1CSSANDWALL [ 1 0 0 -112 ] [ 0 -1 0 150 ] 0 1 1 
( -512 246 -304 ) ( -528 246 -304 ) ( -528 178 -304 ) -1CSSANDWALL [ 1 0 0 -112 ] [ 0 -1 0 150 ] 0 1 1 
( -512 246 -208 ) ( -512 246 -304 ) ( -512 178 -304 ) -1CSSANDWALL [ 0 1 0 -22 ] [ 0 0 -1 0 ] 0 1 1 
}
{
( -528 -66 -208 ) ( -528 -66 -304 ) ( -528 30 -304 ) -1CSSANDWALL [ 0 1 0 66 ] [ 0 0 -1 0 ] 0 1 1 
( -528 30 -208 ) ( -528 30 -304 ) ( -512 30 -304 ) -1CSSANDWALL [ 1 0 0 16 ] [ 0 0 -1 0 ] 0 1 1 
( -512 -66 -304 ) ( -528 -66 -304 ) ( -528 -66 -208 ) -1CSSANDWALL [ 1 0 0 16 ] [ 0 0 -1 0 ] 0 1 1 
( -512 -66 -208 ) ( -528 -66 -208 ) ( -528 30 -208 ) -1CSSANDWALL [ 1 0 0 16 ] [ 0 -1 0 -66 ] 0 1 1 
( -512 30 -304 ) ( -528 30 -304 ) ( -528 -66 -304 ) -1CSSANDWALL [ 1 0 0 16 ] [ 0 -1 0 -66 ] 0 1 1 
( -512 30 -208 ) ( -512 30 -304 ) ( -512 -66 -304 ) -1CSSANDWALL [ 0 1 0 66 ] [ 0 0 -1 0 ] 0 1 1 
}
{
( -512 -82 -304 ) ( -812 -82 -304 ) ( -812 -82 -208 ) -1CSSANDWALL [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 
( -512 -82 -208 ) ( -812 -82 -208 ) ( -812 -66 -208 ) -1CSSANDWALL [ 1 0 0 0 ] [ 0 -1 0 -82 ] 0 1 1 
( -812 -66 -304 ) ( -812 -82 -304 ) ( -512 -82 -304 ) -1CSSANDWALL [ 1 0 0 0 ] [ 0 -1 0 -82 ] 0 1 1 
( -812 -82 -208 ) ( -812 -82 -304 ) ( -812 -66 -304 ) -1CSSANDWALL [ 0 1 0 82 ] [ 0 0 -1 0 ] 0 1 1 
( -512 -66 -304 ) ( -512 -82 -304 ) ( -512 -82 -208 ) -1CSSANDWALL [ 0 1 0 82 ] [ 0 0 -1 0 ] 0 1 1 
( -812 -66 -304 ) ( -512 -66 -304 ) ( -512 -66 -208 ) -1CSSANDWALL [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 
}
  
now I''m using the fopen and fread commands to navigate the file and retrieve the information I need, placing this information into variables forming a linked list of entities each having their own respective properties. Firstly, are fopen and fread good functions to be using for this kind of file? (if anyone knows of a more suitable set of commands please let me know!) Secondly I''m finding it hard to write functions to read the data as the data is usually not set in length of characters, Im finding I have to parse the entire file a character at a time as sometimes a coordinate could be 3 digits long, sometimes it can be 10 digits long, and the only way to read in a coordinate would be to keep reading a character at a time until a space is encountered, I''m wondering if theres a more efficient way, as reading a character at a time seems a little inefficient when you have the ability to read in blocks of data. Thirdly to construct my linked list from this data I''m guessing I need to write my own parsing commands to extract the data in a logical order. So I would need something along the lines of: GetNextCurlyBracketedLine(); GetNextBracketedLine(); GetNextQuotedLine(); GetNextSquareBracketedLine(); These functions would be used like this: Search for a curly bracket and find it''s respective close curly bracket, read all data into a variable to itself be parsed. This would at first load the entire world entity into a variable for further parsing. The parser would then look to see if this entity contained any further entities (search for more curly brackets) pulling the data contained into separate variable holders for further parsing. Once no more entities are found in the base world entity, and all entities within the last entity within the world entity (are ya following me here =p) have been dealt with... the parser can then parse all the entities found, using the other functions to gather the enitity information and assign it to the appropriate point in the linked list. Okay so this is roughly the route I''ve tried to follow, but I''ve found it difficult to maintain a linked list to hold the information. Each entity within the world entity has to know that the world entity is its parent, and may itself have child entities (a breakable window comprised of more than one brush for instance) Now I''m guessing that my problem may not be so much in designing the parser, as maintaining the linked list. I''m familiar with single linked lists where each object has a next and previous pointer, but in this case, the world would have many child pointers, so I''m guessing I need a hierarchical system, but I''m not too confident with designing a hierarchical linked list. Anyways I''m rambling on a lot and I''m kinda losing sight of what exactly I''m asking for help with, but if I''m headed in the wrong direction in any way please point it out and if you can see better ways of achieving what I''m trying to achieve (loading a .map file from disk into an appropriate data structure) please also feel free to comment... thanks for any help anyone can offer =) Steve AKA Mephs
Cheers,SteveLiquidigital Online
Advertisement
Whenever I need to parse a file for some reason, I always just go the whole way and use bison/flex solution.
It means declaring the syntax of the file, but once its done these will do the rest for you getting around most problems oyu are having.

If you want to do the work yourself I suggest using the C++ streaming functions to read/write text files. They make reading whole numbers etc. much easier than reading single chars at a time.
Hope this helps some.

<a href="http://www.purplenose.com>purplenose.com
heh, don''t mean to sound too dumb... but what is the bison/flex solution? Anything I can do a search on to find out more information? I gotta be honest I have never heard that phrase used before, so I wouldnt even know where to start looking and the search engine for gamedev returned absolutely zero on "flex", "bison" or "bison/flex"
Cheers,SteveLiquidigital Online
sorry, I should have done that.
Check out

http://www.combo.org/lex_yacc_page/

lex/yacc are the original parsers (I think just Unix implementations), but scroll down for info on Flex and Bison.
<a href="http://www.purplenose.com>purplenose.com
What you need is some sort of script library that can extract space/quote delimited tokens from string data. Then it''s easy to use atof to get the actual value.

Since this is Half-Life, I will suggest the source code for ZHLT 2.5.3, which contains a script libary designed especially for this reason - parsing MAP files among other things. Check it out, code should be scriplib.c and scriplib.h IIRC.
If you don''t want to use flex and bison, just use the fscanf function.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

This topic is closed to new replies.

Advertisement