Logo Search packages:      
Sourcecode: lebiniou version File versions  Download package

schemes.c

/*
 *  Copyright 1994-2011 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "schemes.h"
#include "globals.h"
#include "xmlutils.h"


static enum PluginOptions
Schemes_parse_one_option(const char *opt)
{
  if (!strcmp(opt, "SFX2D")) return BE_SFX2D;
  if (!strcmp(opt, "SFX3D")) return BE_SFX3D;
  if (!strcmp(opt, "GFX")) return BE_GFX;
  if (!strcmp(opt, "BLUR")) return BE_BLUR;
  if (!strcmp(opt, "DISPLACE")) return BE_DISPLACE;
  if (!strcmp(opt, "LENS")) return BE_LENS;
  if (!strcmp(opt, "SCROLL")) return BE_SCROLL;
  if (!strcmp(opt, "MIRROR")) return BE_MIRROR;
  if (!strcmp(opt, "ROLL")) return BE_ROLL;
  if (!strcmp(opt, "WARP")) return BE_WARP;
  if (!strcmp(opt, "CLEAN")) return BE_CLEAN;
  if (!strcmp(opt, "HOR")) return BEQ_HOR;
  if (!strcmp(opt, "VER")) return BEQ_VER;
  if (!strcmp(opt, "DIAG")) return BEQ_DIAG;
  if (!strcmp(opt, "UP")) return BEQ_UP;
  if (!strcmp(opt, "DOWN")) return BEQ_DOWN;
  if (!strcmp(opt, "LEFT")) return BEQ_LEFT;
  if (!strcmp(opt, "RIGHT")) return BEQ_RIGHT;
  if (!strcmp(opt, "COLORMAP")) return BEQ_COLORMAP;
  if (!strcmp(opt, "PARTICLES")) return BEQ_PARTICLES;
  if (!strcmp(opt, "SPLASH")) return BEQ_SPLASH;
  /*  if (!strcmp(opt, "THREAD")) return BEQ_THREAD; */ /* can not occur in a scheme */
  if (!strcmp(opt, "PICTURE")) return BEQ_PICTURE;
  /*  if (!strcmp(opt, "NORANDOM")) return BEQ_NORANDOM; */ /* can not occur in a scheme */
  /*  if (!strcmp(opt, "DISABLED")) return BEQ_DISABLED; */ /* idem */
  if (!strcmp(opt, "3D")) return BEQ_3D;
  if (!strcmp(opt, "UNIQUE")) return BEQ_UNIQUE;
  if (!strcmp(opt, "TEST")) return BEQ_TEST;
  if (!strcmp(opt, "DEBUG")) return BEQ_DEBUG;
  if (!strcmp(opt, "FIRST")) return BEQ_FIRST;
  if (!strcmp(opt, "FLUSH")) return BEQ_FLUSH;
  /*  if (!strcmp(opt, "NONE")) return BE_NONE; */ /* can not occur in a scheme */

  xerror("[!] Failed to parse option '%s'\n", opt);

  return BE_NONE; /* not reached */
}


static enum PluginOptions
Schemes_parse_option(const char *opt)
{
  int o = 0;
  char *pipe = NULL;

  while ((pipe = strchr(opt, '|')) != NULL) {
    *pipe = '\0';
    if (*opt == '-') {
      opt++;
      o |= -Schemes_parse_one_option(opt);
    } else
      o |= Schemes_parse_one_option(opt);
    opt = pipe + sizeof(char);
  }

  if (*opt == '-') {
    opt++;
    o |= -Schemes_parse_one_option(opt);
  } else
    o |= Schemes_parse_one_option(opt);

  return (enum PluginOptions)o;
}


static u_short
Schemes_parse(Schemes_t *schemes, const xmlDocPtr doc)
{
  xmlNodePtr schemes_node = NULL, scheme_node = NULL;
  u_short size = 0, i;
  xmlChar *wizz;

  /* Start at Root Element */
  schemes_node = xmlDocGetRootElement(doc);
  if (schemes_node == NULL)
    xerror("xmlDocGetRootElement error\n");

  schemes_node = xmlFindElement("schemes", schemes_node);
  if (schemes_node == NULL) {
    printf("[!] No <schemes> found\n");
    return 0;
  }

  wizz = xmlGetProp(schemes_node, (const xmlChar *)"size");
  size = (u_short)getintfield(wizz);
  xmlFree(wizz);
  assert(size > 0);

  schemes->schemes = xcalloc(size, sizeof(SchemeItem_t *));

  scheme_node = schemes_node->xmlChildrenNode;
  for (i = 0; i < size; i++) {
    int length, j;
    xmlNodePtr type_node = NULL;

    scheme_node = xmlFindElement("scheme", scheme_node);
    if (scheme_node == NULL) {
      printf("[!] No <scheme> found\n");
      return 0;
    }

    /* XXX use getinitfield_mandatory */
    wizz = xmlGetProp(scheme_node, (const xmlChar *)"length");
    length = getintfield(wizz);
    xmlFree(wizz);
    assert(length > 0);

    schemes->schemes[i] = xcalloc(length+1, sizeof(SchemeItem_t));

    type_node = scheme_node->xmlChildrenNode;
    for (j = 0; j < length; j++) {
      int res;
      float p;
      enum PluginOptions o;
      xmlChar *token;

      type_node = xmlFindElement("type", type_node);
      if (type_node == NULL) {
      int k;

      printf("[!] No <type> found\n");
      for (k = 0; k <= i; k++)
        xfree(schemes->schemes[k]);
      xfree(schemes->schemes);

      return 0;
      }

      wizz = xmlGetProp(type_node, (const xmlChar *)"proba");
      res = getfloatfield_optional(wizz, &p);
      xmlFree(wizz);
      if (res == -1)
      p = 1.0;

      token = xmlNodeListGetString(doc, type_node->xmlChildrenNode, 1);
      if (token == NULL)
      xerror("No data in <type> element\n");

      o = Schemes_parse_option((const char *)token);
#ifdef XDEBUG
      printf("%d:%d/%d TOKEN: %f / %s => %d\n", i, j, length, p, token, (int)o);
#endif
      xmlFree(token);

      schemes->schemes[i][j].p = p;
      schemes->schemes[i][j].type = o;

      type_node = type_node->next;
    }
    
    scheme_node = scheme_node->next;
  }

  return size;
}


void
Schemes_new(const char *file)
{
  xmlDocPtr doc = NULL; /* XmlTree */

  if (NULL == file)
    xerror("Schemes_new() called but file is NULL\n");

  schemes = xcalloc(1, sizeof(Schemes_t));

  /* BLA ! */
  xmlKeepBlanksDefault(0);
  
  /*
   * build an XML tree from the file
   */
  doc = xmlParseFile(file);
  if (doc == NULL) {
    printf("[!] xmlParseFile '%s' error\n", file);
    printf("[!] No schemes loaded\n");
    xfree(schemes);
    return;
  }

  schemes->size = Schemes_parse(schemes, doc);
  xmlFreeDoc(doc);

  if (!schemes->size) {
    if (libbiniou_verbose)
      printf("[!] No schemes loaded\n");
    xfree(schemes); /* xfree sets the pointer to NULL */
  } else {
    if (libbiniou_verbose)
      printf("[i] Loaded %d scheme%s\n", schemes->size, (schemes->size == 1) ? "": "s");
  }

  schemes->shuffler = Shuffler_new(schemes->size);
  Shuffler_verbose(schemes->shuffler);
}


void
Schemes_new_default()
{
  schemes = xcalloc(1, sizeof(Schemes_t));
  schemes->size = 1;

  schemes->schemes = xcalloc(1, sizeof(SchemeItem_t *));
  schemes->schemes[0] = xcalloc(2, sizeof(SchemeItem_t));

  schemes->schemes[0][0].p = 1.0;
  schemes->schemes[0][0].type = BEQ_UNIQUE;

  schemes->shuffler = NULL;
}


void
Schemes_delete()
{
  if (schemes != NULL) {
    u_short i;
    
    for (i = 0; i < schemes->size; i++)
      xfree(schemes->schemes[i]);
    xfree(schemes->schemes);
    if (NULL != schemes->shuffler)
      Shuffler_delete(schemes->shuffler);
    xfree(schemes);
  }
}

Generated by  Doxygen 1.6.0   Back to index