Exemplo n.º 1
0
static void op_RAND_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                        exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t a = cs_pop(cs);
    if (a == -1)
        cs_push(cs, 0);
    else
        cs_push(cs, rand() % (a + 1));
}
Exemplo n.º 2
0
// Check every op manipulates the stack correctly
TEST op_stack_size() {
    for (size_t i = 0; i < E_OP__LENGTH; i++) {
        const tele_op_t *op = tele_ops[i];

        if (op->get != NULL) {
            scene_state_t ss = {};  // initalise to empty
                                    // (needs dedicated initaliser)
            exec_state_t es;
            es_init(&es);
            es_push(&es);
            es_variables(&es)->script_number = 1;
            command_state_t cs;
            cs_init(&cs);

            // add params to stack (plus an extra 2, to check that too many
            // values aren't removed, warning: note the maximum stack size in
            // state.h)
            const int16_t stack_extra = 2;
            for (int j = 0; j < op->params + stack_extra; j++) cs_push(&cs, 0);

            // execute get
            op->get(op->data, &ss, &es, &cs);

            // check that the stack has the correct number of items in it
            if (op->returns) {
                ASSERT_EQm(op->name, cs_stack_size(&cs), stack_extra + 1);
            }
            else {
                ASSERT_EQm(op->name, cs_stack_size(&cs), stack_extra);
            }
        }

        if (op->set != NULL) {
            scene_state_t ss = {};  // initalise to empty
                                    // (needs dedicated initaliser)
            exec_state_t es;
            es_init(&es);
            command_state_t cs;
            cs_init(&cs);

            // add params to stack (plus an extra 2, to check that too many
            // values aren't removed, warning: note the maximum stack size in
            // state.h)
            // set functions require an extra value on the stack
            const int16_t stack_extra = 2;
            for (int j = 0; j < op->params + stack_extra + 1; j++)
                cs_push(&cs, 0);

            // execute get
            op->set(op->data, &ss, &es, &cs);

            // check that the stack has the correct number of items in it
            ASSERT_EQm(op->name, cs_stack_size(&cs), stack_extra);
        }
    }
    PASS();
}
Exemplo n.º 3
0
static void op_MAX_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                       exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t a, b;
    a = cs_pop(cs);
    b = cs_pop(cs);
    if (a > b)
        cs_push(cs, a);
    else
        cs_push(cs, b);
}
Exemplo n.º 4
0
static void op_LIM_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                       exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t a, b, i;
    i = cs_pop(cs);
    a = cs_pop(cs);
    b = cs_pop(cs);
    if (i < a)
        cs_push(cs, a);
    else if (i > b)
        cs_push(cs, b);
    else
        cs_push(cs, i);
}
Exemplo n.º 5
0
static void op_R_get(const void *NOTUSED(data), scene_state_t *ss,
                         exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t min = ss->variables.r_min;
    int16_t max = ss->variables.r_max;
    if (max < min) {
        int16_t temp = min;
        min = max;
        max = temp;
    }
    int16_t range = max - min + 1;
    if (range == 0)
        cs_push(cs, min);
    else
        cs_push(cs, rand() % range + min);
}
Exemplo n.º 6
0
// Check every mod manipulates the stack correctly
TEST mod_stack_size() {
    for (size_t i = 0; i < E_MOD__LENGTH; i++) {
        const tele_mod_t *mod = tele_mods[i];

        scene_state_t ss = {};  // initalise to empty
                                // (needs dedicated initaliser)
        exec_state_t es;
        es_init(&es);
        command_state_t cs;
        cs_init(&cs);

        // add params to stack (plus an extra 2, to check that too many
        // values aren't removed, warning: note the maximum stack size in
        // state.h)
        const int16_t stack_extra = 2;
        for (int j = 0; j < mod->params + stack_extra; j++) cs_push(&cs, 0);

        // execute func
        const tele_command_t sub_command = { .length = 1,
                                             .separator = 0,
                                             .data = { { .tag = OP,
                                                         .value = E_OP_A } } };
        mod->func(&ss, &es, &cs, &sub_command);

        // check that the stack has the correct number of items in it
        ASSERT_EQm(mod->name, cs_stack_size(&cs), stack_extra);
    }
Exemplo n.º 7
0
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;
    tele_rand_t *ptr = (tele_rand_t *)(base + offset);
    cs_push(cs, ptr->seed);
}
Exemplo n.º 8
0
static void op_MOD_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                       exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t a = cs_pop(cs);
    int16_t b = cs_pop(cs);
    int16_t out = b != 0 ? a % b : 0;
    cs_push(cs, out);
}
Exemplo n.º 9
0
static void op_MUL_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                       exec_state_t *NOTUSED(es), command_state_t *cs) {
    int32_t r = cs_pop(cs);
    r *= cs_pop(cs);
    if (r > INT16_MAX) r = INT16_MAX;
    if (r < INT16_MIN) r = INT16_MIN;
    cs_push(cs, (int16_t)r);
}
Exemplo n.º 10
0
static void op_RRAND_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                         exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t a, b, min, max, range;
    a = cs_pop(cs);
    b = cs_pop(cs);
    if (a < b) {
        min = a;
        max = b;
    }
    else {
        min = b;
        max = a;
    }
    range = max - min + 1;
    if (range == 0)
        cs_push(cs, a);
    else
        cs_push(cs, rand() % range + min);
}
Exemplo n.º 11
0
static void op_QT_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                      exec_state_t *NOTUSED(es), command_state_t *cs) {
    // this rounds negative numbers rather than quantize (choose closer)
    int16_t a, b, c, d, e;
    b = cs_pop(cs);
    a = cs_pop(cs);

    if (a == 0) {
        cs_push(cs, 0);
        return;
    }

    c = b / a;
    d = c * a;
    e = (c + 1) * a;

    if (abs(b - d) < abs(b - e))
        cs_push(cs, d);
    else
        cs_push(cs, e);
}
Exemplo n.º 12
0
static void op_O_get(const void *NOTUSED(data), scene_state_t *ss,
                     exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t min = ss->variables.o_min;
    int16_t max = ss->variables.o_max;
    int16_t wrap = ss->variables.o_wrap;

    // restrict current_value to (wrapped) bounds
    int16_t current_value = normalise_value(min, max, wrap, ss->variables.o);
    cs_push(cs, current_value);

    // calculate new value
    ss->variables.o =
        normalise_value(min, max, wrap, current_value + ss->variables.o_inc);
}
Exemplo n.º 13
0
static void op_DRUNK_get(const void *NOTUSED(data), scene_state_t *ss,
                         exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t min = ss->variables.drunk_min;
    int16_t max = ss->variables.drunk_max;
    int16_t wrap = ss->variables.drunk_wrap;

    // restrict current_value to (wrapped) bounds
    int16_t current_value =
        normalise_value(min, max, wrap, ss->variables.drunk);
    cs_push(cs, current_value);

    // calculate new value
    int16_t new_value = current_value + (rand() % 3) - 1;
    ss->variables.drunk = normalise_value(min, max, wrap, new_value);
}
Exemplo n.º 14
0
static void op_WRAP_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                        exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t a, b, i, c;
    i = cs_pop(cs);
    a = cs_pop(cs);
    b = cs_pop(cs);
    if (a < b) {
        c = b - a + 1;
        while (i >= b) i -= c;
        while (i < a) i += c;
    }
    else {
        c = a - b + 1;
        while (i >= a) i -= c;
        while (i < b) i += c;
    }
    cs_push(cs, i);
}
Exemplo n.º 15
0
void TXReceive(uint8_t model, command_state_t *cs, uint8_t mode, bool shift) {
    // zero-index the output
    uint8_t input = cs_pop(cs) - 1;
    // send the port, device and address
    uint8_t port = input & 3;
    uint8_t device = input >> 2;
    uint8_t address = model + device;
    // inputs are numbered 0-7 for each device - shift is for the second half
    // mode pushes it up so it can read quantized values and note numbers
    port += (shift ? 4 : 0) + (mode << 3);
    // tell the device what value you are going to query
    uint8_t buffer[2];
    buffer[0] = port;
    tele_ii_tx(address, buffer, 1);
    // now read the value
    buffer[0] = 0;
    buffer[1] = 0;
    tele_ii_rx(address, buffer, 2);
    int16_t value = (buffer[0] << 8) + buffer[1];
    cs_push(cs, value);
}
Exemplo n.º 16
0
static void op_EZ_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                      exec_state_t *NOTUSED(es), command_state_t *cs) {
    cs_push(cs, cs_pop(cs) == 0);
}
Exemplo n.º 17
0
static void op_AVG_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                       exec_state_t *NOTUSED(es), command_state_t *cs) {
    int32_t ret = (((int32_t)cs_pop(cs) * 2) + ((int32_t)cs_pop(cs) * 2)) / 2;
    if (ret % 2) ret += 1;
    cs_push(cs, (int16_t)(ret / 2));
}
Exemplo n.º 18
0
static void op_S_L_get(const void *NOTUSED(data), scene_state_t *ss,
                       exec_state_t *NOTUSED(es), command_state_t *cs) {
    cs_push(cs, ss->stack_op.top);
}
Exemplo n.º 19
0
static void op_TOSS_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                        exec_state_t *NOTUSED(es), command_state_t *cs) {
    cs_push(cs, rand() & 1);
}
Exemplo n.º 20
0
static void op_R_MAX_get(const void *NOTUSED(data), scene_state_t *ss,
                         exec_state_t *NOTUSED(es), command_state_t *cs) {
    cs_push(cs, ss->variables.r_max);
}
Exemplo n.º 21
0
// run a single command inside a given exec_state
process_result_t process_command(scene_state_t *ss, exec_state_t *es,
                                 const tele_command_t *c) {
    command_state_t cs;
    cs_init(&cs);  // initialise this here as well as inside the loop, in case
                   // the command has 0 length

    // 1. Do we have a PRE seperator?
    // ------------------------------
    // if we do then only process the PRE part, the MOD will determine if the
    // POST should be run and take care of running it
    ssize_t start_idx = 0;
    ssize_t end_idx = c->separator == -1 ? c->length : c->separator;

    // 2. Determine the location of all the SUB commands
    // -------------------------------------------------
    // an array of structs to hold the start and end of each sub command
    struct sub_idx {
        ssize_t start;
        ssize_t end;
    } subs[COMMAND_MAX_LENGTH];

    ssize_t sub_len = 0;
    ssize_t sub_start = 0;

    // iterate through c->data to find all the SUB_SEPs and add to the array
    for (ssize_t idx = start_idx; idx < end_idx; idx++) {
        tele_word_t word_type = c->data[idx].tag;
        if (word_type == SUB_SEP && idx > sub_start) {
            subs[sub_len].start = sub_start;
            subs[sub_len].end = idx - 1;
            sub_len++;
            sub_start = idx + 1;
        }
    }

    // the last sub command won't have been added, manually add it here
    if (end_idx > sub_start) {
        subs[sub_len].start = sub_start;
        subs[sub_len].end = end_idx - 1;
        sub_len++;
    }

    // 3. Loop through each sub command and execute it
    // -----------------------------------------------
    // iterate through sub commands from left to right
    for (ssize_t sub_idx = 0; sub_idx < sub_len && !es_variables(es)->breaking;
         sub_idx++) {
        const ssize_t sub_start = subs[sub_idx].start;
        const ssize_t sub_end = subs[sub_idx].end;

        // initialise the command state for each sub, otherwise a value left on
        // the stack for the previous sub, can cause the set fn to trigger when
        // it shouldn't
        cs_init(&cs);

        // as we are using a stack based language, we must process commands from
        // right to left
        for (ssize_t idx = sub_end; idx >= sub_start; idx--) {
            const tele_word_t word_type = c->data[idx].tag;
            const int16_t word_value = c->data[idx].value;

            if (word_type == NUMBER) { cs_push(&cs, word_value); }
            else if (word_type == OP) {
                const tele_op_t *op = tele_ops[word_value];

                // if we're in the first command position, and there is a set fn
                // pointer and we have enough params, then run set, else run get
                if (idx == sub_start && op->set != NULL &&
                    cs_stack_size(&cs) >= op->params + 1)
                    op->set(op->data, ss, es, &cs);
                else
                    op->get(op->data, ss, es, &cs);
            }
            else if (word_type == MOD) {
                tele_command_t post_command;
                post_command.comment = false;
                copy_post_command(&post_command, c);
                tele_mods[word_value]->func(ss, es, &cs, &post_command);
            }
        }
    }

    // 4. Return
    // ---------
    // sometimes we have single value left of the stack, if so return it
    if (cs_stack_size(&cs)) {
        process_result_t o = {.has_value = true, .value = cs_pop(&cs) };
        return o;
    }
Exemplo n.º 22
0
static void op_I_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss),
                     exec_state_t *es, command_state_t *cs) {
    cs_push(cs, es_variables(es)->i);
}
Exemplo n.º 23
0
static void op_M_ACT_get(const void *NOTUSED(data), scene_state_t *ss,
                         exec_state_t *NOTUSED(es), command_state_t *cs) {
    cs_push(cs, ss->variables.m_act);
}
Exemplo n.º 24
0
static void op_LAST_get(const void *NOTUSED(data), scene_state_t *ss,
                        exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t script_number = cs_pop(cs) - 1;
    int16_t last = ss_get_script_last(ss, script_number);
    cs_push(cs, last);
}
Exemplo n.º 25
0
static void op_FLIP_get(const void *NOTUSED(data), scene_state_t *ss,
                        exec_state_t *NOTUSED(es), command_state_t *cs) {
    int16_t flip = ss->variables.flip;
    cs_push(cs, flip);
    ss->variables.flip = flip == 0;
}
Exemplo n.º 26
0
static void op_SEED_get(const void *NOTUSED(data), scene_state_t *ss,
                        exec_state_t *NOTUSED(es), command_state_t *cs) {
    cs_push(cs, ss->variables.seed);
}
Exemplo n.º 27
0
static void op_M_SYM_EXCLAMATION_get(const void *NOTUSED(data),
                                     scene_state_t *ss,
                                     exec_state_t *NOTUSED(es),
                                     command_state_t *cs) {
    cs_push(cs, ss->variables.m);
}