2015年12月11日金曜日

Android版の東方VGSでアルバムタイトルが表示されないという件の調査経過

twitterの方で愚痴ろうとしたのですが、少し長いのでブログの方に書いておきます。

先日、久しぶりにAndroid版の東方VGSをアップデートしてみたら、立て続けに2件ほど「アルバムタイトルが表示されなくなった」という報告がレビューで挙ってきました。

どうやら報告は両方ともAndroid 5らしいです。
私はAndroid 5の端末を持っていない(&私の手持ちのAndroid 4.4の端末では再現しない)ので、知り合いが偶然持っていたNexus 5 + Android 5の端末で動かしてみたところ現象を確認。

通常だと、下図のように表示されるはずのところ、

以下のような感じで表示されていました。

そもそも、このタイトル表示は通常のAndroidのTextViewではなく、割と特殊な方法で表示しています。

まず、GitHubの方でも公開している titlelist.txt というテキストファイル(CSVファイル)をSJISに変換したものから以下の形式の構造体を生成していて、それをromdata.binの中に突っ込んでいます。
/* title data */
struct TitleData {
int id;
int songNum;
char copyright[32];
char title[80];
char reserved2[8];
};
view raw game.c hosted with ❤ by GitHub

※1タイトルにつき1インスタンス

そして、それを以下のようにputkanjiという関数で表示
/* Draw song title */
putkanji(4 + bx, 134 + (int)base, 255, _title[ct].title);
putkanji(236 + bx - ((int)strlen(_title[ct].copyright)) * 4, 152 + (int)base, 255, _title[ct].copyright);
if (_title[ct].id == 0x60) {
putkanji((240 - (((int)strlen(_msg)) * 4)) / 2 + bx, 40 + (int)base, 255, "%s", _msg);
}
view raw game.c hosted with ❤ by GitHub


putkanjiはこんな感じ
static unsigned short getcode(unsigned char sjis[2])
{
unsigned char jis[2];
unsigned short ret;
jis[0] = sjis[0];
jis[1] = sjis[1];
if (jis[0] <= 0x9f) {
jis[0] -= 0x71;
} else {
jis[0] -= 0xb1;
}
jis[0] *= 2;
jis[0]++;
if (jis[1] >= 0x7F) {
jis[1] -= 0x01;
}
if (jis[1] >= 0x9e) {
jis[1] -= 0x7d;
jis[0]++;
} else {
jis[1] -= 0x1f;
}
ret = (jis[0] - 0x21) * 94;
ret += jis[1] - 0x21;
return ret;
}
static void putkanji(int x, int y, int col, const char* msg, ...)
{
char buf[256];
int i, j, k;
unsigned char c[2];
int jis;
unsigned char bin;
va_list args;
va_start(args, msg);
vsprintf(buf, msg, args);
va_end(args);
for (i = 0; '\0' != (c[0] = (unsigned char)buf[i]); i++) {
if (c[0] & 0x80) {
c[1] = (unsigned char)buf[i + 1];
jis = (int)getcode(c);
jis *= 12;
for (j = 0; j < 12; j++) {
bin = _kanji[jis + j];
for (k = 0; k < 8; k++, bin <<= 1) {
if (bin & 0x80) {
vge_pixelSP(x + k, y + j, col);
}
}
}
x += 8;
i++;
} else {
c[0] -= 0x20;
vge_putSPM(255, c[0] % 16 * 4, c[0] / 16 * 12, 4, 12, x, y, col);
x += 4;
}
}
}
view raw game.c hosted with ❤ by GitHub


・曲のタイトルは問題なく表示されているのでputkanjiはバグっていない。
・タイトルは表示されていないが「(c)2008」という ASCII コードのみの部分は表示されている
・また、IDは正常に引けている
・つまり、TitleDataのレコード自体はある

という点から文字コードのMBCS部分がデータ破損しているか \0 になっているんじゃないかと思うかもしれませんが、それなら私のAndroid 4.4でも問題なく表示される筈がないのでそれは無いです。

Android 5って実はOSのネイティブ周りの実装が結構強かに変更されているので、OS側のバグを踏んでしまったと考えるのが一番自然ですかねぇ。(この手の問題の原因としてよくあるのがグローバル領域を壊す系だろうか)

さて、どうしたものか。

Android版はバックグラウンド音飛びの件もあるし、公開停止してiPhone版一本で行くのも良いんじゃないだろうかというのが本音なのですが。(要約するとAndroidはもう嫌だ...ということ)

【追記】
エミュレータで現象を再現でき、原因も特定できたので、対策しました。
https://github.com/suzukiplan/Touhou-VGS-MML-data/pull/81

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...