Source Code (Use browser search to find items of interest.)

Class Index

ksokoban'LevelCollection (./kdegames/ksokoban/LevelCollection.H:28)

class LevelCollection {
public:
  LevelCollection(const char *_def, int _len, const QString &_name, int _id=-1);
  LevelCollection(const QString &_path, const QString &_name, int _id=-1);
  ~LevelCollection();

  const QString &name() const { return name_; }
  int id() const { return id_; }
  int level() const { return level_; }
  void level(int _level);
  void levelCompleted();
  int completedLevels() const { return completedLevels_; }
  int noOfLevels() const { return noOfLevels_; }
  bool loadLevel(Map *_map);

protected:
  void indexTextCollection();
  void loadPrefs();


private:
  Array<char *> index_;
  Array<char>   data_;
  //int    dataLen_;

  int      level_;
  int      completedLevels_;
  int      noOfLevels_;
  QString  name_;
  QString  path_;
  int      id_;
};

ksokoban'LevelCollection::indexTextCollection() (./kdegames/ksokoban/LevelCollection.C:30)

LevelCollection::indexTextCollection() {
  enum states {
    BEFORE_NONE, BEFORE_VALID, BEFORE_INVALID,
    DURING_NONE, DURING_VALID, DURING_INVALID
  } state = BEFORE_NONE;

  int levelstart=0, levelend=0;
  for (int pos=0; pos<(data_.size()-1); pos++) {
    switch (state) {
    case BEFORE_NONE:
      switch (data_[pos]) {
      case '#': case '.': case '$': case '+': case '*': case '@':
	state = BEFORE_VALID;
	break;

      case ' ': case '\t': case '\r':
	break;

      case '\n':
	levelstart = pos + 1;
	break;

      default:
	state = BEFORE_INVALID;
	break;
      }
      break;

    case BEFORE_VALID:
      switch (data_[pos]) {
      case '#': case '.': case '$': case '+': case '*': case '@':
      case ' ': case '\t': case '\r':
	break;

      case '\n':
	index_.add(&data_[levelstart]);
	state = DURING_NONE;
	break;

      default:
	state = BEFORE_INVALID;
	break;
      }
      break;

    case BEFORE_INVALID:
      switch (data_[pos]) {
      case '\n':
	levelstart = pos + 1;
	state = BEFORE_NONE;
	break;
      }
      break;

    case DURING_NONE:
      switch (data_[pos]) {
      case '#': case '.': case '$': case '+': case '*': case '@':
	state = DURING_VALID;
	break;

      case ' ': case '\t': case '\r':
	break;

      case '\n':
	data_[levelend] = '\0';
	levelstart = pos + 1;
	state = BEFORE_NONE;
	break;

      default:
	state = DURING_INVALID;
	break;
      }
      break;

    case DURING_VALID:
      switch (data_[pos]) {
      case '#': case '.': case '$': case '+': case '*': case '@':
      case ' ': case '\t': case '\r':
	break;

      case '\n':
	levelend = pos;
	state = DURING_NONE;
	break;

      default:
	state = DURING_INVALID;
	break;
      }
      break;

    case DURING_INVALID:
      switch (data_[pos]) {
      case '\n':
	data_[levelend] = '\0';
	levelstart = pos + 1;
	state = BEFORE_NONE;
	break;
      }
      break;

    default:
      assert(0);
    }
  }

  if (state==DURING_NONE || state==DURING_INVALID) {
    data_[levelend] = '\0';
  }
}

void

ksokoban'LevelCollection::loadPrefs() (./kdegames/ksokoban/LevelCollection.C:143)

LevelCollection::loadPrefs() {
  if (id_ >= 0) {
    KConfig *cfg=(KApplication::kApplication())->config();
    cfg->setGroup("settings");

    QString key;
    key.sprintf("level%d", id_);
    level_ = cfg->readNumEntry(key, 0);

    key.sprintf("status%d", id_);
    unsigned long x = cfg->readUnsignedLongNumEntry(key, 0);

    x = backward(x, 0xc1136a15ul, 0x12ul, 0x80ff0b94ul);
    x = backward(x, 0xd38fd2ddul, 0x01ul, 0xd4d657b4ul);
    x = backward(x, 0x59004eeful, 0x1eul, 0xf6c75e2cul);
    x = backward(x, 0x366c3e25ul, 0x0aul, 0x61ebc208ul);
    x = backward(x, 0x20a784c9ul, 0x15ul, 0x207d488bul);
    x = backward(x, 0xc02864abul, 0x09ul, 0x709e62a3ul);
    x = backward(x, 0xe2a60f19ul, 0x0eul, 0x8bb02c07ul);
    x = backward(x, 0x3b0e11f3ul, 0x13ul, 0x608aef3ful);

    completedLevels_ = x>>16 & 0x3ff;
    if (!cfg->hasKey(key)) completedLevels_ = 0;
    if (((x>>26) & 0x3ful) != (unsigned long) id_) completedLevels_ = 0;
    if ((x & 0xfffful) != (unsigned long) getuid()) completedLevels_ = 0;
    if (completedLevels_ > noOfLevels_) completedLevels_ = 0;

    if (level_ > completedLevels_) level_ = completedLevels_;
    if (level_ >= noOfLevels_) level_ = noOfLevels_-1;
    if (level_ < 0) level_ = 0;
  } else {
    level_ = 0;
    completedLevels_ = noOfLevels_;
  }
}


ksokoban'LevelCollection::LevelCollection() (./kdegames/ksokoban/LevelCollection.C:179)

LevelCollection::LevelCollection(const char *_def, int _len,
				 const QString &_name, int _id) :
  level_(0), completedLevels_(0), noOfLevels_(0),
  name_(_name), id_(_id) {

  data_.add(_def, _len);
  data_.add('\0');

  indexTextCollection();

  noOfLevels_ = index_.size();

  loadPrefs();
}


ksokoban'LevelCollection::LevelCollection() (./kdegames/ksokoban/LevelCollection.C:194)

LevelCollection::LevelCollection(const QString &_path, const QString &_name,
				 int _id) :
  level_(0), completedLevels_(0), noOfLevels_(0),
  name_(_name), path_(_path), id_(_id) {

  char buf[1024];
  int len;

  QFile file(path_);
  if (file.open(IO_Raw | IO_ReadOnly)) {
    while ((len = file.readBlock(buf, 1024)) > 0) {
      data_.add((char *) buf, len);
    }
    file.close();
    data_.add('\0');
  }

  indexTextCollection();

  noOfLevels_ = index_.size();

  loadPrefs();

}


ksokoban'LevelCollection::~LevelCollection() (./kdegames/ksokoban/LevelCollection.C:219)

LevelCollection::~LevelCollection() {
  if (id_ >= 0) {
    KConfig *cfg=(KApplication::kApplication())->config();
    cfg->setGroup ("settings");

    QString key;
    key.sprintf("level%d", id_);
    cfg->writeEntry(key, level_, true, false, false);
  }
}


void

ksokoban'LevelCollection::levelCompleted() (./kdegames/ksokoban/LevelCollection.C:232)

LevelCollection::levelCompleted() {
  if (completedLevels_ < (level_+1)) completedLevels_ = level_+1;

  if (id_ >= 0) {
    unsigned long x=(((unsigned long) getuid()) & 0xfffful);
    x |= ((unsigned long) id_)<<26;
    x |= ((unsigned long) completedLevels_)<<16;

    x = forward(x, 0x608aef3ful, 0x0dul, 0xfb00ef3bul);
    x = forward(x, 0x8bb02c07ul, 0x12ul, 0x2a37dd29ul);
    x = forward(x, 0x709e62a3ul, 0x17ul, 0x23607603ul);
    x = forward(x, 0x207d488bul, 0x0bul, 0xc31fd579ul);
    x = forward(x, 0x61ebc208ul, 0x16ul, 0xbcffadadul);
    x = forward(x, 0xf6c75e2cul, 0x02ul, 0xa2baa00ful);
    x = forward(x, 0xd4d657b4ul, 0x1ful, 0x7e129575ul);
    x = forward(x, 0x80ff0b94ul, 0x0eul, 0x92fc153dul);

    QString key;
    key.sprintf("status%d", id_);

    KConfig *cfg=(KApplication::kApplication())->config();
    cfg->setGroup("settings");
    cfg->writeEntry(key, x, true, false, false);
    cfg->sync();
  }
}


void

ksokoban'LevelCollection::level() (./kdegames/ksokoban/LevelCollection.C:261)

LevelCollection::level(int _level) {
  assert(_level >= 0 && _level < noOfLevels_);

  level_ = _level;
  if (level_ > completedLevels_) level_ = completedLevels_;
  if (level_ >= noOfLevels_) level_ = noOfLevels_ - 1;
  if (level_ < 0) level_ = 0;
}

int

ksokoban'LevelCollection::loadLevel() (./kdegames/ksokoban/LevelCollection.C:303)

LevelCollection::loadLevel(Map *_map) {
  _map->clearMap();

  char *def = index_[level_];
  bool goodMap = true;
  int x=0, y=0, goalsLeft=0;

  int min_x = minX(def);
  if (min_x < 0) {
    min_x = 0;
    goodMap = false;
  }


  _map->xpos_ = -1;
  _map->ypos_ = -1;

  for (int pos=0; def[pos]; pos++) {
    switch(def[pos]) {
    case '\n':
      y++;
      x = 0;
      break;

    case ' ':
      x++;
      break;

    case '\t':
      x = (x+8) & ~7;
      break;

    case '@':
      if (x-min_x > MAX_X || y > MAX_Y) goodMap = false;
      else {
	_map->xpos_ = x-min_x;
	_map->ypos_ = y;
      }
      x++;
      break;

    case '$':
      if (x-min_x > MAX_X || y > MAX_Y) goodMap = false;
      else _map->map(x-min_x, y, OBJECT);
      x++;
      break;

    case '.':
      if (x-min_x > MAX_X || y > MAX_Y) goodMap = false;
      else {
	_map->map(x-min_x, y, GOAL);
	goalsLeft++;
      }
      x++;
      break;

    case '#':
      if (x-min_x > MAX_X || y > MAX_Y) goodMap = false;
      else _map->map(x-min_x, y, WALL);
      x++;
      break;

    case '+':
      if (x-min_x > MAX_X || y > MAX_Y) goodMap = false;
      else {
	_map->xpos_ = x-min_x;
	_map->ypos_ = y;
	_map->map(x-min_x, y, GOAL);
	goalsLeft++;
      }
      x++;
      break;

    case '*':
      if (x-min_x > MAX_X || y > MAX_Y) goodMap = false;
      else _map->map(x-min_x, y, OBJECT|GOAL);
      x++;
      break;

    case '\r':
      break;

    default:
      goodMap = false;
      break;
    }
  }

  if (_map->objectsLeft() != goalsLeft) goodMap = false;
  if (_map->completed()) goodMap = false;

  if (_map->badCoords(_map->xpos_, _map->ypos_)) goodMap = false;
  else {
    if (!_map->empty(_map->xpos_, _map->ypos_)) goodMap = false;
    else if (!_map->fillFloor(_map->xpos_, _map->ypos_)) goodMap = false;
  }

  return goodMap;
}