diff --git a/module/config.mk b/module/config.mk index 78479677..9d8fe09a 100644 --- a/module/config.mk +++ b/module/config.mk @@ -108,6 +108,7 @@ CSRCS = \ ../src/ops/wslash.c \ ../src/ops/turtle.c \ ../src/ops/seed.c \ + ../src/tele_rand.c \ ../libavr32/src/adc.c \ ../libavr32/src/events.c \ ../libavr32/src/euclidean/euclidean.c \ @@ -125,7 +126,6 @@ CSRCS = \ ../libavr32/src/timers.c \ ../libavr32/src/usb.c \ ../libavr32/src/util.c \ - ../libavr32/src/random.c \ ../libavr32/src/usb/ftdi/ftdi.c \ ../libavr32/src/usb/ftdi/uhi_ftdi.c \ ../libavr32/src/usb/hid/hid.c \ diff --git a/simulator/Makefile b/simulator/Makefile index 2fc4fa63..34537aed 100644 --- a/simulator/Makefile +++ b/simulator/Makefile @@ -12,9 +12,9 @@ OBJ = tt.o ../src/teletype.o ../src/command.o ../src/helpers.o \ ../src/ops/telex.o ../src/ops/variables.o ../src/ops/whitewhale.o \ ../src/ops/init.o ../src/ops/grid_ops.o ../src/ops/er301.o \ ../src/ops/fader.o ../src/ops/matrixarchate.o ../src/ops/wslash.o \ - ../src/ops/seed.o \ + ../src/ops/seed.o ../src/tele_rand.o \ ../libavr32/src/euclidean/euclidean.o ../libavr32/src/euclidean/data.o \ - ../libavr32/src/util.o ../libavr32/src/random.o + ../libavr32/src/util.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/src/match_token.rl b/src/match_token.rl index badb4147..5ffb7207 100644 --- a/src/match_token.rl +++ b/src/match_token.rl @@ -576,17 +576,17 @@ # seed "SEED" => { MATCH_OP(E_OP_SEED); }; - "RAND.SEED" => { MATCH_OP(E_OP_RAND_SEED); }; - "RAND.SD" => { MATCH_OP(E_OP_SYM_RAND_SD); }; - "R.SD" => { MATCH_OP(E_OP_SYM_R_SD); }; + "RAND.SEED" => { MATCH_OP(E_OP_RAND_SEED); }; + "RAND.SD" => { MATCH_OP(E_OP_SYM_RAND_SD); }; + "R.SD" => { MATCH_OP(E_OP_SYM_R_SD); }; "TOSS.SEED" => { MATCH_OP(E_OP_TOSS_SEED); }; - "TOSS.SD" => { MATCH_OP(E_OP_SYM_TOSS_SD); }; + "TOSS.SD" => { MATCH_OP(E_OP_SYM_TOSS_SD); }; "PROB.SEED" => { MATCH_OP(E_OP_PROB_SEED); }; - "PROB.SD" => { MATCH_OP(E_OP_SYM_PROB_SD); }; + "PROB.SD" => { MATCH_OP(E_OP_SYM_PROB_SD); }; "DRUNK.SEED" => { MATCH_OP(E_OP_DRUNK_SEED); }; - "DRUNK.SD" => { MATCH_OP(E_OP_SYM_DRUNK_SD); }; + "DRUNK.SD" => { MATCH_OP(E_OP_SYM_DRUNK_SD); }; "P.SEED" => { MATCH_OP(E_OP_P_SEED); }; - "P.SD" => { MATCH_OP(E_OP_SYM_P_SD); }; + "P.SD" => { MATCH_OP(E_OP_SYM_P_SD); }; # MODS # controlflow diff --git a/src/ops/controlflow.c b/src/ops/controlflow.c index 67b11ac8..9f4f5a4d 100644 --- a/src/ops/controlflow.c +++ b/src/ops/controlflow.c @@ -1,8 +1,7 @@ #include "ops/controlflow.h" -#include "random.h" - #include "helpers.h" +#include "tele_rand.h" #include "teletype.h" #include "teletype_io.h" @@ -72,9 +71,9 @@ static void mod_PROB_func(scene_state_t *ss, exec_state_t *es, command_state_t *cs, const tele_command_t *post_command) { int16_t a = cs_pop(cs); - random_state_t *r = &ss->rand_states.s.prob.rand; + tele_rand_t *r = &ss->rand_states.s.prob; - if (random_next(r) % 101 < a) { process_command(ss, es, post_command); } + if (tele_rand_next(r) % 101 < a) { process_command(ss, es, post_command); } } static void mod_IF_func(scene_state_t *ss, exec_state_t *es, diff --git a/src/ops/maths.c b/src/ops/maths.c index 5a22e0eb..63636764 100644 --- a/src/ops/maths.c +++ b/src/ops/maths.c @@ -1,7 +1,7 @@ #include "ops/maths.h" #include // abs -#include "random.h" +#include "tele_rand.h" #include "chaos.h" #include "euclidean/euclidean.h" @@ -231,19 +231,19 @@ static void op_MOD_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), static void op_RAND_get(const void *NOTUSED(data), scene_state_t *ss, exec_state_t *NOTUSED(es), command_state_t *cs) { int16_t a = cs_pop(cs); - random_state_t *r = &ss->rand_states.s.rand.rand; + tele_rand_t *r = &ss->rand_states.s.rand; if (a < 0) - cs_push(cs, -(random_next(r) % (1 - a))); + cs_push(cs, -(tele_rand_next(r) % (1 - a))); else if (a == 32767) - cs_push(cs, random_next(r)); + cs_push(cs, tele_rand_next(r)); else - cs_push(cs, random_next(r) % (a + 1)); + cs_push(cs, tele_rand_next(r) % (a + 1)); } static int16_t push_random(int16_t a, int16_t b, scene_state_t *ss) { int16_t min, max; - random_state_t *r = &ss->rand_states.s.rand.rand; + tele_rand_t *r = &ss->rand_states.s.rand; if (a < b) { min = a; @@ -256,7 +256,7 @@ static int16_t push_random(int16_t a, int16_t b, scene_state_t *ss) { int32_t range = max - min + 1; if (range == 0 || min == max) return min; - int32_t rrand = (int32_t)random_next(r); + int32_t rrand = (int32_t)tele_rand_next(r); rrand = rrand % range + min; return rrand; } @@ -297,8 +297,8 @@ static void op_R_MAX_set(const void *NOTUSED(data), scene_state_t *ss, static void op_TOSS_get(const void *NOTUSED(data), scene_state_t *ss, exec_state_t *NOTUSED(es), command_state_t *cs) { - random_state_t *r = &ss->rand_states.s.toss.rand; - cs_push(cs, (random_next(r) >> 3) & 1); + tele_rand_t *r = &ss->rand_states.s.toss; + cs_push(cs, (tele_rand_next(r) >> 3) & 1); } static void op_MIN_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), diff --git a/src/ops/op.c b/src/ops/op.c index 636b7122..667f6d3e 100644 --- a/src/ops/op.c +++ b/src/ops/op.c @@ -1,7 +1,6 @@ #include "ops/op.h" #include // offsetof -#include "random.h" #include "helpers.h" #include "teletype_io.h" diff --git a/src/ops/patterns.c b/src/ops/patterns.c index c9718aa4..51034759 100644 --- a/src/ops/patterns.c +++ b/src/ops/patterns.c @@ -1,8 +1,7 @@ #include "ops/patterns.h" -#include "random.h" - #include "helpers.h" +#include "tele_rand.h" #include "teletype.h" #include "teletype_io.h" @@ -765,12 +764,12 @@ static int16_t p_rnd_get(scene_state_t *ss, int16_t pn) { pn = normalise_pn(pn); int16_t start = ss_get_pattern_start(ss, pn); int16_t end = ss_get_pattern_end(ss, pn); - random_state_t *r = &ss->rand_states.s.pattern.rand; + tele_rand_t *r = &ss->rand_states.s.pattern; if (end < start) return 0; return ss_get_pattern_val(ss, pn, - random_next(r) % (end - start + 1) + start); + tele_rand_next(r) % (end - start + 1) + start); } static void op_P_RND_get(const void *NOTUSED(data), scene_state_t *ss, diff --git a/src/ops/seed.c b/src/ops/seed.c index 6b259ba7..766ec4f5 100644 --- a/src/ops/seed.c +++ b/src/ops/seed.c @@ -1,5 +1,6 @@ #include "ops/seed.h" #include "helpers.h" +#include "tele_rand.h" #define MAKE_SEED_OP(n, v) \ { \ @@ -7,6 +8,8 @@ .params = 0, .returns = 1, .data = (void *)offsetof(scene_state_t, v) \ } +#define MAKE_SEED_ALIAS_OP(n, v) MAKE_SEED_OP(n, v) + static void op_peek_seed_i16(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); static void op_poke_seed_i16(const void *data, scene_state_t *ss, @@ -17,25 +20,25 @@ static void op_SEED_set(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); // clang-format off -const tele_op_t op_SEED = MAKE_GET_SET_OP(SEED, op_SEED_get, op_SEED_set, 0, true); -const tele_op_t op_RAND_SEED = MAKE_SEED_OP(RAND.SEED, rand_states.s.rand); -const tele_op_t op_SYM_RAND_SD = MAKE_SEED_OP(RAND.SD, rand_states.s.rand); -const tele_op_t op_SYM_R_SD = MAKE_SEED_OP(R.SD, rand_states.s.rand); -const tele_op_t op_TOSS_SEED = MAKE_SEED_OP(TOSS.SEED, rand_states.s.toss); -const tele_op_t op_SYM_TOSS_SD = MAKE_SEED_OP(TOSS.SD, rand_states.s.toss); -const tele_op_t op_PROB_SEED = MAKE_SEED_OP(PROB.SEED, rand_states.s.prob); -const tele_op_t op_SYM_PROB_SD = MAKE_SEED_OP(PROB.SD, rand_states.s.prob); -const tele_op_t op_DRUNK_SEED = MAKE_SEED_OP(DRUNK.SEED, rand_states.s.drunk); -const tele_op_t op_SYM_DRUNK_SD = MAKE_SEED_OP(DRUNK.SD, rand_states.s.drunk); -const tele_op_t op_P_SEED = MAKE_SEED_OP(P.SEED, rand_states.s.pattern); -const tele_op_t op_SYM_P_SD = MAKE_SEED_OP(P.SD, rand_states.s.pattern); +const tele_op_t op_SEED = MAKE_GET_SET_OP(SEED, op_SEED_get, op_SEED_set, 0, true); +const tele_op_t op_RAND_SEED = MAKE_SEED_OP(RAND.SEED, rand_states.s.rand); +const tele_op_t op_SYM_RAND_SD = MAKE_SEED_ALIAS_OP(RAND.SD, rand_states.s.rand); +const tele_op_t op_SYM_R_SD = MAKE_SEED_ALIAS_OP(R.SD, rand_states.s.rand); +const tele_op_t op_TOSS_SEED = MAKE_SEED_OP(TOSS.SEED, rand_states.s.toss); +const tele_op_t op_SYM_TOSS_SD = MAKE_SEED_ALIAS_OP(TOSS.SD, rand_states.s.toss); +const tele_op_t op_PROB_SEED = MAKE_SEED_OP(PROB.SEED, rand_states.s.prob); +const tele_op_t op_SYM_PROB_SD = MAKE_SEED_ALIAS_OP(PROB.SD, rand_states.s.prob); +const tele_op_t op_DRUNK_SEED = MAKE_SEED_OP(DRUNK.SEED, rand_states.s.drunk); +const tele_op_t op_SYM_DRUNK_SD = MAKE_SEED_ALIAS_OP(DRUNK.SD, rand_states.s.drunk); +const tele_op_t op_P_SEED = MAKE_SEED_OP(P.SEED, rand_states.s.pattern); +const tele_op_t op_SYM_P_SD = MAKE_SEED_ALIAS_OP(P.SD, rand_states.s.pattern); // clang-format on static void op_peek_seed_i16(const void *data, scene_state_t *ss, exec_state_t *NOTUSED(es), command_state_t *cs) { char *base = (char *)ss; size_t offset = (size_t)data; - rand_set_t *ptr = (rand_set_t *)(base + offset); + tele_rand_t *ptr = (tele_rand_t *)(base + offset); cs_push(cs, ptr->seed); } @@ -45,10 +48,9 @@ static void op_poke_seed_i16(const void *data, scene_state_t *ss, char *base = (char *)ss; size_t offset = (size_t)data; - rand_set_t *ptr = (rand_set_t *)(base + offset); - ptr->seed = s; + tele_rand_t *ptr = (tele_rand_t *)(base + offset); - random_seed(&ptr->rand, s); + tele_rand_init(ptr, s); } static void op_SEED_get(const void *NOTUSED(data), scene_state_t *ss, @@ -61,9 +63,8 @@ static void op_SEED_set(const void *NOTUSED(data), scene_state_t *ss, uint16_t s = cs_pop(cs); for (u8 i = 0; i < RAND_STATES_COUNT; i++) { - rand_set_t *r = &ss->rand_states.a[i]; - r->seed = s; - random_seed(&r->rand, r->seed); + tele_rand_t *r = &ss->rand_states.a[i]; + tele_rand_init(r, s); } ss->variables.seed = s; diff --git a/src/ops/variables.c b/src/ops/variables.c index 1c77bf40..bc155cc1 100644 --- a/src/ops/variables.c +++ b/src/ops/variables.c @@ -1,9 +1,8 @@ #include "ops/variables.h" -#include "random.h" - #include "helpers.h" #include "ops/op.h" +#include "tele_rand.h" #include "teletype.h" #include "teletype_io.h" @@ -111,7 +110,7 @@ static void op_DRUNK_get(const void *NOTUSED(data), scene_state_t *ss, int16_t min = ss->variables.drunk_min; int16_t max = ss->variables.drunk_max; int16_t wrap = ss->variables.drunk_wrap; - random_state_t *r = &ss->rand_states.s.drunk.rand; + tele_rand_t *r = &ss->rand_states.s.drunk; // restrict current_value to (wrapped) bounds int16_t current_value = @@ -119,7 +118,7 @@ static void op_DRUNK_get(const void *NOTUSED(data), scene_state_t *ss, cs_push(cs, current_value); // calculate new value - int16_t new_value = current_value + (random_next(r) % 3) - 1; + int16_t new_value = current_value + (tele_rand_next(r) % 3) - 1; ss->variables.drunk = normalise_value(min, max, wrap, new_value); } diff --git a/src/state.c b/src/state.c index affd3444..f6763dec 100644 --- a/src/state.c +++ b/src/state.c @@ -130,9 +130,8 @@ void ss_grid_common_init(grid_common_t *gc) { void ss_rand_init(scene_state_t *ss) { for (u8 i = 0; i < RAND_STATES_COUNT; i++) { - rand_set_t *r = &ss->rand_states.a[i]; - r->seed = rand(); - random_init(&r->rand, r->seed, 0, 32767); + tele_rand_t *r = &ss->rand_states.a[i]; + tele_rand_init(r, rand()); } } diff --git a/src/state.h b/src/state.h index e7047ec3..71e7349f 100644 --- a/src/state.h +++ b/src/state.h @@ -7,8 +7,8 @@ #include "command.h" #include "every.h" -#include "random.h" #include "scale.h" +#include "tele_rand.h" #include "turtle.h" #include "types.h" @@ -197,21 +197,17 @@ typedef struct { grid_xypad_t xypad[GRID_XYPAD_COUNT]; } scene_grid_t; -typedef struct { - random_state_t rand; - int16_t seed; -} rand_set_t; typedef union { struct { - rand_set_t rand; - rand_set_t prob; - rand_set_t toss; - rand_set_t pattern; - rand_set_t drunk; + tele_rand_t rand; + tele_rand_t prob; + tele_rand_t toss; + tele_rand_t pattern; + tele_rand_t drunk; } s; - rand_set_t a[RAND_STATES_COUNT]; + tele_rand_t a[RAND_STATES_COUNT]; } scene_rand_t; typedef struct { diff --git a/src/tele_rand.c b/src/tele_rand.c new file mode 100644 index 00000000..ddbcec6b --- /dev/null +++ b/src/tele_rand.c @@ -0,0 +1,13 @@ +#include "tele_rand.h" + +void tele_rand_init(tele_rand_t *r, u32 seed) { + r->z = 1823672; + r->w = seed; + r->seed = seed; +} + +s16 tele_rand_next(tele_rand_t *r) { + r->z = 36969 * (r->z & 65535) + (r->z >> 16); + r->w = 18000 * (r->w & 65535) + (r->w >> 16); + return (r->z << 16) + r->w; +} diff --git a/src/tele_rand.h b/src/tele_rand.h new file mode 100644 index 00000000..9c508f76 --- /dev/null +++ b/src/tele_rand.h @@ -0,0 +1,16 @@ +#ifndef _TELE_RAND_H_ +#define _TELE_RAND_H_ + +#include "types.h" + +typedef struct { + u32 z; + u32 w; + s16 seed; +} tele_rand_t; + +extern void tele_rand_init(tele_rand_t *r, u32 seed); + +extern s16 tele_rand_next(tele_rand_t *r); + +#endif /* _TELE_RAND_H_ */ diff --git a/tests/Makefile b/tests/Makefile index 8f4bbd88..45411f46 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -20,7 +20,7 @@ tests: main.o \ ../src/ops/turtle.o ../src/ops/init.o ../src/ops/grid_ops.o \ ../src/ops/matrixarchate.o ../src/ops/wslash.o ../src/ops/seed.o \ ../libavr32/src/euclidean/data.o ../libavr32/src/euclidean/euclidean.o \ - ../libavr32/src/util.o ../libavr32/src/random.o + ../libavr32/src/util.o ../src/tele_rand.o $(CC) -o $@ $^ $(CFLAGS) ../src/match_token.c: ../src/match_token.rl