Blob Blame Raw

#include <math.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

#include <helianthus.h>

#include "chunk.h"


#define COUNT 100

double t;
double x, y;
double vx = 10, vy = 0;

int rootSeed;

Chunk chunks[COUNT];


void initChunks() {
  srand(time(NULL));
  rootSeed = rand();
  Chunk *c = &chunks[0];
  chunkGenerate(c, rootSeed, NULL, -COUNT/2);
  for(int i = 1; i < COUNT; ++i, ++c)
    chunkGenerate(c+1, rootSeed, c, 1);
}


void prepareChunks(double x) {
  Chunk *first = chunks, *last = first + COUNT - 1;
  int i0 = (int)floor(x/CHUNK_WIDTH) - COUNT/2;
  int offset = i0 - chunks[0].index;
  
  if (offset < 0) {
    Chunk *next = last, *prev = first;
    if (offset > -COUNT) {
      memmove(first - offset, first, sizeof(*chunks)*(COUNT + offset));
      prev = first - offset;
      next = prev - 1;
      offset = 1;
    }
    while(next >= first)
      { chunkGenerate(next, rootSeed, prev, offset); prev = next--; offset = -1; }
  } else
  if (offset > 0) {
    Chunk *next = first, *prev = last;
    if (offset < COUNT) {
      memmove(first, first + offset, sizeof(*chunks)*(COUNT - offset));
      prev = last - offset;
      next = prev + 1;
      offset = 1;
    } else {
      offset -= COUNT - 1;
    }
    while(next <= last)
      { chunkGenerate(next, rootSeed, prev, offset); prev = next++; offset = 1; }
  }
}


void drawChunks(double x, double range, double t) {
  range += 5*2;
  int i0 = (int)floor((x - 0.5*range)/CHUNK_WIDTH) - chunks->index;
  int i1 = (int)floor((x + 0.5*range)/CHUNK_WIDTH) - chunks->index + 1;
  if (i0 < 0) i0 = 0;
  if (i1 > COUNT) i1 = COUNT;
  
  for(int i = i0; i < i1; ++i) chunkDraw(&chunks[i], t, FLAG_GROUND);
  //for(int i = i0; i < i1; ++i) chunkDraw(&chunks[i], t, FLAG_LEAVES);
  for(int i = i0; i < i1; ++i) chunkDraw(&chunks[i], t, FLAG_BRANCHES);
}


double groundLevel(double x) {
  int i = (int)floor(x/CHUNK_WIDTH) - chunks->index;
  if (i < 0) return chunks->y;
  if (i > COUNT-1) return chunks[COUNT-1].y + chunks[COUNT-1].dy;
  return chunkGroundLevel(&chunks[i], x);
}


void init() {
  initChunks();
}


void draw() {
  double dt = worldGetFrameTime();
  t += dt;
  int w = worldGetWidth();
  int h = worldGetHeight();
  double range = w;
  
  double gy = groundLevel(x);
  vy = 0.5*(gy - y + 20);
  x += dt*vx;
  y += dt*vy;
  
  
  if (keyWentDown("space")) initChunks();
  if (keyWentDown("right")) x += 10;
  if (keyWentDown("left")) x -= 10;
  if (keyWentDown("up")) y += 10;
  if (keyWentDown("down")) y -= 10;
  
  saveState();
  translate(0.5*w, 0.5*h);
  zoom(10);
  scale(1, -1);
  translate(-x, -y);
  range /= 10;
  
  prepareChunks(x);
  drawChunks(x, range, t);
  
  restoreState();
}


int main() {
  worldSetVariableFrameRate();
  worldSetResizable(TRUE);
  worldSetInit(&init);
  worldSetDraw(&draw);
  worldRun();
  return 0;
}