3. Trig Helper Functions

3.1. DONE Display Position

CLOSED: [2020-04-20 Mon 22:53] Draws the current program position.

<<trig_static_funcdefs>>=
static void display_pos(page_trig_d *t);
<<trig_functions>>=
static void display_pos(page_trig_d *t)
{
    uint32_t dat;
    int y;

    dat = 1 << t->tvm.istate.pos;

    for (y = 0; y < 4; y++) {
        uint8_t byte;
        byte = dat >> (y * 8);
        monolith_page_mstate_led_row(t->mstate,
                                     0, y + 4,
                                     byte);
    }
}

3.2. WIP Redraw

Redraws the entire grid.

<<trig_static_funcdefs>>=
static void redraw(page_trig_d *t);
<<trig_functions>>=
static void redraw(page_trig_d *t)
{
    select_cell(t, t->curcell);
    display_pos(t);
}

3.3. WIP Select Cell

Selects a cell, zero indexed. Will also redraw the cell pool and cell.

<<trig_static_funcdefs>>=
static void select_cell(page_trig_d *t, int c);
<<trig_functions>>=
static void select_cell(page_trig_d *t, int c)
{
    int x, y;
    trig_cell *cell;
    x = c % 8;
    y = c / 8;
    monolith_page_mstate_led_set(t->mstate,
                                 t->last_x,
                                 t->last_y, 0);
    monolith_page_mstate_led_set(t->mstate, x, y, 1);

    t->last_x = x;
    t->last_y = y;
    t->curcell = c;

    cell = trig_vm_cell_get(&t->tvm, c);

    for (y = 0; y < 8; y++) {
        uint8_t byte;

        if (y < 4) {
            byte = (cell->cmd >> (y * 8)) & 0xFF;
        } else {
            byte = (cell->data >> ((y - 4) * 8)) & 0xFF;
        }

        monolith_page_mstate_led_row(t->mstate,
                                    255, y,
                                    byte);
    }
}

3.4. WIP Toggle Bit

<<trig_static_funcdefs>>=
static void toggle_cell(page_trig_d *t, int x, int y);
<<trig_functions>>=
static void toggle_cell(page_trig_d *t, int x, int y)
{
    int word, pos;
    uint8_t byte;
    trig_cell *c;
    int shift;

    if (y < 4) {
        word = 0;
    } else {
        word = 1;
        y -= 4;
    }

    x -= 8;

    pos = (y * 8) + x;

    c = trig_vm_cell_get(&t->tvm, t->curcell);

    trig_cell_tog(c, word, pos);

    shift = y * 8;

    if (word) {
        byte = (c->data >> shift) & 0xFF;
    } else {
        byte = (c->cmd >> shift) & 0xFF;
    }

    monolith_page_mstate_led_row(t->mstate,
                                 255,
                                 y + word*4,
                                 byte);
}

3.5. DONE Updating the display

CLOSED: [2020-06-18 Thu 09:13] The bottom lefthand rectangle is dedicated to visualizing the current program position. Displays should only update when needed, so an update is only required when the position changes.

How does one handle that for both trigex and an arbitrary number of spawned trigrex?

Use two 32-bit (unsigned) integers. That's how.

Each integer can store an entire state of playhead positions. There are only 32 cells to choose from, so 32 bits is enough.

Two integers are needed for the current state and the previous state. When they differ at the end, it means there is an update.

The way this procedure works is as follows:

Update the previous state, clear the current state.

<<trig_static_funcdefs>>=
static void update_and_clear(page_trig_d *t);
<<trig_functions>>=
static void update_and_clear(page_trig_d *t)
{
    t->dstate_prev = t->dstate;
    t->dstate = 0;
}

Call on any trigrex nodes. These will write write their playhead position to the drawing state using an OR operation via draw_position.


<<trig_static_funcdefs>>=
static void draw_position(page_trig_d *t, int pos);
<<trig_functions>>=
static void draw_position(page_trig_d *t, int pos)
{
    t->dstate |= (1 << pos);
}

trigex gets called after all the trigrex nodes are called. It will OR its own position to the state, then do the state comparison. If there is a change, an update will occur.

The drawing routine maps the bits by splitting the 32-bit word into 4 bytes, with the smallest byte mapping to the top row.

<<trig_static_funcdefs>>=
static void check_and_draw(page_trig_d *t);
<<trig_functions>>=
static void check_and_draw(page_trig_d *t)
{
    if (t->dstate != t->dstate_prev) {
        int y;
        uint32_t s;

        s = t->dstate;
        for (y = 0; y < 4; y++) {
            uint8_t byte;
            byte = (s >> (8 * y)) & 0xFF;

            monolith_page_mstate_led_row(t->mstate,
                                        0, y + 4,
                                        byte);
        }
    }
}



prev | home | next