diff options
| -rw-r--r-- | fmdriver/fmdriver.h | 18 | ||||
| -rw-r--r-- | fmdriver/fmdriver_fmp.c | 55 | ||||
| -rw-r--r-- | fmdriver/fmdriver_fmp.h | 6 | ||||
| -rw-r--r-- | fmdriver/fmdriver_pmd.c | 12 | ||||
| -rw-r--r-- | fmdsp/fmdsp-pacc.c | 263 | ||||
| -rw-r--r-- | fmdsp/fmdsp-pacc.h | 7 | ||||
| -rw-r--r-- | fmdsp/fmdsp_sprites.h | 20 | ||||
| -rw-r--r-- | sdl/main.c | 18 | ||||
| -rw-r--r-- | sdl/unix/Makefile | 2 | 
9 files changed, 395 insertions, 6 deletions
| diff --git a/fmdriver/fmdriver.h b/fmdriver/fmdriver.h index b31c31e..ba36c3e 100644 --- a/fmdriver/fmdriver.h +++ b/fmdriver/fmdriver.h @@ -89,9 +89,23 @@ struct fmdriver_work {    const struct ppz8_functbl *ppz8_functbl;    struct ppz8 *ppz8; +  // if false, 3 line comment +  // if true, PMD memo mode +  bool comment_mode_pmd; +    // CP932 encoded -  //const char *title; -  char comment[3][FMDRIVER_TITLE_BUFLEN]; +  // may contain ANSI escape sequences +  // if !comment_mode_pmd: +  //   three lines, 0 <= line < 3 +  // if comment_mode_pmd: +  //   line 0: #Title +  //   line 1: #Composer +  //   line 2: #Arranger +  //   line 3: #Memo 1st line +  //      : +  //   line n: NULL +  const char *(*get_comment)(struct fmdriver_work *work, int line); +    // only single-byte uppercase cp932    char filename[FMDRIVER_TITLE_BUFLEN];    // always 8 characters and pad with ' ' diff --git a/fmdriver/fmdriver_fmp.c b/fmdriver/fmdriver_fmp.c index c57b975..54f6753 100644 --- a/fmdriver/fmdriver_fmp.c +++ b/fmdriver/fmdriver_fmp.c @@ -1,5 +1,6 @@  #include "fmdriver_fmp.h"
  #include "fmdriver_common.h"
 +#include <string.h>
  static uint8_t fmp_rand71(struct driver_fmp *fmp) {
    // on real PC-98, read from I/O port 0x71 (8253 Timer)
 @@ -3200,6 +3201,48 @@ static void fmp_opna_interrupt(struct fmdriver_work *work) {    }
  }
 +static void fmp_title(
 +    struct fmdriver_work *work,
 +    struct driver_fmp *fmp,
 +    uint16_t offset) {
 +  int l = 0;
 +  int li = 0;
 +  for (int si = 0;; si++) {
 +    if (l >= 3) {
 +      // Z8X
 +      fmp->pdzf.mode = 1;
 +      return;
 +    }
 +    if ((offset + si) >= fmp->datalen) {
 +      fmp->comment[l][0] = 0;
 +      return;
 +    }
 +    if (li >= FMP_COMMENT_BUFLEN) {
 +      fmp->comment[l][0] = 0;
 +      return;
 +    }
 +    uint8_t c = fmp->data[offset+si];
 +    if (c == '\r') {
 +      continue;
 +    } else if (c == '\n') {
 +      fmp->comment[l][li] = 0;
 +      li = 0;
 +      l++;
 +    } else {
 +      fmp->comment[l][li] = c;
 +      if (!c) return;
 +      li++;
 +    }
 +  }
 +}
 +
 +static void fmp_check_pdzf(struct driver_fmp *fmp) {
 +  for (int l = 0; l < 3; l++) {
 +    if (strstr((const char *)fmp->comment[l], "using PDZF")) fmp->pdzf.mode = 2;
 +  }
 +}
 +
 +/*
  // copy title string (CP932) to fmdriver_work struct,
  // and detect which PDZF(/Z8X) mode to use
  static void fmp_title(struct fmdriver_work *work,
 @@ -3289,6 +3332,7 @@ static void fmp_title(struct fmdriver_work *work,      }
    }
  }
 +*/
  bool fmp_load(struct driver_fmp *fmp,
                uint8_t *data, uint16_t datalen)
 @@ -3525,8 +3569,19 @@ bool fmp_load(struct driver_fmp *fmp,    return true;
  }
 +static const char *fmp_get_comment(struct fmdriver_work *work, int line) {
 +  if (line < 0) return 0;
 +  if (line >= 3) return 0;
 +  struct driver_fmp *fmp = work->driver;
 +  if (!fmp->comment[line][0]) return 0;
 +  return (const char *)fmp->comment[line];
 +}
 +
  void fmp_init(struct fmdriver_work *work, struct driver_fmp *fmp) {
    fmp_title(work, fmp, read16le(fmp->data)+4);
 +  fmp_check_pdzf(fmp);
 +  work->comment_mode_pmd = false;
 +  work->get_comment = fmp_get_comment;
    fmp_struct_init(work, fmp);
    fmp_init_parts(work, fmp);
    uint16_t fmtoneptr = fmp->datainfo.fmtoneptr;
 diff --git a/fmdriver/fmdriver_fmp.h b/fmdriver/fmdriver_fmp.h index ead8074..eb89b0b 100644 --- a/fmdriver/fmdriver_fmp.h +++ b/fmdriver/fmdriver_fmp.h @@ -39,6 +39,10 @@ enum {  };  enum { +  FMP_COMMENT_BUFLEN = 256, +}; + +enum {    FMP_DATA_FM_1,    FMP_DATA_FM_2,    FMP_DATA_FM_3, @@ -536,6 +540,8 @@ struct driver_fmp {      } rhythm[2];      uint8_t rhythm_current_note;    } pdzf; + +  uint8_t comment[3][FMP_COMMENT_BUFLEN];  };  // first: call fmp_load with zero_initialized struct driver_fmp and data diff --git a/fmdriver/fmdriver_pmd.c b/fmdriver/fmdriver_pmd.c index a57a916..343152b 100644 --- a/fmdriver/fmdriver_pmd.c +++ b/fmdriver/fmdriver_pmd.c @@ -5872,16 +5872,27 @@ void pmd_filenamecopy(char *dest, const char *src) {    dest[0] = 0;  } +static const char *pmd_get_comment(struct fmdriver_work *work, int line) { +  struct driver_pmd *pmd = work->driver; +  if (line < 0) return 0; +  const char *str = pmd_get_memo(pmd, line + 1); +  if (str && !*str) return 0; +  return str; +} +  void pmd_init(struct fmdriver_work *work,                struct driver_pmd *pmd) {    // TODO: reset ppz8    // 0f99    work->driver = pmd; +  work->comment_mode_pmd = true; +  work->get_comment = pmd_get_comment;    pmd_reset_opna(work, pmd);    pmd_reset_timer(work, pmd);    pmd->playing = true;    work->driver_opna_interrupt = pmd_opna_interrupt; +  /*    static const int memotable[3] = {1, 4, 5};    for (int i = 0; i < 3; i++) {      const char *title = pmd_get_memo(pmd, memotable[i]); @@ -5894,6 +5905,7 @@ void pmd_init(struct fmdriver_work *work,      }      work->comment[i][c] = 0;    } +  */    const char *pcmfile = pmd_get_memo(pmd, -2);    if (pcmfile) {      pmd_filenamecopy(pmd->ppzfile, pcmfile); diff --git a/fmdsp/fmdsp-pacc.c b/fmdsp/fmdsp-pacc.c index bf76693..02b6e17 100644 --- a/fmdsp/fmdsp-pacc.c +++ b/fmdsp/fmdsp-pacc.c @@ -108,8 +108,64 @@ static const uint8_t track_disp_table_13[] = {  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, *tex_logo, *tex_ver, *tex_text, *tex_tri, *tex_curl_left, *tex_curl_right, *tex_play, *tex_stop, *tex_pause, *tex_fade, *tex_ff, *tex_rew, *tex_floppy, *tex_circle, *tex_panpot; -  struct pacc_buf *buf_font_7, *buf_font_2, *buf_font_2_d, *buf_font_1, *buf_font_1_d, *buf_checker, *buf_checker_1, *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_2_d, *buf_solid_3, *buf_solid_3_d, *buf_solid_7, *buf_solid_7_d, *buf_vertical_2, *buf_vertical_3, *buf_vertical_7, *buf_horizontal_2_d, *buf_horizontal_3, *buf_horizontal_7_d, *buf_logo, *buf_ver, *buf_text, *buf_tri, *buf_tri_7, *buf_curl_left, *buf_curl_right, *buf_play, *buf_stop, *buf_pause, *buf_fade, *buf_ff, *buf_rew, *buf_floppy, *buf_circle, *buf_panpot_1_d, *buf_panpot_5_d; +  struct pacc_tex *tex_font; +  struct pacc_tex *tex_checker; +  struct pacc_tex *tex_key_left; +  struct pacc_tex *tex_key_right; +  struct pacc_tex *tex_key_mask; +  struct pacc_tex *tex_key_bg; +  struct pacc_tex *tex_num; +  struct pacc_tex *tex_dt_sign; +  struct pacc_tex *tex_solid; +  struct pacc_tex *tex_vertical; +  struct pacc_tex *tex_horizontal; +  struct pacc_tex *tex_logo; +  struct pacc_tex *tex_ver; +  struct pacc_tex *tex_text; +  struct pacc_tex *tex_tri; +  struct pacc_tex *tex_curl_left; +  struct pacc_tex *tex_curl_right; +  struct pacc_tex *tex_play; +  struct pacc_tex *tex_stop; +  struct pacc_tex *tex_pause; +  struct pacc_tex *tex_fade; +  struct pacc_tex *tex_ff; +  struct pacc_tex *tex_rew; +  struct pacc_tex *tex_floppy; +  struct pacc_tex *tex_circle; +  struct pacc_tex *tex_panpot; +  struct pacc_tex *tex_comment; +  struct pacc_tex *tex_comment_tri; +  struct pacc_buf *buf_font_7; +  struct pacc_buf *buf_font_2, *buf_font_2_d; +  struct pacc_buf *buf_font_1, *buf_font_1_d; +  struct pacc_buf *buf_checker, *buf_checker_1; +  struct pacc_buf *buf_key_left; +  struct pacc_buf *buf_key_right; +  struct pacc_buf *buf_key_mask, *buf_key_mask_sub; +  struct pacc_buf *buf_key_bg; +  struct pacc_buf *buf_num; +  struct pacc_buf *buf_dt_sign; +  struct pacc_buf *buf_solid_2, *buf_solid_2_d, *buf_solid_3, *buf_solid_3_d, *buf_solid_7, *buf_solid_7_d; +  struct pacc_buf *buf_vertical_2, *buf_vertical_3, *buf_vertical_7; +  struct pacc_buf *buf_horizontal_2_d, *buf_horizontal_3, *buf_horizontal_7_d; +  struct pacc_buf *buf_logo; +  struct pacc_buf *buf_ver; +  struct pacc_buf *buf_text; +  struct pacc_buf *buf_tri, *buf_tri_7; +  struct pacc_buf *buf_curl_left; +  struct pacc_buf *buf_curl_right; +  struct pacc_buf *buf_play; +  struct pacc_buf *buf_stop; +  struct pacc_buf *buf_pause; +  struct pacc_buf *buf_fade; +  struct pacc_buf *buf_ff; +  struct pacc_buf *buf_rew; +  struct pacc_buf *buf_floppy; +  struct pacc_buf *buf_circle; +  struct pacc_buf *buf_panpot_1_d, *buf_panpot_5_d; +  struct pacc_buf *buf_comment; +  struct pacc_buf *buf_comment_tri_d;    struct opna *opna;    struct fmdriver_work *work;    struct fmplayer_fft_input_data *fftin; @@ -129,6 +185,10 @@ struct fmdsp_pacc {    uint8_t leveldata[FMDSP_LEVEL_COUNT];    uint8_t levelcnt[FMDSP_LEVEL_COUNT];    uint8_t leveldropdiv[FMDSP_LEVEL_COUNT]; +  const struct fmdsp_font *font16; +  int comment_offset; +  bool comment_prev_avail; +  bool comment_next_avail;  };  static struct pacc_tex *tex_from_font( @@ -195,6 +255,8 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {        fp->pacc.buf_delete(fp->buf_circle);        fp->pacc.buf_delete(fp->buf_panpot_1_d);        fp->pacc.buf_delete(fp->buf_panpot_5_d); +      fp->pacc.buf_delete(fp->buf_comment); +      fp->pacc.buf_delete(fp->buf_comment_tri_d);        fp->pacc.tex_delete(fp->tex_font);        fp->pacc.tex_delete(fp->tex_checker);        fp->pacc.tex_delete(fp->tex_key_left); @@ -221,6 +283,8 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {        fp->pacc.tex_delete(fp->tex_floppy);        fp->pacc.tex_delete(fp->tex_circle);        fp->pacc.tex_delete(fp->tex_panpot); +      fp->pacc.tex_delete(fp->tex_comment); +      fp->pacc.tex_delete(fp->tex_comment_tri);      }      free(fp);    } @@ -351,6 +415,8 @@ static void update_track_without_key(            track->fmslotmask[2] ? ' ' : '3',            track->fmslotmask[3] ? ' ' : '4');        break; +    default: +      break;      }    }    if (!track->playing) { @@ -529,6 +595,10 @@ struct fmdsp_pacc *fmdsp_pacc_init(    if (!fp->tex_circle) goto err;    fp->tex_panpot = fp->pacc.gen_tex(fp->pc, PANPOT_W, PANPOT_H*6);    if (!fp->tex_panpot) goto err; +  fp->tex_comment = fp->pacc.gen_tex(fp->pc, PC98_W, COMMENT_H*3); +  if (!fp->tex_comment) goto err; +  fp->tex_comment_tri = fp->pacc.gen_tex(fp->pc, COMMENT_TRI_W, COMMENT_TRI_H*2); +  if (!fp->tex_comment_tri) goto err;    uint8_t *buf;    buf = fp->pacc.tex_lock(fp->tex_checker); @@ -593,6 +663,9 @@ struct fmdsp_pacc *fmdsp_pacc_init(    buf = fp->pacc.tex_lock(fp->tex_panpot);    memcpy(buf, s_panpot, PANPOT_W*PANPOT_H*6);    fp->pacc.tex_unlock(fp->tex_panpot); +  buf = fp->pacc.tex_lock(fp->tex_comment_tri); +  memcpy(buf, s_comment_tri, COMMENT_TRI_W*COMMENT_TRI_H*2); +  fp->pacc.tex_unlock(fp->tex_comment_tri);    buf = fp->pacc.tex_lock(fp->tex_solid);    buf[0] = 1;    fp->pacc.tex_unlock(fp->tex_solid); @@ -729,9 +802,14 @@ struct fmdsp_pacc *fmdsp_pacc_init(    if (!fp->buf_panpot_1_d) goto err;    fp->buf_panpot_5_d = fp->pacc.gen_buf(fp->pc, fp->tex_panpot, pacc_buf_mode_stream);    if (!fp->buf_panpot_5_d) goto err; +  fp->buf_comment = fp->pacc.gen_buf(fp->pc, fp->tex_comment, pacc_buf_mode_static); +  if (!fp->buf_comment) goto err; +  fp->buf_comment_tri_d = fp->pacc.gen_buf(fp->pc, fp->tex_comment_tri, pacc_buf_mode_stream); +  if (!fp->buf_comment_tri_d) 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.buf_rect(fp->pc, fp->buf_comment, 0, COMMENT_Y, PC98_W, COMMENT_H*3);    memcpy(fp->target_palette, s_palettes[0], sizeof(fp->target_palette));    fp->mode_changed = true;    return fp; @@ -1231,7 +1309,7 @@ static void update_default(struct fmdsp_pacc *fp) {    // circle    int clock = 8;    if (fp->work->playing) { -    if (fp->work->paused && (fp->framecnt % 60) < 30) { +    if (fp->work->paused && (fp->framecnt % 32) < 16) {        clock = 8;      } else {        clock = (fp->work->timerb_cnt / 8) % 8; @@ -1511,6 +1589,7 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {    fp->pacc.buf_clear(fp->buf_circle);    fp->pacc.buf_clear(fp->buf_panpot_1_d);    fp->pacc.buf_clear(fp->buf_panpot_5_d); +  fp->pacc.buf_clear(fp->buf_comment_tri_d);    unsigned mask = 0;    if (fp->opna) {      mask = opna_get_mask(fp->opna); @@ -1571,6 +1650,22 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {        break;      }    } +  if ((fp->framecnt % 32) < 16) { +    if (fp->comment_prev_avail) { +      fp->pacc.buf_rect_off( +          fp->pc, fp->buf_comment_tri_d, +          COMMENT_TRI_X, COMMENT_TRI_U_Y, +          COMMENT_TRI_W, COMMENT_TRI_H, +          0, 0); +    } +    if (fp->comment_next_avail) { +      fp->pacc.buf_rect_off( +          fp->pc, fp->buf_comment_tri_d, +          COMMENT_TRI_X, COMMENT_TRI_D_Y, +          COMMENT_TRI_W, COMMENT_TRI_H, +          0, COMMENT_TRI_H); +    } +  }    fp->pacc.begin_clear(fp->pc);    fp->pacc.color(fp->pc, 1);    fp->pacc.draw(fp->pc, fp->buf_font_1, pacc_mode_color); @@ -1611,6 +1706,9 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {    fp->pacc.draw(fp->pc, fp->buf_curl_left, pacc_mode_copy);    fp->pacc.draw(fp->pc, fp->buf_curl_right, pacc_mode_copy);    fp->pacc.draw(fp->pc, fp->buf_circle, pacc_mode_copy); +  fp->pacc.color(fp->pc, 2); +  fp->pacc.draw(fp->pc, fp->buf_comment, pacc_mode_color_trans); +  fp->pacc.draw(fp->pc, fp->buf_comment_tri_d, pacc_mode_color_trans);    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); @@ -1669,3 +1767,162 @@ void fmdsp_pacc_set_right_mode(struct fmdsp_pacc *fp, enum fmdsp_right_mode mode    fp->rmode = mode;    fp->mode_changed = true;  } + +static void font_putchar( +    uint8_t *tex, int texwidth, +    const void *data, +    int x, int y, int w, int h) { +  const uint8_t *font = data; +  for (int yi = 0; yi < h; yi++) { +    for (int xi = 0; xi < w; xi++) { +      if (font[yi] & (1<<(7-xi))) { +        tex[(y+yi)*texwidth+(x+xi)] = 1; +      } +    } +  } +} + +static void font_putline( +    const char *strptr, +    uint8_t *tex, int texwidth, +    const struct fmdsp_font *font, +    int x, int y) { +  const uint8_t *cp932str = (const uint8_t *)strptr; +  bool sjis_is2nd = false; +  uint8_t sjis_1st; +  int fw = font->width_half; +  int fh = font->height; +  int xo = 0; + +  while (*cp932str) { +    if (!sjis_is2nd) { +      if (!sjis_is_mb_start(*cp932str)) { +        if (*cp932str == '\t') { +          xo += fw*8; +          xo -= (xo % (fw*8)); +          cp932str++; +        } else { +          if ((x+xo+fw) > texwidth) return; +          const void *fp = font->get(font, *cp932str++, FMDSP_FONT_ANK); +          if (fp) { +            font_putchar(tex, texwidth, fp, x+xo, y, fw, fh); +          } +          xo += fw; +        } +      } else { +        sjis_is2nd = true; +        sjis_1st = *cp932str++; +      } +    } else { +      uint8_t sjis_2nd = *cp932str++; +      uint16_t jis = sjis2jis(sjis_1st, sjis_2nd); +      bool half = jis_is_halfwidth(jis); +      if ((x+xo+fw*(half ? 1 : 2)) > texwidth) return; +      const void *fp = font->get(font, jis, FMDSP_FONT_JIS_LEFT); +      if (fp) { +        font_putchar(tex, texwidth, fp, x+xo, y, fw, fh); +      } +      xo += fw; +      if (!half) { +        fp = font->get(font, jis, FMDSP_FONT_JIS_RIGHT); +        if (fp) { +          font_putchar(tex, texwidth, fp, x+xo, y, fw, fh); +        } +        xo += 8; +      } +      sjis_is2nd = false; +    } +  } +} + +void fmdsp_pacc_set_font16(struct fmdsp_pacc *fp, const struct fmdsp_font *font) { +  fp->font16 = font; +} + +static void draw_tri(uint8_t *buf, int width, int x, int y) { +  for (int yi = 0; yi < 3; yi++) { +    for (int xi = 0; xi <= yi; xi++) { +      buf[(y+yi)*width+x+xi] = 1; +    } +  } +} + +static void fmdsp_pacc_comment_draw(struct fmdsp_pacc *fp) { +  if (!fp->font16) return; +  if (!fp->work) return; +  uint8_t *buf = fp->pacc.tex_lock(fp->tex_comment); +  memset(buf, 0, PC98_W*COMMENT_H*3); +  const char *str; +  if (fp->work->comment_mode_pmd) { +    fp->comment_prev_avail = fp->comment_offset; +    fp->comment_next_avail = +      fp->work->get_comment(fp->work, fp->comment_offset+2+1+1); +    for (int i = 0; i < 3; i++) { +      int n = i + fp->comment_offset; +      if (n == 0) { +        str = fp->work->get_comment(fp->work, 0); +        if (str) { +          font_putline("MUS", buf, PC98_W, &font_fmdsp_small, +              14, COMMENT_H*i+7); +          font_putline("IC", buf, PC98_W, &font_fmdsp_small, +              28, COMMENT_H*i+7); +          font_putline("T", buf, PC98_W, &font_fmdsp_small, +              40, COMMENT_H*i+7); +          font_putline("ITLE", buf, PC98_W, &font_fmdsp_small, +              44, COMMENT_H*i+7); +          draw_tri(buf, PC98_W, 65, COMMENT_H*i+10); +          font_putline(str, buf, PC98_W, fp->font16, 81, COMMENT_H*i); +        } +      } else if (n == 1) { +        str = fp->work->get_comment(fp->work, 1); +        if (str) { +          font_putline("COMPOSER", buf, PC98_W, &font_fmdsp_small, +              24, COMMENT_H*i+7); +          draw_tri(buf, PC98_W, 65, COMMENT_H*i+10); +          font_putline(str, buf, PC98_W, fp->font16, 81, COMMENT_H*i); +        } +        str = fp->work->get_comment(fp->work, 2); +        if (str) { +          font_putline("ARRANGER", buf, PC98_W, &font_fmdsp_small, +              312, COMMENT_H*i+7); +          draw_tri(buf, PC98_W, 353, COMMENT_H*i+10); +          font_putline(str, buf, PC98_W, fp->font16, 371, COMMENT_H*i); +        } +      } else { +        str = fp->work->get_comment(fp->work, n+1); +        if (str) { +          font_putline("MEMO", buf, PC98_W, &font_fmdsp_small, +              44, COMMENT_H*i+7); +          draw_tri(buf, PC98_W, 65, COMMENT_H*i+10); +          font_putline(str, buf, PC98_W, fp->font16, 81, COMMENT_H*i); +        } +      } +    } +  } else { +    fp->comment_prev_avail = false; +    fp->comment_next_avail = false; +    for (int i = 0; i < 3; i++) { +      const char *str = fp->work->get_comment(fp->work, i); +      if (str) font_putline(str, buf, PC98_W, fp->font16, 0, i*COMMENT_H); +    } +  } +  fp->pacc.tex_unlock(fp->tex_comment); +} + +void fmdsp_pacc_comment_reset(struct fmdsp_pacc *fp) { +  fp->comment_offset = 0; +  fmdsp_pacc_comment_draw(fp); +} + +void fmdsp_pacc_comment_scroll(struct fmdsp_pacc *fp, bool down) { +  if (!fp->work) return; +  if (!fp->work->comment_mode_pmd) return; +  if (down) { +    if (fp->work->get_comment(fp->work, fp->comment_offset+2+1+1)) { +      fp->comment_offset++; +    } +  } else { +    if (fp->comment_offset > 0) fp->comment_offset--; +  } +  fmdsp_pacc_comment_draw(fp); +} diff --git a/fmdsp/fmdsp-pacc.h b/fmdsp/fmdsp-pacc.h index 992a8eb..b5d7bf8 100644 --- a/fmdsp/fmdsp-pacc.h +++ b/fmdsp/fmdsp-pacc.h @@ -1,12 +1,15 @@  #ifndef MYON_FMDSP_PACC_H_INCLUDED  #define MYON_FMDSP_PACC_H_INCLUDED +#include <stdbool.h> +  struct fmdsp_pacc;  struct pacc_ctx;  struct pacc_vtable;  struct fmdriver_work work;  struct opna opna;  struct fmplayer_fft_input_data; +struct fmdsp_font;  enum {    FMDSP_PALETTE_COLORS = 10, @@ -48,4 +51,8 @@ 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); +void fmdsp_pacc_set_font16(struct fmdsp_pacc *fp, const struct fmdsp_font *font); +void fmdsp_pacc_comment_reset(struct fmdsp_pacc *fp); +void fmdsp_pacc_comment_scroll(struct fmdsp_pacc *fp, bool down); +  #endif // MYON_FMDSP_PACC_H_INCLUDED diff --git a/fmdsp/fmdsp_sprites.h b/fmdsp/fmdsp_sprites.h index c942e24..fa0c032 100644 --- a/fmdsp/fmdsp_sprites.h +++ b/fmdsp/fmdsp_sprites.h @@ -176,6 +176,11 @@ enum {    LEVEL_TRACK_Y = LEVEL_Y-9,    LEVEL_PROG_Y = PANPOT_Y+15,    LEVEL_KEY_Y = LEVEL_PROG_Y+7, +  COMMENT_TRI_W = 7, +  COMMENT_TRI_H = 4, +  COMMENT_TRI_X = 8, +  COMMENT_TRI_U_Y = 349, +  COMMENT_TRI_D_Y = 387,  };  enum { @@ -982,3 +987,18 @@ static uint8_t s_panpot[6][PANPOT_W*PANPOT_H] = {      0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,    },  }; + +static const uint8_t s_comment_tri[2][COMMENT_TRI_W*COMMENT_TRI_H] = { +  { +    0, 0, 0, 1, 0, 0, 0, +    0, 0, 1, 1, 1, 0, 0, +    0, 1, 1, 1, 1, 1, 0, +    1, 1, 1, 1, 1, 1, 1, +  }, +  { +    1, 1, 1, 1, 1, 1, 1, +    0, 1, 1, 1, 1, 1, 0, +    0, 0, 1, 1, 1, 0, 0, +    0, 0, 0, 1, 0, 0, 0, +  }, +}; @@ -3,12 +3,14 @@  #include <stdatomic.h>  #include "pacc/pacc.h"  #include "fmdsp/fmdsp-pacc.h" +#include "fmdsp/font.h"  #include "libopna/opna.h"  #include "libopna/opnatimer.h"  #include "fmdriver/fmdriver.h"  #include "common/fmplayer_file.h"  #include "common/fmplayer_common.h"  #include "fft/fft.h" +#include "fmdsp/fontrom_shinonome.inc"  bool loadgl(void); @@ -32,6 +34,7 @@ static struct {    struct fmdsp_pacc *fp;    atomic_flag fftdata_flag;    int scale; +  struct fmdsp_font font16;  } g = {    .fftdata_flag = ATOMIC_FLAG_INIT,    .scale = 1, @@ -65,6 +68,7 @@ static void openfile(const char *path) {    g.fmfile = file;    fmplayer_init_work_opna(&g.work, &g.ppz8, &g.opna, &g.timer, &g.adpcmram);    fmplayer_file_load(&g.work, g.fmfile, 1); +  fmdsp_pacc_comment_reset(g.fp);    SDL_UnlockAudioDevice(g.adev);    SDL_PauseAudioDevice(g.adev, 0);  } @@ -156,6 +160,8 @@ int main(int argc, char **argv) {      return 1;    }    fmdsp_pacc_set(g.fp, &g.work, &g.opna, &g.fftin); +  fmdsp_font_from_font_rom(&g.font16, fmdsp_shinonome_font_rom); +  fmdsp_pacc_set_font16(g.fp, &g.font16);    SDL_EventState(SDL_DROPFILE, SDL_ENABLE); @@ -193,6 +199,18 @@ int main(int argc, char **argv) {          default:            break;          } +        if (e.key.keysym.mod & KMOD_SHIFT) { +          switch (e.key.keysym.scancode) { +          case SDL_SCANCODE_UP: +            fmdsp_pacc_comment_scroll(g.fp, false); +            break; +          case SDL_SCANCODE_DOWN: +            fmdsp_pacc_comment_scroll(g.fp, true); +            break; +          default: +            break; +          } +        }          if (e.key.keysym.mod & KMOD_CTRL) {            switch (e.key.keysym.scancode) {            case SDL_SCANCODE_F1: diff --git a/sdl/unix/Makefile b/sdl/unix/Makefile index ea22098..62dd177 100644 --- a/sdl/unix/Makefile +++ b/sdl/unix/Makefile @@ -8,7 +8,7 @@ vpath %.c ../../fft  SDLCONFIG:=sdl2-config  OBJS:=main.o  OBJS+=pacc-gl.o -OBJS+=fmdsp-pacc.o font_fmdsp_small.o fmdsp_platform_unix.o +OBJS+=fmdsp-pacc.o font_fmdsp_small.o fmdsp_platform_unix.o font_rom.o  OBJS+=opna.o opnafm.o opnassg.o opnadrum.o opnaadpcm.o opnatimer.o opnassg-sinc-c.o opnassg-sinc-sse2.o  OBJS+=fmdriver_pmd.o fmdriver_fmp.o ppz8.o fmdriver_common.o  OBJS+=fmplayer_file.o fmplayer_work_opna.o fmplayer_file_unix.o fmplayer_drumrom_unix.o | 
