Skip to content
Permalink
Browse files

Re-apply Catfact's patch

  • Loading branch information
burnsauce committed Oct 29, 2017
1 parent 6856799 commit 16b9f236a131bc15b0a5663b1f36a07c77e5443a
Showing with 76 additions and 74 deletions.
  1. +2 −2 module/live_mode.c
  2. +1 −1 module/main.c
  3. +62 −61 src/chaos.c
  4. +5 −4 src/chaos.h
  5. +6 −6 src/ops/op.c
@@ -230,8 +230,8 @@ uint8_t screen_refresh_live() {

if (show_vars && ((dirty & D_VARS) || (dirty & D_LIST))) {
int16_t* vp = &scene_state.variables.a;
// 8 int16_t all in a row, point at the first one
// relies on variable ordering. see: src/state.h
// 8 int16_t all in a row, point at the first one
// relies on variable ordering. see: src/state.h
bool changed = dirty & D_LIST;
char s[8];

@@ -30,6 +30,7 @@
#include "util.h"

// this
#include "chaos.h"
#include "conf_board.h"
#include "edit_mode.h"
#include "flash.h"
@@ -44,7 +45,6 @@
#include "teletype.h"
#include "teletype_io.h"
#include "usb_disk_mode.h"
#include "chaos.h"


////////////////////////////////////////////////////////////////////////////////
@@ -18,39 +18,39 @@ static const int chaos_cell_count = 8;
static const int chaos_cell_max = 0xff;

static chaos_state_t chaos_state = {
.ix = 5000, .ir = 5000, .alg = CHAOS_LOGISTIC
.ix = 5000, .ir = 5000, .alg = CHAOS_ALGO_LOGISTIC
};

void chaos_init() {
chaos_scale_values(&chaos_state);
}

// scale integer state and param values to float, as appropriate for given
// algorithm
// scale integer state and param values to float,
// as appropriate for current algorithm
static void chaos_scale_values(chaos_state_t* state) {
switch(state->alg) {
case CHAOS_HENON:
// for henon, x in [-1.5, 1.5], r in [1, 1.4]
state->fx = state->ix / (float)chaos_value_max * 1.5;
state->fr = 1.f + state->ir / (float)chaos_param_max * 0.4;
if(state->fr < 1.f) { state->fr = 1.f; }
if(state->fr > 1.4) { state->fr = 1.4f; }
break;
case CHAOS_CELLULAR:
// 1d binary CA takes binary state and rule
if(state->ix > chaos_cell_max) { state->ix = chaos_cell_max; }
if(state->ix < 0 ) { state->ix = 0; }
// rule is 8 bits
if(state->ir > 0xff) { state->ir = 0xff; }
if(state->ir < 0 ) { state->ir = 0; }
break;
case CHAOS_CUBIC:
case CHAOS_LOGISTIC: // fall through
default:
// for cubic / logistic, x in [-1, 1] and r in [3.2, 4)
state->fx = state->ix / (float)chaos_value_max;
state->fr = state->ir / (float)chaos_param_max * 0.9999 + 3.0;
break;
switch (state->alg) {
case CHAOS_ALGO_HENON:
// for henon, x in [-1.5, 1.5], r in [1, 1.4]
state->fx = state->ix / (float)chaos_value_max * 1.5;
state->fr = 1.f + state->ir / (float)chaos_param_max * 0.4;
if (state->fr < 1.f) { state->fr = 1.f; }
if (state->fr > 1.4) { state->fr = 1.4f; }
break;
case CHAOS_ALGO_CELLULAR:
// 1d binary CA takes binary state and rule
if (state->ix > chaos_cell_max) { state->ix = chaos_cell_max; }
if (state->ix < 0) { state->ix = 0; }
// rule is 8 bits
if (state->ir > 0xff) { state->ir = 0xff; }
if (state->ir < 0) { state->ir = 0; }
break;
case CHAOS_ALGO_CUBIC:
case CHAOS_ALGO_LOGISTIC: // fall through
default:
// for cubic / logistic, x in [-1, 1] and r in [3.2, 4)
state->fx = state->ix / (float)chaos_value_max;
state->fr = state->ir / (float)chaos_param_max * 0.9999 + 3.0;
break;
}
}

@@ -60,27 +60,26 @@ void chaos_set_val(int16_t val) {
}

static int16_t logistic_get_val() {
if(chaos_state.fx < 0.f) { chaos_state.fx = 0.f; }
chaos_state.fx =
chaos_state.fx * chaos_state.fr * (1.f - chaos_state.fx);
if (chaos_state.fx < 0.f) { chaos_state.fx = 0.f; }
chaos_state.fx = chaos_state.fx * chaos_state.fr * (1.f - chaos_state.fx);
chaos_state.ix = chaos_state.fx * (float)chaos_value_max;
return chaos_state.ix;
return chaos_state.ix;
}

static int16_t cubic_get_val() {
float x3 = chaos_state.fx * chaos_state.fx * chaos_state.fx;
chaos_state.fx =
chaos_state.fr * x3 + chaos_state.fx * (1.f - chaos_state.fr);
chaos_state.fr * x3 + chaos_state.fx * (1.f - chaos_state.fr);
chaos_state.ix = chaos_state.fx * (float)chaos_value_max;
return chaos_state.ix;
}

static int16_t henon_get_val() {
float x0_2 = chaos_state.fx0 * chaos_state.fx0;
float x = 1.f - (x0_2 * chaos_state.fr) + (chaos_henon_b * chaos_state.fx1);
// clamp to avoid blowup
if (x < -1.5) { x = -1.5; }
if (x > 1.5) { x = 1.5; }
// reflect bounds to avoid blowup
while (x < -1.5) { x = -1.5 - x; }
while (x > 1.5) { x = 1.5 - x; }
chaos_state.fx1 = chaos_state.fx0;
chaos_state.fx0 = chaos_state.fx;
chaos_state.fx = x;
@@ -93,27 +92,27 @@ static int16_t cellular_get_val() {
uint8_t y = 0;
uint8_t code = 0;
for (int i = 0; i < chaos_cell_count; ++i) {
// 3-bit code representing cell and neighbor state
code = 0;
// LSb in neighbor code = right-side neighor, wrapping
if (i == 0) {
if (x & 0x80) { code |= 0b001; }
}
else {
if (x & (1 << (i - 1))) { code |= 0b001; }
}
// MSb in neighbor code = left-side neighbor, wrapping
if (i == chaos_cell_count - 1) {
if (x & 1) { code |= 0b100; }
}
else {
if (x & (1 << (i + 1))) { code |= 0b100; }
}
// middle bit = old value of this cell
if (x & (1 << i)) { code |= 0b010; }
// lookup the bit in the rule specified by this code;
// this is the new bit value
if (chaos_state.ir & (1 << code)) { y |= (1 << i); }
// 3-bit code representing cell and neighbor state
code = 0;
// LSb in neighbor code = right-side neighor, wrapping
if (i == 0) {
if (x & 0x80) { code |= 0b001; }
}
else {
if (x & (1 << (i - 1))) { code |= 0b001; }
}
// MSb in neighbor code = left-side neighbor, wrapping
if (i == chaos_cell_count - 1) {
if (x & 1) { code |= 0b100; }
}
else {
if (x & (1 << (i + 1))) { code |= 0b100; }
}
// middle bit = old value of this cell
if (x & (1 << i)) { code |= 0b010; }
// lookup the bit in the rule specified by this code;
// this is the new bit value
if (chaos_state.ir & (1 << code)) { y |= (1 << i); }
}
chaos_state.ix = y;
return chaos_state.ix;
@@ -122,11 +121,11 @@ static int16_t cellular_get_val() {

int16_t chaos_get_val() {
switch (chaos_state.alg) {
case CHAOS_LOGISTIC: return logistic_get_val();
case CHAOS_CUBIC: return cubic_get_val();
case CHAOS_HENON: return henon_get_val();
case CHAOS_CELLULAR: return cellular_get_val();
default: return 0;
case CHAOS_ALGO_LOGISTIC: return logistic_get_val();
case CHAOS_ALGO_CUBIC: return cubic_get_val();
case CHAOS_ALGO_HENON: return henon_get_val();
case CHAOS_ALGO_CELLULAR: return cellular_get_val();
default: return 0;
}
}

@@ -140,8 +139,10 @@ int16_t chaos_get_r() {
}

void chaos_set_alg(int16_t a) {
if (a > CHAOS_CELLULAR || a < CHAOS_LOGISTIC) a = CHAOS_LOGISTIC;
if (a < 0) { a = 0; }
if (a >= CHAOS_ALGO_COUNT) { a = CHAOS_ALGO_COUNT - 1; }
chaos_state.alg = a;
chaos_scale_values(&chaos_state);
}

int16_t chaos_get_alg() {
@@ -3,10 +3,11 @@
#include <stdint.h>

typedef enum {
CHAOS_LOGISTIC, // logistic map
CHAOS_CUBIC, // cubic map
CHAOS_HENON, // henon map
CHAOS_CELLULAR // 1-d binary cellular automaton
CHAOS_ALGO_LOGISTIC, // logistic map
CHAOS_ALGO_CUBIC, // cubic map
CHAOS_ALGO_HENON, // henon map
CHAOS_ALGO_CELLULAR, // 1-d binary cellular automaton
CHAOS_ALGO_COUNT // unused, don't remve
} chaos_algo_t;

// keep value and parameter in both integer and float formats
@@ -65,12 +65,12 @@ const tele_op_t *tele_ops[E_OP__LENGTH] = {
&op_LT, &op_GT, &op_LTE, &op_GTE, &op_NZ, &op_EZ, &op_RSH, &op_LSH, &op_EXP,
&op_ABS, &op_AND, &op_OR, &op_JI, &op_SCALE, &op_N, &op_V, &op_VV, &op_ER,
&op_BPM, &op_BIT_OR, &op_BIT_AND, &op_BIT_NOT, &op_BIT_XOR, &op_BSET,
&op_BGET, &op_BCLR, &op_XOR, &op_CHAOS, &op_CHAOS_R, &op_CHAOS_ALG, &op_SYM_PLUS,
&op_SYM_DASH, &op_SYM_STAR, &op_SYM_FORWARD_SLASH, &op_SYM_PERCENTAGE,
&op_SYM_EQUAL_x2, &op_SYM_EXCLAMATION_EQUAL, &op_SYM_LEFT_ANGLED,
&op_SYM_RIGHT_ANGLED, &op_SYM_LEFT_ANGLED_EQUAL, &op_SYM_RIGHT_ANGLED_EQUAL,
&op_SYM_EXCLAMATION, &op_SYM_LEFT_ANGLED_x2, &op_SYM_RIGHT_ANGLED_x2,
&op_SYM_AMPERSAND_x2, &op_SYM_PIPE_x2,
&op_BGET, &op_BCLR, &op_XOR, &op_CHAOS, &op_CHAOS_R, &op_CHAOS_ALG,
&op_SYM_PLUS, &op_SYM_DASH, &op_SYM_STAR, &op_SYM_FORWARD_SLASH,
&op_SYM_PERCENTAGE, &op_SYM_EQUAL_x2, &op_SYM_EXCLAMATION_EQUAL,
&op_SYM_LEFT_ANGLED, &op_SYM_RIGHT_ANGLED, &op_SYM_LEFT_ANGLED_EQUAL,
&op_SYM_RIGHT_ANGLED_EQUAL, &op_SYM_EXCLAMATION, &op_SYM_LEFT_ANGLED_x2,
&op_SYM_RIGHT_ANGLED_x2, &op_SYM_AMPERSAND_x2, &op_SYM_PIPE_x2,

// stack
&op_S_ALL, &op_S_POP, &op_S_CLR, &op_S_L,

0 comments on commit 16b9f23

Please sign in to comment.