about summary refs log tree commit diff stats
path: root/Archipelago/vendor
diff options
context:
space:
mode:
Diffstat (limited to 'Archipelago/vendor')
0 files changed, 0 insertions, 0 deletions
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#include "animation_system.h"
#include <fstream>
#include <string>
#include <list>
#include "game.h"
#include "vector.h"
#include "util.h"

void AnimationSystem::initSprite(int spriteId, std::string_view filename, Renderer& renderer) {
  std::ifstream datafile(filename.data());
  if (!datafile.is_open()) {
    throw std::invalid_argument(std::string("Could not find sprite datafile: ") + std::string(filename));
  }

  Sprite& sprite = game_.getSprite(spriteId);
  sprite.isAnimated = true;

  char ch;
  std::string line;

  std::string imagename;
  datafile >> imagename;
  sprite.textureId = renderer.loadImageFromFile(imagename);

  std::string framefilename;
  datafile >> framefilename;

  std::ifstream framefile(framefilename);
  if (!framefile.is_open()) {
    throw std::invalid_argument("Could not find frame datafile: " + framefilename);
  }

  vec2i cellSize;
  framefile >> cellSize.w();
  framefile >> ch; //,
  framefile >> cellSize.h();
  std::getline(framefile, line); // cell size

  int framesPerRow;
  framefile >> framesPerRow;
  std::getline(framefile, line); // frames per row

  int numFrames;
  framefile >> numFrames;
  std::getline(framefile, line); // frames
  std::getline(framefile, line); // blank

  for (int i=0; i<numFrames; i++) {
    SpriteFrame f;
    framefile >> f.size.w();
    framefile >> ch; //,
    framefile >> f.size.h();
    framefile >> ch; //,
    framefile >> f.center.x();
    framefile >> ch; //,
    framefile >> f.center.y();
    std::getline(framefile, line); // blank

    f.srcRect.x = (i % framesPerRow) * cellSize.w();
    f.srcRect.y = (i / framesPerRow) * cellSize.h();
    f.srcRect.w = f.size.w();
    f.srcRect.h = f.size.h();

    sprite.frames.push_back(std::move(f));
  }

  std::string animLine;
  std::getline(datafile, animLine); // blank
  while (std::getline(datafile, animLine)) {
    std::regex re(R"(([a-z]+)\[([a-z_]+)\]: ([0-9,]+))");
    std::smatch m;
    std::regex_match(animLine, m, re);

    std::vector<int> frames;
    auto framestrs = splitStr<std::list<std::string>>(m[3], ",");
    for (const std::string& f : framestrs) {
      frames.push_back(std::stoi(f));
    }

    int animId = sprite.animations.size();
    sprite.animations.push_back(std::move(frames));

    Direction dir = directionFromString(std::string(m[2]));
    sprite.nameDirToAnim[m[1]][dir] = animId;
  }

  updateAnimation(spriteId);
}

void AnimationSystem::tick(double dt) {
  animTimer_.accumulate(dt);
  while (animTimer_.step()) {
    for (Sprite& sprite : game_.getSprites() | game_.spriteView()) {
      if (sprite.isAnimated) {
        sprite.animationFrame++;
        if (sprite.animationFrame >= sprite.animations[sprite.animationId].size()) {
          sprite.animationFrame = 0;
        }
      }
    }
  }
}

void AnimationSystem::setSpriteDirection(int spriteId, Direction dir) {
  Sprite& sprite = game_.getSprite(spriteId);
  if (sprite.dir != dir) {
    sprite.dir = dir;
    updateAnimation(spriteId);
  }
}

void AnimationSystem::setSpriteAnimation(int spriteId, std::string_view name) {
  Sprite& sprite = game_.getSprite(spriteId);
  if (sprite.animationName != name) {
    sprite.animationName = name;
    updateAnimation(spriteId);
  }
}

void AnimationSystem::updateAnimation(int spriteId) {
  Sprite& sprite = game_.getSprite(spriteId);
  sprite.animationId = sprite.nameDirToAnim[sprite.animationName][sprite.dir];
  sprite.animationFrame = 0;
}