aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fmdriver/fmdriver.h18
-rw-r--r--fmdriver/fmdriver_fmp.c55
-rw-r--r--fmdriver/fmdriver_fmp.h6
-rw-r--r--fmdriver/fmdriver_pmd.c12
-rw-r--r--fmdsp/fmdsp-pacc.c263
-rw-r--r--fmdsp/fmdsp-pacc.h7
-rw-r--r--fmdsp/fmdsp_sprites.h20
-rw-r--r--sdl/main.c18
-rw-r--r--sdl/unix/Makefile2
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,
+ },
+};
diff --git a/sdl/main.c b/sdl/main.c
index e46a660..5a103b4 100644
--- a/sdl/main.c
+++ b/sdl/main.c
@@ -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