Blame onefile/gen-dungeon.c

a5e8d6
a5e8d6
#include <math.h></math.h>
a5e8d6
#include <stdlib.h></stdlib.h>
a5e8d6
#include <string.h></string.h>
a5e8d6
#include <helianthus.h></helianthus.h>
a5e8d6
a5e8d6
a5e8d6
#define TILESIZE     512
a5e8d6
#define ROWS           8
a5e8d6
#define COLS          12
a5e8d6
a5e8d6
a5e8d6
const double cellRatio = 1.0;
a5e8d6
const double genRatio  = 0.5;
a5e8d6
a5e8d6
Animation tiles[1024];
a5e8d6
a5e8d6
int tilesCount = 0;
a5e8d6
a5e8d6
Framebuffer framebuffer;
a5e8d6
Animation fbAnim;
a5e8d6
a5e8d6
a5e8d6
void groundLine(double len) {
a5e8d6
  double ky = 0.02;
a5e8d6
  double x = 0;
a5e8d6
  double y = 0;
a5e8d6
  moveTo(x, y);
a5e8d6
  while(x < len) {
a5e8d6
    double ny;
a5e8d6
    do { ny = (randomFloat()*2 - 1)*ky; } while(fabs(y + ny) > ky);
a5e8d6
    y += ny;
a5e8d6
    x += (1 + (randomFloat()*2 - 1)*0.5)*ky;
a5e8d6
    if (x >= len) { x = len; y = 0; }
a5e8d6
    lineTo(x, y);
a5e8d6
  }
a5e8d6
  strokePath();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
void generate() {
a5e8d6
  saveState();
a5e8d6
a5e8d6
  target(framebuffer);
a5e8d6
  background(COLOR_TRANSPARENT);
a5e8d6
  clear();
a5e8d6
  zoom(TILESIZE*cellRatio*genRatio);
a5e8d6
a5e8d6
  fill(colorByRGBA(1, 1, 1, 1));
a5e8d6
  noStroke();
a5e8d6
  double thikness  = 0.02/cellRatio*genRatio;
a5e8d6
  strokeWidth(thikness);
a5e8d6
a5e8d6
  saveState();
a5e8d6
  translate(0.5, 0.5);
a5e8d6
  if (tilesCount > 0)
a5e8d6
    for(int y = 0; y < ROWS; ++y)
a5e8d6
      for(int x = 0; x < COLS; ++x) {
a5e8d6
        saveState();
a5e8d6
        translate(x, y);
a5e8d6
        zoom(1/cellRatio);
a5e8d6
        rectTextured(tiles[rand()%tilesCount], -0.5, -0.5, 1, 1);
a5e8d6
        restoreState();
a5e8d6
      }
a5e8d6
  restoreState();
a5e8d6
a5e8d6
  saveState();
a5e8d6
  stroke(COLOR_BLACK);
a5e8d6
  double k = 1/3.0;
a5e8d6
  saveState();
a5e8d6
    translate(0.5 - k, 0.5);
a5e8d6
    for(int i = 0; i < ROWS; ++i) {
a5e8d6
      saveState();
a5e8d6
      translate(0, i - k);
a5e8d6
      groundLine(COLS + 2*k - 1);
a5e8d6
      restoreState();
a5e8d6
      saveState();
a5e8d6
      translate(0, i + k);
a5e8d6
      groundLine(COLS + 2*k - 1);
a5e8d6
      restoreState();
a5e8d6
    }
a5e8d6
  restoreState();
a5e8d6
  saveState();
a5e8d6
    rotate(90);
a5e8d6
    scale(1, -1);
a5e8d6
    translate(0.5 - k, 0.5);
a5e8d6
    for(int i = 0; i < COLS; ++i) {
a5e8d6
      saveState();
a5e8d6
      translate(0, i - k);
a5e8d6
      groundLine(ROWS + 2*k - 1);
a5e8d6
      restoreState();
a5e8d6
      saveState();
a5e8d6
      translate(0, i + k);
a5e8d6
      groundLine(ROWS + 2*k -  1);
a5e8d6
      restoreState();
a5e8d6
    }
a5e8d6
  restoreState();
a5e8d6
  restoreState();
a5e8d6
a5e8d6
  viewportSave("data/output/generated-dungeon.png");
a5e8d6
  restoreState();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
Animation subImage(int width, int height, unsigned char *pixels, int x, int y, int w, int h) {
a5e8d6
  if (x < 0 || y < 0 || x + w > width || y + h > height || !pixels)
a5e8d6
    return NULL;
a5e8d6
  unsigned char *px = calloc(4, w*h);
a5e8d6
  for(int i = 0; i < h; ++i)
a5e8d6
    memcpy(px + i*w*4, pixels + ((y+i)*width + x)*4, w*4);
a5e8d6
  Animation anim = createAnimationFromImage(w, h, px, FALSE);
a5e8d6
  free(px);
a5e8d6
  return anim;
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
void init() {
a5e8d6
  int w = 0;
a5e8d6
  int h = 0;
a5e8d6
  unsigned char *px = NULL;
a5e8d6
  imageLoad("data/dungeon.png", &w, &h, &px);
a5e8d6
  int s = TILESIZE + TILESIZE/2;
a5e8d6
  for(int y = 0; y < 2; ++y)
a5e8d6
    for(int x = 0; x < 6; ++x)
a5e8d6
      if ((tiles[tilesCount] = subImage(w, h, px, x*TILESIZE + TILESIZE/4, y*TILESIZE + TILESIZE/4, TILESIZE, TILESIZE)))
a5e8d6
        ++tilesCount;
a5e8d6
  free(px);
a5e8d6
a5e8d6
  w = ceil(TILESIZE*COLS*cellRatio*genRatio - 0.001);
a5e8d6
  h = ceil(TILESIZE*ROWS*cellRatio*genRatio - 0.001);
a5e8d6
  framebuffer = createFramebuffer(w, h);
a5e8d6
  fbAnim = createAnimationFromFramebuffer(framebuffer);
a5e8d6
a5e8d6
  generate();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
void draw() {
a5e8d6
  background(COLOR_WHITE);
a5e8d6
a5e8d6
  double w = windowGetWidth();
a5e8d6
  double h = windowGetHeight();
a5e8d6
a5e8d6
  if (keyWentDown("space")) generate();
a5e8d6
a5e8d6
  saveState();
a5e8d6
  translate(w/2, h/2);
a5e8d6
  zoom(w/COLS);
a5e8d6
  fill(COLOR_WHITE);
a5e8d6
  noStroke();
a5e8d6
  rectTextured(fbAnim, -COLS/2.0, -ROWS/2.0, COLS, ROWS);
a5e8d6
  restoreState();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
int main() {
a5e8d6
  windowSetVariableFrameRate();
a5e8d6
  windowSetResizable(TRUE);
a5e8d6
  windowSetInit(&init);
a5e8d6
  windowSetDraw(&draw);
a5e8d6
  windowRun();
a5e8d6
}
a5e8d6