Skip to content

Reading from wz file

Lien Chiang edited this page Apr 21, 2016 · 3 revisions

Reading from wz file

There are some keywords we must understand before we get started: Node and Variable.

Node

The wz file contains 1 ~ 10000 nodes. These nodes construct a node tree. There are two types of nodes: directory node and file node. Each node has their name, which called node name.

For example, the Character.wz contains these nodes:

  • Accessory
    • 01010000.img
    • 01010001.img
    • ...
  • Afterimage
    • axe.img
    • barehands.img
    • ...
  • ...
  • 00002000.img
  • 00002001.img
  • 00002002.img
  • ...

The Accessory and Afterimage are the names of these two directory nodes, which contains several child nodes, eg: 01010000.img, 01010001.img, axe.img and barehands.img. Each child nodes may contain child nodes if the child node is directory node. That makes these nodes become a node tree. The 00002000.img, 00002001.img and 00002002.img are file node, which does not have any child node, but has multiple variables instead. We will discuss the variable below.

Example Code

Lets see how to read the nodes:

#include <wz/file.h>

int main(void) {
  wzctx ctx;
  if (wz_init_ctx(&ctx)) return 1;
  wzfile file;
  if (wz_open_file(&file, "Character.wz", &ctx))
    return wz_free_ctx(&ctx), 1;
  wznode * root = wz_open_root_node(&file);
  uint32_t len  = wz_get_nodes_len(root);
  for (uint32_t i = 0; i < len; i++) {
    wznode * node = wz_open_node_at(root, i);
    printf(" %s\n", wz_get_node_name(node));
    if (node->type == WZ_NODE_DIR) {
      uint32_t node_len = wz_get_nodes_len(node);
      for (uint32_t j = 0; j < node_len; j++) {
        wznode * child = wz_open_node_at(node, j);
        printf("  %s\n", wz_get_node_name(child));
        wz_close_node(child);
      }
    }
    wz_close_node(node);
  }
  wz_close_node(root);
  wz_close_file(&file);
  wz_free_ctx(&ctx);
}

Variable

The file node contains 1 ~ 100000 variables. These variables construct a variable tree. There are four types of variables: integer, float, string and object. The object can be list, image, convex, vector, audio or uol. Only two types of object can have child nodes: list and image. list and image would be explained before the other types of variables.

List and Image

For example, 01010000.img contains these variables:

  • angry
    • 0
      • default
        • map
          • brow
        • origin
        • z
  • bewildered
  • blaze
  • ...

The angry, 0, map, bewildered and blaze are list, which contains several child variables. In this example, the 0 is the child variable of angry, the default is the child variable of 0, and the brow is the child variable of map. The default is image, which have width, height and pixels of the image. Image may also have some child variables, eg: map, origin and z.

After the variable types are added, the node tree became more easy to understand:

  • angry - list
    • 0 - list
      • default - image
        • map - list
          • brow
        • origin
        • z
  • bewildered - list
  • blaze - list
  • ...

Integer, Float and String

Integer may be 16, 32 or 64 bit of integer. The wz library normalize these different types to 64 bit. Float may be 32 or 64 bit of floating-point number. The wz library normalize these types to 64 bit. String may be ASCII or UTF16-LE encoded string. The wz library normalize these types to UTF8.

In previous example, the z is a String and contains these characters: accessoryFace

Convex, Vector, Audio and Uol

Convex contains multiple vectors, eg: (1, 2), (3, 4) and (5, 6). Vector contains only one vector, eg: (1, 2). Audio may be PCM or MP3 encoded music. Uol is just a string and this string means the path to another node to reduce redundant nodes.

In previous example, the brow are vector and contains this vector: (-10, 43)

Example Code

Lets see how to read the variables:

#include <inttypes.h>
#include <wz/file.h>

int main(void) {
  wzctx ctx;
  if (wz_init_ctx(&ctx)) return 1;
  wzfile file;
  if (wz_open_file(&file, "Character.wz", &ctx))
    return wz_free_ctx(&ctx), 1;
  wznode * root_node = wz_open_root_node(&file);
  wznode * node      = wz_open_node(root_node, "00002001.img");
  wzvar * root_var   = wz_open_root_var(node);
  wzvar * var_prone  = wz_open_var(root_var, "prone/0");
  wzvar * var_face   = wz_open_var(var_prone, "face");
  wzvar * var_delay  = wz_open_var(var_prone, "delay");
  wzvar * var_arm    = wz_open_var(var_prone, "arm");
  int64_t face       = wz_get_int(var_face);
  int64_t delay      = wz_get_int(var_delay);
  wzimg * arm        = wz_get_img(var_arm);
  printf("face: %"PRId64"\n"
         "delay: %"PRId64"\n"
         "arm: %"PRIu32" x %"PRIu32"\n",
         face, delay, arm->w, arm->h);
  wz_close_file(&file);
  wz_free_ctx(&ctx);
}

In this example, The var_arm is actually a uol, which points to another image variable. We do not need to find the variable uol pointing to because the wz library has automatically done this job. We can simple treat the uol as the variable it points, so we directly call wz_get_img(var_arm) to get image.

We can also iterate the variables:

#include <wz/file.h>

int main(void) {
  wzctx ctx;
  if (wz_init_ctx(&ctx)) return 1;
  wzfile file;
  if (wz_open_file(&file, "Character.wz", &ctx))
    return wz_free_ctx(&ctx), 1;
  wznode * root_node = wz_open_root_node(&file);
  wznode * node      = wz_open_node(root_node, "Weapon/01212000.img");
  wzvar * root_var   = wz_open_root_var(node);
  uint32_t len       = wz_get_vars_len(root_var);
  for (uint32_t i = 0; i < len; i++) {
    wzvar * var = wz_open_var_at(root_var, i);
    printf(" %s\n", wz_get_var_name(var));
    uint32_t var_len = wz_get_vars_len(var);
    for (uint32_t j = 0; j < var_len; j++) {
      wzvar * child = wz_open_var_at(var, j);
      printf("  %s\n", wz_get_var_name(child));
      wz_close_var(child);
    }
    wz_close_var(var);
  }
  wz_close_var(root_var);
  wz_close_node(root_node);
  wz_close_file(&file);
  wz_free_ctx(&ctx);
}