From 61add3b7d799a43859f776d2ffbb51edc925ea37 Mon Sep 17 00:00:00 2001 From: Takamichi Horikawa Date: Sat, 9 Sep 2017 20:04:46 +0900 Subject: fmdsp: pacc: add layout mode change --- fmdsp/fmdsp-pacc.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++---- fmdsp/fmdsp-pacc.h | 33 +++++++ sdl/main.c | 48 ++++++++++ 3 files changed, 327 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 #include 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 diff --git a/sdl/main.c b/sdl/main.c index 43053a3..01c2437 100644 --- a/sdl/main.c +++ b/sdl/main.c @@ -156,6 +156,54 @@ int main(int argc, char **argv) { openfile(e.drop.file); SDL_free(e.drop.file); break; + case SDL_KEYDOWN: + if (e.key.keysym.scancode == SDL_SCANCODE_F11) { + if (e.key.keysym.mod & KMOD_SHIFT) { + fmdsp_pacc_set_right_mode( + g.fp, + (fmdsp_pacc_right_mode(g.fp) + 1) % FMDSP_RIGHT_MODE_CNT); + } else { + fmdsp_pacc_set_left_mode( + g.fp, + (fmdsp_pacc_left_mode(g.fp) + 1) % FMDSP_LEFT_MODE_CNT); + } + } + if (e.key.keysym.mod & KMOD_CTRL) { + switch (e.key.keysym.scancode) { + case SDL_SCANCODE_F1: + fmdsp_pacc_palette(g.fp, 0); + break; + case SDL_SCANCODE_F2: + fmdsp_pacc_palette(g.fp, 1); + break; + case SDL_SCANCODE_F3: + fmdsp_pacc_palette(g.fp, 2); + break; + case SDL_SCANCODE_F4: + fmdsp_pacc_palette(g.fp, 3); + break; + case SDL_SCANCODE_F5: + fmdsp_pacc_palette(g.fp, 4); + break; + case SDL_SCANCODE_F6: + fmdsp_pacc_palette(g.fp, 5); + break; + case SDL_SCANCODE_F7: + fmdsp_pacc_palette(g.fp, 6); + break; + case SDL_SCANCODE_F8: + fmdsp_pacc_palette(g.fp, 7); + break; + case SDL_SCANCODE_F9: + fmdsp_pacc_palette(g.fp, 8); + break; + case SDL_SCANCODE_F10: + fmdsp_pacc_palette(g.fp, 9); + break; + default: + break; + } + } } } fmdsp_pacc_render(g.fp); -- cgit v1.2.3