From df4e48ec16a4a2315e4f99ca91f4ad2f0b27fcea Mon Sep 17 00:00:00 2001 From: Per Inge Mathisen Date: Wed, 6 Apr 2011 22:06:17 +0200 Subject: [PATCH] qt branch: Kill off the over-engineered tagfile format. Replacing it with the more retro ini file format. --- data/Makefile.am | 1 - data/base/multiplay/script/scavfact.js | 2 +- data/base/tagdefinitions/savegame/effects.def | 27 - .../tagdefinitions/savegame/firesupport.def | 28 - data/base/tagdefinitions/savegame/map.def | 215 --- data/base/tagdefinitions/savegame/score.def | 19 - data/base/tagdefinitions/tagfile_basic.def | 37 - data/base/tagdefinitions/tagfile_virtual.def | 14 - lib/framework/Makefile.am | 2 - lib/framework/tagfile.cpp | 1428 ----------------- lib/framework/tagfile.h | 102 -- lib/framework/vector.h | 1 + lib/framework/wzapp.cpp | 42 + lib/framework/wzapp.h | 4 + src/effects.cpp | 159 +- src/game.cpp | 79 +- src/main.cpp | 2 - src/map.cpp | 1 - src/scores.cpp | 78 +- 19 files changed, 161 insertions(+), 2080 deletions(-) delete mode 100644 data/base/tagdefinitions/savegame/effects.def delete mode 100644 data/base/tagdefinitions/savegame/firesupport.def delete mode 100644 data/base/tagdefinitions/savegame/map.def delete mode 100644 data/base/tagdefinitions/savegame/score.def delete mode 100644 data/base/tagdefinitions/tagfile_basic.def delete mode 100644 data/base/tagdefinitions/tagfile_virtual.def delete mode 100644 lib/framework/tagfile.cpp delete mode 100644 lib/framework/tagfile.h diff --git a/data/Makefile.am b/data/Makefile.am index b9f465273..0699d3331 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -26,7 +26,6 @@ BASELIST = \ shaders\ stats \ structs \ - tagdefinitions \ texpages \ tileset \ wrf diff --git a/data/base/multiplay/script/scavfact.js b/data/base/multiplay/script/scavfact.js index 116413bea..dd9a36fe6 100644 --- a/data/base/multiplay/script/scavfact.js +++ b/data/base/multiplay/script/scavfact.js @@ -8,7 +8,7 @@ const buggy = "BarbarianBuggy"; const bloke = "BaBaPeople"; const jeep = "BabaJeep"; const firetruck = "BabaFireTruck"; -const cannonbus = "BabaBusCan" +const cannonbus = "BabaBusCan"; const firebus = "BabaFireCan"; // scav group diff --git a/data/base/tagdefinitions/savegame/effects.def b/data/base/tagdefinitions/savegame/effects.def deleted file mode 100644 index c17a487e1..000000000 --- a/data/base/tagdefinitions/savegame/effects.def +++ /dev/null @@ -1,27 +0,0 @@ -# -# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, -# EN for group end, BO for boolean -# VM: Must be no longer than the size given here; set to 00 for repeating groups -# default value cannot be set for VM > 1, ST, GR or EN -# -01 ST 12 - # Format identifier: "FXData" -02 GR 00 - # EFFECTS GROUP - 01 US 01 - # control - 02 US 01 - # group - 03 US 01 - # type - 04 US 01 - # frameNumber - 05 US 01 - # size - 06 US 01 - # baseScale - 07 US 01 - # specific - 08 FP 03 - # Position vector - 09 FP 03 - # Velocity vector - 0A SI 03 - # Rotation vector - 0B SI 03 - # Spin vector - 0C US 01 - # birthTime - 0D US 01 - # lastFrame - 0E US 01 - # frameDelay - 0F US 01 - # lifeSpan - 10 US 01 - # radius - 11 ST 00 - # IMD file name - FF EN 00 - diff --git a/data/base/tagdefinitions/savegame/firesupport.def b/data/base/tagdefinitions/savegame/firesupport.def deleted file mode 100644 index ad9cd51ac..000000000 --- a/data/base/tagdefinitions/savegame/firesupport.def +++ /dev/null @@ -1,28 +0,0 @@ -# -# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, -# EN for group end, BO for boolean -# VM: Must be no longer than the size given here; set to 00 for repeating groups -# default value cannot be set for VM > 1, ST, GR or EN -# -01 ST 12 - # Format identifier: "WZTAGFILE1" -02 GR 00 - # DROID GROUP - 01 US 01 - # Droid ID - 02 US 03 - # Droid position in (x,y,z) coordinates - 03 FP 01 - # RETIRED (had unknown usage) - 04 FP 03 - # RETIRED (had unknown usage) - 05 US 500 - # Long unsigned byte array - 06 US 500 - # Long unsigned byte array - 09 GR 00 - # Droid weapon group - 01 US 01 - # Weapon type - 02 US 01 10 # Ammo left - 03 US 01 0 # Time last fired - 04 US 01 0 # Recoil value - 05 SI 03 - # Array of signed int - FF EN 00 - - FF EN 00 - -03 GR 00 - # STRUCTURE GROUP - 01 US 01 - # Structure ID - 02 US 03 - # Structure position in (x,y,z) coordinates - FF EN 00 - -04 US 01 09 # Some default value of 9 diff --git a/data/base/tagdefinitions/savegame/map.def b/data/base/tagdefinitions/savegame/map.def deleted file mode 100644 index 3f44d8bbd..000000000 --- a/data/base/tagdefinitions/savegame/map.def +++ /dev/null @@ -1,215 +0,0 @@ -# -# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, -# EN for group end, BO for boolean -# VM: Must be no longer than the size given here; set to 00 for repeating groups -# default value cannot be set for VM > 1, ST, GR or EN -# -01 ST 01 - # Format identifier: "WZTAGFILE1" -03 GR 01 - # MAP INFO GROUP - 01 US 01 64 # Map width - 02 US 01 64 # Map height - FF EN 00 - -04 GR 01 - # CAMERA INFO GROUP - 01 FP 03 - # Camera position - 02 FP 03 - # Camera rotation - FF EN 00 - -05 GR 00 - # TEXTURE GROUP - 01 ST 80 - # Texture name - FF EN 00 - -0a GR 00 - # TILE GROUP - 01 US 01 0 # Terrain type - 02 US 01 0 # Texture number - 03 US 01 0 # Triangle flip - 04 US 01 0 # Texture x flip - 05 US 01 0 # Texture y flip - 06 US 01 0 # Not blocking (even if structure or feature on it) - 07 US 01 0 # *RETIRED* Do not draw flag - 08 US 01 0 # Height of first corner - 09 US 01 0 # Visibility bits - 0a US 01 0 # Info bits - 0b US 01 0 # Rotation - FF EN 00 - -0b GR 00 - # GATEWAY GROUP - 01 US 04 - # (x1, y1, x2, y2) coordinates - FF EN 00 - -0c GR 00 - # TEXTURE <=> TERRAIN TYPE MAPPING GROUP - 01 US 01 0 # The terrain type of this texture - FF EN 00 - -0d GR 00 - # PLAYER INFO GROUP - 01 GR 00 - # RESEARCH GROUP - 01 US 01 1 # Is research possible of this tech? - 02 US 01 0 # Research status - 03 US 01 0 # Current research points - FF EN 00 - - 02 GR 00 - # STRUCTURE LIMITS GROUP - 01 ST 80 - # Name of structure - 02 US 01 255 # Limit - FF EN 00 - - 03 GR 00 - # FLAGS GROUP - 01 US 01 - # Type - 02 US 01 0 # Frame number last drawn - 03 US 03 - # Screen coordinates and radius (x, y, r) - 04 US 04 - # Player that the position belongs to - 05 BO 05 0 # Is position selected by the player? - 06 US 03 - # World coordinates (x, y, z) - 07 US 01 0 # Factory index - 08 US 01 0 # Factory type - 09 US 01 - # Repair ID - only set if factory type is REPAIR_FLAG - 0a BO 01 0 # Do not register flag in flag list (commanders) - FF EN 00 - - 04 GR 00 - # MESSAGE GROUP - 01 SI 01 -1 # Object ID, if set, use it rather than name below; -1 means unset - 02 ST 80 - # Name - 03 BO 01 0 # Is message read? - FF EN 00 - - FF EN 00 - -0e GR 00 - # PRODUCTION RUNS GROUP (factory types) - 01 GR 00 - # Number of factories - 01 GR 00 - # Production runs for each factory - 01 US 01 0 # Quantity - 02 US 01 0 # Built - 03 SI 01 -1 # Template multiplayerID, -1 if none - FF EN 00 - - FF EN 00 - - FF EN 00 - -0f GR 00 - # OBJECT GROUP - 01 GR 00 - # BASE OBJECT GROUP - 01 US 01 - # Object type (always type droid) - 02 US 01 - # Unique object id - 03 US 03 - # (x, y, z) position coordinates - 04 FP 01 - # Direction - 05 SI 01 - # Pitch - 06 SI 01 - # Roll - 07 US 01 - # Player - 08 US 01 - # Selection group - 09 US 01 - # Selected - 0a US 01 - # Cluster - 0b US 08 - # Visibility per player - 0c US 01 - # Died (in game time) - 0d US 01 - # Last smoke emission (in game time) - 0e BO 01 - # On fire? - 0f US 01 - # Burn start (in game time) - 10 US 01 - # Total accumulated burn damage - FF EN 00 - - 02 GR 00 - # SENSOR GROUP - 01 US 01 0 # Sensor range - 02 US 01 0 # Sensor power - 03 US 01 0 # ECM range - 04 US 01 0 # ECM power - FF EN 00 - - 03 GR 00 - # OBJECT STAT GROUP - 01 US 01 - # Original body points - 02 US 01 2 # Number of weapon classes - 03 GR 00 - # ARMOUR GROUP (for each defined side) - 01 US 01 0 # Armour vs kinetic weapons - 02 US 02 0 # Armour vs heat weapons - FF EN 00 - - 04 US 01 - # Resistance (used in electronic warfare) - FF EN 00 - - 04 GR 00 - # WEAPON GROUP - 01 US 01 - # Weapon type - 02 US 01 0 # Weapon rotation - 03 US 01 0 # Weapon pitch - 04 US 01 0 # hitPoints REMOVED - 05 US 01 0 # Ammo - 06 US 01 0 # Time frame it was last fired - 07 US 01 0 # recoilValue (EXPLAIN ME) - 08 SI 01 -1 # ID of weapon target, -1 if none - FF EN 00 - - 0a GR 00 - # DROID GROUP - 01 US 01 - # Droid type - 02 US 0a - # Components - 03 BO 01 0 # Transport on mission? - 07 US 01 - # Weight - 08 US 01 - # Base speed - 09 ST 60 - # Droid name (typically template name) - 0a US 01 - # Current body points - 0b FP 01 - # Experience - 0c US 01 - # Name version (EXPLAIN ME) - 0e SI 01 -1 # Current job target ID (repairing stuff etc) - 0f SI 01 -1 # Current stats target ID (building stuff etc) - 10 SI 01 -1 # Current base target ID (rearm pad etc) - 11 US 01 0 # Current order - 12 US 04 - # Current order parameters - 13 GR 00 - # DROID ORDER GROUP (queued orders) - 01 US 01 - # Order - 02 US 04 - # Order parameters - FF EN 00 - - 14 SI 01 0 # Formation direction - 15 SI 01 0 # Formation X - 16 SI 01 0 # Formation Y - 17 US 03 - # VTOL ammo (for each weapon) - 18 SI 02 - # Droid movement final destination (x, y) - 19 SI 02 - # Droid movement origin (x, y) - 1a SI 02 - # Droid movement immediate target (x, y) - 1b FP 03 - # Fractions of x,y,z - 1c FP 01 - # Droid speed - 1d SI 02 - # Vector for the end of path boundary (x, y) - 1e US 02 - # Position of last bump (x, y) - 1f SI 01 - # Direction of motion (not the direction the droid is facing) - 20 SI 01 - # Direction at last bump - 21 US 01 - # Time of first bump with something - 22 US 01 - # Time of last bump with a droid - relative to bumpTime - 23 US 01 - # When MOVEPAUSE started - relative to bumpTime - 24 US 01 - # VTOL movement speed - 25 GR 00 - # PATH GROUP (each item is a position in a path) - 01 US 01 - # (x, y) position node - FF EN 00 - - 26 US 01 0 # Path status - 27 US 01 0 # Current position in path - FF EN 00 - - 0b GR 00 - # STRUCTURE GROUP (EXPLAIN ME) - 01 US 01 - # Structure type - 02 SI 01 0 # currentPowerAccrued - 03 US 01 0 # lastResistance - 04 US 01 0 # targetted - 05 US 01 0 # timeLastHit - 06 US 01 0 # lastHitWeapon - 07 US 01 1 # status (0 = being built, 1 = built, 2 = being demolished) - 08 SI 01 0 # currentBuildPts - FF EN 00 - - 0c GR 00 - # FEATURE GROUP - 01 US 01 0 # Time frame it was created - FF EN 00 - - 0d GR 00 - # FACTORY GROUP - 01 US 01 0 # Capacity (the max size of body the factory can produce) - 02 US 01 0 # Quantity (the number of droids to produce OR for selectedPlayer, how many loops to perform) - 03 US 01 0 # Loops performed - 04 US 01 0 # Production output (droid build points produced per build cycle) - 05 US 01 0 # powerAccrued (used to keep track of power before building a droid) - 06 SI 01 -1 # ID of template used, -1 for none - 07 US 01 0 # timeStarted - 08 US 01 0 # timeToBuild - 09 US 01 0 # timeStartHold - 0a US 01 0 # secondaryOrder - 0b SI 01 -1 # Factory number, also used to find right flag after game load, oddly enough; -1 for none - 0c SI 01 -1 # Commander ID, if any, -1 if none - FF EN 00 - - 0e GR 00 - # RESEARCH GROUP - 01 US 01 0 # Number of upgrades it has - 02 US 01 0 # powerAccrued - 03 US 01 0 # timeStartHold - 04 US 01 0 # ID of research target - 05 US 01 0 # Time frame research started - FF EN 00 - - 0f GR 00 - # RESOURCE EXTRACTOR GROUP - 01 US 01 0 # Maximum amount of power that can be extracted from this resource - 02 SI 01 -1 # ID of power plant that owns this resource, if any, -1 if none - FF EN 00 - - 10 GR 00 - # POWER PLANT GROUP - 01 US 01 0 # Number of upgrades it has - FF EN 00 - - 11 GR 00 - # REPAIR FACILITY GROUP - 01 US 01 0 # timeStarted - 02 US 01 0 # powerAccrued - 03 SI 01 -1 # Object being repaired, if any, -1 if none - 04 SI 01 -1 # Research facility number, also used to find right flag after game load, -1 for none - FF EN 00 - - 12 GR 00 - # REARM PAD GROUP - 01 US 01 0 # reArmPoints - 02 US 01 0 # timeStarted - 03 US 01 0 # currentPtsAdded - 04 SI 01 -1 # Object being rearmed, if any, -1 if none - FF EN 00 - - FF EN 00 - diff --git a/data/base/tagdefinitions/savegame/score.def b/data/base/tagdefinitions/savegame/score.def deleted file mode 100644 index a0b2acab3..000000000 --- a/data/base/tagdefinitions/savegame/score.def +++ /dev/null @@ -1,19 +0,0 @@ -# -# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, -# EN for group end, BO for boolean -# VM: Must be no longer than the size given here; set to 00 for repeating groups -# default value cannot be set for VM > 1, ST, GR or EN -# -01 ST 12 - # Format identifier: "ScoreData" -02 US 01 - # units built -03 US 01 - # units killed -04 US 01 - # units lost -05 US 01 - # structures built -06 US 01 - # structures killed -07 US 01 - # structures lost -08 US 01 - # artifacts found -09 US 01 - # mission started -0A US 01 - # shots on target -0B US 01 - # shots off target -0C US 01 - # babas mowed down diff --git a/data/base/tagdefinitions/tagfile_basic.def b/data/base/tagdefinitions/tagfile_basic.def deleted file mode 100644 index f4cc3cf82..000000000 --- a/data/base/tagdefinitions/tagfile_basic.def +++ /dev/null @@ -1,37 +0,0 @@ -# -# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, -# EN for group end, BO for boolean -# VM: Must be no longer than the size given here; set to 00 for repeating groups -# default value cannot be set for VM > 1, ST, GR or EN -# -01 ST 12 - # Format identifier: "WZTAGFILE1" -02 GR 00 - # DROID GROUP - 01 US 01 - # Droid ID - 02 US 03 - # Droid position in (x,y,z) coordinates - 03 FP 01 - # RETIRED (had unknown usage) - 04 FP 03 - # RETIRED (had unknown usage) - 05 US 500 - # Long unsigned byte array - 06 US 500 - # Long unsigned byte array - 07 GR 00 - # Write-only group - 01 US 01 0 # Simple value - 02 US 01 0 # Simple value - 03 GR 00 - # Another nested group - 01 US 01 0 # Default value - FF EN 00 - - FF EN 00 - - 08 GR 00 - # Empty group - FF EN 00 - - 09 GR 00 - # Droid weapon group - 01 US 01 - # Weapon type - 02 US 01 10 # Ammo left - 03 US 01 0 # Time last fired - 04 US 01 0 # Recoil value - 05 SI 03 - # Array of signed int - FF EN 00 - - FF EN 00 - -03 GR 00 - # STRUCTURE GROUP - 01 US 01 - # Structure ID - 02 US 03 - # Structure position in (x,y,z) coordinates - FF EN 00 - -04 US 01 9 # Some default value of 9 diff --git a/data/base/tagdefinitions/tagfile_virtual.def b/data/base/tagdefinitions/tagfile_virtual.def deleted file mode 100644 index 0af421d79..000000000 --- a/data/base/tagdefinitions/tagfile_virtual.def +++ /dev/null @@ -1,14 +0,0 @@ -# -# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, -# EN for group end, BO for boolean -# VM: Must be no longer than the size given here; set to 00 for repeating groups -# default value cannot be set for VM > 1, ST, GR or EN -# -01 US 01 1 -02 SI 01 2 -03 FP 01 3 -04 US 01 4 -05 SI 01 5 -06 ST 80 - -07 BO 01 1 diff --git a/lib/framework/Makefile.am b/lib/framework/Makefile.am index 7a40f6ee0..ecc594e67 100644 --- a/lib/framework/Makefile.am +++ b/lib/framework/Makefile.am @@ -65,7 +65,6 @@ noinst_HEADERS = \ string_ext.h \ strres.h \ strresly.h \ - tagfile.h \ treap.h \ trig.h \ types.h \ @@ -100,7 +99,6 @@ libframework_a_SOURCES = \ SDL_framerate.cpp \ stdio_ext.cpp \ strres.cpp \ - tagfile.cpp \ treap.cpp \ trig.cpp \ utf.cpp diff --git a/lib/framework/tagfile.cpp b/lib/framework/tagfile.cpp deleted file mode 100644 index c41f95295..000000000 --- a/lib/framework/tagfile.cpp +++ /dev/null @@ -1,1428 +0,0 @@ -// Written by Per I Mathisen, 2007 -// Released into the public domain, no rights reserved. -// ANSI C + stdint.h -// -// See header file for documentation. -#include "tagfile.h" - -#include "frame.h" - -#include "string_ext.h" -#include "physfs_ext.h" - -// Tags of values 0x0 and 0xFF are reserved as instance separators and group end -// tags, respectively. You cannot use a separator in your definition file, but -// you must use the group end tag whenever you use a group tag. -#define TAG_SEPARATOR 0 -#define TAG_GROUP_END 255 - -// This value is saved in the binary file and is used for fast and safe skipping -// ahead through the file, even though we may not know every tag definition in it. -enum internal_types -{ - TF_INT_U8, TF_INT_U16, TF_INT_U32, TF_INT_S8, TF_INT_S16, TF_INT_S32, TF_INT_FLOAT, - TF_INT_U16_ARRAY, TF_INT_FLOAT_ARRAY, TF_INT_U8_ARRAY, TF_INT_GROUP, TF_INT_BOOL, - TF_INT_S32_ARRAY -}; - -// A definition group -struct define_t -{ - unsigned int vm; //! value multiple - element_t element; //! tag number - char vr[2]; //! value representation (type) - define_t *parent; //! parent group - define_t *group; //! child group - define_t *next; //! sibling group - define_t *current; //! where in the sibling list we currently are - bool defaultval; //! default value - union { - uint32_t uint32_tval; - int32_t int32_tval; - float floatval; - } val; //! actual data - // debugging temp variables below - int countItems; // check group items against number of separators given - int expectedItems; // group items expected in current group -}; - - -static bool tag_error = false; // are we in an error condition? -static define_t *first = NULL; // keep track of first group -static define_t *current = NULL; // currently iterated group -static int line = 0; // current definition line, report in error message -static bool readmode = true; // are we in read or write mode? -static char *bufptr = NULL; // pointer to definition file buffer -static PHYSFS_file *handle = NULL; -static int lastAccess = -1; // track last accessed tag to detect user errors -static int countGroups = 0; // check group recursion count while reading definition -static char saveDefine[PATH_MAX]; // save define file for error messages -static char saveTarget[PATH_MAX]; // save binary file for error messages - -#undef DEBUG_TAGFILE - -static void tf_error(const char * fmt, ...) WZ_DECL_FORMAT(printf, 1, 2); -static void tf_print_nested_groups(unsigned int level, define_t *group); - - -#define TF_ERROR(...) \ -do { \ - tf_error(__VA_ARGS__); \ - assert(!"tagfile error"); \ -} while(0) - - -#define VALIDATE_TAG(_def, _tag, _name) \ -do { \ - if (_def[0] != current->vr[0] || _def[1] != current->vr[1]) \ - TF_ERROR("Tag %#04x is given as a %s but this does not conform to value representation \"%c%c\"", \ - (unsigned int)tag, _name, current->vr[0], current->vr[1]); \ -} while(0) - - -#define CHECK_VALID_TAG(_tag) \ -do { \ - assert(tag != TAG_SEPARATOR && tag != TAG_GROUP_END); \ -} while(0) - - -/* -static inline WZ_DECL_CONST const char * bool2string(bool var) -{ - return (var ? "true" : "false"); -} -*/ - - -void tf_error(const char * fmt, ...) -{ - va_list ap; - char errorBuffer[255]; - - tag_error = true; - - va_start(ap, fmt); - vsnprintf(errorBuffer, sizeof(errorBuffer), fmt, ap); - va_end(ap); - debug(LOG_ERROR, "%s", errorBuffer); - - tf_print_nested_groups(0, current); - - debug(LOG_ERROR, "While %s '%s' using definition file '%s'\n", readmode ? "reading" : "writing", saveTarget, saveDefine); -} - - -// Print the calling strack for nested groups on error -void tf_print_nested_groups(unsigned int level, define_t *group) -{ - if (group == NULL) - { - return; - } - - if (level == 0) - { - debug(LOG_ERROR, "Group trace:"); - } - debug(LOG_ERROR, " #%u: %#04x %2.2s %5u default:%s", level, (unsigned int)group->element, group->vr, group->vm, bool2string(group->defaultval)); - - if (group->parent != NULL) - { - tf_print_nested_groups(level+1, group->parent); - } -} - - -// scan one definition group from definition file; returns true on success -static bool scan_defines(define_t *node, define_t *group) -{ - bool group_end = false; - - while (*bufptr != '\0' && !group_end) - { - int count, retval; - unsigned int readelem; - char vr[3]; - - memset(vr, 0, sizeof(vr)); - node->group = NULL; - node->parent = group; - node->val.uint32_tval = 0; - node->vm = 0; - node->next = NULL; - node->element = 0xFF; - node->expectedItems = 0; - node->countItems = 0; - current = node; // for accurate error reporting - - // check line endings - while (*bufptr == '\n' || *bufptr == '\r') - { - if (*bufptr == '\n') - { - line++; - } - bufptr++; - } - // remove whitespace - while (*bufptr == ' ' || *bufptr == '\t') - { - bufptr++; - } - // check if # comment line or whitespace - if (*bufptr == '#' || *bufptr == '\0') - { - while (*bufptr != '\n' && *bufptr != '\0') - { - bufptr++; // discard rest of line - } - continue; // check empty lines and whitespace again - } - - retval = sscanf(bufptr, "%x %2s %u%n", &readelem, (char *)&vr, &node->vm, &count); - node->element = readelem; - while (retval <= 0 && *bufptr != '\n' && *bufptr != '\0') /// TODO: WTF? - { - printf("WTF\n"); - bufptr++; // not a valid line, so discard it - } - if (retval < 3) - { - TF_ERROR("Bad definition, line %d (retval==%d)", line, retval); - return false; - } - node->vr[0] = vr[0]; - node->vr[1] = vr[1]; - bufptr += count; - if (node->vr[0] == 'S' && node->vr[1] == 'I') - { - retval = sscanf(bufptr, " %d", &node->val.int32_tval); - } - else if ((node->vr[0] == 'U' && node->vr[1] == 'S') || (node->vr[0] == 'B' && node->vr[1] == 'O')) - { - retval = sscanf(bufptr, " %u", &node->val.uint32_tval); - } - else if (node->vr[0] == 'F' && node->vr[1] == 'P') - { - retval = sscanf(bufptr, " %f", &node->val.floatval); - } - else if ((node->vr[0] == 'S' && node->vr[1] == 'T') - || (node->vr[0] == 'G' && node->vr[1] == 'R') - || (node->vr[0] == 'E' && node->vr[1] == 'N')) - { - retval = 0; // these do not take a default value - } - else - { - TF_ERROR("Invalid value representation %c%c line %d", node->vr[0], node->vr[1], line); - return false; - } - node->defaultval = (retval == 1); - while (*bufptr != '\n' && *bufptr != '\0') - { - bufptr++; // discard rest of line - } - - if (node->vr[0] == 'G' || node->vr[1] == 'R') - { - bool success; - - countGroups++; - node->group = (define_t *)malloc(sizeof(*node)); - success = scan_defines(node->group, node); - - if (!success) - { - return false; // error - } - } - else if (node->vr[0] == 'E' || node->vr[1] == 'N') - { - group_end = true; // un-recurse now - countGroups--; - } - if (*bufptr != '\0' && !group_end) - { - node->next = (define_t *)malloc(sizeof(*node)); - node = node->next; - } - } - node->next = NULL; // terminate linked list - return true; -} - -static bool init(const char *definition, const char *datafile, bool write) -{ - PHYSFS_file *fp; - PHYSFS_sint64 fsize, fsize2; - char *buffer; - - tag_error = false; - line = 1; - fp = PHYSFS_openRead(definition); - debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(definition), definition); - sstrcpy(saveDefine, definition); - sstrcpy(saveTarget, datafile); - if (!fp) - { - TF_ERROR("Error opening definition file %s: %s", definition, PHYSFS_getLastError()); - return false; - } - - fsize = PHYSFS_fileLength(fp); - assert(fsize > 0); - - buffer = bufptr = (char *)malloc(fsize + 1); - if (!buffer || !bufptr) - { - debug(LOG_FATAL, "init(): Out of memory"); - abort(); - return false; - } - - bufptr[fsize] = '\0'; // ensure it is zero terminated - - fsize2 = PHYSFS_read(fp, bufptr, 1, fsize); - if (fsize != fsize2) - { - TF_ERROR("Could not read definitions: %s", PHYSFS_getLastError()); - return false; - } - current = NULL; // keeps track of parent group below - first = (define_t *)malloc(sizeof(*first)); - first->parent = NULL; - first->group = NULL; - first->next = NULL; - first->current = NULL; - scan_defines(first, NULL); - free(buffer); - bufptr = NULL; - PHYSFS_close(fp); - - if (countGroups != 0) - { - TF_ERROR("Error in definition file %s - group tags do not match end tags!", definition); - countGroups = 0; - return false; - } - - if (write) - { - fp = PHYSFS_openWrite(datafile); - } - else - { - fp = PHYSFS_openRead(datafile); - } - debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(datafile), datafile); - handle = fp; - if (!fp) - { - debug(LOG_ERROR, "Error opening data file %s: %s", datafile, PHYSFS_getLastError()); - tagClose(); - return false; - } - readmode = !write; - current = first; -#ifdef DEBUG_TAGFILE - debug(LOG_ERROR, "opening %s", datafile); -#endif - return true; -} - -bool tagOpenWrite(const char *definition, const char *datafile) -{ - return init(definition, datafile, true); -} - -bool tagOpenRead(const char *definition, const char *datafile) -{ - return init(definition, datafile, false); -} - -static void remove_defines(define_t *df) -{ - define_t *iter; - - for (iter = df; iter != NULL;) - { - define_t *del = iter; - - if (iter->group) // Also remove subgroups - { - remove_defines(iter->group); - } - iter = iter->next; - free(del); - } -} - -void tagClose() -{ - if (handle) - { - PHYSFS_close(handle); - } - remove_defines(first); - lastAccess = -1; // reset sanity counter -} - - -bool tagGetError() -{ - return tag_error; -} - - -// skip ahead in definition list to given element -static bool scan_to(element_t tag) -{ - if (tag == TAG_SEPARATOR) - { - return true; // does not exist in definition - } - if (lastAccess >= tag) - { - TF_ERROR("Trying to access tag %#04x that is not larger than previous tag.", (unsigned int)tag); - return false; - } - lastAccess = tag; - // Set the right node - for (; current->next && current->element < tag; current = current->next) {} - if (current->element != tag) - { - TF_ERROR("Unknown element %#04x sought", (unsigned int)tag); - return false; - } - return true; -} - - -/********* TAGREAD *********/ - - -// scan forward to after given tag (if read case, we may skip -// several tags to get there) -static bool scanforward(element_t tag) -{ - element_t read_tag; - uint8_t tag_type; - PHYSFS_sint64 readsize = 0, fpos; - uint16_t array_size; - int groupskip = 0; // levels of nested groups to skip - - assert(readmode); - if (tag_error || current == NULL || !readmode) - { - return false; - } - - // Skip in this group-definition until we have reached destination tag - if (!scan_to(tag) || PHYSFS_eof(handle)) - { - return false; // error, or try default value - } - readsize = PHYSFS_read(handle, &read_tag, 1, 1); - while (readsize == 1) // Read from file till we've reached the destination - { - if (read_tag == tag && groupskip <= 0) - { - assert(current->element == tag || tag == TAG_SEPARATOR); - return true; - } - else if (read_tag == TAG_GROUP_END || (read_tag == TAG_SEPARATOR && groupskip > 0)) - { - /* New element ready already, repeat loop */ - if (read_tag == TAG_GROUP_END) - { - groupskip--; - if (groupskip < 0) - { - break; // tag not found - } - } - readsize = PHYSFS_read(handle, &read_tag, 1, 1); - continue; // no type, no payload - } - else if (read_tag == TAG_SEPARATOR || (read_tag > tag && groupskip <= 0 && tag != TAG_SEPARATOR)) - { - break; // did not find it - } - - /* If we got down here, we found something that we need to skip */ - - readsize = PHYSFS_read(handle, &tag_type, 1, 1); - if (readsize != 1) - { - TF_ERROR("Error reading tag type when skipping: %s", PHYSFS_getLastError()); - return false; - } - - /* Skip payload */ - - switch (tag_type) - { - case TF_INT_U16_ARRAY: - case TF_INT_FLOAT_ARRAY: - case TF_INT_U8_ARRAY: - case TF_INT_S32_ARRAY: - if (!PHYSFS_readUBE16(handle, &array_size)) - { - TF_ERROR("Error reading array length when skipping: %s", PHYSFS_getLastError()); - return false; - } - break; - default: - array_size = 1; - } - - fpos = PHYSFS_tell(handle); - switch (tag_type) - { - case TF_INT_U8_ARRAY: - case TF_INT_U8: - case TF_INT_BOOL: - case TF_INT_S8: fpos += 1 * array_size; break; - case TF_INT_FLOAT: - case TF_INT_U16_ARRAY: - case TF_INT_U16: - case TF_INT_S16: fpos += 2 * array_size; break; - case TF_INT_FLOAT_ARRAY: - case TF_INT_U32: - case TF_INT_S32_ARRAY: - case TF_INT_S32: fpos += 4 * array_size; break; - case TF_INT_GROUP: - fpos += 2; - groupskip++; -#ifdef DEBUG_TAGFILE - debug(LOG_ERROR, "skipping group 0x%02x (groupskip==%d)", (unsigned int)read_tag, groupskip); -#endif - break; - default: - TF_ERROR("Invalid value type in buffer"); - return false; - } - - PHYSFS_seek(handle, fpos); - - /* New element ready now, repeat loop */ - readsize = PHYSFS_read(handle, &read_tag, 1, 1); - } - if (readsize != 1) - { - TF_ERROR("Could not read tag: %s", PHYSFS_getLastError()); - return false; - } - else - { - // If we come here, we failed to find the tag. Roll back the last element found, and - // check for default value. - fpos = PHYSFS_tell(handle); - fpos -= sizeof(element_t); - PHYSFS_seek(handle, fpos); - assert(current != NULL); - assert(current->element == tag); - - if (!current->defaultval) - { - TF_ERROR("Tag not found and no default: %#04x", (unsigned int)tag); - return false; - } - } - - return false; // tag not found before end of instance, group or file -} - -bool tagReadNext() -{ - // scan forward until we find a separator value element tag in this group - if (!scanforward(TAG_SEPARATOR)) - { - return false; - } - lastAccess = -1; // reset requirement that tags are increasing in value - if (current->parent == NULL) - { - current = first; // topmost group - } - else - { - current = current->parent->group; // reset to start of group tag index - } - current->parent->group->countItems++; // sanity checking - return true; -} - -uint16_t tagReadEnter(element_t tag) -{ - uint16_t elements; - element_t tagtype; - - assert(readmode); - if (!scanforward(tag) || !readmode) - { - return 0; // none found; avoid error reporting here - } - lastAccess = -1; // reset requirement that tags are increasing in value - if (!PHYSFS_readUBE8(handle, &tagtype)) - { - TF_ERROR("Error reading group type: %s", PHYSFS_getLastError()); - return 0; - } - if (tagtype != TF_INT_GROUP) - { - TF_ERROR("Error in group VR, tag %#04x", (unsigned int)tag); - return 0; - } - if (!PHYSFS_readUBE16(handle, &elements)) - { - TF_ERROR("Error accessing group size: %s", PHYSFS_getLastError()); - return 0; - } - if (!current->group) - { - TF_ERROR("Cannot enter group, none defined for element %x!", (unsigned int)current->element); - return 0; - } -#ifdef DEBUG_TAGFILE - debug(LOG_ERROR, "entering 0x%02x", (unsigned int)tag); -#endif - assert(current->group->parent != NULL); - assert(current->element == tag); - current->group->expectedItems = elements; // for debugging and consistency checking - current->group->countItems = 0; // ditto - current->group->parent->current = current; // save where we are. ok, this is very contrived code. - current = current->group; - return elements; -} - -void tagReadLeave(element_t tag) -{ - if (!scanforward(TAG_GROUP_END)) - { - TF_ERROR("Cannot leave group, group end tag not found!"); - return; - } - if (tag_error) - { - return; - } - if (current->parent == NULL) - { - TF_ERROR("Cannot leave group, at highest level already!"); - return; - } - if (current->parent->group->expectedItems > current->parent->group->countItems + 1) - { - TF_ERROR("Expected to read %d items in group, found %d", - current->parent->group->expectedItems, current->parent->group->countItems); - } - current = current->parent->current; // resume iteration - if (current->element != tag) - { - TF_ERROR("Trying to leave the wrong group! We are in %x, leaving %#04x", - current->parent != NULL ? (unsigned int)current->parent->element : 0, (unsigned int)tag); - return; - } - lastAccess = current->element; // restart iteration requirement - assert(current != NULL); -} - -uint32_t tagRead(element_t tag) -{ - uint8_t tagtype; - - if (!scanforward(tag)) - { - if (current->defaultval && current->element == tag) - { - return current->val.uint32_tval; - } - return 0; - } - - if (!PHYSFS_readUBE8(handle, &tagtype)) - { - TF_ERROR("tagread: Tag type not found: %#04x", (unsigned int)tag); - tag_error = true; - return 0; - } - if (tagtype == TF_INT_U32) - { - uint32_t val; - (void) PHYSFS_readUBE32(handle, &val); - return val; - } - else if (tagtype == TF_INT_U16) - { - uint16_t val; - (void) PHYSFS_readUBE16(handle, &val); - return val; - } - else if (tagtype == TF_INT_U8) - { - uint8_t val; - (void) PHYSFS_readUBE8(handle, &val); - return val; - } - else - { - TF_ERROR("readtag: Error reading tag %#04x, bad type", (unsigned int)tag); - return 0; - } -} - -int32_t tagReads(element_t tag) -{ - uint8_t tagtype; - - if (!scanforward(tag)) - { - if (current->defaultval && current->element == tag) - { - return current->val.int32_tval; - } - return 0; - } - - if (!PHYSFS_readUBE8(handle, &tagtype)) - { - TF_ERROR("tagreads: Tag type not found: %#04x", (unsigned int)tag); - return 0; - } - if (tagtype == TF_INT_S32) - { - int32_t val; - (void) PHYSFS_readSBE32(handle, &val); - return val; - } - else if (tagtype == TF_INT_S16) - { - int16_t val; - (void) PHYSFS_readSBE16(handle, &val); - return val; - } - else if (tagtype == TF_INT_S8) - { - int8_t val; - (void) PHYSFS_readSBE8(handle, &val); - return val; - } - else - { - TF_ERROR("readtags: Error reading tag %#04x, bad type", (unsigned int)tag); - return 0; - } -} - -float tagReadf(element_t tag) -{ - uint8_t tagtype; - - if (!scanforward(tag)) - { - if (current->defaultval && current->element == tag) - { - return current->val.floatval; - } - return 0; - } - - if (!PHYSFS_readUBE8(handle, &tagtype)) - { - TF_ERROR("tagreadf: Tag type not found: %#04x", (unsigned int)tag); - return 0; - } - if (tagtype == TF_INT_FLOAT) - { - float val; - (void) PHYSFS_readBEFloat(handle, &val); - return val; - } - else - { - TF_ERROR("readtagf: Error reading tag %#04x, bad type", (unsigned int)tag); - return 0; - } -} - -bool tagReadBool(element_t tag) -{ - uint8_t tagtype; - - if (!scanforward(tag)) - { - if (current->defaultval && current->element == tag) - { - return current->val.uint32_tval; - } - return 0; - } - - if (!PHYSFS_readUBE8(handle, &tagtype)) - { - TF_ERROR("tagReadBool: Tag type not found: %#04x", (unsigned int)tag); - return 0; - } - if (tagtype == TF_INT_BOOL || tagtype == TF_INT_U8) - { - uint8_t val; - (void) PHYSFS_readUBE8(handle, &val); - return val; - } - else - { - TF_ERROR("readTagBool: Error reading tag %#04x, bad type", (unsigned int)tag); - return 0; - } -} - -bool tagReadfv(element_t tag, uint16_t size, float *vals) -{ - uint8_t tagtype; - uint16_t count; - int i; - - if (!scanforward(tag)) - { - return false; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || tagtype != TF_INT_FLOAT_ARRAY) - { - TF_ERROR("tagreadfv: Tag type not found: %#04x", (unsigned int)tag); - return false; - } - if (!PHYSFS_readUBE16(handle, &count) || count != size) - { - TF_ERROR("tagreadfv: Bad size: %#04x", (unsigned int)tag); - return false; - } - for (i = 0; i < size; i++) - { - if (!PHYSFS_readBEFloat(handle, &vals[i])) - { - TF_ERROR("tagreadfv: Error reading index %d, tag %#04x", i, (unsigned int)tag); - return false; - } - } - return true; -} - -uint8_t *tagRead8vDup(element_t tag, int *size) -{ - uint8_t tagtype, *values; - uint16_t count; - int i; - - if (!scanforward(tag)) - { - *size = 0; - return NULL; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || tagtype != TF_INT_U8_ARRAY) - { - TF_ERROR("tagread8vDup: Tag type not found: %#04x", (unsigned int)tag); - *size = -1; - return NULL; - } - if (!PHYSFS_readUBE16(handle, &count)) - { - TF_ERROR("tagread8vDup: Read error (end of file?): %s", PHYSFS_getLastError()); - *size = -1; - return NULL; - } - values = (uint8_t *)malloc(count); - *size = count; - for (i = 0; i < count; i++) - { - if (!PHYSFS_readUBE8(handle, &values[i])) - { - TF_ERROR("tagread8vDup: Error reading index %d, tag %#04x", i, (unsigned int)tag); - return NULL; - } - } - return values; -} - -bool tagRead8v(element_t tag, uint16_t size, uint8_t *vals) -{ - uint8_t tagtype; - uint16_t count; - int i; - - if (!scanforward(tag)) - { - return false; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || tagtype != TF_INT_U8_ARRAY) - { - TF_ERROR("tagread8v: Tag type not found: %#04x", (unsigned int)tag); - return false; - } - if (!PHYSFS_readUBE16(handle, &count) || count != size) - { - TF_ERROR("tagread8v: Bad size: %#04x", (unsigned int)tag); - return false; - } - for (i = 0; i < size; i++) - { - if (!PHYSFS_readUBE8(handle, &vals[i])) - { - TF_ERROR("tagread8v: Error reading index %d, tag %#04x", i, (unsigned int)tag); - return false; - } - } - return true; -} - -bool tagRead16v(element_t tag, uint16_t size, uint16_t *vals) -{ - uint8_t tagtype; - uint16_t count; - int i; - - if (!scanforward(tag)) - { - return false; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || tagtype != TF_INT_U16_ARRAY) - { - TF_ERROR("tagread16v: Tag type not found: %#04x", (unsigned int)tag); - return false; - } - if (!PHYSFS_readUBE16(handle, &count) || count != size) - { - TF_ERROR("tagread16v: Bad size: %#04x", (unsigned int)tag); - return false; - } - for (i = 0; i < size; i++) - { - if (!PHYSFS_readUBE16(handle, &vals[i])) - { - TF_ERROR("tagread16v: Error reading index %d, tag %#04x", i, (unsigned int)tag); - return false; - } - } - return true; -} - -bool tagReads32v(element_t tag, uint16_t size, int32_t *vals) -{ - uint8_t tagtype; - uint16_t count; - int i; - - if (!scanforward(tag)) - { - return false; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || tagtype != TF_INT_S32_ARRAY) - { - TF_ERROR("tagreads32v: Tag type not found: %d", (int)tag); - return false; - } - if (!PHYSFS_readUBE16(handle, &count) || count != size) - { - TF_ERROR("tagreads32v: Bad size: %d", (int)tag); - return false; - } - for (i = 0; i < size; i++) - { - if (!PHYSFS_readSBE32(handle, &vals[i])) - { - TF_ERROR("tagreads32v: Error reading index %d, tag %d", i, (int)tag); - return false; - } - } - return true; -} - -bool tagReadString(element_t tag, uint16_t size, char *buffer) -{ - uint8_t tagtype = 255; - PHYSFS_uint16 actualsize = 0; - PHYSFS_sint64 readsize = 0; - - if (!scanforward(tag)) - { - return false; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || !PHYSFS_readUBE16(handle, &actualsize) || tagtype != TF_INT_U8_ARRAY) - { - TF_ERROR("Error reading string size: %s", PHYSFS_getLastError()); - return false; - } - if (actualsize > size) - { - TF_ERROR("String size %d larger than user maxlen %d", (int)actualsize, (int)size); - return false; - } - readsize = PHYSFS_read(handle, buffer, 1, actualsize); - if (readsize != actualsize) - { - TF_ERROR("Unfinished string: %s", PHYSFS_getLastError()); - return false; - } - // Return string MUST be zero terminated! - if (*(buffer + actualsize - 1) != '\0') - { - TF_ERROR("Element %#04x is a string that is not zero terminated", (unsigned int)tag); - return false; - } - return true; -} - -char *tagReadStringDup(element_t tag) -{ - uint8_t tagtype; - PHYSFS_uint16 actualsize; - PHYSFS_sint64 readsize; - char *buffer; - - if (!scanforward(tag)) - { - return NULL; - } - if (!PHYSFS_readUBE8(handle, &tagtype) || !PHYSFS_readUBE16(handle, &actualsize)) - { - TF_ERROR("tagread_stringdup: Error reading string size: %s", PHYSFS_getLastError()); - return NULL; - } - if (tagtype != TF_INT_U8_ARRAY) - { - TF_ERROR("tagread_stringdup: Bad string format"); - return NULL; - } - buffer = (char *)malloc(actualsize); - assert(buffer != NULL); - readsize = PHYSFS_read(handle, buffer, 1, actualsize); - if (readsize != actualsize || *(buffer + actualsize - 1) != '\0') - { - TF_ERROR("tagread_stringdup: Unfinished or unterminated string: %s", PHYSFS_getLastError()); - free(buffer); - return NULL; - } - return buffer; -} - - -/********* TAGWRITE *********/ - - -static bool write_tag(element_t tag) -{ - PHYSFS_sint64 size; - - if (tag_error || current == NULL || readmode) - { - return false; - } - size = PHYSFS_write(handle, &tag, 1, 1); - if (size != 1) - { - TF_ERROR("Could not write tag: %s", PHYSFS_getLastError()); - return false; - } - return true; -} - -bool tagWriteNext() -{ - if (tag_error || !write_tag(TAG_SEPARATOR)) - { - return false; - } - if (current->parent == NULL) - { - current = first; // topmost group - } - else - { - current = current->parent->group; // reset to start of group tag index - } - lastAccess = -1; // reset sanity counter - current->parent->group->countItems++; // sanity checking - // it has no payload - return true; -} - -bool tagWriteEnter(element_t tag, uint16_t elements) -{ - CHECK_VALID_TAG(tag); - if (tag_error || !write_tag(tag) || !scan_to(tag)) - { - return false; - } - assert(current->element == tag); - VALIDATE_TAG("GR", tag, "group"); - ASSERT(current->group != NULL, "Cannot write group, none defined for element %#04x!", (unsigned int)tag); - assert(current->group->parent != NULL); - (void) PHYSFS_writeUBE8(handle, TF_INT_GROUP); - (void) PHYSFS_writeUBE16(handle, elements); - current->group->expectedItems = elements; // for debugging and consistency checking - current->group->countItems = 0; // ditto - current->group->parent->current = current; // save where we are. ok, this is very contrived code. - current = current->group; - lastAccess = -1; // reset sanity counter, since we are in a new group - return true; -} - -bool tagWriteLeave(element_t tag) -{ - CHECK_VALID_TAG(tag); - if (tag_error || !write_tag(TAG_GROUP_END) || !scan_to(TAG_GROUP_END)) - { - return false; - } - ASSERT(current->parent != NULL, "Cannot leave group %d, at highest level already!", (int)tag); - if (current->parent == NULL) - { - TF_ERROR("Cannot leave group, at highest level already!"); - return false; - } - if (current->parent->group->expectedItems > current->parent->group->countItems + 1) // may omit last separator - { - TF_ERROR("Expected %d items in group when writing, found %d", - current->parent->group->expectedItems, current->parent->group->countItems); - } - current = current->parent->current; // resume at next tag - assert(current != NULL); - if (current->element != tag) - { - TF_ERROR("Trying to leave the wrong group! We are in %x, leaving %#04x", - current->parent != NULL ? (unsigned int)current->parent->element : 0, (unsigned int)tag); - return false; - } - lastAccess = current->element; // restart iteration requirement - // it has no payload - return true; -} - -bool tagWrite(element_t tag, uint32_t val) -{ - CHECK_VALID_TAG(tag); - if (!scan_to(tag)) - { - return false; - } - VALIDATE_TAG("US", tag, "unsigned"); - if (current->defaultval && current->val.uint32_tval == val) - { - return true; // using default value to save disk space - } - if (!write_tag(tag)) - { - return false; - } - if (val > UINT16_MAX) - { - (void) PHYSFS_writeUBE8(handle, TF_INT_U32); - (void) PHYSFS_writeUBE32(handle, val); - } - else if (val > UINT8_MAX) - { - (void) PHYSFS_writeUBE8(handle, TF_INT_U16); - (void) PHYSFS_writeUBE16(handle, val); - } - else - { - (void) PHYSFS_writeUBE8(handle, TF_INT_U8); - (void) PHYSFS_writeUBE8(handle, val); - } - return true; -} - -bool tagWrites(element_t tag, int32_t val) -{ - CHECK_VALID_TAG(tag); - if (!scan_to(tag)) - { - return false; - } - VALIDATE_TAG("SI", tag, "signed"); - if (current->defaultval && current->val.int32_tval == val) - { - return true; // using default value to save disk space - } - if (!write_tag(tag)) - { - return false; - } - if (val > INT16_MAX) - { - (void) PHYSFS_writeUBE8(handle, TF_INT_S32); - (void) PHYSFS_writeSBE32(handle, val); - } - else if (val > INT8_MAX) - { - (void) PHYSFS_writeUBE8(handle, TF_INT_S16); - (void) PHYSFS_writeSBE16(handle, val); - } - else - { - (void) PHYSFS_writeUBE8(handle, TF_INT_S8); - (void) PHYSFS_writeSBE8(handle, val); - } - return true; -} - -bool tagWritef(element_t tag, float val) -{ - CHECK_VALID_TAG(tag); - if (!scan_to(tag)) - { - return false; - } - VALIDATE_TAG("FP", tag, "floating point"); - if (current->defaultval && current->val.floatval == val) - { - return true; // using default value to save disk space - } - if (!write_tag(tag)) - { - return false; - } - (void) PHYSFS_writeUBE8(handle, TF_INT_FLOAT); - (void) PHYSFS_writeBEFloat(handle, val); - return true; -} - -bool tagWriteBool(element_t tag, bool val) -{ - CHECK_VALID_TAG(tag); - if (!scan_to(tag)) - { - return false; - } - VALIDATE_TAG("BO", tag, "boolean"); - if (current->defaultval && current->val.uint32_tval == val) - { - return true; // using default value to save disk space - } - if (!write_tag(tag)) - { - return false; - } - (void) PHYSFS_writeUBE8(handle, TF_INT_BOOL); - (void) PHYSFS_writeUBE8(handle, val); - return true; -} - -bool tagWritefv(element_t tag, uint16_t count, const float *vals) -{ - int i; - - CHECK_VALID_TAG(tag); - if (!scan_to(tag) || !write_tag(tag)) - { - return false; - } - VALIDATE_TAG("FP", tag, "floating point (multiple)"); - (void) PHYSFS_writeUBE8(handle, TF_INT_FLOAT_ARRAY); - (void) PHYSFS_writeUBE16(handle, count); - for (i = 0; i < count; i++) - { - (void) PHYSFS_writeBEFloat(handle, vals[i]); - } - return true; -} - -bool tagWrite8v(element_t tag, uint16_t count, const uint8_t *vals) -{ - int i; - - CHECK_VALID_TAG(tag); - if (!scan_to(tag) || !write_tag(tag)) - { - return false; - } - VALIDATE_TAG("US", tag, "unsigned (multiple)"); - (void) PHYSFS_writeUBE8(handle, TF_INT_U8_ARRAY); - (void) PHYSFS_writeUBE16(handle, count); - for (i = 0; i < count; i++) - { - (void) PHYSFS_writeUBE8(handle, vals[i]); - } - return true; -} - -bool tagWrite16v(element_t tag, uint16_t count, const uint16_t *vals) -{ - int i; - - CHECK_VALID_TAG(tag); - if (!scan_to(tag) || !write_tag(tag)) - { - return false; - } - VALIDATE_TAG("US", tag, "unsigned (multiple)"); - (void) PHYSFS_writeUBE8(handle, TF_INT_U16_ARRAY); - (void) PHYSFS_writeUBE16(handle, count); - for (i = 0; i < count; i++) - { - (void) PHYSFS_writeUBE16(handle, vals[i]); - } - return true; -} - -bool tagWrites32v(element_t tag, uint16_t count, const int32_t *vals) -{ - int i; - - CHECK_VALID_TAG(tag); - if (!scan_to(tag) || !write_tag(tag)) - { - return false; - } - VALIDATE_TAG("SI", tag, "signed (multiple)"); - (void) PHYSFS_writeUBE8(handle, TF_INT_S32_ARRAY); - (void) PHYSFS_writeUBE16(handle, count); - for (i = 0; i < count; i++) - { - (void) PHYSFS_writeSBE32(handle, vals[i]); - } - return true; -} - -bool tagWriteString(element_t tag, const char *buffer) -{ - size_t size; - - CHECK_VALID_TAG(tag); - if (!scan_to(tag) || !write_tag(tag)) - { - return false; - } - VALIDATE_TAG("ST", tag, "text string"); - - // find size of string - size = strlen(buffer) + 1; - if (size > current->vm && current->vm != 0) - { - TF_ERROR("Given string is too long (size %d > limit %u)", (int)size, current->vm); - return false; - } - (void) PHYSFS_writeUBE8(handle, TF_INT_U8_ARRAY); - (void) PHYSFS_writeUBE16(handle, size); - (void) PHYSFS_write(handle, buffer, 1, size); - return true; -} - - -/********* TAGFILE UNIT TEST *********/ - - -#define BLOB_SIZE 11 -// unit test function -void tagTest() -{ - static const char virtual_definition[] = "tagdefinitions/tagfile_virtual.def"; - static const char basic_definition[] = "tagdefinitions/tagfile_basic.def"; - static const char writename[] = "test.wzs"; - static const char cformat[] = "WZTAGFILE1"; - char format[300], *formatdup; - uint16_t droidpos[3]; - uint8_t blob[BLOB_SIZE]; - float fv[3]; - - // Set our testing blob to a bunch of 0x01 bytes - memset(blob, 1, BLOB_SIZE); // 1111111... - - tagOpenWrite(virtual_definition, writename); - tagWrites(0x05, 11); - tagWriteString(0x06, cformat); - tagClose(); - - tagOpenRead(virtual_definition, writename); - assert(tagRead(0x01) == 1); - assert(tagReads(0x02) == 2); - assert(tagReadf(0x03) == 3); - assert(tagRead(0x04) == 4); - assert(tagReads(0x05) == 11); - formatdup = tagReadStringDup(0x06); - assert(strncmp(formatdup, cformat, 9) == 0); - free(formatdup); - assert(tagReads(0x07) == 1); - tagClose(); - - tagOpenWrite(basic_definition, writename); - tagWriteString(0x01, cformat); - tagWriteEnter(0x02, 1); - tagWrite(0x01, 101); - droidpos[0] = 11; - droidpos[1] = 13; - droidpos[2] = 15; - tagWrite16v(0x02, 3, droidpos); - fv[0] = 0.1f; - fv[1] = 1.1f; - fv[2] = -1.3f; - tagWritefv(0x03, 3, fv); - tagWrite8v(0x05, BLOB_SIZE, blob); - tagWrite8v(0x06, BLOB_SIZE, blob); - tagWriteEnter(0x07, 1); // group to test skipping - tagWrite(0x01, 0); // using default - tagWrite(0x02, 1); - tagWriteEnter(0x03, 1); - tagWriteLeave(0x03); - tagWriteNext(); - tagWrite(0x01, 1); - tagWrite(0x02, 0); - tagWriteEnter(0x03, 1); - tagWrite(0x01, 1); - tagWriteNext(); - tagWriteLeave(0x03); - // deliberately no 'next' here - tagWriteLeave(0x07); - tagWriteEnter(0x08, 1); - // empty, skipped group - tagWriteLeave(0x08); - tagWriteEnter(0x09, 1); - { - int32_t v[3] = { -1, 0, 1 }; - - tagWrite(0x01, 1); - tagWrites32v(0x05, 3, v); - } - tagWriteLeave(0x09); - tagWriteLeave(0x02); - tagClose(); - - memset(droidpos, 0, 6); - memset(fv, 0, 6); - memset(blob, 0, BLOB_SIZE); - tagOpenRead(basic_definition, writename); - tagReadString(0x01, 200, format); - assert(strncmp(format, cformat, 9) == 0); - tagReadEnter(0x02); - { - int32_t v[3]; - int size; - uint8_t *blobptr; - - assert(tagRead(0x01) == 101); - tagRead16v(0x02, 3, droidpos); - assert(droidpos[0] == 11); - assert(droidpos[1] == 13); - assert(droidpos[2] == 15); - tagReadfv(0x03, 3, fv); - assert(fv[0] - 0.1f < 0.001); - assert(fv[1] - 1.1f < 0.001); - assert(fv[2] + 1.3f < 0.001); - tagRead8v(0x05, BLOB_SIZE, blob); - blobptr = tagRead8vDup(0x06, &size); - assert(size == BLOB_SIZE); - assert(blob[BLOB_SIZE / 2] == 1); - assert(blobptr[BLOB_SIZE / 2] == 1); - tagReadEnter(0x09); - tagReads32v(0x05, 3, v); - assert(v[0] == -1); - assert(v[1] == 0); - assert(v[2] == 1); - tagReadLeave(0x09); - free(blobptr); - } - tagReadLeave(0x02); - assert(tagRead(0x04) == 9); - tagClose(); - fprintf(stdout, "\tTagfile self-test: PASSED\n"); -} diff --git a/lib/framework/tagfile.h b/lib/framework/tagfile.h deleted file mode 100644 index 10ad5e326..000000000 --- a/lib/framework/tagfile.h +++ /dev/null @@ -1,102 +0,0 @@ -// Written by Per I Mathisen, 2007 -// Released into the public domain, no rights reserved. -// -// The tagfile format is portable, nested, tagged binary format that should be -// useful for storing information that needs to be accessible several years -// into the future. That is, it is an easily extensible binary format, a feature -// usually reserved for text based formats. It also uses default values to -// reduce space, and despite its tagged nature, it consumes only a minimal overhead -// through the use a well-defined protocol file that is loaded separately. -// -// Each user of this code should define a protocol that is henceforth called -// the defined format. This consists of a series of tags that may contain either -// information or new tag groups. The tag groups can be nested until you run out -// of memory. Each tag group has its own namespace of tags. Each tag has a defined -// value representation (VR), a defined value multiplicity (VM), and an optional -// default value. -// -// Tags that have the default value may be omitted, and the read code will simply -// insert the default value when the tag is read. A group must be present in order -// for the read code to enter it even if all tags inside have default values. -// -// Each group can contain multiple instances of the same tag set. These are -// separated by separator tags. You can have any number of instances in a group, -// but you must know the number of instances beforehand. -// -// When reading and writing tags, remember to ALWAYS do so with successively -// increasing tag value. Do not write tag number 3 before tag number 1. -// -// See the included defined format files for more information on how to write them. - -#ifndef _tagfile_h -#define _tagfile_h - -#include "lib/framework/types.h" - -typedef uint8_t element_t; - -/** Open definition file and data file; return true if successful. */ -bool tagOpenWrite(const char *definition, const char *datafile); - -/** Open definition file and data file; return true if successful. */ -bool tagOpenRead(const char *definition, const char *datafile); - -/** Clean up and close the tagfile system down. */ -void tagClose(void); - -/** Report last error, then zeroes the internal error variable. If it - * returns false, there is no error. */ -bool tagGetError(void); - -/** Built-in unit test. */ -void tagTest(void); - -/*** tagWrite ***/ - -/** Enter a group given by tag which contains the given number of elements. */ -bool tagWriteEnter(element_t tag, uint16_t elements); - -/** Leave the given group. The group is given for consistency checking only. */ -bool tagWriteLeave(element_t tag); - -/** Start writing a new instance of a group. */ -bool tagWriteNext(void); - -/* Write methods */ -bool tagWrite(element_t tag, uint32_t val); -bool tagWrites(element_t tag, int32_t val); -bool tagWritef(element_t tag, float val); -bool tagWritefv(element_t tag, uint16_t count, const float *vals); -bool tagWrite8v(element_t tag, uint16_t count, const uint8_t *vals); -bool tagWrite16v(element_t tag, uint16_t count, const uint16_t *vals); -bool tagWrites32v(element_t tag, uint16_t count, const int32_t *vals); -bool tagWriteString(element_t tag, const char *string); -bool tagWriteBool(element_t tag, bool val); - -/*** tagread ***/ - -/** Enter a group given by tag and return the number of elements in it. */ -uint16_t tagReadEnter(element_t tag); - -/** Leave the given group. The group is given for consistency checking only. */ -void tagReadLeave(element_t tag); - -/** Start reading a new instance of a group. Returns false if no more entities - * to read, which can be used for iteration, if desired. */ -bool tagReadNext(void); - -/* Read methods */ -uint32_t tagRead(element_t tag); -int32_t tagReads(element_t tag); -bool tagReadBool(element_t tag); -float tagReadf(element_t tag); -bool tagReadfv(element_t tag, uint16_t size, float *vals); -uint8_t *tagRead8vDup(element_t tag, int *size); -bool tagRead8v(element_t tag, uint16_t size, uint8_t *vals); -bool tagRead16v(element_t tag, uint16_t size, uint16_t *vals); -bool tagReads16v(element_t tag, uint16_t size, int16_t *vals); -bool tagReads32v(element_t tag, uint16_t size, int32_t *vals); -bool tagReadString(element_t tag, uint16_t size, char *buffer); -char *tagReadStringDup(element_t tag); - -#endif diff --git a/lib/framework/vector.h b/lib/framework/vector.h index 4e9fc7954..aea875feb 100644 --- a/lib/framework/vector.h +++ b/lib/framework/vector.h @@ -56,6 +56,7 @@ struct Vector3f Vector3f() {} Vector3f(float x, float y, float z) : x(x), y(y), z(z) {} Vector3f(Vector3i const &v) : x(v.x), y(v.y), z(v.z) {} + Vector3f(Vector3f const &v) : x(v.x), y(v.y), z(v.z) {} Vector3f(Vector2f const &xy, int z) : x(xy.x), y(xy.y), z(z) {} float x, y, z; diff --git a/lib/framework/wzapp.cpp b/lib/framework/wzapp.cpp index 644ed17bb..9317e4bec 100644 --- a/lib/framework/wzapp.cpp +++ b/lib/framework/wzapp.cpp @@ -1317,3 +1317,45 @@ static int WZkeyToQtKey(int code) return 0; // nothing found (should never happen) } + +void WzConfig::setVector3f(const QString &name, const Vector3f &v) +{ + QStringList l; + l.push_back(QString::number(v.x)); + l.push_back(QString::number(v.y)); + l.push_back(QString::number(v.z)); + setValue(name, l); +} + +Vector3f WzConfig::vector3f(const QString &name) +{ + Vector3f r; + ASSERT_OR_RETURN(r, contains(name), "Missing %s", name.toUtf8().constData()); + QList v = value(name).toList(); + ASSERT(v.size() == 3, "Bad list of %s", name.toUtf8().constData()); + r.x = v[0].toDouble(); + r.y = v[1].toDouble(); + r.z = v[2].toDouble(); + return r; +} + +void WzConfig::setVector3i(const QString &name, const Vector3i &v) +{ + QStringList l; + l.push_back(QString::number(v.x)); + l.push_back(QString::number(v.y)); + l.push_back(QString::number(v.z)); + setValue(name, l); +} + +Vector3i WzConfig::vector3i(const QString &name) +{ + Vector3i r; + ASSERT_OR_RETURN(r, contains(name), "Missing %s", name.toUtf8().constData()); + QList v = value(name).toList(); + ASSERT(v.size() == 3, "Bad list of %s", name.toUtf8().constData()); + r.x = v[0].toInt(); + r.y = v[1].toInt(); + r.z = v[2].toInt(); + return r; +} diff --git a/lib/framework/wzapp.h b/lib/framework/wzapp.h index 438ccefa2..323785159 100644 --- a/lib/framework/wzapp.h +++ b/lib/framework/wzapp.h @@ -42,6 +42,10 @@ class WzConfig : public QSettings { public: WzConfig(const QString &name, QObject *parent = 0) : QSettings(QString("wz::") + name, QSettings::IniFormat, parent) {} + Vector3f vector3f(const QString &name); + void setVector3f(const QString &name, const Vector3f &v); + Vector3i vector3i(const QString &name); + void setVector3i(const QString &name, const Vector3i &v); }; class WzMainWindow : public QGLWidget diff --git a/src/effects.cpp b/src/effects.cpp index 2bf72d4f3..c9df63cab 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -35,10 +35,9 @@ * STILL NEED TO REMOVE SOME MAGIC NUMBERS INTO #DEFINES!!! * ************************************************************ */ -#include "lib/framework/frame.h" +#include "lib/framework/wzapp.h" #include "lib/framework/frameresource.h" #include "lib/framework/input.h" -#include "lib/framework/tagfile.h" #include "lib/framework/math_ext.h" #include "lib/ivis_opengl/ivisdef.h" //ivis matrix code @@ -2537,134 +2536,98 @@ void effectResetUpdates(void) } -static const char FXData_tag_definition[] = "tagdefinitions/savegame/effects.def"; -static const char FXData_file_identifier[] = "FXData"; - /** This will save out the effects data */ -bool writeFXData(const char* fileName) +bool writeFXData(const char *fileName) { EFFECT *it; + int i = 0; - if (!tagOpenWrite(FXData_tag_definition, fileName)) + WzConfig ini(fileName); + if (ini.status() != QSettings::NoError) { - ASSERT(false, "writeFXData: error while opening file (%s)", fileName); + debug(LOG_ERROR, "Could not open %s", fileName); return false; } - - tagWriteString(0x01, FXData_file_identifier); - - // Enter effects group and dump all active EFFECTs - tagWriteEnter(0x02, activeList.num); - - for (it = activeList.first; it != NULL; it = it->next) + for (it = activeList.first; it != NULL; it = it->next, i++) { - tagWrite(0x01, it->control); - tagWrite(0x02, it->group); - tagWrite(0x03, it->type); - tagWrite(0x04, it->frameNumber); - tagWrite(0x05, it->size); - tagWrite(0x06, it->baseScale); - tagWrite(0x07, it->specific); + ini.beginGroup("effect_" + QString::number(i)); + ini.setValue("control", it->control); + ini.setValue("group", it->group); + ini.setValue("type", it->type); + ini.setValue("frameNumber", it->frameNumber); + ini.setValue("size", it->size); + ini.setValue("baseScale", it->baseScale); + ini.setValue("specific", it->specific); + ini.setVector3f("position", it->position); + ini.setVector3f("velocity", it->velocity); + ini.setVector3i("rotation", it->rotation); + ini.setVector3i("spin", it->spin); + ini.setValue("birthTime", it->birthTime); + ini.setValue("lastFrame", it->lastFrame); + ini.setValue("frameDelay", it->frameDelay); + ini.setValue("lifeSpan", it->lifeSpan); + ini.setValue("radius", it->radius); - tagWritefv (0x08, 3, &it->position.x); - tagWritefv (0x09, 3, &it->velocity.x); - tagWrites32v (0x0A, 3, &it->rotation.x); - tagWrites32v (0x0B, 3, &it->spin.x); + const char *imd_name = resGetNamefromData("IMD", it->imd); + if (imd_name) + { + ini.setValue("imd_name", imd_name); + } - tagWrite(0x0C, it->birthTime); - tagWrite(0x0D, it->lastFrame); - tagWrite(0x0E, it->frameDelay); - tagWrite(0x0F, it->lifeSpan); - tagWrite(0x10, it->radius); - - tagWriteString(0x11, resGetNamefromData("IMD", it->imd)); - - // Move on to reading the next effect group - tagWriteNext(); + // Move on to reading the next effect + ini.endGroup(); } - // Leave the effects group again... - tagWriteLeave(0x02); - - // Close the file - tagClose(); // Everything is just fine! return true; } /** This will read in the effects data */ -bool readFXData(const char* fileName) +bool readFXData(const char *fileName) { - unsigned int count, i; - char strbuffer[25]; - - if (!tagOpenRead(FXData_tag_definition, fileName)) - { - debug(LOG_ERROR, "readFXData: error while opening file (%s)", fileName); - return false; - } - - // Read & verify the format header identifier - tagReadString(0x01, sizeof(strbuffer), strbuffer); - if (strncmp(strbuffer, FXData_file_identifier, sizeof(strbuffer)) != 0) - { - debug(LOG_ERROR, "readFXData: Weird file type found (in file %s)? Has header string: %s", fileName, strbuffer); - return false; - } - // Clear out anything that's there already! initEffectsSystem(); - // Enter effects group and load all EFFECTs - count = tagReadEnter(0x02); - for(i = 0; i < count; ++i) + WzConfig ini(fileName); + if (ini.status() != QSettings::NoError) { - char imd_name[PATH_MAX]; + debug(LOG_ERROR, "Could not open %s", fileName); + return false; + } + QStringList list = ini.childGroups(); + for (int i = 0; i < list.size(); ++i) + { + ini.beginGroup(list[i]); EFFECT *curEffect = Effect_malloc(); - /* Deal with out-of-memory conditions */ - if (curEffect == NULL) { - debug(LOG_ERROR, "Out of memory"); - return false; - } - - curEffect->control = tagRead(0x01); - curEffect->group = (EFFECT_GROUP)tagRead(0x02); - curEffect->type = (EFFECT_TYPE)tagRead(0x03); - curEffect->frameNumber = tagRead(0x04); - curEffect->size = tagRead(0x05); - curEffect->baseScale = tagRead(0x06); - curEffect->specific = tagRead(0x07); - - tagReadfv (0x08, 3, &curEffect->position.x); - tagReadfv (0x09, 3, &curEffect->velocity.x); - tagReads32v (0x0A, 3, &curEffect->rotation.x); - tagReads32v (0x0B, 3, &curEffect->spin.x); - - curEffect->birthTime = tagRead(0x0C); - curEffect->lastFrame = tagRead(0x0D); - curEffect->frameDelay = tagRead(0x0E); - curEffect->lifeSpan = tagRead(0x0F); - curEffect->radius = tagRead(0x10); - tagReadString(0x11, sizeof(imd_name), imd_name); - - if (imd_name[0] != '\0') + curEffect->control = ini.value("control").toInt(); + curEffect->group = (EFFECT_GROUP)ini.value("group").toInt(); + curEffect->type = (EFFECT_TYPE)ini.value("type").toInt(); + curEffect->frameNumber = ini.value("control").toInt(); + curEffect->size = ini.value("control").toInt(); + curEffect->baseScale = ini.value("control").toInt(); + curEffect->specific = ini.value("control").toInt(); + curEffect->position = ini.vector3f("position"); + curEffect->velocity = ini.vector3f("velocity"); + curEffect->rotation = ini.vector3i("rotation"); + curEffect->spin = ini.vector3i("spin"); + curEffect->birthTime = ini.value("control").toInt(); + curEffect->lastFrame = ini.value("control").toInt(); + curEffect->frameDelay = ini.value("control").toInt(); + curEffect->lifeSpan = ini.value("control").toInt(); + curEffect->radius = ini.value("control").toInt(); + if (ini.contains("imd_name")) { - curEffect->imd = (iIMDShape*)resGetData("IMD", imd_name); + curEffect->imd = (iIMDShape*)resGetData("IMD", ini.value("imd_name").toString().toUtf8().constData()); } else { curEffect->imd = NULL; } - // Move on to reading the next effect group - tagReadNext(); + // Move on to reading the next effect + ini.endGroup(); } - // Leave the effects group again... - tagReadLeave(0x02); - - // Close the file - tagClose(); /* Hopefully everything's just fine by now */ return true; diff --git a/src/game.cpp b/src/game.cpp index ac9a35bb3..078d04540 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -17,7 +17,7 @@ along with Warzone 2100; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "lib/framework/frame.h" +#include "lib/framework/wzapp.h" /* Standard library headers */ #include @@ -29,7 +29,6 @@ #include "lib/framework/frameint.h" #include "lib/framework/physfs_ext.h" #include "lib/framework/strres.h" -#include "lib/framework/tagfile.h" #include "lib/gamelib/gtime.h" #include "lib/ivis_opengl/ivisdef.h" @@ -2131,8 +2130,8 @@ static bool loadSaveStructLimits(char *pFileData, UDWORD filesize); static bool loadSaveStructLimitsV(char *pFileData, UDWORD filesize, UDWORD numLimits); static bool writeStructLimitsFile(char *pFileName); -static bool readFiresupportDesignators(char *pFileName); -static bool writeFiresupportDesignators(char *pFileName); +static bool readFiresupportDesignators(const char *pFileName); +static bool writeFiresupportDesignators(const char *pFileName); static bool writeScriptState(char *pFileName); @@ -2809,7 +2808,7 @@ bool loadGame(const char *pGameToLoad, bool keepObjects, bool freeMem, bool User { //load in the message list file aFileName[fileExten] = '\0'; - strcat(aFileName, "fxstate.tag"); + strcat(aFileName, "fxstate.ini"); // load the fx data from the file if (!readFXData(aFileName)) @@ -3126,7 +3125,7 @@ bool loadGame(const char *pGameToLoad, bool keepObjects, bool freeMem, bool User { //load in the message list file aFileName[fileExten] = '\0'; - strcat(aFileName, "score.tag"); + strcat(aFileName, "score.ini"); // Load the fx data from the chosen file if (!readScoreData(aFileName)) @@ -3175,7 +3174,7 @@ bool loadGame(const char *pGameToLoad, bool keepObjects, bool freeMem, bool User { //load in the command list file aFileName[fileExten] = '\0'; - strcat(aFileName, "firesupport.tag"); + strcat(aFileName, "firesupport.ini"); if (!readFiresupportDesignators(aFileName)) { @@ -3532,7 +3531,7 @@ bool saveGame(char *aFileName, GAME_TYPE saveType) //create the message filename CurrentFileName[fileExtension] = '\0'; - strcat(CurrentFileName, "fxstate.tag"); + strcat(CurrentFileName, "fxstate.ini"); /*Write the data to the file*/ if (!writeFXData(CurrentFileName)) { @@ -3543,7 +3542,7 @@ bool saveGame(char *aFileName, GAME_TYPE saveType) //added at V15 save //create the message filename CurrentFileName[fileExtension] = '\0'; - strcat(CurrentFileName, "score.tag"); + strcat(CurrentFileName, "score.ini"); /*Write the data to the file*/ if (!writeScoreData(CurrentFileName)) { @@ -3563,7 +3562,7 @@ bool saveGame(char *aFileName, GAME_TYPE saveType) //create the message filename CurrentFileName[fileExtension] = '\0'; - strcat(CurrentFileName, "firesupport.tag"); + strcat(CurrentFileName, "firesupport.ini"); /*Write the data to the file*/ if (!writeFiresupportDesignators(CurrentFileName)) { @@ -9912,82 +9911,50 @@ bool writeStructLimitsFile(char *pFileName) return false; } -static const char FireSupport_tag_definition[] = "tagdefinitions/savegame/firesupport.def"; -static const char FireSupport_file_identifier[] = "FIRESUPPORT"; - /*! * Load the current fire-support designated commanders (the one who has fire-support enabled) */ -bool readFiresupportDesignators(char *pFileName) +bool readFiresupportDesignators(const char *pFileName) { - unsigned int numPlayers, player; - char formatIdentifier[12] = ""; - - if (!tagOpenRead(FireSupport_tag_definition, pFileName)) + WzConfig ini(pFileName); + if (ini.status() != QSettings::NoError) { - debug(LOG_ERROR, "readFiresupportDesignators: Failed to open savegame %s", pFileName); + debug(LOG_ERROR, "Could not open %s", pFileName); return false; } - debug(LOG_MAP, "Reading tagged savegame %s with definition %s:", pFileName, FireSupport_tag_definition); - - tagReadString(0x01, 12, formatIdentifier); - if (strcmp(formatIdentifier, FireSupport_file_identifier) != 0) + QStringList list = ini.childGroups(); + for (int i = 0; i < list.size(); ++i) { - debug(LOG_ERROR, "readFiresupportDesignators: Incompatble %s, 'FIRESUPPORT' expected", pFileName); - return false; - } - - numPlayers = tagReadEnter(0x02); - for (player = 0; player < numPlayers; player++) - { - uint32_t id = tagRead(0x01); + uint32_t id = ini.value("Player_" + QString::number(i) + "/id", NULL_ID).toInt(); if (id != NULL_ID) { cmdDroidSetDesignator((DROID*)getBaseObjFromId(id)); } - tagReadNext(); } - tagReadLeave(0x02); - - tagClose(); - return true; } - /*! * Save the current fire-support designated commanders (the one who has fire-support enabled) */ -bool writeFiresupportDesignators(char *pFileName) +bool writeFiresupportDesignators(const char *pFileName) { - unsigned int player; + int player; - if (!tagOpenWrite(FireSupport_tag_definition, pFileName)) + WzConfig ini(pFileName); + if (ini.status() != QSettings::NoError) { - debug(LOG_ERROR, "writeFiresupportDesignators: Failed to create savegame %s", pFileName); + debug(LOG_ERROR, "Could not open %s", pFileName); return false; } - debug(LOG_MAP, "Creating tagged savegame %s with definition %s:", pFileName, FireSupport_tag_definition); - - tagWriteString(0x01, FireSupport_file_identifier); - tagWriteEnter(0x02, MAX_PLAYERS); for (player = 0; player < MAX_PLAYERS; player++) { - DROID * psDroid = cmdDroidGetDesignator(player); + DROID *psDroid = cmdDroidGetDesignator(player); if (psDroid != NULL) { - tagWrite(0x01, psDroid->id); + ini.setValue("Player_" + QString::number(player) + "/id", psDroid->id); } - else - { - tagWrite(0x01, NULL_ID); - } - tagWriteNext(); } - tagWriteLeave(0x02); - - tagClose(); - return true; } diff --git a/src/main.cpp b/src/main.cpp index 3ef1293c8..0bd076a5e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,7 +34,6 @@ #include "lib/framework/configfile.h" #include "lib/framework/input.h" #include "lib/framework/physfs_ext.h" -#include "lib/framework/tagfile.h" #include "lib/framework/wzapp_c.h" #include "lib/exceptionhandler/exceptionhandler.h" #include "lib/exceptionhandler/dumpinfo.h" @@ -1305,7 +1304,6 @@ int finalInitialization() /* Runtime unit testing */ if (selfTest) { - tagTest(); parseTest(); levTest(); mapTest(); diff --git a/src/map.cpp b/src/map.cpp index 2a8a60001..3f0c3b517 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -29,7 +29,6 @@ #include "lib/framework/endian_hack.h" #include "lib/framework/file.h" #include "lib/framework/physfs_ext.h" -#include "lib/framework/tagfile.h" #include "lib/ivis_opengl/tex.h" #include "lib/netplay/netplay.h" // For syncDebug diff --git a/src/scores.cpp b/src/scores.cpp index c74d4aff9..aa41db0fc 100644 --- a/src/scores.cpp +++ b/src/scores.cpp @@ -27,10 +27,9 @@ #include // -------------------------------------------------------------------- -#include "lib/framework/frame.h" +#include "lib/framework/wzapp.h" #include "lib/framework/math_ext.h" #include "lib/framework/strres.h" -#include "lib/framework/tagfile.h" #include "lib/gamelib/gtime.h" #include "console.h" #include "scores.h" @@ -556,36 +555,29 @@ void fillUpStats( void ) infoBars[STAT_STR_BUILT].number = missionData.strBuilt; } -static const char ScoreData_tag_definition[] = "tagdefinitions/savegame/score.def"; -static const char ScoreData_file_identifier[] = "ScoreData"; - // ----------------------------------------------------------------------------------- /* This will save out the score data */ bool writeScoreData(const char* fileName) { - if (!tagOpenWrite(ScoreData_tag_definition, fileName)) + WzConfig ini(fileName); + if (ini.status() != QSettings::NoError) { - ASSERT(false, "writeScoreData: error while opening file (%s)", fileName); + debug(LOG_ERROR, "Could not open %s", fileName); return false; } - tagWriteString(0x01, ScoreData_file_identifier); - // Dump the scores for the current player - tagWrite(0x02, missionData.unitsBuilt); - tagWrite(0x03, missionData.unitsKilled); - tagWrite(0x04, missionData.unitsLost); - tagWrite(0x05, missionData.strBuilt); - tagWrite(0x06, missionData.strKilled); - tagWrite(0x07, missionData.strLost); - tagWrite(0x08, missionData.artefactsFound); - tagWrite(0x09, missionData.missionStarted); - tagWrite(0x0A, missionData.shotsOnTarget); - tagWrite(0x0B, missionData.shotsOffTarget); - tagWrite(0x0C, missionData.babasMowedDown); - - // Close the file - tagClose(); + ini.setValue("unitsBuilt", missionData.unitsBuilt); + ini.setValue("unitsKilled", missionData.unitsKilled); + ini.setValue("unitsLost", missionData.unitsLost); + ini.setValue("strBuilt", missionData.strBuilt); + ini.setValue("strKilled", missionData.strKilled); + ini.setValue("strLost", missionData.strLost); + ini.setValue("artefactsFound", missionData.artefactsFound); + ini.setValue("missionStarted", missionData.missionStarted); + ini.setValue("shotsOnTarget", missionData.shotsOnTarget); + ini.setValue("shotsOffTarget", missionData.shotsOffTarget); + ini.setValue("babasMowedDown", missionData.babasMowedDown); // Everything is just fine! return true; @@ -595,37 +587,25 @@ bool writeScoreData(const char* fileName) /* This will read in the score data */ bool readScoreData(const char* fileName) { - char strbuffer[25]; - - if (!tagOpenRead(ScoreData_tag_definition, fileName)) + WzConfig ini(fileName); + if (ini.status() != QSettings::NoError) { - debug(LOG_ERROR, "readFXData: error while opening file (%s)", fileName); - return false; - } - - // Read & verify the format header identifier - tagReadString(0x01, sizeof(strbuffer), strbuffer); - if (strncmp(strbuffer, ScoreData_file_identifier, sizeof(strbuffer)) != 0) - { - debug(LOG_ERROR, "readScoreData: Weird file type found (in file %s)? Has header string: %s", fileName, strbuffer); + debug(LOG_ERROR, "Could not open %s", fileName); return false; } // Retrieve the score data for the current player - missionData.unitsBuilt = tagRead(0x02); - missionData.unitsKilled = tagRead(0x03); - missionData.unitsLost = tagRead(0x04); - missionData.strBuilt = tagRead(0x05); - missionData.strKilled = tagRead(0x06); - missionData.strLost = tagRead(0x07); - missionData.artefactsFound = tagRead(0x08); - missionData.missionStarted = tagRead(0x09); - missionData.shotsOnTarget = tagRead(0x0A); - missionData.shotsOffTarget = tagRead(0x0B); - missionData.babasMowedDown = tagRead(0x0C); - - // Close the file - tagClose(); + missionData.unitsBuilt = ini.value("unitsBuilt").toInt(); + missionData.unitsKilled = ini.value("unitsKilled").toInt(); + missionData.unitsLost = ini.value("unitsLost").toInt(); + missionData.strBuilt = ini.value("strBuilt").toInt(); + missionData.strKilled = ini.value("strKilled").toInt(); + missionData.strLost = ini.value("strLost").toInt(); + missionData.artefactsFound = ini.value("artefactsFound").toInt(); + missionData.missionStarted = ini.value("missionStarted").toInt(); + missionData.shotsOnTarget = ini.value("shotsOnTarget").toInt(); + missionData.shotsOffTarget = ini.value("shotsOffTarget").toInt(); + missionData.babasMowedDown = ini.value("babasMowedDown").toInt(); /* Hopefully everything's just fine by now */ return true;