// scroll the current selection void select_scroll(s8 dir) { const s32 max = net_num_ops() - 1; s16 newSel; s16 newIdx; if(dir < 0) { /// SCROLL DOWN // if selection is already zero, do nothing if(*pageSelect == 0) { // print_dbg("\r\n reached min selection in inputs scroll. "); return; } // remove highlight from old center render_scroll_apply_hl(SCROLL_CENTER_LINE, 0); // decrement selection newSel = *pageSelect - 1; ///// these bounds checks shouldn't really be needed here... // if(newSel < 0) { newSel = 0; } // if(newSel > max ) { newSel = max; } *pageSelect = newSel; // add new content at top newIdx = newSel - SCROLL_LINES_BELOW; if(newIdx < 0) { // empty row region_fill(lineRegion, 0); } else { render_line(newIdx); } // render tmp region to bottom of scroll // (this also updates scroll byte offset) render_to_scroll_top(); // add highlight to new center render_scroll_apply_hl(SCROLL_CENTER_LINE, 1); } else { // SCROLL UP // if selection is already max, do nothing if(*pageSelect == max) { // print_dbg("\r\n reached max selection in inputs scroll. "); return; } // remove highlight from old center render_scroll_apply_hl(SCROLL_CENTER_LINE, 0); // increment selection newSel = *pageSelect + 1; *pageSelect = newSel; // add new content at bottom of screen newIdx = newSel + SCROLL_LINES_ABOVE; if(newIdx > max) { // empty row region_fill(lineRegion, 0); } else { render_line(newIdx); } // render tmp region to bottom of scroll // (this also updates scroll byte offset) render_to_scroll_bottom(); // add highlight to new center render_scroll_apply_hl(SCROLL_CENTER_LINE, 1); } }
// redraw all lines, force selection void redraw_ins(void) { u8 i=0; s32 n = *pageSelect - 3; // num_ins() includes param count! const s32 max = net_num_ins() - 1; // set scroll region // FIXME: should be separate function i guess render_set_scroll(¢erScroll); print_dbg("\r\n redraw_ins() "); while(i<8) { if(n == -1) { // draw a blank line region_fill(lineRegion, 0); } else if(n == (max+1)) { // draw a blank line region_fill(lineRegion, 0); } else { if(n < -1) { n += (max + 2); } if( n > max ) { n -= (max + 2); } render_line( n, 0xa ); } render_to_scroll_line(i, n == *pageSelect ? 1 : 0); ++i; ++n; } }
// function keys void handle_key_0(s32 val) { // load module if(val == 0) { return; } if(check_key(0)) { region_fill(headRegion, 0x0); font_string_region_clip(headRegion, "loading DSP module...", 0, 0, 0xa, 0); headRegion->dirty = 1; render_update(); net_clear_user_ops(); files_load_dsp(*pageSelect); bfin_wait_ready(); net_report_params(); bfin_enable(); // render status to head region region_fill(headRegion, 0x0); font_string_region_clip(headRegion, "finished loading.", 0, 0, 0xa, 0); headRegion->dirty = 1; render_update(); } show_foot(); }
// store void handle_key_0(s32 val) { if(val == 0) { return; } if(check_key(0)) { region_fill(headRegion, 0x0); font_string_region_clip(headRegion, "writing scene to card...", 0, 0, 0xa, 0); headRegion->dirty = 1; render_update(); region_fill(headRegion, 0x0); // files_store_scene_name(sceneData->desc.sceneName, 1); files_store_scene_name(sceneData->desc.sceneName); print_dbg("\r\n stored scene, back to handler"); font_string_region_clip(headRegion, "done writing.", 0, 0, 0xa, 0); headRegion->dirty = 1; render_update(); // refresh // redraw_lines(); redraw_scenes(); } show_foot(); }
// scroll the current selection static void select_scroll(s32 dir) { // index for new content s16 newIdx; s16 newSel; if(dir < 0) { /// SCROLL DOWN if(*pageSelect == 0) { return; } // remove highlight from old center // render_scroll_apply_hl(SCROLL_CENTER_LINE, 0); // redraw center row without editing cursor, etc render_line(*pageSelect, 0xa); // copy to scroll render_to_scroll_center(); newSel = *pageSelect - 1; *pageSelect = newSel; // add new content at top newIdx = newSel - SCROLL_LINES_BELOW; if(newIdx < 0) { // empty row region_fill(lineRegion, 0); } else { render_line(newIdx, 0xa); } // render tmp region to bottom of scroll // (this also updates scroll byte offset) render_to_scroll_top(); // add highlight to new center render_scroll_apply_hl(SCROLL_CENTER_LINE, 1); } else { // SCROLL UP // if selection is already max, do nothing if(*pageSelect == (maxPresetIdx) ) { return; } // remove highlight from old center render_scroll_apply_hl(SCROLL_CENTER_LINE, 0); // increment selection newSel = *pageSelect + 1; *pageSelect = newSel; // add new content at bottom of screen newIdx = newSel + SCROLL_LINES_ABOVE; if(newIdx > maxPresetIdx) { // empty row region_fill(lineRegion, 0); } else { render_line(newIdx, 0xa); } // render tmp region to bottom of scroll // (this also updates scroll byte offset) render_to_scroll_bottom(); // add highlight to new center render_scroll_apply_hl(SCROLL_CENTER_LINE, 1); } }
// redraw with current state void op_bignum_redraw(op_bignum_t* bignum) { //// TEST /* u32 i, j; */ /* u8* dat = &(bignum->reg.data[0]); */ // region* r = &(bignum->reg); if(bignum->enable <= 0) { return; } // print value to text buffer op_print(tmpStr, bignum->val); print_dbg("\r\n op_bignum_redraw , "); print_dbg(tmpStr); // blank region_fill(&(bignum->reg), 0); // render text to region region_string_aa(&(bignum->reg), tmpStr, 0, 0, 1); // ascii art /* print_dbg("\r\n"); */ /* for(i=0; i< OP_BIGNUM_PX_H; i++) { */ /* for(j=0; j< OP_BIGNUM_PX_W; j++) { */ /* if(*dat > 0) { print_dbg("#"); } else { print_dbg("_"); } */ /* dat++; */ /* } */ /* print_dbg("\r\n"); */ /* } */ // FIXME: this should NOT go here. //gfx ops should inherit from op_poll, // and only call for a redraw every 100 ms or whatever. // screen_draw_region(r->x, r->y, r->w, r->h, r->data); }
// draw editing string to given region, with cursor highlight void render_edit_string(region* reg, char* str, u8 len, u8 cursor) { u8 i; u8* dst = (u8*)reg->data; u32 off = 0; // const u32 squarePx = (FONT_CHARW+2) * FONT_CHARH; u32 dif; region_fill(reg, 0x0); for(i=0; i<len; ++i) { if(str[i] == 0) { break; } if(i == cursor) { /// fixme: net art // region_fill_part(reg, off, squarePx, 0xf); // hack a column fill with a space character font_glyph(' ', dst, reg->w, 0x0, 0xf); dst += 2; off += 2; font_glyph_fixed(str[i], dst, reg->w, 0x0, 0xf); dif = FONT_CHARW + 2; dst += dif; off += dif; } else { dif = font_glyph(str[i], dst, reg->w, 0xf, 0x0) + 1; dst += dif; off += dif; } } reg->dirty = 1; }
// display the function key labels according to current state static void show_foot0(void) { u8 fill = 0; if(keyPressed == 0) { fill = 0x5; } region_fill(footRegion[0], fill); font_string_region_clip(footRegion[0], "LOAD", 0, 0, 0xf, fill); }
static void show_foot1(void) { u8 fill = 0; if(keyPressed == 1) { fill = 0x5; } region_fill(footRegion[1], fill); font_string_region_clip(footRegion[1], "OUTS", 0, 0, 0xf, fill); }
// fill tmp region with new content // given input index and foreground color static void render_line(s16 idx, u8 fg) { region_fill(lineRegion, 0x0); if( (idx >= 0) && (idx < maxPresetIdx) ) { clearln(); appendln((const char*)preset_name(idx)); font_string_region_clip(lineRegion, lineBuf, 2, 0, fg, 0); } }
// fill tmp region with new content // given input index static void render_line(s16 idx, u16 max) { region_fill(lineRegion, 0x0); if((idx > max) || (idx < 0)) { return; } clearln(); appendln((const char*)files_get_dsp_name(idx)); endln(); font_string_region_clip(lineRegion, lineBuf, 0, 0, 0xa, 0); }
static void show_foot3(void) { u8 fill = 0; u8 fore = 0xf; if(altMode) { fill = 0xf; fore = 0; } region_fill(footRegion[3], fill); font_string_region_clip(footRegion[3], "ALT", 0, 0, fore, fill); }
// fill tmp region with new content // given input index and foreground color static void render_line(s16 idx, u8 fg) { region_fill(lineRegion, 0x0); if( (idx >= 0) && (idx < files_get_scene_count()) ) { clearln(); appendln((const char*)files_get_scene_name(idx)); // stick a null character at the end... lineBuf[SCENE_NAME_LEN - 1] = '\0'; font_string_region_clip(lineRegion, lineBuf, 2, 0, fg, 0); } }
// input x position void op_bignum_in_x(op_bignum_t* bignum, const io_t v) { // blank so we don't leave a trail region_fill(&(bignum->reg), 0); if (v > OP_BIGNUM_X_MAX) { bignum->x = bignum->reg.x = OP_BIGNUM_X_MAX; } else { bignum->x = bignum->reg.x = v; } op_bignum_redraw(bignum); }
// render new operator type name void render_op_type(void) { const char* name = op_registry[userOpTypes[newOpType]].name; // print_dbg("\r\n new op selection: "); // print_dbg(name); region_fill(headRegion, 0x0); clearln(); appendln_char('+'); appendln(name); endln(); font_string_region_clip(headRegion, lineBuf, 0, 0, 0xa, 0); }
// display the function key labels according to current state static void show_foot0(void) { u8 fill = 0; if(keyPressed == 0) { fill = 0x5; } region_fill(footRegion[0], fill); if(altMode) { font_string_region_clip(footRegion[0], "FOLLOW", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[0], "STORE", 0, 0, 0xf, fill); } }
static void show_foot2(void) { u8 fill = 0; if(keyPressed == 2) { fill = 0x5; } region_fill(footRegion[2], fill); if(targetSelect) { font_string_region_clip(footRegion[2], "CONN", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[2], "DISC", 0, 0, 0xf, fill); } }
/// initialize void op_screen_init(void* op) { op_screen_t* screen = (op_screen_t*)op; // superclass functions screen->super.in_fn = op_screen_in; screen->super.pickle = (op_pickle_fn) (&op_screen_pickle); screen->super.unpickle = (op_unpickle_fn) (&op_screen_unpickle); // polled operator superclass screen->op_poll.handler = (poll_handler_t)(&op_screen_poll_handler); screen->op_poll.op = screen; // superclass val screen->super.numInputs = 6; screen->super.numOutputs = 0; screen->super.in_val = screen->in_val; screen->in_val[0] = &(screen->enable); screen->in_val[1] = &(screen->period); screen->in_val[2] = &(screen->val); screen->in_val[3] = &(screen->fill); screen->in_val[4] = &(screen->x); screen->in_val[5] = &(screen->y); screen->super.out = screen->outs; screen->super.opString = op_screen_opstring; screen->super.inString = op_screen_instring; screen->super.outString = op_screen_outstring; screen->super.type = eOpScreen; // class val screen->enable = 0; screen->period = op_from_int(50); screen->val = 0xf; screen->fill = 0; screen->x = 0; screen->y = 0; // init graphics /*.. this is sort of retarded, doing stuff normally accomplished in region_alloc() or in static init, but doing a dumb memory hack on it to share a tmp data space between instances. */ screen->reg.dirty = 0; screen->reg.x = 0; screen->reg.y = 0; screen->reg.w = OP_SCREEN_PX_W; screen->reg.h = OP_SCREEN_PX_H; screen->reg.len = OP_SCREEN_GFX_BYTES; screen->reg.data = (u8*) (screen->regData); region_fill(&(screen->reg), 0); }
// render a given line void render_line(s16 idx) { region_fill(lineRegion, 0x0); if((idx >= 0) && (idx < net_num_ops()) ) { clearln(); appendln_idx_lj((u8)idx); appendln_char('.'); appendln(net_op_name(idx)); endln(); font_string_region_clip(lineRegion, lineBuf, 0, 0, 0xa, 0); // region_fill_part(lineRegion, LINE_UNDERLINE_OFFSET, LINE_UNDERLINE_LEN, 0x1); } }
static void show_foot2(void) { u8 fill = 0; if(keyPressed == 2) { fill = 0x5; } region_fill(footRegion[2], fill); if(altMode) { font_string_region_clip(footRegion[2], "COPY", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[2], "CLEAR", 0, 0, 0xf, fill); } }
/// initialize void op_bignum_init(void* op) { op_bignum_t* bignum = (op_bignum_t*)op; // superclass functions bignum->super.in_fn = op_bignum_in; bignum->super.pickle = (op_pickle_fn) (&op_bignum_pickle); bignum->super.unpickle = (op_unpickle_fn) (&op_bignum_unpickle); // polled operator superclass bignum->op_poll.handler = (poll_handler_t)(&op_bignum_poll_handler); bignum->op_poll.op = bignum; // superclass val bignum->super.numInputs = 5; bignum->super.numOutputs = 0; bignum->super.in_val = bignum->in_val; bignum->in_val[0] = &(bignum->enable); bignum->in_val[1] = &(bignum->period); bignum->in_val[2] = &(bignum->val); bignum->in_val[3] = &(bignum->x); bignum->in_val[4] = &(bignum->y); bignum->super.out = bignum->outs; bignum->super.opString = op_bignum_opstring; bignum->super.inString = op_bignum_instring; bignum->super.outString = op_bignum_outstring; bignum->super.type = eOpBignum; // class val bignum->enable = 0; bignum->period = op_from_int(50); bignum->val = 0; bignum->x = 0; bignum->y = 0; // init graphics /*.. this is sort of retarded, doing stuff normally accomplished in region_alloc() or in static init, but doing a dumb memory hack on it to share a tmp data space between instances. */ bignum->reg.dirty = 0; bignum->reg.x = 0; bignum->reg.y = 0; bignum->reg.w = OP_BIGNUM_PX_W; bignum->reg.h = OP_BIGNUM_PX_H; bignum->reg.len = OP_BIGNUM_GFX_BYTES; bignum->reg.data = (u8*) (bignum->regData); region_fill(&(bignum->reg), 0); }
// init void init_page_presets(void) { u8 i, n; print_dbg("\r\n alloc PRESETS page"); // allocate regions region_alloc(&scrollRegion); // init scroll scroll_init(¢erScroll, &scrollRegion); // fill regions region_fill(&scrollRegion, 0x0); // fill the scroll with actual line values... n = 3; i = 0; //// need to actually set the scroll region at least temporarily render_set_scroll(¢erScroll); redraw_lines(); }
// fill tmp region with new content // given input index and foreground color static void render_line(s16 idx, u8 fg) { const s16 opIdx = net_in_op_idx(idx); region_fill(lineRegion, 0x0); if(opIdx >= 0) { // operator input // build descriptor string clearln(); appendln_idx_lj(opIdx); appendln_char('.'); appendln( net_op_name(opIdx) ); appendln_char('/'); appendln( net_in_name(idx) ); endln(); font_string_region_clip(lineRegion, lineBuf, 4, 0, fg, 0); clearln(); op_print(lineBuf, net_get_in_value(idx)); font_string_region_clip(lineRegion, lineBuf, LINE_VAL_POS_SHORT, 0, fg, 0); } else { // parameter input clearln(); appendln_idx_lj( (int)net_param_idx(idx)); appendln_char('.'); appendln( net_in_name(idx)); endln(); font_string_region_clip(lineRegion, lineBuf, 4, 0, 0xa, 0); clearln(); // op_print(lineBuf, net_get_in_value(idx)); /// FIXME: this is pretty dumb, // params and inputs should just be on separate pages i guess net_get_param_value_string(lineBuf, idx); font_string_region_clip(lineRegion, lineBuf, LINE_VAL_POS_LONG, 0, fg, 0); } // draw something to indicate play mode visibility if(net_get_in_play(idx)) { font_string_region_clip(lineRegion, ".", 0, 0, fg, 0); } // draw something to indicate preset inclusion if(net_get_in_preset(idx)) { font_string_region_clip(lineRegion, ".", 126, 0, fg, 0); } }
// select void select_ops(void) { // assign global scroll region pointer // also marks dirty render_set_scroll(¢erScroll); // other regions are static in top-level render, with global handles region_fill(headRegion, 0x0); font_string_region_clip(headRegion, "OPERATORS", 0, 0, 0xf, 0x1); // assign handlers app_event_handlers[ kEventEncoder0 ] = &handle_enc_0 ; app_event_handlers[ kEventEncoder1 ] = &handle_enc_1 ; app_event_handlers[ kEventEncoder2 ] = &handle_enc_2 ; app_event_handlers[ kEventEncoder3 ] = &handle_enc_3 ; app_event_handlers[ kEventSwitch0 ] = &handle_key_0 ; app_event_handlers[ kEventSwitch1 ] = &handle_key_1 ; app_event_handlers[ kEventSwitch2 ] = &handle_key_2 ; app_event_handlers[ kEventSwitch3 ] = &handle_key_3 ; }
static void show_foot1(void) { u8 fill = 0; if(keyPressed == 1) { fill = 0x5; } region_fill(footRegion[1], fill); if(altMode) { font_string_region_clip(footRegion[1], "SPLIT", 0, 0, 0xf, fill); } else { if(net_get_out_preset((u32)(*pageSelect))) { // if(inPreset) { font_string_region_clip(footRegion[1], "EXC", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[1], "INC", 0, 0, 0xf, fill); } } }
uint8_t screen_refresh_help() { if (!dirty) { return 0; } // clamp value of page_no if (page_no >= HELP_PAGES) page_no = HELP_PAGES - 1; // clamp value of offset if (offset >= help_length[page_no] - 8) offset = help_length[page_no] - 8; const char** text = help_pages[page_no]; for (uint8_t y = 0; y < 8; y++) { region_fill(&line[y], 0); font_string_region_clip_tab(&line[y], text[y + offset], 2, 0, 0xa, 0); } dirty = false; return 0xFF; };
static void show_foot1(void) { u8 fill = 0; if(keyPressed == 1) { fill = 0x5; } region_fill(footRegion[1], fill); if(altMode) { if(net_get_in_play(*pageSelect)) { font_string_region_clip(footRegion[1], "HIDE", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[1], "SHOW", 0, 0, 0xf, fill); } } else { if(net_get_in_preset(*pageSelect)) { font_string_region_clip(footRegion[1], "EXC", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[1], "INC", 0, 0, 0xf, fill); } } }
// init void init_page_outs(void) { u8 i, n; print_dbg("\r\n alloc OUTS page"); // allocate regions region_alloc(&scrollRegion); // init scroll scroll_init(¢erScroll, &scrollRegion); // fill regions region_fill(&scrollRegion, 0x0); // fill the scroll with actual line values... n = 3; i = 0; //// need to actually set the scroll region at least temporarily render_set_scroll(¢erScroll); while(i<5) { render_line(i, 0xa); render_to_scroll_line(n, i == 0 ? 1 : 0); ++n; ++i; } }
static void show_foot2(void) { u8 fill = 0; if(keyPressed == 2) { fill = 0x5; } region_fill(footRegion[2], fill); if(altMode) { #if 0 if(playFilter) { font_string_region_clip(footRegion[2], "ALL", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[2], "FILT", 0, 0, 0xf, fill); } #endif } else { if(zeroed) { font_string_region_clip(footRegion[2], "MAX", 0, 0, 0xf, fill); } else { font_string_region_clip(footRegion[2], "ZERO", 0, 0, 0xf, fill); } } }
//---------------------- // ---- extern // init void init_page_dsp(void) { u8 i, n; u16 max = files_get_dsp_count() - 1; print_dbg("\r\n alloc DSP page"); // allocate regions region_alloc(&scrollRegion); // init scroll scroll_init(¢erScroll, &scrollRegion); // fill regions region_fill(&scrollRegion, 0x0); // fill the scroll with actual line values... n = 3; i = 0; //// need to actually set the scroll region at least temporarily render_set_scroll(¢erScroll); // also, reset scroller! while(i<5) { render_line(i, max); render_to_scroll_line(n, i == 0 ? 1 : 0); ++n; ++i; } }