diff options
author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-01-18 23:37:07 +0900 |
---|---|---|
committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-01-18 23:37:07 +0900 |
commit | e8fd09abf68b944b05554c82adb577514cad5ca5 (patch) | |
tree | f8882715e86534cec2dc20154fd24c6bef3c668b /fmdsp | |
parent | 09ea1fe272aca6ebb6840f02765acd44ac3ecebc (diff) |
improve FMDSP and enable title display on win32
Diffstat (limited to 'fmdsp')
-rw-r--r-- | fmdsp/fmdsp.c | 144 | ||||
-rw-r--r-- | fmdsp/fmdsp.h | 6 | ||||
-rw-r--r-- | fmdsp/fmdsp_sprites.h | 1 | ||||
-rw-r--r-- | fmdsp/font.h | 60 | ||||
-rw-r--r-- | fmdsp/font_rom.c | 24 |
5 files changed, 161 insertions, 74 deletions
diff --git a/fmdsp/fmdsp.c b/fmdsp/fmdsp.c index 4698842..bf29f56 100644 --- a/fmdsp/fmdsp.c +++ b/fmdsp/fmdsp.c @@ -1,5 +1,6 @@ #include "fmdsp.h" #include "fmdsp_sprites.h" +#include "font.h" #include "fmdriver/fmdriver.h" static void vramblit(uint8_t *vram, int x, int y, @@ -21,6 +22,16 @@ static void vramblit_color(uint8_t *vram, int x, int y, } } +static void vramfill_color(uint8_t *vram, int x, int y, + int w, int h, + uint8_t color) { + for (int yi = 0; yi < h; yi++) { + for (int xi = 0; xi < w; xi++) { + vram[(y+yi)*PC98_W+(x+xi)] = color; + } + } +} + static void vramblit_key(uint8_t *vram, int x, int y, const uint8_t *data, int w, int h, uint8_t key, uint8_t color) { @@ -34,66 +45,53 @@ static void vramblit_key(uint8_t *vram, int x, int y, } } -void fmdsp_init(struct fmdsp *fmdsp) { +void fmdsp_init(struct fmdsp *fmdsp, const struct fmdsp_font *font98) { for (int i = 0; i < FMDSP_PALETTE_COLORS; i++) { fmdsp->palette[i*3+0] = s_palettes[0][i*3+0]; fmdsp->palette[i*3+1] = s_palettes[0][i*3+1]; fmdsp->palette[i*3+2] = s_palettes[0][i*3+2]; } + fmdsp->font98 = font98; } -static bool sjis_is_mb_start(uint8_t c) { - if (0x81 <= c && c <= 0x9f) return true; - if (0xe0 <= c && c <= 0xef) return true; - return false; -} -static uint16_t sjis2jis(uint8_t sjis_1st, uint8_t sjis_2nd) { - uint16_t jis; - if (sjis_1st >= 0xe0) sjis_1st -= 0x40; - sjis_1st -= 0x81; - jis = sjis_1st << 9; - if (sjis_2nd >= 0x80) sjis_2nd--; - if (sjis_2nd >= 0x9e) { - jis |= 0x100 | (sjis_2nd - 0x9e); - } else { - jis |= (sjis_2nd - 0x40); - } - jis += 0x2121; - return jis; -} - -static void vram_putchar(uint16_t ptr, uint8_t *vram, const uint8_t *font, - int x, int y, uint8_t color) { - for (int yi = 0; yi < 16; yi++) { - for (int xi = 0; xi < 8; xi++) { - if (font[(ptr<<4)+yi] & (1<<(7-xi))) { +static void vram_putchar(uint8_t *vram, const void *data, + int x, int y, int w, int h, uint8_t color) { + 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))) { vram[(y+yi)*PC98_W+(x+xi)] = color; } } } } -static void fmdsp_putline(const char *strptr, uint8_t *vram, const uint8_t *font, - int y, uint8_t color) { +static void fmdsp_putline(const char *strptr, uint8_t *vram, + const struct fmdsp_font *font, + int x, int y, uint8_t color) { const uint8_t *cp932str = (const uint8_t *)strptr; bool sjis_is2nd = false; uint8_t sjis_1st; - int x = 0; + 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') { - if ((x+8*8) > PC98_W) return; - x += 8*8; - x &= ~(8*8-1); + xo += fw*8; + xo -= (xo % (fw*8)); cp932str++; } else { - if ((x+8) > PC98_W) return; - vram_putchar(0x8000+*cp932str++, vram, font, x, y, color); - x += 8; + if ((x+xo+8) > PC98_W) return; + const void *fp = font->get(font, *cp932str++, FMDSP_FONT_ANK); + if (fp) { + vram_putchar(vram, fp, x+xo, y, fw, fh, color); + } + xo += fw; } } else { sjis_is2nd = true; @@ -102,15 +100,19 @@ static void fmdsp_putline(const char *strptr, uint8_t *vram, const uint8_t *font } else { uint8_t sjis_2nd = *cp932str++; uint16_t jis = sjis2jis(sjis_1st, sjis_2nd); - uint8_t jis_1st = jis >> 8; - uint8_t jis_2nd = jis; - bool half = (jis_1st == 0x29); - if ((x+(half ? 8 : 16)) > PC98_W) return; - vram_putchar((jis_2nd<<8) | (jis_1st-0x20), vram, font, x, y, color); - x += 8; + bool half = jis_is_halfwidth(jis); + if ((x+xo+(half ? 8 : 16)) > PC98_W) return; + const void *fp = font->get(font, jis, FMDSP_FONT_JIS_LEFT); + if (fp) { + vram_putchar(vram, fp, x+xo, y, fw, fh, color); + } + xo += fw; if (!half) { - vram_putchar((jis_2nd<<8) | (jis_1st-0x20+0x80), vram, font, x, y, color); - x += 8; + fp = font->get(font, jis, FMDSP_FONT_JIS_RIGHT); + if (fp) { + vram_putchar(vram, fp, x+xo, y, fw, fh, color); + } + xo += 8; } sjis_is2nd = false; } @@ -119,7 +121,6 @@ static void fmdsp_putline(const char *strptr, uint8_t *vram, const uint8_t *font void fmdsp_vram_init(struct fmdsp *fmdsp, struct fmdriver_work *work, - const uint8_t *font, uint8_t *vram) { for (int y = 0; y < PC98_H; y++) { for (int x = 0; x < PC98_W; x++) { @@ -127,6 +128,23 @@ void fmdsp_vram_init(struct fmdsp *fmdsp, } } for (int t = 0; t < 10; t++) { + struct fmdriver_track_status *track = &work->track_status[t]; + uint8_t *track_type; + switch (track->type) { + case FMDRIVER_TRACK_FM: + track_type = s_t_fm; + break; + case FMDRIVER_TRACK_SSG: + track_type = s_t_ssg; + break; + case FMDRIVER_TRACK_ADPCM: + track_type = s_t_adpcm; + break; + } + vramblit(vram, 1, TRACK_H*t+1, track_type, TNAME_W, TNAME_H); + vramblit(vram, NUM_X+NUM_W*0, TRACK_H*t+1, s_num[(track->num/10)%10], NUM_W, NUM_H); + vramblit(vram, NUM_X+NUM_W*1, TRACK_H*t+1, s_num[track->num%10], NUM_W, NUM_H); + vramblit(vram, 1, TRACK_H*t+7, s_track, TNAME_W, TNAME_H); vramblit(vram, KEY_LEFT_X, TRACK_H*t+KEY_Y, s_key_left, KEY_LEFT_W, KEY_H); for (int i = 0; i < KEY_OCTAVES; i++) { @@ -155,8 +173,11 @@ void fmdsp_vram_init(struct fmdsp *fmdsp, } vram[(PC98_H-height)*PC98_W] = 0; vram[(PC98_H-1)*PC98_W] = 0; - for (int i = 0; i < 3; i++) { - fmdsp_putline(work->comment[i], vram, font, COMMENT_Y+COMMENT_H*i, 2); + if (fmdsp->font98) { + for (int i = 0; i < 3; i++) { + fmdsp_putline(work->comment[i], vram, fmdsp->font98, + 0, COMMENT_Y+COMMENT_H*i, 2); + } } } @@ -164,24 +185,13 @@ void fmdsp_update(struct fmdsp *fmdsp, const struct fmdriver_work *work, uint8_t *vram) { for (int t = 0; t < 10; t++) { struct fmdriver_track_status *track = &work->track_status[t]; - uint8_t *track_type; - switch (track->type) { - case FMDRIVER_TRACK_FM: - track_type = s_t_fm; - break; - case FMDRIVER_TRACK_SSG: - track_type = s_t_ssg; - break; - case FMDRIVER_TRACK_ADPCM: - track_type = s_t_adpcm; - break; - case FMDRIVER_TRACK_PPZ8: - track_type = s_t_ppz8; + switch (track->info) { + case FMDRIVER_TRACK_INFO_PPZ8: + vramblit(vram, TINFO_X, TRACK_H*t+7, s_t_ppz8, TNAME_W, TNAME_H); break; + default: + vramfill_color(vram, TINFO_X, TRACK_H*t+7, TNAME_W, TNAME_H, 0); } - vramblit(vram, 1, TRACK_H*t+1, track_type, TNAME_W, TNAME_H); - vramblit(vram, NUM_X+NUM_W*0, TRACK_H*t+1, s_num[(track->num/10)%10], NUM_W, NUM_H); - vramblit(vram, NUM_X+NUM_W*1, TRACK_H*t+1, s_num[track->num%10], NUM_W, NUM_H); for (int i = 0; i < KEY_OCTAVES; i++) { vramblit(vram, KEY_X+KEY_W*i, TRACK_H*t+KEY_Y, s_key_bg, KEY_W, KEY_H); @@ -240,13 +250,3 @@ static void fontrom_copy_rows(uint8_t *font, const uint8_t *fontrom, } } } - -void fmdsp_font_from_fontrom(uint8_t *font, const uint8_t *fontrom) { - // ANK - for (int i = 0; i < 256*16; i++) { - font[0x80000+i] = fontrom[0x800+i]; - } - fontrom_copy_rows(font, fontrom, 0x21, 0x50); - fontrom_copy_rows(font, fontrom, 0x50, 0x76); - fontrom_copy_rows(font, fontrom, 0x78, 0x7d); -} diff --git a/fmdsp/fmdsp.h b/fmdsp/fmdsp.h index 4c6af0c..a7b245a 100644 --- a/fmdsp/fmdsp.h +++ b/fmdsp/fmdsp.h @@ -2,6 +2,7 @@ #define MYON_FMDSP_H_INCLUDED #include <stdint.h> +#include "font.h" #ifdef __cplusplus extern "C" { @@ -19,13 +20,14 @@ enum { struct fmdsp { uint8_t palette[FMDSP_PALETTE_COLORS*3]; uint8_t target_palette[FMDSP_PALETTE_COLORS*3]; + const struct fmdsp_font *font98; + }; struct fmdriver_work; -void fmdsp_init(struct fmdsp *fmdsp); +void fmdsp_init(struct fmdsp *fmdsp, const struct fmdsp_font *font); void fmdsp_vram_init(struct fmdsp *fmdsp, struct fmdriver_work *work, - const uint8_t *font, uint8_t *vram); void fmdsp_update(struct fmdsp *fmdsp, const struct fmdriver_work *work, uint8_t *vram); void fmdsp_vrampalette(struct fmdsp *fmdsp, const uint8_t *vram, uint8_t *vram32, int stride); diff --git a/fmdsp/fmdsp_sprites.h b/fmdsp/fmdsp_sprites.h index 8554985..1fe6c13 100644 --- a/fmdsp/fmdsp_sprites.h +++ b/fmdsp/fmdsp_sprites.h @@ -10,6 +10,7 @@ enum { TRACK_H = 32, TNAME_W = 26, TNAME_H = 5, + TINFO_X = 48, NUM_X = 31, NUM_W = 8, NUM_H = 11, diff --git a/fmdsp/font.h b/fmdsp/font.h new file mode 100644 index 0000000..689df04 --- /dev/null +++ b/fmdsp/font.h @@ -0,0 +1,60 @@ +#ifndef MYON_FMDSP_FONT_H_INCLUDED +#define MYON_FMDSP_FONT_H_INCLUDED + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +static inline bool sjis_is_mb_start(uint8_t c) { + if (0x81 <= c && c <= 0x9f) return true; + if (0xe0 <= c && c <= 0xef) return true; + return false; +} + +static inline bool jis_is_halfwidth(uint16_t jis) { + return (jis>>8) == 0x29; +} + +static inline uint16_t sjis2jis(uint8_t sjis_1st, uint8_t sjis_2nd) { + uint16_t jis; + if (sjis_1st >= 0xe0) sjis_1st -= 0x40; + sjis_1st -= 0x81; + jis = sjis_1st << 9; + if (sjis_2nd >= 0x80) sjis_2nd--; + if (sjis_2nd >= 0x9e) { + jis |= 0x100 | (sjis_2nd - 0x9e); + } else { + jis |= (sjis_2nd - 0x40); + } + jis += 0x2121; + return jis; +} + +enum fmdsp_font_type { + FMDSP_FONT_ANK, + FMDSP_FONT_JIS_LEFT, + FMDSP_FONT_JIS_RIGHT +}; + +struct fmdsp_font { + const void *(* get)(const struct fmdsp_font *font, + uint16_t addr, enum fmdsp_font_type type); + const void *data; + uint8_t width_half; + uint8_t height; +}; + +enum { + FONT_ROM_FILESIZE = 0x46800 +}; + +void fmdsp_font_from_font_rom(struct fmdsp_font *font, const void *data); + +#ifdef __cplusplus +} +#endif + +#endif // MYON_FMDSP_FONT_H_INCLUDED diff --git a/fmdsp/font_rom.c b/fmdsp/font_rom.c new file mode 100644 index 0000000..de6bc19 --- /dev/null +++ b/fmdsp/font_rom.c @@ -0,0 +1,24 @@ +#include "font.h" + +static const void *font_rom_get(const struct fmdsp_font *font, + uint16_t jis, enum fmdsp_font_type type) { + const uint8_t *fontdata = font->data; + const uint8_t *fontptr; + if (type == FMDSP_FONT_ANK) { + fontptr = fontdata + 0x800 + (jis<<4); + } else { + uint8_t row = jis >> 8; + uint8_t cell = jis; + fontptr = fontdata + (0x800 + (0x60*16*2*(row-0x20)) + (cell<<5)); + if (type == FMDSP_FONT_JIS_RIGHT) fontptr += 16; + } + if ((fontptr + (16*16/8)) > (fontdata + FONT_ROM_FILESIZE)) fontptr = 0; + return fontptr; +} + +void fmdsp_font_from_font_rom(struct fmdsp_font *font, const void *data) { + font->data = data; + font->width_half = 8; + font->height = 16; + font->get = font_rom_get; +} |