~l3kn/quad

62aa9128e61adb239c9df99e5177c116c16049d2 — Leon Rische 4 months ago d8d7b08
Add hotkeys for selecting current rule
2 files changed, 75 insertions(+), 28 deletions(-)

M README.md
M quad.c
M README.md => README.md +14 -10
@@ 17,13 17,13 @@ Run with `make run`.
## Interface

1. There are 8 rules
2. Rules are referenced by a small squares indicating their position in
2. Rule 1 (top left) is expended to the image on the right
3. Rules are referenced by a small squares indicating their position in
   the editor interface
3. Each rule has one slot for each quadrant of the image
4. Each rule has a fallback slot that's used when a square gets too
4. Each rule has one slot for each quadrant of the image
5. Each rule has a fallback slot that's used when a square gets too
   small to be subdivided further
5. Slots can contain patterns or references to rules
6. The fallback slot can only contain a pattern
6. Slots can contain patterns or references to rules, the fallback slot can only contain a pattern
7. To place a pattern in a slot, click it in the pallette at the top,
   then click on the slot
8. To place a reference to a rule in a slot, click on the small square next to it (the


@@ 31,10 31,14 @@ Run with `make run`.

## Controls

- `1` decrease resolution
- `2` increase resolution
- `i` invert colors
- `1`...`8` select rule to use for image
- `c` clear rules

- `d` decrease resolution
- `i` increase resolution

- `o` toggle outlines
- `q` quit
- `v` invert colors

- `r` save as bitmap (`quad-render.bpm`)
- `c` clear rules
- `q` quit

M quad.c => quad.c +61 -18
@@ 1,5 1,7 @@
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <SDL2/SDL.h>


@@ 7,6 9,7 @@
#include "patterns.h"

int width, height, size, menu_size, menu_width;
int currentRule = 0;

#define PADDING 20
#define SCALE 2


@@ 37,8 40,8 @@ Node selection;
Rule rules[8];
int colors[2] = { COLOR_BLACK, COLOR_WHITE };

int outline = 1;
int quit = 0;
bool outline = true;
bool quit = false;
int limit = 1;

void drawSquare(int x, int y, int s, unsigned long long pattern, int outline) {


@@ 52,10 55,9 @@ void drawSquare(int x, int y, int s, unsigned long long pattern, int outline) {
    SDL_RenderDrawRect(renderer, &rect);
  }

  int px, py;
  unsigned long long index;
  for (px = x; px < x + s; px++) {
    for (py = y; py < y + s; py++) {
  for (int px = x; px < x + s; ++px) {
    for (int py = y; py < y + s; ++py) {
      index = (((px - CANVAS_X) / SCALE) % 8) * 8 + (((py - CANVAS_Y) / SCALE) % 8);
      if ((pattern & (1UL << index)) > 0) {
        SDL_RenderDrawPoint(renderer, px, py);


@@ 99,7 101,7 @@ void saveBMP() {
void drawNumber(int x, int y, int n) {
  int h = menu_size / 2;
  int o = menu_size / 8;
  int pattern = (n >= 4) ? WHITE : BLACK;
  Pattern pattern = (n >= 4) ? WHITE : BLACK;

  if (n & 2) {
    y += h;


@@ 138,16 140,15 @@ void drawRule(int x, int y, int n) {
}

void drawMenu() {
  int i, j, x, y;
  for (i = 0; i < 10; i++) {
    x = i * menu_size + PADDING;
    for (j = 0; j < 4; j ++) {
      y = j * menu_size + PADDING;
  for (int i = 0; i < 10; ++i) {
    int x = i * menu_size + PADDING;
    for (int j = 0; j < 4; j ++) {
      int y = j * menu_size + PADDING;
      drawSquare(x, y, menu_size, patterns[i + 10 * j], 1);
    }
  }

  for (i = 0; i < 8; i++) {
  for (int i = 0; i < 8; ++i) {
    drawRule(PADDING + (i % 2) * 6 * menu_size,
             (5 + 3 * (i / 2)) * menu_size + PADDING, i);
  }


@@ 167,14 168,14 @@ void draw() {

  drawMenu();
  drawSquare(CANVAS_X, CANVAS_Y, size, BLACK, 1);
  expandRule(0, 0, size, &rules[0]);
  expandRule(0, 0, size, &rules[currentRule]);

  SDL_RenderPresent(renderer);
}

void reset() {
  struct node pat0 = { PATTERN, 0 };
  for (int i = 0; i < 8; i++) {
  for (int i = 0; i < 8; ++i) {
    rules[i].quads[0] = pat0;
    rules[i].quads[1] = pat0;
    rules[i].quads[2] = pat0;


@@ 199,27 200,67 @@ void handleKey(SDL_Event* event) {
    reset();
    draw();
    break;
  case SDLK_i: {
  case SDLK_v: {
    int tmp = colors[0];
    colors[0] = colors[1];
    colors[1] = tmp;
    draw();
    break;
  }
  case SDLK_1: {
  case SDLK_d: {
    if (limit < size / 2) {
      limit <<= 1;
      draw();
    }
    break;
  }
  case SDLK_2: {
  case SDLK_i: {
    if (limit > 1) {
      limit >>= 1;
      draw();
    }
    break;
  }
  case SDLK_1: {
    currentRule = 0;
    draw();
    break;
  }
  case SDLK_2: {
    currentRule = 1;
    draw();
    break;
  }
  case SDLK_3: {
    currentRule = 2;
    draw();
    break;
  }
  case SDLK_4: {
    currentRule = 3;
    draw();
    break;
  }
  case SDLK_5: {
    currentRule = 4;
    draw();
    break;
  }
  case SDLK_6: {
    currentRule = 5;
    draw();
    break;
  }
  case SDLK_7: {
    currentRule = 6;
    draw();
    break;
  }
  case SDLK_8: {
    currentRule = 7;
    draw();
    break;
  }
  }
}



@@ 297,7 338,7 @@ int main(int argc, char* argv[]) {
    while (SDL_PollEvent(&event)) {
      switch (event.type) {
      case SDL_QUIT:
        quit = 1;
        quit = true;
        break;
      case SDL_KEYDOWN:
        handleKey(&event);


@@ 319,4 360,6 @@ int main(int argc, char* argv[]) {
  SDL_DestroyRenderer(renderer);
  SDL_DestroyWindow(window);
  SDL_Quit();

  return EXIT_SUCCESS;
}