diff options
| -rw-r--r-- | code/fe310/eos/Makefile | 2 | ||||
| -rw-r--r-- | code/fe310/eos/eve.c | 291 | ||||
| -rw-r--r-- | code/fe310/eos/eve.h | 23 | ||||
| -rw-r--r-- | code/fe310/eos/eve_kbd.c | 115 | ||||
| -rw-r--r-- | code/fe310/eos/eve_kbd.h | 18 | ||||
| -rw-r--r-- | code/fe310/eos/eve_text.c | 160 | ||||
| -rw-r--r-- | code/fe310/eos/eve_text.h | 25 | ||||
| -rw-r--r-- | code/fe310/eos/msgq.c | 1 | 
8 files changed, 458 insertions, 177 deletions
diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile index 133a36a..95e0da5 100644 --- a/code/fe310/eos/Makefile +++ b/code/fe310/eos/Makefile @@ -2,7 +2,7 @@ include ../common.mk  CFLAGS += -I../include -I../drivers -obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o uart.o spi.o net.o wifi.o cell.o sock.o eve.o eve_text.o +obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o uart.o spi.o net.o wifi.o cell.o sock.o eve.o eve_kbd.o eve_text.o  %.o: %.c %.h diff --git a/code/fe310/eos/eve.c b/code/fe310/eos/eve.c index bd94be2..98a729d 100644 --- a/code/fe310/eos/eve.c +++ b/code/fe310/eos/eve.c @@ -13,9 +13,12 @@  #include "eve.h"  #include "irq_def.h" -#define MEM_WRITE   0x800000 +#define MEM_WRITE       0x800000 -#define EVE_PIN_INT 0 +#define EVE_PIN_INT     0 +#define EVE_MAX_TOUCH   5 + +#define EVE_ETYPE_INT   1  static char eve_cmd_burst;  static uint16_t eve_cmd_offset; @@ -24,9 +27,33 @@ static uint32_t eve_dl_addr;  static int eve_int_mask = EVE_INT_TAG | EVE_INT_TOUCH;  static int eve_multitouch = 0;  static uint8_t eve_tag0; -EVETag eve_tag[5]; +static EOSTouch eve_touch[5]; +static uint8_t eve_touch_evt[256];  static eos_eve_fptr_t eve_renderer; +static const uint32_t _reg_touch[] = { +    REG_CTOUCH_TOUCH0_XY, +    REG_CTOUCH_TOUCH1_XY, +    REG_CTOUCH_TOUCH2_XY, +    REG_CTOUCH_TOUCH3_XY +}; + +static const uint32_t _reg_tag[] = { +    REG_TOUCH_TAG, +    REG_TOUCH_TAG1, +    REG_TOUCH_TAG2, +    REG_TOUCH_TAG3, +    REG_TOUCH_TAG4 +}; + +static const uint32_t _reg_track[] = { +    REG_TRACKER, +    REG_TRACKER_1, +    REG_TRACKER_2, +    REG_TRACKER_3, +    REG_TRACKER_4 +}; +  void eos_eve_command(uint8_t command, uint8_t parameter) {      eos_spi_cs_set();      eos_spi_xchg24(((uint32_t)command << 16) | ((uint32_t)parameter << 8), 0); @@ -263,147 +290,148 @@ void eos_eve_cmd_burst_end(void) {  static void eve_handler_int(void) {      GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); -    eos_evtq_push_isr(EOS_EVT_UI, NULL, 0); +    eos_evtq_push_isr(EOS_EVT_UI | EVE_ETYPE_INT, NULL, 0);      return;  }  static void eve_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { -    char render = 0; -    int touch_tag_idx = -1; -    uint8_t flags = eos_eve_read8(REG_INT_FLAGS) & eve_int_mask; +    uint8_t flags;      uint8_t touch_tag;      uint32_t touch_xy; -    EVETag *tag; - +    uint32_t touch_track; +    uint8_t tag0 = eve_tag0; +    uint8_t touch_idx = 0; +    int touch_idx_max = -1; +    int i; +    EOSTouch *touch; + +    eos_spi_dev_start(EOS_SPI_DEV_DISP); +    flags = eos_eve_read8(REG_INT_FLAGS) & eve_int_mask;      if (!eve_multitouch) { -        if (flags & EVE_INT_TAG) { -            touch_tag = eos_eve_read8(REG_TOUCH_TAG); -            eve_tag[0].value_prev = eve_tag[0].value; -            eve_tag[0].value = touch_tag; -            touch_tag_idx = 0; -            if (touch_tag) eve_tag0 = touch_tag; -        } +        touch = &eve_touch[0]; + +        tag0 = eve_tag0; +        touch->evt &= (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK);          touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH0_XY);          if (touch_xy == 0x80008000) { -            eve_tag[0].t = 0; +            touch_tag = 0; +            eve_tag0 = 0; +            touch->t = 0; +            touch->evt &= ~(EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); +            if (eve_int_mask & EVE_INT_CONVCOMPLETE) { +                eve_int_mask &= ~EVE_INT_CONVCOMPLETE; +                eos_eve_write8(REG_INT_MASK, eve_int_mask); +            }          } else { -            eve_tag[0].t = 1; -            eve_tag[0].x = touch_xy >> 16; -            eve_tag[0].y = touch_xy & 0xffff; +            touch->t = 1; +            touch->x = touch_xy >> 16; +            touch->y = touch_xy & 0xffff; +            if ((flags & EVE_INT_TAG) && !(touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK))) { +                touch_tag = eos_eve_read8(REG_TOUCH_TAG); +            } else { +                touch_tag = touch->tag; +            } +            if (touch->evt & EOS_TOUCH_ETYPE_TRACK) { +                touch_track = eos_eve_read32(REG_TRACKER); +                touch->tracker.tag = touch_track & 0xffff; +                touch->tracker.val = touch_track >> 16; +            } +            if (touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK)) { +                touch_idx = 1; +                touch_idx_max = 1; +            }              if (flags & EVE_INT_TOUCH) {                  eve_multitouch = 1; -                eve_int_mask |= EVE_INT_CONVCOMPLETE; -                eos_eve_write8(REG_INT_MASK, eve_int_mask); +                if (!(eve_int_mask & EVE_INT_CONVCOMPLETE)) { +                    eve_int_mask |= EVE_INT_CONVCOMPLETE; +                    eos_eve_write8(REG_INT_MASK, eve_int_mask); +                }              }          } -    } else if (flags & EVE_INT_CONVCOMPLETE) { -        tag = &eve_tag[0]; -        touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH0_XY); -        if (touch_xy == 0x80008000) { -            touch_tag = 0; -            tag->t = 0; -        } else { -            touch_tag = eos_eve_read8(REG_TOUCH_TAG); -            tag->t = 1; -            tag->x = touch_xy >> 16; -            tag->y = touch_xy & 0xffff; -        } -        if (touch_tag != tag->value) { -            tag->value_prev = tag->value; -            tag->value = touch_tag; -            touch_tag_idx = 0; -        } - -        tag = &eve_tag[1]; -        touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH1_XY); -        if (touch_xy == 0x80008000) { -            touch_tag = 0; -            tag->t = 0; -        } else { -            touch_tag = eos_eve_read8(REG_TOUCH_TAG1); -            tag->t = 1; -            tag->x = touch_xy >> 16; -            tag->y = touch_xy & 0xffff; -        } -        if (touch_tag != tag->value) { -            tag->value_prev = tag->value; -            tag->value = touch_tag; -            touch_tag_idx = 1; -        } - -        tag = &eve_tag[2]; -        touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH2_XY); -        if (touch_xy == 0x80008000) { -            touch_tag = 0; -            tag->t = 0; -        } else { -            touch_tag = eos_eve_read8(REG_TOUCH_TAG2); -            tag->t = 1; -            tag->x = touch_xy >> 16; -            tag->y = touch_xy & 0xffff; -        } -        if (touch_tag != tag->value) { -            tag->value_prev = tag->value; -            tag->value = touch_tag; -            touch_tag_idx = 2; -        } - -        tag = &eve_tag[3]; -        touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH3_XY); -        if (touch_xy == 0x80008000) { -            touch_tag = 0; -            tag->t = 0; -        } else { -            touch_tag = eos_eve_read8(REG_TOUCH_TAG3); -            tag->t = 1; -            tag->x = touch_xy >> 16; -            tag->y = touch_xy & 0xffff; -        } -        if (touch_tag != tag->value) { -            tag->value_prev = tag->value; -            tag->value = touch_tag; -            touch_tag_idx = 3; -        } - -        tag = &eve_tag[4]; -        touch_xy = ((uint32_t)eos_eve_read16(REG_CTOUCH_TOUCH4_X) << 16) | eos_eve_read16(REG_CTOUCH_TOUCH4_Y); -        if (touch_xy == 0x80008000) { -            touch_tag = 0; -            tag->t = 0; -        } else { -            touch_tag = eos_eve_read8(REG_TOUCH_TAG4); -            tag->t = 1; -            tag->x = touch_xy >> 16; -            tag->y = touch_xy & 0xffff; +        if ((touch_tag != touch->tag) && !(touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK))) { +            touch->tag_prev = touch->tag; +            touch->tag = touch_tag; +            touch_idx = 1; +            touch_idx_max = 1; +            if (touch->tag) touch->evt |= EOS_TOUCH_ETYPE_DOWN; +            if (touch->tag_prev) touch->evt |= EOS_TOUCH_ETYPE_UP; +            if (touch_tag && !eve_tag0) { +                eve_tag0 = touch_tag; +                tag0 = touch_tag; +                if (eve_touch_evt[touch_tag]) { +                    touch->evt |= eve_touch_evt[touch_tag]; +                    touch->tracker.tag = 0; +                    if (!(eve_int_mask & EVE_INT_CONVCOMPLETE)) { +                        eve_int_mask |= EVE_INT_CONVCOMPLETE; +                        eos_eve_write8(REG_INT_MASK, eve_int_mask); +                    } +                } +            }          } -        if (touch_tag != tag->value) { -            tag->value_prev = tag->value; -            tag->value = touch_tag; -            touch_tag_idx = 4; +    } else if (flags & EVE_INT_CONVCOMPLETE) { +        int touched = 0; + +        for (i=0; i<EVE_MAX_TOUCH; i++) { +            touch = &eve_touch[i]; + +            touch->evt &= (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); +            touch_xy = i < 4 ? eos_eve_read32(_reg_touch[i]) : (((uint32_t)eos_eve_read16(REG_CTOUCH_TOUCH4_X) << 16) | eos_eve_read16(REG_CTOUCH_TOUCH4_Y)); +            if (touch_xy == 0x80008000) { +                touch_tag = 0; +                touch->t = 0; +                touch->evt &= ~(EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); +            } else { +                touch->t = 1; +                touch->x = touch_xy >> 16; +                touch->y = touch_xy & 0xffff; +                if (!(touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK))) { +                    touch_tag = eos_eve_read8(_reg_tag[i]); +                } else { +                    touch_tag = touch->tag; +                } +                if (touch->evt & EOS_TOUCH_ETYPE_TRACK) { +                    touch_track = eos_eve_read32(_reg_track[i]); +                    touch->tracker.tag = touch_track & 0xffff; +                    touch->tracker.val = touch_track >> 16; +                } +                if (touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK)) { +                    touch_idx |= (1 << i); +                    touch_idx_max = i + 1; +                } +                touched = 1; +            } +            if (touch_tag != touch->tag) { +                touch->tag_prev = touch->tag; +                touch->tag = touch_tag; +                touch_idx |= (1 << i); +                touch_idx_max = i + 1; +                if (touch->tag) touch->evt |= EOS_TOUCH_ETYPE_DOWN; +                if (touch->tag_prev) touch->evt |= EOS_TOUCH_ETYPE_UP; +                if (eve_touch_evt[touch_tag]) { +                    touch->evt |= eve_touch_evt[touch_tag]; +                    touch->tracker.tag = 0; +                } +            }          } -        if (!eve_tag[1].t && !eve_tag[2].t && !eve_tag[3].t && !eve_tag[4].t) { +        if (!touched) { +            eve_tag0 = 0;              eve_multitouch = 0;              eve_int_mask &= ~EVE_INT_CONVCOMPLETE;              eos_eve_write8(REG_INT_MASK, eve_int_mask);          }      } -    if (touch_tag_idx != -1) render = 1; -    if (render) eve_renderer(eve_tag0, touch_tag_idx); - -    /* -    uint32_t track = eos_eve_read32(REG_TRACKER); -    printf("F:%x TAG:%x %x %x %x %x %x\n", flags, eve_tag0, eve_tag[0].value, eve_tag[1].value, eve_tag[2].value, eve_tag[3].value, eve_tag[4].value); -    if (flags & 0x04) { -        track_tag = track & 0xffff; -        track_val = track >> 16; +    if (touch_idx_max != -1) { +        for (i=0; i<touch_idx_max; i++) { +            if (touch_idx & 1) eve_renderer(tag0, i); +            touch_idx = touch_idx >> 1; +        }      } -    */      GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INT);      GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); -    return; +    eos_spi_dev_stop();  }  int eos_eve_init(void) { @@ -514,10 +542,33 @@ int eos_eve_init(void) {      return EOS_OK;  } -void eos_eve_set_renderer(eos_eve_fptr_t renderer) { +void eos_eve_set_renderer(eos_eve_fptr_t renderer, uint8_t flags) {      eve_renderer = renderer; +    eos_evtq_set_flags(EOS_EVT_UI | EVE_ETYPE_INT, flags); +} + +EOSTouch *eos_touch_evt(uint8_t tag0, int touch_idx, uint8_t tag_min, uint8_t tag_max, uint8_t *evt) { +    uint8_t tag; +    EOSTouch *ret = NULL; + +    *evt = 0; +    if ((touch_idx < 0) || (touch_idx > 4)) return ret; + +    ret = &eve_touch[touch_idx]; +    if ((tag0 < tag_min) || (tag0 > tag_max)) return ret; + +    tag = eve_touch[touch_idx].tag; +    if ((tag >= tag_min) && (tag <= tag_max)) *evt |= (eve_touch[touch_idx].evt & (EOS_TOUCH_ETYPE_DOWN | EOS_TOUCH_ETYPE_DRAG)); + +    tag = eve_touch[touch_idx].tag_prev; +    if ((tag >= tag_min) && (tag <= tag_max)) *evt |= (eve_touch[touch_idx].evt & EOS_TOUCH_ETYPE_UP); + +    tag = eve_touch[touch_idx].tracker.tag; +    if ((tag >= tag_min) && (tag <= tag_max)) *evt |= (eve_touch[touch_idx].evt & EOS_TOUCH_ETYPE_TRACK); + +    return ret;  } -EVETag *eos_eve_tag(void) { -    return eve_tag; +void eos_touch_set_evt(uint8_t tag, uint8_t evt) { +    eve_touch_evt[tag] = evt;  } diff --git a/code/fe310/eos/eve.h b/code/fe310/eos/eve.h index bf6c4e8..dc22f80 100644 --- a/code/fe310/eos/eve.h +++ b/code/fe310/eos/eve.h @@ -2,13 +2,23 @@  #include "eve_def.h" -typedef struct EVETag { +#define EOS_TOUCH_ETYPE_DOWN    0x01 +#define EOS_TOUCH_ETYPE_UP      0x02 +#define EOS_TOUCH_ETYPE_DRAG    0x04 +#define EOS_TOUCH_ETYPE_TRACK   0x08 + +typedef struct EOSTouch {      uint16_t x;      uint16_t y; -    uint8_t value; -    uint8_t value_prev; +    uint8_t tag; +    uint8_t tag_prev; +    uint8_t evt;      char t; -} EVETag; +    struct { +        uint16_t tag; +        uint16_t val; +    } tracker; +} EOSTouch;  typedef void (*eos_eve_fptr_t) (uint8_t, int); @@ -38,5 +48,6 @@ void eos_eve_cmd_burst_start(void);  void eos_eve_cmd_burst_end(void);  int eos_eve_init(void); -void eos_eve_set_renderer(eos_eve_fptr_t renderer); -EVETag *eos_eve_tag(void);
\ No newline at end of file +void eos_eve_set_renderer(eos_eve_fptr_t renderer, uint8_t flags); +EOSTouch *eos_touch_evt(uint8_t tag0, int touch_idx, uint8_t tag_min, uint8_t tag_max, uint8_t *evt); +void eos_touch_set_evt(uint8_t tag, uint8_t evt); diff --git a/code/fe310/eos/eve_kbd.c b/code/fe310/eos/eve_kbd.c new file mode 100644 index 0000000..00d5328 --- /dev/null +++ b/code/fe310/eos/eve_kbd.c @@ -0,0 +1,115 @@ +#include "eve.h" +#include "eve_kbd.h" + +#define FLAG_SHIFT  0x01 +#define FLAG_CTRL   0x02 +#define FLAG_FN     0x04 + +#define KEY_SHIFT   0x11 +#define KEY_CTRL    0x12 +#define KEY_FN      0x13 + +#define KEY_DEL     0x08 +#define KEY_RET     0x0a + +#define KEYS_Y      575 +#define KEYS_FSIZE  29 +#define KEYS_HEIGHT 40 +#define KEYS_RSIZE  45 + +void eos_kbd_init(EOSKbd *kbd, eos_kbd_fptr_t key_down_f, uint32_t mem_addr, uint32_t *mem_next) { +    eos_eve_write16(REG_CMD_DL, 0); +    eos_kbd_update(kbd); +    eos_eve_cmd_exec(1); +    kbd->mem_addr = mem_addr; +    kbd->mem_size = eos_eve_read16(REG_CMD_DL); +    kbd->key_modifier = 0; +    kbd->key_count = 0; +    kbd->key_down = 0; +    kbd->key_down_f = key_down_f; +    eos_eve_cmd(CMD_MEMCPY, "www", kbd->mem_addr, EVE_RAM_DL, kbd->mem_size); +    eos_eve_cmd_exec(1); +    *mem_next = kbd->mem_addr + kbd->mem_size; +} + +void eos_kbd_draw(EOSKbd *kbd, uint8_t tag0, int touch_idx) { +    uint8_t evt; +    EOSTouch *t = eos_touch_evt(tag0, touch_idx, 1, 127, &evt); + +    if (t && evt) { +        if (evt & EOS_TOUCH_ETYPE_DOWN) { +            uint8_t _tag = t->tag; + +            if (_tag >= KEY_SHIFT && _tag <= KEY_FN) { +                if (touch_idx == 0) { +                    uint8_t f = (1 << (_tag - KEY_SHIFT)); + +                    kbd->key_modifier = f; +                    kbd->key_modifier_sticky &= f; +                    kbd->key_modifier_lock &= f; +                    if (kbd->key_modifier_lock & f) { +                        kbd->key_modifier_lock &= ~f; +                    } else if (kbd->key_modifier_sticky & f) { +                        kbd->key_modifier_sticky &= ~f; +                        kbd->key_modifier_lock |= f; +                    } else { +                        kbd->key_modifier_sticky |= f; +                    } +                } +            } else { +                kbd->key_count++; +                kbd->key_down = _tag; +                if (kbd->key_down_f) { +                    int c = _tag; + +                    if ((kbd->key_modifier & FLAG_CTRL) && (_tag >= '?') && (_tag <= '_')) c = (_tag - '@') & 0x7f; +                    kbd->key_down_f(c); +                } +            } +        } +        if (evt & EOS_TOUCH_ETYPE_UP) { +            uint8_t _tag = t->tag_prev; + +            if (_tag >= KEY_SHIFT && _tag <= KEY_FN) { +                if (touch_idx == 0) { +                    uint8_t f = (1 << (_tag - KEY_SHIFT)); + +                    if (!((kbd->key_modifier_lock | kbd->key_modifier_sticky) & f)) { +                        kbd->key_modifier &= ~f; +                    } +                } +            } else { +                if (kbd->key_count) kbd->key_count--; +                if (!kbd->key_count) kbd->key_down = 0; +                if (kbd->key_modifier_sticky) { +                    if (touch_idx == 0) kbd->key_modifier &= ~kbd->key_modifier_sticky; +                    kbd->key_modifier_sticky = 0; +                } +            } +        } +        eos_kbd_update(kbd); +    } else { +        eos_eve_cmd(CMD_APPEND, "ww", kbd->mem_addr, kbd->mem_size); +    } +} + +void eos_kbd_update(EOSKbd *kbd) { +    eos_eve_cmd_dl(SAVE_CONTEXT()); +    eos_eve_cmd(CMD_KEYS, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 0, 480, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & (FLAG_FN | FLAG_SHIFT) ? "!@#$%^&*()" : (kbd->key_modifier & FLAG_CTRL ? " @[\\]^_?  " : "1234567890")); +    eos_eve_cmd(CMD_KEYS, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 1, 480, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & FLAG_FN ? "-_=+[]{}\\|" : kbd->key_modifier & (FLAG_SHIFT | FLAG_CTRL) ? "QWERTYUIOP" : "qwertyuiop"); +    eos_eve_cmd(CMD_KEYS, "hhhhhhs", 24, KEYS_Y + KEYS_RSIZE * 2, 432, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & FLAG_FN ? "`~   ;:'\"" : kbd->key_modifier & (FLAG_SHIFT | FLAG_CTRL) ? "ASDFGHJKL" : "asdfghjkl"); +    eos_eve_cmd(CMD_KEYS, "hhhhhhs", 72, KEYS_Y + KEYS_RSIZE * 3, 335, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & FLAG_FN ? " ,.<>/?" : kbd->key_modifier & (FLAG_SHIFT | FLAG_CTRL) ? "ZXCVBNM" : "zxcvbnm"); +    eos_eve_cmd_dl(TAG(KEY_SHIFT)); +    eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 3, 69, KEYS_HEIGHT, 21, kbd->key_modifier & FLAG_SHIFT ? EVE_OPT_FLAT : 0, "shift"); +    eos_eve_cmd_dl(TAG(KEY_DEL)); +    eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 410, KEYS_Y + KEYS_RSIZE * 3, 70, KEYS_HEIGHT, 21, kbd->key_down == KEY_DEL ? EVE_OPT_FLAT : 0, "del"); +    eos_eve_cmd_dl(TAG(KEY_FN)); +    eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 4, 69, KEYS_HEIGHT, 21, kbd->key_modifier & FLAG_FN ? EVE_OPT_FLAT : 0, "fn"); +    eos_eve_cmd_dl(TAG(KEY_CTRL)); +    eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 72, KEYS_Y + KEYS_RSIZE * 4, 69, KEYS_HEIGHT, 21, kbd->key_modifier & FLAG_CTRL ? EVE_OPT_FLAT : 0, "ctrl"); +    eos_eve_cmd_dl(TAG(' ')); +    eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 144, KEYS_Y + KEYS_RSIZE * 4, 263, KEYS_HEIGHT, 21, kbd->key_down == ' ' ? EVE_OPT_FLAT : 0, ""); +    eos_eve_cmd_dl(TAG(KEY_RET)); +    eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 410, KEYS_Y + KEYS_RSIZE * 4, 69, KEYS_HEIGHT, 21, kbd->key_down == KEY_RET ? EVE_OPT_FLAT : 0, "ret"); +    eos_eve_cmd_dl(RESTORE_CONTEXT()); +}
\ No newline at end of file diff --git a/code/fe310/eos/eve_kbd.h b/code/fe310/eos/eve_kbd.h new file mode 100644 index 0000000..60a2ff2 --- /dev/null +++ b/code/fe310/eos/eve_kbd.h @@ -0,0 +1,18 @@ +#include <stdint.h> + +typedef void (*eos_kbd_fptr_t) (int); + +typedef struct EOSKbd { +    uint32_t mem_addr; +    uint16_t mem_size; +    uint8_t key_count; +    uint8_t key_down; +    uint8_t key_modifier; +    uint8_t key_modifier_sticky; +    uint8_t key_modifier_lock; +    eos_kbd_fptr_t key_down_f; +} EOSKbd; + +void eos_kbd_init(EOSKbd *kbd, eos_kbd_fptr_t key_down_f, uint32_t mem_addr, uint32_t *mem_next); +void eos_kbd_draw(EOSKbd *kbd, uint8_t tag0, int touch_idx); +void eos_kbd_update(EOSKbd *kbd);
\ No newline at end of file diff --git a/code/fe310/eos/eve_text.c b/code/fe310/eos/eve_text.c index 4e343a0..93e628c 100644 --- a/code/fe310/eos/eve_text.c +++ b/code/fe310/eos/eve_text.c @@ -1,100 +1,180 @@  #include "eve.h"  #include "eve_text.h" -static int _line_diff(EVEText *box, int line) { -    if (line > box->line_idx) { -        return line - box->line_idx; -    } else { -        return box->buf_line_h - box->line_idx + line; -    } -} +#define TEXT_ATTR   0x0A +#define TEXT_CRSR   0x02DB + +#define LINE_IDX_ADD(l1,l2,s)       (((((l1) + (l2)) % (s)) + (s)) % (s)) +#define LINE_IDX_SUB(l1,l2,s)       (((((l1) - (l2)) % (s)) + (s)) % (s)) -static void _line_scroll(EVEText *box) { +#define LINE_IDX_LTE(l1,l2,s,h)     (LINE_IDX_SUB(l2,l1,s) <= (s) - (h)) +#define LINE_IDX_DIFF(l1,l2,s)      ((l1) > (l2) ? (l1) - (l2) : (s) - (l2) + (l1)) + +static void scroll1(EOSText *box) {      box->line_idx = (box->line_idx + 1) % box->buf_line_h;      eos_eve_cmd(CMD_MEMSET, "www", box->buf_addr + box->buf_idx, 0x0, box->w * 2);      eos_eve_cmd_exec(1); -    eos_eve_text_update(box); +    box->dirty = 1;  } -void eos_eve_text_init(EVEText *box, int x, int y, int w, int h, uint8_t bitmap_handle, uint32_t mem_addr, int buf_line_h, uint32_t *mem_next) { +void eos_text_init(EOSText *box, int x, int y, int w, int h, double scale_x, double scale_y, uint8_t tag, int buf_line_h, uint32_t mem_addr, uint32_t *mem_next) {      box->x = x;      box->y = y;      box->w = w;      box->h = h; -    box->bitmap_handle = bitmap_handle; +    box->tag = tag; +    box->transform_a = 256/scale_x; +    box->transform_e = 256/scale_y; +    box->ch_w = scale_x * 8; +    box->ch_h = scale_y * 16; +    box->dl_size = 17;      box->buf_addr = mem_addr;      box->buf_line_h = buf_line_h;      box->buf_idx = 0;      box->line_idx = 0; +    if (box->transform_a != 256) { +        box->dl_size += 1; +    } +    if (box->transform_e != 256) { +        box->dl_size += 1; +    } + +    eos_touch_set_evt(tag, EOS_TOUCH_ETYPE_DRAG);      eos_eve_cmd(CMD_MEMSET, "www", mem_addr, 0x0, w * 2 * buf_line_h);      eos_eve_cmd_exec(1); -    eos_eve_text_update(box); -    *mem_next = box->buf_addr + box->w * 2 * box->buf_line_h + 12 * 4; +    eos_text_update(box, -1); +    *mem_next = box->buf_addr + box->w * 2 * box->buf_line_h + box->dl_size * 4;  } -void eos_eve_text_draw(EVEText *box) { -    eos_eve_cmd(CMD_APPEND, "ww", box->buf_addr + box->w * 2 * box->buf_line_h, 12 * 4); +void eos_text_draw(EOSText *box, uint8_t tag0, int touch_idx) { +    static int y0; +    static int line_idx = -1; +    static int line_idx_last; +    uint8_t evt; +    EOSTouch *t = eos_touch_evt(tag0, touch_idx, box->tag, box->tag, &evt); + +    if (t && evt) { +        if (evt & EOS_TOUCH_ETYPE_DOWN) { +            y0 = t->y; +            if (line_idx < 0) { +                line_idx = box->line_idx; +                line_idx_last = line_idx; +            } +        } +        if (evt & EOS_TOUCH_ETYPE_UP) { +            line_idx = line_idx_last; +        } +        if (evt & EOS_TOUCH_ETYPE_DRAG) { +            int _line_idx = LINE_IDX_ADD(line_idx, (y0 - t->y) / box->ch_h, box->buf_line_h); +            if (LINE_IDX_LTE(_line_idx, box->line_idx, box->buf_line_h, box->h)) { +                eos_text_update(box, _line_idx); +                line_idx_last = _line_idx; +            } +        } +    } else if (line_idx >= 0) { +        line_idx = -1; +        box->dirty = 1; +    } + +    if (box->dirty) { +        eos_text_update(box, -1); +        box->dirty = 0; +    } +    eos_eve_cmd(CMD_APPEND, "ww", box->buf_addr + box->w * 2 * box->buf_line_h, box->dl_size * 4);  } -void eos_eve_text_update(EVEText *box) { +void eos_text_update(EOSText *box, int line_idx) {      int text_h1;      int text_h2; -    if (box->line_idx + box->h > box->buf_line_h) { -        text_h1 = box->buf_line_h - box->line_idx; +    if (line_idx < 0) line_idx = box->line_idx; + +    if (line_idx + box->h > box->buf_line_h) { +        text_h1 = box->buf_line_h - line_idx;          text_h2 = box->h - text_h1;      } else {          text_h1 = box->h;          text_h2 = 0;      }      eos_eve_dl_start(box->buf_addr + box->w * 2 * box->buf_line_h); -    eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle)); -    eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr + box->line_idx * box->w * 2)); + +    eos_eve_dl_write(SAVE_CONTEXT()); +    eos_eve_dl_write(BEGIN(EVE_BITMAPS)); +    eos_eve_dl_write(TAG(box->tag)); +    eos_eve_dl_write(VERTEX_FORMAT(0)); +    eos_eve_dl_write(BITMAP_HANDLE(15)); +    if (box->transform_a != 256) { +        eos_eve_dl_write(BITMAP_TRANSFORM_A(box->transform_a)); +    } +    if (box->transform_e != 256) { +        eos_eve_dl_write(BITMAP_TRANSFORM_E(box->transform_e)); +    } +    eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr + line_idx * box->w * 2));      eos_eve_dl_write(BITMAP_LAYOUT(EVE_TEXTVGA, box->w * 2, text_h1)); -    eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * 8, text_h1 * 16)); +    eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * box->ch_w, text_h1 * box->ch_h)); +    eos_eve_dl_write(BITMAP_SIZE_H(box->w * box->ch_w, text_h1 * box->ch_h)); +    eos_eve_dl_write(VERTEX2F(box->x, box->y));      if (text_h2) { -        eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle+1));          eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr));          eos_eve_dl_write(BITMAP_LAYOUT(EVE_TEXTVGA, box->w * 2, text_h2)); -        eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * 8, text_h2 * 16)); +        eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * box->ch_w, text_h2 * box->ch_h)); +        eos_eve_dl_write(BITMAP_SIZE_H(box->w * box->ch_w, text_h2 * box->ch_h)); +        eos_eve_dl_write(VERTEX2F(box->x, box->y + text_h1 * box->ch_h));      } else {          eos_eve_dl_write(NOP());          eos_eve_dl_write(NOP());          eos_eve_dl_write(NOP());          eos_eve_dl_write(NOP()); -    } - -    eos_eve_dl_write(BEGIN(EVE_BITMAPS)); -    eos_eve_dl_write(VERTEX2II(box->x, box->y, 0, 0)); -    if (text_h2) { -        eos_eve_dl_write(VERTEX2II(box->x, box->y + text_h1 * 16, 1, 0)); -    } else {          eos_eve_dl_write(NOP());      } +      eos_eve_dl_write(END()); +    eos_eve_dl_write(RESTORE_CONTEXT());  } -void eos_eve_text_putc(EVEText *box, int c) { +void eos_text_putc(EOSText *box, int c) {      int line_c, line_n; -    line_c = box->buf_idx / 2 / box->w; +    switch (c) { +        case '\b': +            eos_text_backspace(box); +            break; +        case '\r': +        case '\n': +            eos_text_newline(box); +            break; +        default: +            line_c = box->buf_idx / 2 / box->w; -    eos_eve_write16(box->buf_addr + box->buf_idx, 0x0A00 | (c & 0xff)); -    box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2); +            eos_eve_write16(box->buf_addr + box->buf_idx, 0x0200 | (c & 0xff)); +            box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2); +            eos_eve_write16(box->buf_addr + box->buf_idx, TEXT_CRSR); -    line_n = box->buf_idx / 2 / box->w; -    if ((line_c != line_n) && (_line_diff(box, line_n) == box->h)) { -        _line_scroll(box); +            line_n = box->buf_idx / 2 / box->w; +            if ((line_c != line_n) && (LINE_IDX_DIFF(line_n, box->line_idx, box->buf_line_h) == box->h)) scroll1(box); +            break;      }  } -void eos_eve_text_newline(EVEText *box) { +void eos_text_newline(EOSText *box) {      int line = (box->buf_idx / 2 / box->w + 1) % box->buf_line_h; + +    eos_eve_write16(box->buf_addr + box->buf_idx, 0);      box->buf_idx = line * box->w * 2; -    if (_line_diff(box, line) == box->h) { -        _line_scroll(box); +    if (LINE_IDX_DIFF(line, box->line_idx, box->buf_line_h) == box->h) scroll1(box); +    eos_eve_write16(box->buf_addr + box->buf_idx, TEXT_CRSR); +} + +void eos_text_backspace(EOSText *box) { +    uint16_t c; + +    eos_eve_write16(box->buf_addr + box->buf_idx, 0); +    box->buf_idx = (box->buf_idx - 2) % (box->buf_line_h * box->w * 2); +    if (eos_eve_read16(box->buf_addr + box->buf_idx) == 0) { +        box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2);      } +    eos_eve_write16(box->buf_addr + box->buf_idx, TEXT_CRSR);  }
\ No newline at end of file diff --git a/code/fe310/eos/eve_text.h b/code/fe310/eos/eve_text.h index 350be45..794f430 100644 --- a/code/fe310/eos/eve_text.h +++ b/code/fe310/eos/eve_text.h @@ -1,19 +1,26 @@  #include <stdint.h> -typedef struct EVEText { +typedef struct EOSText {      int x;      int y;      int w;      int h; -    uint32_t buf_addr;      int buf_line_h;      int buf_idx;      int line_idx; -    uint8_t bitmap_handle; -} EVEText; +    uint32_t buf_addr; +    uint16_t transform_a; +    uint16_t transform_e; +    uint8_t tag; +    uint8_t ch_h; +    uint8_t ch_w; +    uint8_t dl_size; +    char dirty; +} EOSText; -void eos_eve_text_init(EVEText *box, int x, int y, int w, int h, uint8_t bitmap_handle, uint32_t mem_addr, int buf_line_h, uint32_t *mem_next); -void eos_eve_text_draw(EVEText *box); -void eos_eve_text_update(EVEText *box); -void eos_eve_text_putc(EVEText *box, int c); -void eos_eve_text_newline(EVEText *box); +void eos_text_init(EOSText *box, int x, int y, int w, int h, double scale_x, double scale_y, uint8_t tag, int buf_line_h, uint32_t mem_addr, uint32_t *mem_next); +void eos_text_draw(EOSText *box, uint8_t tag0, int touch_idx); +void eos_text_update(EOSText *box, int line_idx); +void eos_text_putc(EOSText *box, int c); +void eos_text_newline(EOSText *box); +void eos_text_backspace(EOSText *box); diff --git a/code/fe310/eos/msgq.c b/code/fe310/eos/msgq.c index 2b20f31..07ea70f 100644 --- a/code/fe310/eos/msgq.c +++ b/code/fe310/eos/msgq.c @@ -10,7 +10,6 @@  #define IDX_LT(a,b)             ((uint8_t)((uint8_t)(a) - (uint8_t)(b)) > IDX_HALF)  #define IDX_LTE(a,b)            ((uint8_t)((uint8_t)(b) - (uint8_t)(a)) < IDX_HALF) -  void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) {      msgq->idx_r = 0;      msgq->idx_w = 0;  | 
