LCOV - code coverage report
Current view: top level - src - rendersystem.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 96 97 99.0 %
Date: 2020-10-15 20:26:03 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #include "rendersystem.h"
       2             : 
       3             : #include "game.h"
       4             : 
       5           5 : RenderSystem::RenderSystem(Game& game) : game_(game), randomArray2D_(64, 64, 0) {
       6       20485 :     for (int& v : randomArray2D_.data()) {
       7       20480 :         v = randInt(0, INT32_MAX);
       8             :     }
       9           5 : }
      10             : 
      11           5 : void RenderSystem::update() {
      12           5 :     const int slowBy = 2;
      13             :     static int slowDown = 0;
      14           5 :     bool updateAnimation = slowDown++ >= slowBy;
      15           5 :     if (updateAnimation)
      16           1 :         slowDown = 0;
      17             : 
      18           5 :     tick_++;
      19             : 
      20         502 :     for (auto& sprite : game_.sprites.values()) {
      21         497 :         if (updateAnimation) {
      22         103 :             if (sprite.animated) {
      23          83 :                 sprite.frameCounter++;
      24          83 :                 if (sprite.frameCounter >= sprite.frameRate && !sprite.frames.empty()) {
      25          44 :                     sprite.frame = (sprite.frame + 1) % sprite.frames.size();
      26          44 :                     sprite.frameCounter = 0;
      27             :                 }
      28             :             }
      29             : 
      30         103 :             if (sprite.flashTimer > 0) {
      31           0 :                 sprite.flashTimer--;
      32             :             }
      33             :         }
      34             :     }
      35           5 : }
      36             : 
      37           5 : void RenderSystem::render() {
      38           5 :     game_.window.clear();
      39             : 
      40           5 :     const recti& b = game_.worldBounds;
      41             : 
      42          30 :     auto renderLayer = [&](RenderLayer layer) {
      43        4499 :         for (const auto& sprite : game_.sprites.values()) {
      44        2982 :             if (sprite.renderLayer == layer) {
      45         497 :                 vec2i p = sprite.position;
      46         497 :                 if (game_.onScreen(p) && b.contains(p)) {
      47         495 :                     vec2i sc = game_.screenCoord(p);
      48         495 :                     bool flash = sprite.flashTimer > 0;
      49        1485 :                     game_.window.set(sc.x, sc.y, sprite.frames[sprite.frame],
      50         990 :                                      flash ? TB_WHITE : sprite.fg, sprite.bg);
      51             :                 }
      52             :             }
      53             :         }
      54          35 :     };
      55             : 
      56           5 :     renderGround();
      57             : 
      58             :     // Ground sprites
      59          15 :     for (auto layer : {RenderLayer::Ground, RenderLayer::GroundCover}) {
      60          10 :         renderLayer(layer);
      61             :     }
      62             : 
      63           5 :     renderOcean();
      64             : 
      65             :     // Remaining sprites
      66          40 :     for (auto layer :
      67           5 :          {RenderLayer::Particles, RenderLayer::MobBelow, RenderLayer::Mob, RenderLayer::MobAbove}) {
      68          20 :         renderLayer(layer);
      69             :     }
      70           5 : }
      71             : 
      72           5 : void RenderSystem::renderGround() {
      73           5 :     const vec2i ws{game_.window.width(), game_.window.height()};
      74           5 :     const recti& b = game_.worldBounds;
      75             : 
      76         645 :     for (int y = 0; y < ws.y; y++) {
      77      164480 :         for (int x = 0; x < ws.x; x++) {
      78      163840 :             vec2i p = game_.worldCoord({x, y});
      79      163840 :             if (game_.onScreen(p) && b.contains(p)) {
      80       30720 :                 game_.window.set(x, y, game_.groundTile(p), TB_WHITE, TB_BLACK);
      81             :             }
      82             :         }
      83             :     }
      84           5 : }
      85             : 
      86           5 : void RenderSystem::renderOcean() {
      87           5 :     const vec2i ws{game_.window.width(), game_.window.height()};
      88           5 :     const recti& b = game_.worldBounds;
      89             : 
      90             :     // Maps a coordinate to a random int
      91      135840 :     auto hash = [&](vec2i p) -> size_t {
      92      271680 :         auto mod = [](int x, int m) {
      93      271680 :             if (x >= 0)
      94      136590 :                 return x % m;
      95             :             else
      96      135090 :                 return m - 1 - (-x % m);
      97             :         };
      98      407520 :         int px = mod(p.x + tick_ / 32, randomArray2D_.width());
      99      271680 :         int py = mod(p.y - tick_ / 256, randomArray2D_.height());
     100      135840 :         return randomArray2D_(px, py);
     101           5 :     };
     102             : 
     103             :     // Main mass
     104         645 :     for (int y = 0; y < ws.y; y++) {
     105      164480 :         for (int x = 0; x < ws.x; x++) {
     106      163840 :             vec2i p = game_.worldCoord({x, y});
     107      163840 :             if (game_.onScreen(p) && !b.contains(p)) {
     108      133120 :                 char c = hash(p) % 16 == 0 ? '~' : ' ';
     109      133120 :                 game_.window.set(x, y, c, TB_WHITE, TB_BLUE);
     110             :             }
     111             :         }
     112             :     }
     113             : 
     114             :     // Edges
     115          15 :     for (bool fg : {false, true}) {
     116          10 :         int tick = fg ? tick_ + 50 : tick_;
     117             : 
     118          30 :         for (int yEdge : {-1, 1}) {
     119          20 :             int y = (yEdge == -1) ? (b.top - b.height + 1) : b.top;
     120        2580 :             for (int x = b.left; x < b.left + b.width; x++) {
     121        2560 :                 double mag = cos(tick * 0.03);
     122        2560 :                 int depth = 1 + (int)(2 + 2 * mag * sin(tick * 0.01 + x * 0.1));
     123        8980 :                 for (int dy = 0; dy < depth; dy++) {
     124        6420 :                     vec2i p{x, y - dy * yEdge};
     125        6420 :                     vec2i sc = game_.screenCoord(p);
     126        6420 :                     if (game_.onScreen(p)) {
     127        6420 :                         if (fg) {
     128        3220 :                             char c = (dy == depth - 1) ? '~' : hash(p) % 4 == 0 ? '~' : ' ';
     129        3220 :                             game_.window.set(sc.x, sc.y, c, TB_WHITE, TB_BLUE);
     130             :                         } else {
     131        3200 :                             game_.window.set(sc.x, sc.y, '~', TB_BLUE, TB_BLACK);
     132             :                         }
     133             :                     }
     134             :                 }
     135             :             }
     136             :         }
     137             : 
     138          30 :         for (int xEdge : {-1, 1}) {
     139          20 :             int x = (xEdge == -1) ? b.left : (b.left + b.width - 1);
     140         980 :             for (int y = b.top - b.height + 1; y <= b.top; y++) {
     141         960 :                 double mag = cos(tick * 0.03);
     142         960 :                 int depth = 1 + (int)(2 + 2 * mag * sin(tick * 0.01 + y * 0.1));
     143        3440 :                 for (int dx = 0; dx < depth; dx++) {
     144        2480 :                     vec2i p{x - dx * xEdge, y};
     145        2480 :                     vec2i sc = game_.screenCoord(p);
     146        2480 :                     if (game_.onScreen(p)) {
     147        2480 :                         if (fg) {
     148        1260 :                             char c = (dx == depth - 1) ? '~' : hash(p) % 4 == 0 ? '~' : ' ';
     149        1260 :                             game_.window.set(sc.x, sc.y, c, TB_WHITE, TB_BLUE);
     150             :                         } else {
     151        1220 :                             game_.window.set(sc.x, sc.y, '~', TB_BLUE, TB_BLACK);
     152             :                         }
     153             :                     }
     154             :                 }
     155             :             }
     156             :         }
     157             :     }
     158           5 : }

Generated by: LCOV version 1.13