diff options
Diffstat (limited to 'fmdsp')
| -rw-r--r-- | fmdsp/fmdsp-pacc.c | 266 | ||||
| -rw-r--r-- | fmdsp/fmdsp-pacc.h | 33 | 
2 files changed, 279 insertions, 20 deletions
| diff --git a/fmdsp/fmdsp-pacc.c b/fmdsp/fmdsp-pacc.c index c55e6f2..912c7f7 100644 --- a/fmdsp/fmdsp-pacc.c +++ b/fmdsp/fmdsp-pacc.c @@ -4,19 +4,17 @@  #include "fmdriver/fmdriver.h"  #include "libopna/opna.h" -enum { -  FMDSP_PALETTE_COLORS = 10, -}; -  #include "fmdsp_sprites.h"  #include <stdlib.h>  #include <string.h>  enum { -  PC98_W = 640, -  PC98_H = 400, -  CHECKER_H = (16+3)*3+8, -  CHECKER_Y = PC98_H-CHECKER_H, +  FADEDELTA = 16, +}; + +enum { +  KEY_S_OFF_Y = 4, +  LOGO_W = LOGO_FM_W + 2 + LOGO_DS_W + 2 + LOGO_P_W,  };  static const struct { @@ -46,7 +44,7 @@ static const struct {    {FMDRIVER_TRACKTYPE_PPZ8, 8},  }; -static const uint8_t track_disp_table_default[] = { +static const uint8_t track_disp_table_opna[] = {    FMDRIVER_TRACK_FM_1,    FMDRIVER_TRACK_FM_2,    FMDRIVER_TRACK_FM_3, @@ -84,15 +82,38 @@ static const uint8_t track_disp_table_ppz8[] = {    FMDRIVER_TRACK_ADPCM,    FMDRIVER_TRACK_NUM,  }; +static const uint8_t track_disp_table_13[] = { +  FMDRIVER_TRACK_FM_1, +  FMDRIVER_TRACK_FM_2, +  FMDRIVER_TRACK_FM_3, +  FMDRIVER_TRACK_FM_3_EX_1, +  FMDRIVER_TRACK_FM_3_EX_2, +  FMDRIVER_TRACK_FM_3_EX_3, +  FMDRIVER_TRACK_FM_4, +  FMDRIVER_TRACK_FM_5, +  FMDRIVER_TRACK_FM_6, +  FMDRIVER_TRACK_SSG_1, +  FMDRIVER_TRACK_SSG_2, +  FMDRIVER_TRACK_SSG_3, +  FMDRIVER_TRACK_ADPCM, +  FMDRIVER_TRACK_NUM, +};  struct fmdsp_pacc {    struct pacc_ctx *pc;    struct pacc_vtable pacc; -  struct pacc_tex *tex_font, *tex_checker, *tex_key_left, *tex_key_right, *tex_key_mask, *tex_key_bg, *tex_num, *tex_dt_sign, *tex_solid, *tex_vertical, *tex_horizontal; -  struct pacc_buf *buf_font_2, *buf_font_2_d, *buf_font_1, *buf_font_1_d, *buf_checker, *buf_key_left, *buf_key_right, *buf_key_mask, *buf_key_mask_sub, *buf_key_bg, *buf_num, *buf_dt_sign, *buf_solid_2, *buf_solid_3, *buf_solid_7, *buf_vertical_2, *buf_vertical_3, *buf_vertical_7; +  struct pacc_tex *tex_font, *tex_checker, *tex_key_left, *tex_key_right, *tex_key_mask, *tex_key_bg, *tex_num, *tex_dt_sign, *tex_solid, *tex_vertical, *tex_horizontal, *tex_logo; +  struct pacc_buf *buf_font_2, *buf_font_2_d, *buf_font_1, *buf_font_1_d, *buf_checker, *buf_key_left, *buf_key_right, *buf_key_mask, *buf_key_mask_sub, *buf_key_bg, *buf_num, *buf_dt_sign, *buf_solid_2, *buf_solid_3, *buf_solid_7, *buf_vertical_2, *buf_vertical_3, *buf_vertical_7, *buf_logo;    struct opna *opna;    struct fmdriver_work *work; +  uint8_t curr_palette[FMDSP_PALETTE_COLORS*3]; +  uint8_t target_palette[FMDSP_PALETTE_COLORS*3]; +  enum fmdsp_left_mode lmode; +  enum fmdsp_right_mode rmode; +  bool mode_changed; +  bool masked[FMDRIVER_TRACK_NUM]; +  bool masked_rhythm;  };  static struct pacc_tex *tex_from_font( @@ -134,6 +155,7 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {        fp->pacc.buf_delete(fp->buf_vertical_2);        fp->pacc.buf_delete(fp->buf_vertical_3);        fp->pacc.buf_delete(fp->buf_vertical_7); +      fp->pacc.buf_delete(fp->buf_logo);        fp->pacc.tex_delete(fp->tex_font);        fp->pacc.tex_delete(fp->tex_checker);        fp->pacc.tex_delete(fp->tex_key_left); @@ -145,6 +167,7 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {        fp->pacc.tex_delete(fp->tex_solid);        fp->pacc.tex_delete(fp->tex_vertical);        fp->pacc.tex_delete(fp->tex_horizontal); +      fp->pacc.tex_delete(fp->tex_logo);      }      free(fp);    } @@ -198,6 +221,19 @@ static void init_track_without_key(        x+TDETAIL_M_X, y+6, "M:");  } +static void init_track_13(struct fmdsp_pacc *fp, int x) { +  const uint8_t *track_table = track_disp_table_13; +  for (int i = 0; i < 13; i++) { +    int t = track_table[i]; +    init_track_without_key(fp, t, x, TRACK_H_S*i); +    fp->pacc.buf_rect_off(fp->pc, fp->buf_key_left, x+KEY_LEFT_X, TRACK_H_S*i+KEY_Y, KEY_LEFT_W, KEY_H_S, 0, KEY_S_OFF_Y); +    for (int j = 0; j < KEY_OCTAVES; j++) { +      fp->pacc.buf_rect_off(fp->pc, fp->buf_key_bg, x+KEY_X+KEY_W*j, TRACK_H_S*i+KEY_Y, KEY_W, KEY_H_S, 0, KEY_S_OFF_Y); +    } +    fp->pacc.buf_rect_off(fp->pc, fp->buf_key_right, x+KEY_X+KEY_W*KEY_OCTAVES, TRACK_H_S*i+KEY_Y, KEY_RIGHT_W, KEY_H_S, 0, KEY_S_OFF_Y); +  } +} +  static void init_track_10(struct fmdsp_pacc *fp, const uint8_t *track_table, int x) {    for (int i = 0; i < 10; i++) {      int t = track_table[i]; @@ -317,6 +353,33 @@ static void update_track_without_key(        x+BAR_X+BAR_W*(track->ticks>>2), y+BAR_Y, BAR_W, BAR_H);  } +static void update_track_13(struct fmdsp_pacc *fp, int x) { +  const uint8_t *track_table = track_disp_table_13; +  for (int it = 0; it < 13; it++) { +    int t = track_table[it]; +    const struct fmdriver_track_status *track = &fp->work->track_status[t]; +    update_track_without_key(fp, t, x, TRACK_H_S*it); +    for (int i = 0; i < KEY_OCTAVES; i++) { +      if (track->playing || track->info == FMDRIVER_TRACK_INFO_SSGEFF) { +        if ((track->actual_key >> 4) == i) { +          fp->pacc.buf_rect_off( +              fp->pc, fp->buf_key_mask_sub, +              x+KEY_X+KEY_W*i, TRACK_H_S*it+KEY_Y, +              KEY_W, KEY_H_S, +              0, KEY_H*(track->actual_key&0xf) + KEY_S_OFF_Y); +        } +        if ((track->key >> 4) == i) { +          fp->pacc.buf_rect_off( +              fp->pc, fp->buf_key_mask, +              x+KEY_X+KEY_W*i, TRACK_H_S*it+KEY_Y, +              KEY_W, KEY_H_S, +              0, KEY_H*(track->key&0xf) + KEY_S_OFF_Y); +        } +      } +    } +  } +} +  static void update_track_10(struct fmdsp_pacc *fp, const uint8_t *track_table, int x) {    for (int it = 0; it < 10; it++) {      int t = track_table[it]; @@ -367,13 +430,15 @@ struct fmdsp_pacc *fmdsp_pacc_init(    fp->tex_num = fp->pacc.gen_tex(fp->pc, NUM_W, NUM_H*11);    if (!fp->tex_num) goto err;    fp->tex_dt_sign = fp->pacc.gen_tex(fp->pc, DT_SIGN_W, DT_SIGN_H*3); -  if (!fp->tex_num) goto err; +  if (!fp->tex_dt_sign) goto err;    fp->tex_solid = fp->pacc.gen_tex(fp->pc, 1, 1); -  if (!fp->tex_num) goto err; +  if (!fp->tex_solid) goto err;    fp->tex_vertical = fp->pacc.gen_tex(fp->pc, 2, 1); -  if (!fp->tex_num) goto err; +  if (!fp->tex_vertical) goto err;    fp->tex_horizontal = fp->pacc.gen_tex(fp->pc, 1, 2); -  if (!fp->tex_num) goto err; +  if (!fp->tex_horizontal) goto err; +  fp->tex_logo = fp->pacc.gen_tex(fp->pc, LOGO_W, LOGO_H); +  if (!fp->tex_logo) goto err;    uint8_t *buf;    buf = fp->pacc.tex_lock(fp->tex_checker); @@ -415,6 +480,22 @@ struct fmdsp_pacc *fmdsp_pacc_init(      }    }    fp->pacc.tex_unlock(fp->tex_key_mask); +  buf = fp->pacc.tex_lock(fp->tex_logo); +  for (int y = 0; y < LOGO_H; y++) { +    memcpy( +        buf + y*LOGO_W, +        s_logo_fm + y*LOGO_FM_W, +        LOGO_FM_W); +    memcpy( +        buf + y*LOGO_W + LOGO_FM_W + 2, +        s_logo_ds + y*LOGO_DS_W, +        LOGO_DS_W); +    memcpy( +        buf + y*LOGO_W + LOGO_FM_W + 2 + LOGO_DS_W + 2, +        s_logo_p + y*LOGO_P_W, +        LOGO_P_W); +  } +  fp->pacc.tex_unlock(fp->tex_logo);    fp->buf_font_1 = fp->pacc.gen_buf(fp->pc, fp->tex_font, pacc_buf_mode_static);    if (!fp->buf_font_1) goto err; @@ -452,19 +533,84 @@ struct fmdsp_pacc *fmdsp_pacc_init(    if (!fp->buf_vertical_3) goto err;    fp->buf_vertical_7 = fp->pacc.gen_buf(fp->pc, fp->tex_vertical, pacc_buf_mode_stream);    if (!fp->buf_vertical_7) goto err; +  fp->buf_logo = fp->pacc.gen_buf(fp->pc, fp->tex_logo, pacc_buf_mode_static); +  if (!fp->buf_logo) goto err;    fp->pacc.buf_rect_off(fp->pc, fp->buf_checker, 1, CHECKER_Y, PC98_W-1, CHECKER_H, 1, 0);    fp->pacc.buf_rect(fp->pc, fp->buf_checker, 0, CHECKER_Y+2, 1, CHECKER_H-4); -  fp->pacc.palette(fp->pc, s_palettes[5], FMDSP_PALETTE_COLORS); -  init_track_10(fp, track_disp_table_default, 0); -  init_track_10(fp, track_disp_table_ppz8, 320); +  memcpy(fp->target_palette, s_palettes[0], sizeof(fp->target_palette)); +  fp->mode_changed = true;    return fp;  err:    fmdsp_pacc_release(fp);    return 0;  } +static void mode_update(struct fmdsp_pacc *fp) { +  fp->pacc.buf_clear(fp->buf_font_1); +  fp->pacc.buf_clear(fp->buf_font_2); +  fp->pacc.buf_clear(fp->buf_key_left); +  fp->pacc.buf_clear(fp->buf_key_right); +  fp->pacc.buf_clear(fp->buf_key_bg); +  fp->pacc.buf_clear(fp->buf_logo); +  switch (fp->lmode) { +  case FMDSP_LEFT_MODE_OPNA: +    init_track_10(fp, track_disp_table_opna, 0); +    break; +  case FMDSP_LEFT_MODE_OPN: +    init_track_10(fp, track_disp_table_opn, 0); +    break; +  case FMDSP_LEFT_MODE_13: +    init_track_13(fp, 0); +    break; +  case FMDSP_LEFT_MODE_PPZ8: +    init_track_10(fp, track_disp_table_ppz8, 0); +    break; +  default: +    break; +  } +  switch (fp->rmode) { +  case FMDSP_RIGHT_MODE_DEFAULT: +    fp->pacc.buf_rect( +        fp->pc, fp->buf_logo, +        LOGO_FM_X, LOGO_Y, LOGO_W, LOGO_H); +    break; +  case FMDSP_RIGHT_MODE_TRACK_INFO: +    break; +  case FMDSP_RIGHT_MODE_PPZ8: +    init_track_10(fp, track_disp_table_ppz8, 320); +    break; +  default: +    break; +  } +} +  void fmdsp_pacc_render(struct fmdsp_pacc *fp) { +  if (memcmp(fp->curr_palette, fp->target_palette, sizeof(fp->target_palette))) { +    for (int i = 0; i < FMDSP_PALETTE_COLORS*3; i++) { +      uint8_t p = fp->curr_palette[i]; +      uint8_t t = fp->target_palette[i]; +      if (p < t) { +        if ((p + FADEDELTA) < t) { +          p += FADEDELTA; +        } else { +          p = t; +        } +      } else if (p > t) { +        if (p > (t + FADEDELTA)) { +          p -= FADEDELTA; +        } else { +          p = t; +        } +      } +      fp->curr_palette[i] = p; +    } +    fp->pacc.palette(fp->pc, fp->curr_palette, FMDSP_PALETTE_COLORS); +  } +  if (fp->mode_changed) { +    mode_update(fp); +    fp->mode_changed = false; +  }    fp->pacc.buf_clear(fp->buf_key_mask);    fp->pacc.buf_clear(fp->buf_key_mask_sub);    fp->pacc.buf_clear(fp->buf_font_1_d); @@ -477,9 +623,64 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {    fp->pacc.buf_clear(fp->buf_vertical_2);    fp->pacc.buf_clear(fp->buf_vertical_3);    fp->pacc.buf_clear(fp->buf_vertical_7); +  unsigned mask = 0; +  if (fp->opna) { +    mask = opna_get_mask(fp->opna); +  } +  fp->masked[FMDRIVER_TRACK_FM_1] = mask & LIBOPNA_CHAN_FM_1; +  fp->masked[FMDRIVER_TRACK_FM_2] = mask & LIBOPNA_CHAN_FM_2; +  fp->masked[FMDRIVER_TRACK_FM_3] = mask & LIBOPNA_CHAN_FM_3; +  fp->masked[FMDRIVER_TRACK_FM_3_EX_1] = mask & LIBOPNA_CHAN_FM_3; +  fp->masked[FMDRIVER_TRACK_FM_3_EX_2] = mask & LIBOPNA_CHAN_FM_3; +  fp->masked[FMDRIVER_TRACK_FM_3_EX_3] = mask & LIBOPNA_CHAN_FM_3; +  fp->masked[FMDRIVER_TRACK_FM_4] = mask & LIBOPNA_CHAN_FM_4; +  fp->masked[FMDRIVER_TRACK_FM_5] = mask & LIBOPNA_CHAN_FM_5; +  fp->masked[FMDRIVER_TRACK_FM_6] = mask & LIBOPNA_CHAN_FM_6; +  fp->masked[FMDRIVER_TRACK_SSG_1] = mask & LIBOPNA_CHAN_SSG_1; +  fp->masked[FMDRIVER_TRACK_SSG_2] = mask & LIBOPNA_CHAN_SSG_2; +  fp->masked[FMDRIVER_TRACK_SSG_3] = mask & LIBOPNA_CHAN_SSG_3; +  fp->masked[FMDRIVER_TRACK_ADPCM] = mask & LIBOPNA_CHAN_ADPCM; +  fp->masked_rhythm = (mask & LIBOPNA_CHAN_DRUM_ALL) == LIBOPNA_CHAN_DRUM_ALL; +  unsigned ppz8mask = 0; +  if (fp->work && fp->work->ppz8) { +    ppz8mask = ppz8_get_mask(fp->work->ppz8); +  } +  fp->masked[FMDRIVER_TRACK_PPZ8_1] = ppz8mask & (1u<<0); +  fp->masked[FMDRIVER_TRACK_PPZ8_2] = ppz8mask & (1u<<1); +  fp->masked[FMDRIVER_TRACK_PPZ8_3] = ppz8mask & (1u<<2); +  fp->masked[FMDRIVER_TRACK_PPZ8_4] = ppz8mask & (1u<<3); +  fp->masked[FMDRIVER_TRACK_PPZ8_5] = ppz8mask & (1u<<4); +  fp->masked[FMDRIVER_TRACK_PPZ8_6] = ppz8mask & (1u<<5); +  fp->masked[FMDRIVER_TRACK_PPZ8_7] = ppz8mask & (1u<<6); +  fp->masked[FMDRIVER_TRACK_PPZ8_8] = ppz8mask & (1u<<7);    if (fp->work) { -    update_track_10(fp, track_disp_table_default, 0); -    update_track_10(fp, track_disp_table_ppz8, 320); +    switch (fp->lmode) { +    case FMDSP_LEFT_MODE_OPNA: +      update_track_10(fp, track_disp_table_opna, 0); +      break; +    case FMDSP_LEFT_MODE_OPN: +      update_track_10(fp, track_disp_table_opn, 0); +      break; +    case FMDSP_LEFT_MODE_13: +      update_track_13(fp, 0); +      break; +    case FMDSP_LEFT_MODE_PPZ8: +      update_track_10(fp, track_disp_table_ppz8, 0); +      break; +    default: +      break; +    } +    switch (fp->rmode) { +    case FMDSP_RIGHT_MODE_DEFAULT: +      break; +    case FMDSP_RIGHT_MODE_TRACK_INFO: +      break; +    case FMDSP_RIGHT_MODE_PPZ8: +      update_track_10(fp, track_disp_table_ppz8, 320); +      break; +    default: +      break; +    }    }    fp->pacc.begin_clear(fp->pc);    fp->pacc.color(fp->pc, 1); @@ -502,6 +703,7 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {    fp->pacc.draw(fp->pc, fp->buf_key_left, pacc_mode_copy);    fp->pacc.draw(fp->pc, fp->buf_key_bg, pacc_mode_copy);    fp->pacc.draw(fp->pc, fp->buf_key_right, pacc_mode_copy); +  fp->pacc.draw(fp->pc, fp->buf_logo, pacc_mode_copy);    fp->pacc.color(fp->pc, 8);    fp->pacc.draw(fp->pc, fp->buf_key_mask_sub, pacc_mode_color_trans);    fp->pacc.color(fp->pc, 6); @@ -512,3 +714,27 @@ void fmdsp_pacc_set(struct fmdsp_pacc *fp, struct fmdriver_work *work, struct op    fp->work = work;    fp->opna = opna;  } + +void fmdsp_pacc_palette(struct fmdsp_pacc *fp, int p) { +  if (p < 0) return; +  if (p >= PALETTE_NUM) return; +  memcpy(fp->target_palette, s_palettes[p], sizeof(fp->target_palette)); +} + +enum fmdsp_left_mode fmdsp_pacc_left_mode(const struct fmdsp_pacc *fp) { +  return fp->lmode; +} + +enum fmdsp_right_mode fmdsp_pacc_right_mode(const struct fmdsp_pacc *fp) { +  return fp->rmode; +} + +void fmdsp_pacc_set_left_mode(struct fmdsp_pacc *fp, enum fmdsp_left_mode mode) { +  fp->lmode = mode; +  fp->mode_changed = true; +} + +void fmdsp_pacc_set_right_mode(struct fmdsp_pacc *fp, enum fmdsp_right_mode mode) { +  fp->rmode = mode; +  fp->mode_changed = true; +} diff --git a/fmdsp/fmdsp-pacc.h b/fmdsp/fmdsp-pacc.h index b5f1021..fb19b79 100644 --- a/fmdsp/fmdsp-pacc.h +++ b/fmdsp/fmdsp-pacc.h @@ -7,10 +7,43 @@ struct pacc_vtable;  struct fmdriver_work work;  struct opna opna; +enum { +  FMDSP_PALETTE_COLORS = 10, +}; + +enum { +  PC98_W = 640, +  PC98_H = 400, +  CHECKER_H = (16+3)*3+8, +  CHECKER_Y = PC98_H-CHECKER_H, +}; + +enum fmdsp_left_mode { +  FMDSP_LEFT_MODE_OPNA, // FM1, 2, 3, 4, 5, 6, SSG1, 2, 3, PCM +  FMDSP_LEFT_MODE_OPN,  // FM1, 2, 3, FMEX1, 2, 3, SSG1, 2, 3, PCM +  FMDSP_LEFT_MODE_13,   // FM1, 2, 3, FMEX1, 2, 3, FM4, 5, 6, SSG1, 2, 3, PCM +  FMDSP_LEFT_MODE_PPZ8, // PPZ8 1, 2, 3, 4, 5, 6, 7, 8, PCM +  FMDSP_LEFT_MODE_CNT +}; + +enum fmdsp_right_mode { +  FMDSP_RIGHT_MODE_DEFAULT, +  FMDSP_RIGHT_MODE_TRACK_INFO, +  FMDSP_RIGHT_MODE_PPZ8, +  FMDSP_RIGHT_MODE_CNT +}; +  struct fmdsp_pacc *fmdsp_pacc_init(      struct pacc_ctx *pc, const struct pacc_vtable *vtable);  void fmdsp_pacc_set(struct fmdsp_pacc *pacc, struct fmdriver_work *work, struct opna *opna);  void fmdsp_pacc_release(struct fmdsp_pacc *fp);  void fmdsp_pacc_render(struct fmdsp_pacc *fp); +void fmdsp_pacc_palette(struct fmdsp_pacc *fp, int p); + +enum fmdsp_left_mode fmdsp_pacc_left_mode(const struct fmdsp_pacc *fp); +void fmdsp_pacc_set_left_mode(struct fmdsp_pacc *fp, enum fmdsp_left_mode mode); +enum fmdsp_right_mode fmdsp_pacc_right_mode(const struct fmdsp_pacc *fp); +void fmdsp_pacc_set_right_mode(struct fmdsp_pacc *fp, enum fmdsp_right_mode mode); +  #endif // MYON_FMDSP_PACC_H_INCLUDED | 
