aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakamichi Horikawa <takamichiho@gmail.com>2017-04-15 01:00:20 +0900
committerTakamichi Horikawa <takamichiho@gmail.com>2017-04-15 01:00:20 +0900
commit680ab52d9e151676b8f90d105b23d2d0d89b0471 (patch)
tree5a05e82900393d2e1ecdf034cf1735d4ebfaec98
parent428126ee4c8802a4b5f9c9ee491d54013857741b (diff)
add fmdsp fft analyzer
-rw-r--r--fft/fft.c154
-rw-r--r--fft/fft.h35
-rw-r--r--fft/fftwindow.h1026
-rw-r--r--fmdriver/fmdriver.h8
-rw-r--r--fmdriver/fmdriver_fmp.c10
-rw-r--r--fmdriver/fmdriver_pmd.c13
-rw-r--r--fmdsp/fmdsp-vramlookup-neon.s5
-rw-r--r--fmdsp/fmdsp.c371
-rw-r--r--fmdsp/fmdsp.h14
-rw-r--r--fmdsp/fmdsp_platform_info.h9
-rw-r--r--fmdsp/fmdsp_platform_unix.c44
-rw-r--r--fmdsp/fmdsp_platform_win.c57
-rw-r--r--fmdsp/fmdsp_sprites.h405
-rw-r--r--fmdsp/font_fmdsp_small_data.h15
-rw-r--r--gtk/Makefile.am4
-rw-r--r--gtk/fmplayer.xpm2
-rw-r--r--gtk/fmplayer32.xpm2
-rw-r--r--gtk/main.c23
-rw-r--r--libopna/opna.c2
-rw-r--r--libopna/opna.h1
-rw-r--r--win32/amd64/Makefile1
-rw-r--r--win32/fmplayer.mak4
-rw-r--r--win32/main.c25
-rw-r--r--win32/wavewrite.c6
-rw-r--r--win32/x86/Makefile1
25 files changed, 2162 insertions, 75 deletions
diff --git a/fft/fft.c b/fft/fft.c
new file mode 100644
index 0000000..69c0971
--- /dev/null
+++ b/fft/fft.c
@@ -0,0 +1,154 @@
+#include "fft.h"
+#include <math.h>
+#include <string.h>
+
+void fft_write(struct fmplayer_fft_data *data, const int16_t *buf, unsigned len) {
+ if (len > FFTLEN) {
+ unsigned discard = FFTLEN - len;
+ buf += discard*2;
+ len = FFTLEN;
+ }
+ unsigned towrite = FFTLEN - data->ind;
+ if (towrite > len) towrite = len;
+ for (unsigned i = 0; i < towrite; i++) {
+ data->buf[data->ind+i] = ((uint32_t)buf[2*i+0] + buf[2*i+1]) / 2;
+ }
+ data->ind = (data->ind + towrite) % FFTLEN;
+ buf += towrite*2;
+ len -= towrite;
+
+ for (unsigned i = 0; i < len; i++) {
+ data->buf[i] = ((uint32_t)buf[2*i+0] + buf[2*i+1]) / 2;
+ }
+ data->ind = (data->ind + len) % FFTLEN;
+}
+
+static const uint16_t fftfreqtab[FFTDISPLEN+1] = {
+ 0,
+ 18, 19, 21, 22, 23, 25, 26, 28, 29, 31,
+ 33, 35, 37, 39, 42, 44, 47, 50, 53, 56,
+ 59, 63, 66, 70, 75, 79, 84, 89, 94, 100,
+ 106, 112, 119, 126, 133, 141, 150, 158, 168, 178,
+ 189, 200, 212, 224, 238, 252, 267, 283, 300, 317,
+ 336, 356, 378, 400, 424, 449, 476, 504, 534, 566,
+ 600, 635, 673, 713, 756, 801, 848, 899, 952, 1009,
+};
+
+enum {
+ HFFTLENBIT = 12,
+ HFFTLEN = 1<<HFFTLENBIT,
+};
+
+static uint16_t window[FFTLEN];
+static float tritab[FFTLEN + FFTLEN/4];
+
+void fft_init_table(void) {
+ const double pi = acos(0.0) * 2.0;
+ double alpha = 0.54;
+ double beta = 1.0 - alpha;
+ for (unsigned i = 0; i < FFTLEN; i++) {
+ double v = alpha - beta * cos(2.0*pi*i/(FFTLEN-1));
+ window[i] = v * (1<<16);
+ }
+ for (unsigned i = 0; i < (FFTLEN + FFTLEN/4); i++) {
+ tritab[i] = sin(2.0*pi*i/FFTLEN);
+ }
+}
+
+static float coscalc(unsigned i) {
+ return tritab[(i & (FFTLEN-1)) + FFTLEN/4];
+}
+
+static float sincalc(unsigned i) {
+ return tritab[i & (FFTLEN-1)];
+}
+
+static float ar(unsigned i) {
+ return 0.5f*(1.0f-sincalc(i));
+}
+
+static float ai(unsigned i) {
+ return -0.5f*coscalc(i);
+}
+
+static float br(unsigned i) {
+ return 0.5f*(1.0f+sincalc(i));
+}
+
+static float bi(unsigned i) {
+ return 0.5f*coscalc(i);
+}
+
+static void fft_real(float *fftbuf) {
+ unsigned b = 0;
+ for (unsigned i = 0; i < HFFTLEN; i++) {
+ unsigned ii = 0;
+ for (unsigned bit = 0; bit < HFFTLENBIT; bit++) {
+ ii |= ((i >> bit) & 1u) << (HFFTLENBIT-bit-1);
+ }
+ fftbuf[(!b)*FFTLEN+i*2+0] = fftbuf[b*FFTLEN+ii*2+0];
+ fftbuf[(!b)*FFTLEN+i*2+1] = fftbuf[b*FFTLEN+ii*2+1];
+ }
+ b = !b;
+ for (unsigned bit = 0; bit < HFFTLENBIT; bit++) {
+ for (unsigned i = 0; i < HFFTLEN; i++) {
+ unsigned ei = i & ~(1u<<bit);
+ unsigned oi = i | (1u<<bit);
+ float are = fftbuf[b*FFTLEN+oi*2+0];
+ float aim = fftbuf[b*FFTLEN+oi*2+1];
+ float bre = coscalc(i<<(HFFTLENBIT-bit));
+ float bim = sincalc(i<<(HFFTLENBIT-bit));
+ float cre = are*bre - aim*bim;
+ float cim = are*bim + aim*bre;
+ fftbuf[(!b)*FFTLEN+i*2+0] = fftbuf[b*FFTLEN+ei*2+0] + cre;
+ fftbuf[(!b)*FFTLEN+i*2+1] = fftbuf[b*FFTLEN+ei*2+1] + cim;
+ }
+ b = !b;
+ }
+ for (unsigned i = 0; i < HFFTLEN; i++) {
+ float xr = fftbuf[b*FFTLEN+i*2+0];
+ float rxr = fftbuf[b*FFTLEN+0];
+ if (i) rxr = fftbuf[b*FFTLEN+(HFFTLEN-i)*2+0];
+ float xi = fftbuf[b*FFTLEN+i*2+1];
+ float rxi = fftbuf[b*FFTLEN+1];
+ if (i) rxi = fftbuf[b*FFTLEN+(HFFTLEN-i)*2+1];
+ fftbuf[(!b)*FFTLEN+i*2+0] = xr * ar(i) - xi * ai(i) + rxr * br(i) + rxi * bi(i);
+ fftbuf[(!b)*FFTLEN+i*2+1] = xi * ar(i) + xr * ai(i) + rxr * bi(i) - rxi * br(i);
+ }
+ if (!b) {
+ memcpy(fftbuf, fftbuf+FFTLEN, FFTLEN*sizeof(fftbuf[0]));
+ }
+}
+
+void fft_calc(struct fmplayer_fft_disp_data *ddata, struct fmplayer_fft_input_data *idata) {
+ for (int i = 0; i < FFTLEN; i++) {
+ int fi = (i + idata->fdata.ind) % FFTLEN;
+ idata->work[i] = (((int32_t)idata->fdata.buf[fi]) * window[i]) >> 16;
+ }
+ for (int i = 0; i < FFTLEN; i++) {
+ idata->fwork[i] = ((float)idata->work[i])/32768;
+ }
+ fft_real(idata->fwork);
+ for (int i = 1; i < FFTLEN/2; i++) {
+ float re = idata->fwork[i*2];
+ float im = idata->fwork[i*2+1];
+ idata->fwork[i] = sqrtf((re*re) + (im*im));
+ }
+ for (int i = 0; i < FFTLEN/2; i++) {
+ idata->fwork[i] = idata->fwork[i] / sqrtf(FFTLEN);
+ }
+ float dbuf[FFTDISPLEN];
+ for (int i = 0; i < FFTDISPLEN; i++) {
+ dbuf[i] = 0.0f;
+ for (int j = fftfreqtab[i]; j < fftfreqtab[i+1]; j++) {
+ dbuf[i] += idata->fwork[j];
+ }
+ dbuf[i] /= fftfreqtab[i+1] - fftfreqtab[i];
+ }
+ for (int i = 0; i < FFTDISPLEN; i++) {
+ float res = (dbuf[i] > (1.0f / 256)) ? (4.0f*log2f(dbuf[i]) + 32.0f) : 0.0f;
+ if (res > 31.0f) res = 31.0f;
+ if (res < 0.0f) res = 0.0f;
+ ddata->buf[i] = res;
+ }
+}
diff --git a/fft/fft.h b/fft/fft.h
new file mode 100644
index 0000000..b446739
--- /dev/null
+++ b/fft/fft.h
@@ -0,0 +1,35 @@
+#ifndef MYON_FMPLAYER_FFT_FFT_H_INCLUDED
+#define MYON_FMPLAYER_FFT_FFT_H_INCLUDED
+
+#include <stdint.h>
+
+enum {
+ FFTLEN = 8192,
+ FFTDISPLEN = 70,
+};
+
+struct fmplayer_fft_data {
+ int16_t buf[FFTLEN];
+ unsigned ind;
+};
+
+struct fmplayer_fft_input_data {
+ struct fmplayer_fft_data fdata;
+ int16_t work[FFTLEN];
+ double dwork[FFTLEN];
+ float fwork[FFTLEN*2];
+};
+
+struct fmplayer_fft_disp_data {
+ // 0 - 31
+ // 4 per 6db
+ uint8_t buf[FFTDISPLEN];
+};
+
+void fft_init_table(void);
+
+void fft_write(struct fmplayer_fft_data *data, const int16_t *buf, unsigned len);
+
+void fft_calc(struct fmplayer_fft_disp_data *ddata, struct fmplayer_fft_input_data *idata);
+
+#endif // MYON_FMPLAYER_FFT_FFT_H_INCLUDED
diff --git a/fft/fftwindow.h b/fft/fftwindow.h
new file mode 100644
index 0000000..7dd26dc
--- /dev/null
+++ b/fft/fftwindow.h
@@ -0,0 +1,1026 @@
+static const uint16_t window[8192] = {
+ 5242, 5242, 5242, 5242, 5243, 5243, 5243, 5243,
+ 5243, 5243, 5243, 5243, 5244, 5244, 5244, 5244,
+ 5245, 5245, 5245, 5246, 5246, 5246, 5247, 5247,
+ 5247, 5248, 5248, 5249, 5249, 5250, 5250, 5251,
+ 5251, 5252, 5253, 5253, 5254, 5255, 5255, 5256,
+ 5257, 5257, 5258, 5259, 5260, 5260, 5261, 5262,
+ 5263, 5264, 5265, 5265, 5266, 5267, 5268, 5269,
+ 5270, 5271, 5272, 5273, 5274, 5275, 5276, 5278,
+ 5279, 5280, 5281, 5282, 5283, 5285, 5286, 5287,
+ 5288, 5290, 5291, 5292, 5294, 5295, 5296, 5298,
+ 5299, 5301, 5302, 5303, 5305, 5306, 5308, 5309,
+ 5311, 5313, 5314, 5316, 5317, 5319, 5321, 5322,
+ 5324, 5326, 5328, 5329, 5331, 5333, 5335, 5336,
+ 5338, 5340, 5342, 5344, 5346, 5348, 5350, 5352,
+ 5354, 5356, 5358, 5360, 5362, 5364, 5366, 5368,
+ 5370, 5372, 5374, 5376, 5379, 5381, 5383, 5385,
+ 5388, 5390, 5392, 5394, 5397, 5399, 5401, 5404,
+ 5406, 5409, 5411, 5414, 5416, 5419, 5421, 5424,
+ 5426, 5429, 5431, 5434, 5436, 5439, 5442, 5444,
+ 5447, 5450, 5452, 5455, 5458, 5461, 5464, 5466,
+ 5469, 5472, 5475, 5478, 5481, 5484, 5486, 5489,
+ 5492, 5495, 5498, 5501, 5504, 5507, 5511, 5514,
+ 5517, 5520, 5523, 5526, 5529, 5532, 5536, 5539,
+ 5542, 5545, 5549, 5552, 5555, 5559, 5562, 5565,
+ 5569, 5572, 5576, 5579, 5582, 5586, 5589, 5593,
+ 5596, 5600, 5604, 5607, 5611, 5614, 5618, 5622,
+ 5625, 5629, 5633, 5636, 5640, 5644, 5648, 5651,
+ 5655, 5659, 5663, 5667, 5671, 5675, 5678, 5682,
+ 5686, 5690, 5694, 5698, 5702, 5706, 5710, 5714,
+ 5719, 5723, 5727, 5731, 5735, 5739, 5743, 5748,
+ 5752, 5756, 5760, 5765, 5769, 5773, 5778, 5782,
+ 5786, 5791, 5795, 5799, 5804, 5808, 5813, 5817,
+ 5822, 5826, 5831, 5835, 5840, 5845, 5849, 5854,
+ 5858, 5863, 5868, 5872, 5877, 5882, 5887, 5891,
+ 5896, 5901, 5906, 5911, 5915, 5920, 5925, 5930,
+ 5935, 5940, 5945, 5950, 5955, 5960, 5965, 5970,
+ 5975, 5980, 5985, 5990, 5995, 6001, 6006, 6011,
+ 6016, 6021, 6027, 6032, 6037, 6042, 6048, 6053,
+ 6058, 6064, 6069, 6074, 6080, 6085, 6091, 6096,
+ 6102, 6107, 6113, 6118, 6124, 6129, 6135, 6140,
+ 6146, 6152, 6157, 6163, 6169, 6174, 6180, 6186,
+ 6192, 6197, 6203, 6209, 6215, 6221, 6226, 6232,
+ 6238, 6244, 6250, 6256, 6262, 6268, 6274, 6280,
+ 6286, 6292, 6298, 6304, 6310, 6316, 6322, 6329,
+ 6335, 6341, 6347, 6353, 6359, 6366, 6372, 6378,
+ 6385, 6391, 6397, 6404, 6410, 6416, 6423, 6429,
+ 6436, 6442, 6448, 6455, 6461, 6468, 6475, 6481,
+ 6488, 6494, 6501, 6507, 6514, 6521, 6527, 6534,
+ 6541, 6548, 6554, 6561, 6568, 6575, 6581, 6588,
+ 6595, 6602, 6609, 6616, 6623, 6630, 6636, 6643,
+ 6650, 6657, 6664, 6671, 6678, 6686, 6693, 6700,
+ 6707, 6714, 6721, 6728, 6735, 6743, 6750, 6757,
+ 6764, 6772, 6779, 6786, 6793, 6801, 6808, 6815,
+ 6823, 6830, 6838, 6845, 6853, 6860, 6868, 6875,
+ 6883, 6890, 6898, 6905, 6913, 6920, 6928, 6936,
+ 6943, 6951, 6959, 6966, 6974, 6982, 6990, 6997,
+ 7005, 7013, 7021, 7029, 7036, 7044, 7052, 7060,
+ 7068, 7076, 7084, 7092, 7100, 7108, 7116, 7124,
+ 7132, 7140, 7148, 7156, 7164, 7172, 7180, 7189,
+ 7197, 7205, 7213, 7221, 7230, 7238, 7246, 7255,
+ 7263, 7271, 7280, 7288, 7296, 7305, 7313, 7322,
+ 7330, 7338, 7347, 7355, 7364, 7373, 7381, 7390,
+ 7398, 7407, 7415, 7424, 7433, 7441, 7450, 7459,
+ 7467, 7476, 7485, 7494, 7502, 7511, 7520, 7529,
+ 7538, 7547, 7555, 7564, 7573, 7582, 7591, 7600,
+ 7609, 7618, 7627, 7636, 7645, 7654, 7663, 7672,
+ 7681, 7691, 7700, 7709, 7718, 7727, 7736, 7746,
+ 7755, 7764, 7773, 7783, 7792, 7801, 7811, 7820,
+ 7829, 7839, 7848, 7857, 7867, 7876, 7886, 7895,
+ 7905, 7914, 7924, 7933, 7943, 7952, 7962, 7972,
+ 7981, 7991, 8001, 8010, 8020, 8030, 8039, 8049,
+ 8059, 8069, 8078, 8088, 8098, 8108, 8118, 8128,
+ 8137, 8147, 8157, 8167, 8177, 8187, 8197, 8207,
+ 8217, 8227, 8237, 8247, 8257, 8267, 8277, 8288,
+ 8298, 8308, 8318, 8328, 8338, 8349, 8359, 8369,
+ 8379, 8390, 8400, 8410, 8421, 8431, 8441, 8452,
+ 8462, 8472, 8483, 8493, 8504, 8514, 8525, 8535,
+ 8546, 8556, 8567, 8577, 8588, 8599, 8609, 8620,
+ 8630, 8641, 8652, 8662, 8673, 8684, 8695, 8705,
+ 8716, 8727, 8738, 8749, 8759, 8770, 8781, 8792,
+ 8803, 8814, 8825, 8836, 8847, 8858, 8869, 8880,
+ 8891, 8902, 8913, 8924, 8935, 8946, 8957, 8968,
+ 8979, 8990, 9002, 9013, 9024, 9035, 9047, 9058,
+ 9069, 9080, 9092, 9103, 9114, 9126, 9137, 9148,
+ 9160, 9171, 9183, 9194, 9205, 9217, 9228, 9240,
+ 9251, 9263, 9275, 9286, 9298, 9309, 9321, 9332,
+ 9344, 9356, 9367, 9379, 9391, 9403, 9414, 9426,
+ 9438, 9450, 9461, 9473, 9485, 9497, 9509, 9521,
+ 9532, 9544, 9556, 9568, 9580, 9592, 9604, 9616,
+ 9628, 9640, 9652, 9664, 9676, 9688, 9700, 9712,
+ 9725, 9737, 9749, 9761, 9773, 9785, 9798, 9810,
+ 9822, 9834, 9847, 9859, 9871, 9884, 9896, 9908,
+ 9921, 9933, 9945, 9958, 9970, 9983, 9995, 10008,
+ 10020, 10033, 10045, 10058, 10070, 10083, 10095, 10108,
+ 10121, 10133, 10146, 10158, 10171, 10184, 10196, 10209,
+ 10222, 10235, 10247, 10260, 10273, 10286, 10299, 10311,
+ 10324, 10337, 10350, 10363, 10376, 10389, 10402, 10414,
+ 10427, 10440, 10453, 10466, 10479, 10492, 10506, 10519,
+ 10532, 10545, 10558, 10571, 10584, 10597, 10610, 10624,
+ 10637, 10650, 10663, 10676, 10690, 10703, 10716, 10730,
+ 10743, 10756, 10770, 10783, 10796, 10810, 10823, 10836,
+ 10850, 10863, 10877, 10890, 10904, 10917, 10931, 10944,
+ 10958, 10971, 10985, 10999, 11012, 11026, 11039, 11053,
+ 11067, 11080, 11094, 11108, 11121, 11135, 11149, 11163,
+ 11176, 11190, 11204, 11218, 11232, 11245, 11259, 11273,
+ 11287, 11301, 11315, 11329, 11343, 11357, 11371, 11385,
+ 11399, 11413, 11427, 11441, 11455, 11469, 11483, 11497,
+ 11511, 11525, 11539, 11554, 11568, 11582, 11596, 11610,
+ 11625, 11639, 11653, 11667, 11682, 11696, 11710, 11724,
+ 11739, 11753, 11767, 11782, 11796, 11811, 11825, 11840,
+ 11854, 11868, 11883, 11897, 11912, 11926, 11941, 11955,
+ 11970, 11985, 11999, 12014, 12028, 12043, 12058, 12072,
+ 12087, 12102, 12116, 12131, 12146, 12160, 12175, 12190,
+ 12205, 12220, 12234, 12249, 12264, 12279, 12294, 12309,
+ 12323, 12338, 12353, 12368, 12383, 12398, 12413, 12428,
+ 12443, 12458, 12473, 12488, 12503, 12518, 12533, 12548,
+ 12563, 12579, 12594, 12609, 12624, 12639, 12654, 12669,
+ 12685, 12700, 12715, 12730, 12746, 12761, 12776, 12792,
+ 12807, 12822, 12837, 12853, 12868, 12884, 12899, 12914,
+ 12930, 12945, 12961, 12976, 12992, 13007, 13023, 13038,
+ 13054, 13069, 13085, 13100, 13116, 13131, 13147, 13163,
+ 13178, 13194, 13210, 13225, 13241, 13257, 13272, 13288,
+ 13304, 13320, 13335, 13351, 13367, 13383, 13398, 13414,
+ 13430, 13446, 13462, 13478, 13494, 13510, 13525, 13541,
+ 13557, 13573, 13589, 13605, 13621, 13637, 13653, 13669,
+ 13685, 13701, 13717, 13734, 13750, 13766, 13782, 13798,
+ 13814, 13830, 13846, 13863, 13879, 13895, 13911, 13927,
+ 13944, 13960, 13976, 13993, 14009, 14025, 14041, 14058,
+ 14074, 14091, 14107, 14123, 14140, 14156, 14172, 14189,
+ 14205, 14222, 14238, 14255, 14271, 14288, 14304, 14321,
+ 14337, 14354, 14371, 14387, 14404, 14420, 14437, 14454,
+ 14470, 14487, 14504, 14520, 14537, 14554, 14570, 14587,
+ 14604, 14621, 14637, 14654, 14671, 14688, 14705, 14721,
+ 14738, 14755, 14772, 14789, 14806, 14823, 14840, 14856,
+ 14873, 14890, 14907, 14924, 14941, 14958, 14975, 14992,
+ 15009, 15026, 15043, 15060, 15078, 15095, 15112, 15129,
+ 15146, 15163, 15180, 15197, 15215, 15232, 15249, 15266,
+ 15283, 15301, 15318, 15335, 15353, 15370, 15387, 15404,
+ 15422, 15439, 15456, 15474, 15491, 15508, 15526, 15543,
+ 15561, 15578, 15596, 15613, 15630, 15648, 15665, 15683,
+ 15700, 15718, 15735, 15753, 15771, 15788, 15806, 15823,
+ 15841, 15858, 15876, 15894, 15911, 15929, 15947, 15964,
+ 15982, 16000, 16018, 16035, 16053, 16071, 16088, 16106,
+ 16124, 16142, 16160, 16177, 16195, 16213, 16231, 16249,
+ 16267, 16285, 16302, 16320, 16338, 16356, 16374, 16392,
+ 16410, 16428, 16446, 16464, 16482, 16500, 16518, 16536,
+ 16554, 16572, 16590, 16608, 16626, 16645, 16663, 16681,
+ 16699, 16717, 16735, 16753, 16772, 16790, 16808, 16826,
+ 16844, 16863, 16881, 16899, 16917, 16936, 16954, 16972,
+ 16991, 17009, 17027, 17046, 17064, 17082, 17101, 17119,
+ 17138, 17156, 17174, 17193, 17211, 17230, 17248, 17267,
+ 17285, 17304, 17322, 17341, 17359, 17378, 17396, 17415,
+ 17433, 17452, 17471, 17489, 17508, 17526, 17545, 17564,
+ 17582, 17601, 17620, 17638, 17657, 17676, 17695, 17713,
+ 17732, 17751, 17769, 17788, 17807, 17826, 17845, 17863,
+ 17882, 17901, 17920, 17939, 17958, 17977, 17995, 18014,
+ 18033, 18052, 18071, 18090, 18109, 18128, 18147, 18166,
+ 18185, 18204, 18223, 18242, 18261, 18280, 18299, 18318,
+ 18337, 18356, 18375, 18394, 18413, 18432, 18452, 18471,
+ 18490, 18509, 18528, 18547, 18567, 18586, 18605, 18624,
+ 18643, 18663, 18682, 18701, 18720, 18740, 18759, 18778,
+ 18798, 18817, 18836, 18856, 18875, 18894, 18914, 18933,
+ 18952, 18972, 18991, 19011, 19030, 19049, 19069, 19088,
+ 19108, 19127, 19147, 19166, 19186, 19205, 19225, 19244,
+ 19264, 19283, 19303, 19322, 19342, 19362, 19381, 19401,
+ 19420, 19440, 19460, 19479, 19499, 19519, 19538, 19558,
+ 19578, 19597, 19617, 19637, 19656, 19676, 19696, 19716,
+ 19735, 19755, 19775, 19795, 19814, 19834, 19854, 19874,
+ 19894, 19914, 19933, 19953, 19973, 19993, 20013, 20033,
+ 20053, 20073, 20093, 20113, 20132, 20152, 20172, 20192,
+ 20212, 20232, 20252, 20272, 20292, 20312, 20332, 20352,
+ 20372, 20392, 20413, 20433, 20453, 20473, 20493, 20513,
+ 20533, 20553, 20573, 20594, 20614, 20634, 20654, 20674,
+ 20694, 20715, 20735, 20755, 20775, 20795, 20816, 20836,
+ 20856, 20876, 20897, 20917, 20937, 20958, 20978, 20998,
+ 21019, 21039, 21059, 21080, 21100, 21120, 21141, 21161,
+ 21181, 21202, 21222, 21243, 21263, 21284, 21304, 21324,
+ 21345, 21365, 21386, 21406, 21427, 21447, 21468, 21488,
+ 21509, 21529, 21550, 21570, 21591, 21612, 21632, 21653,
+ 21673, 21694, 21715, 21735, 21756, 21776, 21797, 21818,
+ 21838, 21859, 21880, 21900, 21921, 21942, 21962, 21983,
+ 22004, 22025, 22045, 22066, 22087, 22108, 22128, 22149,
+ 22170, 22191, 22211, 22232, 22253, 22274, 22295, 22316,
+ 22336, 22357, 22378, 22399, 22420, 22441, 22462, 22482,
+ 22503, 22524, 22545, 22566, 22587, 22608, 22629, 22650,
+ 22671, 22692, 22713, 22734, 22755, 22776, 22797, 22818,
+ 22839, 22860, 22881, 22902, 22923, 22944, 22965, 22986,
+ 23007, 23028, 23049, 23071, 23092, 23113, 23134, 23155,
+ 23176, 23197, 23218, 23240, 23261, 23282, 23303, 23324,
+ 23346, 23367, 23388, 23409, 23430, 23452, 23473, 23494,
+ 23515, 23537, 23558, 23579, 23600, 23622, 23643, 23664,
+ 23686, 23707, 23728, 23750, 23771, 23792, 23814, 23835,
+ 23856, 23878, 23899, 23920, 23942, 23963, 23985, 24006,
+ 24028, 24049, 24070, 24092, 24113, 24135, 24156, 24178,
+ 24199, 24221, 24242, 24264, 24285, 24307, 24328, 24350,
+ 24371, 24393, 24414, 24436, 24457, 24479, 24500, 24522,
+ 24543, 24565, 24587, 24608, 24630, 24651, 24673, 24695,
+ 24716, 24738, 24760, 24781, 24803, 24825, 24846, 24868,
+ 24890, 24911, 24933, 24955, 24976, 24998, 25020, 25041,
+ 25063, 25085, 25107, 25128, 25150, 25172, 25194, 25215,
+ 25237, 25259, 25281, 25302, 25324, 25346, 25368, 25390,
+ 25412, 25433, 25455, 25477, 25499, 25521, 25543, 25564,
+ 25586, 25608, 25630, 25652, 25674, 25696, 25718, 25739,
+ 25761, 25783, 25805, 25827, 25849, 25871, 25893, 25915,
+ 25937, 25959, 25981, 26003, 26025, 26047, 26069, 26091,
+ 26113, 26135, 26157, 26179, 26201, 26223, 26245, 26267,
+ 26289, 26311, 26333, 26355, 26377, 26399, 26421, 26443,
+ 26465, 26488, 26510, 26532, 26554, 26576, 26598, 26620,
+ 26642, 26664, 26687, 26709, 26731, 26753, 26775, 26797,
+ 26820, 26842, 26864, 26886, 26908, 26930, 26953, 26975,
+ 26997, 27019, 27042, 27064, 27086, 27108, 27130, 27153,
+ 27175, 27197, 27219, 27242, 27264, 27286, 27309, 27331,
+ 27353, 27375, 27398, 27420, 27442, 27465, 27487, 27509,
+ 27532, 27554, 27576, 27599, 27621, 27643, 27666, 27688,
+ 27710, 27733, 27755, 27777, 27800, 27822, 27845, 27867,
+ 27889, 27912, 27934, 27957, 27979, 28001, 28024, 28046,
+ 28069, 28091, 28114, 28136, 28158, 28181, 28203, 28226,
+ 28248, 28271, 28293, 28316, 28338, 28361, 28383, 28406,
+ 28428, 28451, 28473, 28496, 28518, 28541, 28563, 28586,
+ 28608, 28631, 28653, 28676, 28698, 28721, 28744, 28766,
+ 28789, 28811, 28834, 28856, 28879, 28902, 28924, 28947,
+ 28969, 28992, 29014, 29037, 29060, 29082, 29105, 29128,
+ 29150, 29173, 29195, 29218, 29241, 29263, 29286, 29309,
+ 29331, 29354, 29377, 29399, 29422, 29445, 29467, 29490,
+ 29513, 29535, 29558, 29581, 29603, 29626, 29649, 29671,
+ 29694, 29717, 29740, 29762, 29785, 29808, 29830, 29853,
+ 29876, 29899, 29921, 29944, 29967, 29990, 30012, 30035,
+ 30058, 30081, 30103, 30126, 30149, 30172, 30195, 30217,
+ 30240, 30263, 30286, 30308, 30331, 30354, 30377, 30400,
+ 30422, 30445, 30468, 30491, 30514, 30537, 30559, 30582,
+ 30605, 30628, 30651, 30674, 30696, 30719, 30742, 30765,
+ 30788, 30811, 30833, 30856, 30879, 30902, 30925, 30948,
+ 30971, 30994, 31016, 31039, 31062, 31085, 31108, 31131,
+ 31154, 31177, 31200, 31222, 31245, 31268, 31291, 31314,
+ 31337, 31360, 31383, 31406, 31429, 31452, 31475, 31497,
+ 31520, 31543, 31566, 31589, 31612, 31635, 31658, 31681,
+ 31704, 31727, 31750, 31773, 31796, 31819, 31842, 31865,
+ 31888, 31911, 31934, 31957, 31980, 32003, 32025, 32048,
+ 32071, 32094, 32117, 32140, 32163, 32186, 32209, 32232,
+ 32255, 32278, 32301, 32324, 32347, 32370, 32393, 32416,
+ 32439, 32462, 32485, 32509, 32532, 32555, 32578, 32601,
+ 32624, 32647, 32670, 32693, 32716, 32739, 32762, 32785,
+ 32808, 32831, 32854, 32877, 32900, 32923, 32946, 32969,
+ 32992, 33015, 33038, 33061, 33084, 33108, 33131, 33154,
+ 33177, 33200, 33223, 33246, 33269, 33292, 33315, 33338,
+ 33361, 33384, 33407, 33430, 33454, 33477, 33500, 33523,
+ 33546, 33569, 33592, 33615, 33638, 33661, 33684, 33707,
+ 33731, 33754, 33777, 33800, 33823, 33846, 33869, 33892,
+ 33915, 33938, 33962, 33985, 34008, 34031, 34054, 34077,
+ 34100, 34123, 34146, 34169, 34193, 34216, 34239, 34262,
+ 34285, 34308, 34331, 34354, 34377, 34401, 34424, 34447,
+ 34470, 34493, 34516, 34539, 34562, 34585, 34609, 34632,
+ 34655, 34678, 34701, 34724, 34747, 34770, 34794, 34817,
+ 34840, 34863, 34886, 34909, 34932, 34955, 34978, 35002,
+ 35025, 35048, 35071, 35094, 35117, 35140, 35163, 35187,
+ 35210, 35233, 35256, 35279, 35302, 35325, 35348, 35372,
+ 35395, 35418, 35441, 35464, 35487, 35510, 35533, 35557,
+ 35580, 35603, 35626, 35649, 35672, 35695, 35718, 35742,
+ 35765, 35788, 35811, 35834, 35857, 35880, 35903, 35927,
+ 35950, 35973, 35996, 36019, 36042, 36065, 36088, 36112,
+ 36135, 36158, 36181, 36204, 36227, 36250, 36273, 36296,
+ 36320, 36343, 36366, 36389, 36412, 36435, 36458, 36481,
+ 36504, 36528, 36551, 36574, 36597, 36620, 36643, 36666,
+ 36689, 36712, 36736, 36759, 36782, 36805, 36828, 36851,
+ 36874, 36897, 36920, 36943, 36966, 36990, 37013, 37036,
+ 37059, 37082, 37105, 37128, 37151, 37174, 37197, 37220,
+ 37244, 37267, 37290, 37313, 37336, 37359, 37382, 37405,
+ 37428, 37451, 37474, 37497, 37520, 37544, 37567, 37590,
+ 37613, 37636, 37659, 37682, 37705, 37728, 37751, 37774,
+ 37797, 37820, 37843, 37866, 37889, 37912, 37935, 37958,
+ 37982, 38005, 38028, 38051, 38074, 38097, 38120, 38143,
+ 38166, 38189, 38212, 38235, 38258, 38281, 38304, 38327,
+ 38350, 38373, 38396, 38419, 38442, 38465, 38488, 38511,
+ 38534, 38557, 38580, 38603, 38626, 38649, 38672, 38695,
+ 38718, 38741, 38764, 38787, 38810, 38833, 38856, 38879,
+ 38902, 38925, 38948, 38971, 38994, 39017, 39039, 39062,
+ 39085, 39108, 39131, 39154, 39177, 39200, 39223, 39246,
+ 39269, 39292, 39315, 39338, 39361, 39384, 39406, 39429,
+ 39452, 39475, 39498, 39521, 39544, 39567, 39590, 39613,
+ 39636, 39658, 39681, 39704, 39727, 39750, 39773, 39796,
+ 39819, 39841, 39864, 39887, 39910, 39933, 39956, 39979,
+ 40002, 40024, 40047, 40070, 40093, 40116, 40139, 40161,
+ 40184, 40207, 40230, 40253, 40276, 40298, 40321, 40344,
+ 40367, 40390, 40412, 40435, 40458, 40481, 40504, 40526,
+ 40549, 40572, 40595, 40618, 40640, 40663, 40686, 40709,
+ 40731, 40754, 40777, 40800, 40822, 40845, 40868, 40891,
+ 40913, 40936, 40959, 40981, 41004, 41027, 41050, 41072,
+ 41095, 41118, 41140, 41163, 41186, 41209, 41231, 41254,
+ 41277, 41299, 41322, 41345, 41367, 41390, 41413, 41435,
+ 41458, 41481, 41503, 41526, 41549, 41571, 41594, 41616,
+ 41639, 41662, 41684, 41707, 41730, 41752, 41775, 41797,
+ 41820, 41842, 41865, 41888, 41910, 41933, 41955, 41978,
+ 42001, 42023, 42046, 42068, 42091, 42113, 42136, 42158,
+ 42181, 42203, 42226, 42248, 42271, 42293, 42316, 42339,
+ 42361, 42384, 42406, 42428, 42451, 42473, 42496, 42518,
+ 42541, 42563, 42586, 42608, 42631, 42653, 42676, 42698,
+ 42720, 42743, 42765, 42788, 42810, 42833, 42855, 42877,
+ 42900, 42922, 42945, 42967, 42989, 43012, 43034, 43056,
+ 43079, 43101, 43123, 43146, 43168, 43191, 43213, 43235,
+ 43258, 43280, 43302, 43324, 43347, 43369, 43391, 43414,
+ 43436, 43458, 43481, 43503, 43525, 43547, 43570, 43592,
+ 43614, 43636, 43659, 43681, 43703, 43725, 43747, 43770,
+ 43792, 43814, 43836, 43859, 43881, 43903, 43925, 43947,
+ 43969, 43992, 44014, 44036, 44058, 44080, 44102, 44124,
+ 44147, 44169, 44191, 44213, 44235, 44257, 44279, 44301,
+ 44323, 44346, 44368, 44390, 44412, 44434, 44456, 44478,
+ 44500, 44522, 44544, 44566, 44588, 44610, 44632, 44654,
+ 44676, 44698, 44720, 44742, 44764, 44786, 44808, 44830,
+ 44852, 44874, 44896, 44918, 44940, 44962, 44984, 45006,
+ 45027, 45049, 45071, 45093, 45115, 45137, 45159, 45181,
+ 45203, 45224, 45246, 45268, 45290, 45312, 45334, 45355,
+ 45377, 45399, 45421, 45443, 45465, 45486, 45508, 45530,
+ 45552, 45573, 45595, 45617, 45639, 45660, 45682, 45704,
+ 45726, 45747, 45769, 45791, 45812, 45834, 45856, 45878,
+ 45899, 45921, 45943, 45964, 45986, 46008, 46029, 46051,
+ 46072, 46094, 46116, 46137, 46159, 46180, 46202, 46224,
+ 46245, 46267, 46288, 46310, 46331, 46353, 46375, 46396,
+ 46418, 46439, 46461, 46482, 46504, 46525, 46547, 46568,
+ 46590, 46611, 46632, 46654, 46675, 46697, 46718, 46740,
+ 46761, 46783, 46804, 46825, 46847, 46868, 46889, 46911,
+ 46932, 46954, 46975, 46996, 47018, 47039, 47060, 47082,
+ 47103, 47124, 47145, 47167, 47188, 47209, 47231, 47252,
+ 47273, 47294, 47316, 47337, 47358, 47379, 47401, 47422,
+ 47443, 47464, 47485, 47506, 47528, 47549, 47570, 47591,
+ 47612, 47633, 47655, 47676, 47697, 47718, 47739, 47760,
+ 47781, 47802, 47823, 47844, 47865, 47886, 47907, 47929,
+ 47950, 47971, 47992, 48013, 48034, 48055, 48076, 48097,
+ 48117, 48138, 48159, 48180, 48201, 48222, 48243, 48264,
+ 48285, 48306, 48327, 48348, 48368, 48389, 48410, 48431,
+ 48452, 48473, 48494, 48514, 48535, 48556, 48577, 48598,
+ 48618, 48639, 48660, 48681, 48701, 48722, 48743, 48764,
+ 48784, 48805, 48826, 48847, 48867, 48888, 48909, 48929,
+ 48950, 48971, 48991, 49012, 49032, 49053, 49074, 49094,
+ 49115, 49135, 49156, 49177, 49197, 49218, 49238, 49259,
+ 49279, 49300, 49320, 49341, 49361, 49382, 49402, 49423,
+ 49443, 49464, 49484, 49505, 49525, 49545, 49566, 49586,
+ 49607, 49627, 49647, 49668, 49688, 49708, 49729, 49749,
+ 49769, 49790, 49810, 49830, 49851, 49871, 49891, 49912,
+ 49932, 49952, 49972, 49993, 50013, 50033, 50053, 50073,
+ 50094, 50114, 50134, 50154, 50174, 50194, 50215, 50235,
+ 50255, 50275, 50295, 50315, 50335, 50355, 50375, 50395,
+ 50415, 50436, 50456, 50476, 50496, 50516, 50536, 50556,
+ 50576, 50596, 50615, 50635, 50655, 50675, 50695, 50715,
+ 50735, 50755, 50775, 50795, 50815, 50834, 50854, 50874,
+ 50894, 50914, 50934, 50953, 50973, 50993, 51013, 51033,
+ 51052, 51072, 51092, 51112, 51131, 51151, 51171, 51190,
+ 51210, 51230, 51250, 51269, 51289, 51308, 51328, 51348,
+ 51367, 51387, 51407, 51426, 51446, 51465, 51485, 51504,
+ 51524, 51543, 51563, 51582, 51602, 51621, 51641, 51660,
+ 51680, 51699, 51719, 51738, 51758, 51777, 51796, 51816,
+ 51835, 51855, 51874, 51893, 51913, 51932, 51951, 51971,
+ 51990, 52009, 52029, 52048, 52067, 52086, 52106, 52125,
+ 52144, 52163, 52183, 52202, 52221, 52240, 52259, 52278,
+ 52298, 52317, 52336, 52355, 52374, 52393, 52412, 52431,
+ 52450, 52469, 52489, 52508, 52527, 52546, 52565, 52584,
+ 52603, 52622, 52641, 52660, 52678, 52697, 52716, 52735,
+ 52754, 52773, 52792, 52811, 52830, 52849, 52867, 52886,
+ 52905, 52924, 52943, 52961, 52980, 52999, 53018, 53037,
+ 53055, 53074, 53093, 53111, 53130, 53149, 53168, 53186,
+ 53205, 53224, 53242, 53261, 53279, 53298, 53317, 53335,
+ 53354, 53372, 53391, 53409, 53428, 53446, 53465, 53483,
+ 53502, 53520, 53539, 53557, 53576, 53594, 53613, 53631,
+ 53650, 53668, 53686, 53705, 53723, 53741, 53760, 53778,
+ 53796, 53815, 53833, 53851, 53870, 53888, 53906, 53924,
+ 53943, 53961, 53979, 53997, 54015, 54034, 54052, 54070,
+ 54088, 54106, 54124, 54142, 54160, 54179, 54197, 54215,
+ 54233, 54251, 54269, 54287, 54305, 54323, 54341, 54359,
+ 54377, 54395, 54413, 54431, 54449, 54466, 54484, 54502,
+ 54520, 54538, 54556, 54574, 54592, 54609, 54627, 54645,
+ 54663, 54681, 54698, 54716, 54734, 54752, 54769, 54787,
+ 54805, 54822, 54840, 54858, 54875, 54893, 54911, 54928,
+ 54946, 54963, 54981, 54999, 55016, 55034, 55051, 55069,
+ 55086, 55104, 55121, 55139, 55156, 55174, 55191, 55208,
+ 55226, 55243, 55261, 55278, 55295, 55313, 55330, 55347,
+ 55365, 55382, 55399, 55417, 55434, 55451, 55469, 55486,
+ 55503, 55520, 55537, 55555, 55572, 55589, 55606, 55623,
+ 55640, 55658, 55675, 55692, 55709, 55726, 55743, 55760,
+ 55777, 55794, 55811, 55828, 55845, 55862, 55879, 55896,
+ 55913, 55930, 55947, 55964, 55981, 55998, 56014, 56031,
+ 56048, 56065, 56082, 56099, 56115, 56132, 56149, 56166,
+ 56182, 56199, 56216, 56233, 56249, 56266, 56283, 56299,
+ 56316, 56333, 56349, 56366, 56382, 56399, 56416, 56432,
+ 56449, 56465, 56482, 56498, 56515, 56531, 56548, 56564,
+ 56581, 56597, 56614, 56630, 56646, 56663, 56679, 56696,
+ 56712, 56728, 56745, 56761, 56777, 56793, 56810, 56826,
+ 56842, 56859, 56875, 56891, 56907, 56923, 56940, 56956,
+ 56972, 56988, 57004, 57020, 57036, 57052, 57068, 57085,
+ 57101, 57117, 57133, 57149, 57165, 57181, 57197, 57213,
+ 57229, 57244, 57260, 57276, 57292, 57308, 57324, 57340,
+ 57356, 57371, 57387, 57403, 57419, 57435, 57450, 57466,
+ 57482, 57498, 57513, 57529, 57545, 57560, 57576, 57592,
+ 57607, 57623, 57639, 57654, 57670, 57685, 57701, 57716,
+ 57732, 57748, 57763, 57779, 57794, 57809, 57825, 57840,
+ 57856, 57871, 57887, 57902, 57917, 57933, 57948, 57963,
+ 57979, 57994, 58009, 58025, 58040, 58055, 58070, 58086,
+ 58101, 58116, 58131, 58146, 58162, 58177, 58192, 58207,
+ 58222, 58237, 58252, 58267, 58282, 58297, 58312, 58327,
+ 58342, 58357, 58372, 58387, 58402, 58417, 58432, 58447,
+ 58462, 58477, 58492, 58506, 58521, 58536, 58551, 58566,
+ 58581, 58595, 58610, 58625, 58640, 58654, 58669, 58684,
+ 58698, 58713, 58728, 58742, 58757, 58771, 58786, 58801,
+ 58815, 58830, 58844, 58859, 58873, 58888, 58902, 58917,
+ 58931, 58946, 58960, 58974, 58989, 59003, 59018, 59032,
+ 59046, 59061, 59075, 59089, 59103, 59118, 59132, 59146,
+ 59160, 59175, 59189, 59203, 59217, 59231, 59246, 59260,
+ 59274, 59288, 59302, 59316, 59330, 59344, 59358, 59372,
+ 59386, 59400, 59414, 59428, 59442, 59456, 59470, 59484,
+ 59498, 59512, 59525, 59539, 59553, 59567, 59581, 59595,
+ 59608, 59622, 59636, 59650, 59663, 59677, 59691, 59704,
+ 59718, 59732, 59745, 59759, 59773, 59786, 59800, 59813,
+ 59827, 59840, 59854, 59867, 59881, 59894, 59908, 59921,
+ 59935, 59948, 59962, 59975, 59988, 60002, 60015, 60028,
+ 60042, 60055, 60068, 60082, 60095, 60108, 60121, 60134,
+ 60148, 60161, 60174, 60187, 60200, 60213, 60227, 60240,
+ 60253, 60266, 60279, 60292, 60305, 60318, 60331, 60344,
+ 60357, 60370, 60383, 60396, 60409, 60422, 60434, 60447,
+ 60460, 60473, 60486, 60499, 60511, 60524, 60537, 60550,
+ 60562, 60575, 60588, 60600, 60613, 60626, 60638, 60651,
+ 60664, 60676, 60689, 60701, 60714, 60727, 60739, 60752,
+ 60764, 60777, 60789, 60801, 60814, 60826, 60839, 60851,
+ 60863, 60876, 60888, 60900, 60913, 60925, 60937, 60950,
+ 60962, 60974, 60986, 60999, 61011, 61023, 61035, 61047,
+ 61059, 61071, 61084, 61096, 61108, 61120, 61132, 61144,
+ 61156, 61168, 61180, 61192, 61204, 61216, 61228, 61240,
+ 61251, 61263, 61275, 61287, 61299, 61311, 61322, 61334,
+ 61346, 61358, 61369, 61381, 61393, 61405, 61416, 61428,
+ 61440, 61451, 61463, 61474, 61486, 61498, 61509, 61521,
+ 61532, 61544, 61555, 61567, 61578, 61590, 61601, 61612,
+ 61624, 61635, 61647, 61658, 61669, 61681, 61692, 61703,
+ 61714, 61726, 61737, 61748, 61759, 61771, 61782, 61793,
+ 61804, 61815, 61826, 61837, 61849, 61860, 61871, 61882,
+ 61893, 61904, 61915, 61926, 61937, 61948, 61959, 61970,
+ 61980, 61991, 62002, 62013, 62024, 62035, 62046, 62056,
+ 62067, 62078, 62089, 62099, 62110, 62121, 62131, 62142,
+ 62153, 62163, 62174, 62185, 62195, 62206, 62216, 62227,
+ 62237, 62248, 62258, 62269, 62279, 62290, 62300, 62311,
+ 62321, 62331, 62342, 62352, 62362, 62373, 62383, 62393,
+ 62404, 62414, 62424, 62434, 62445, 62455, 62465, 62475,
+ 62485, 62495, 62505, 62516, 62526, 62536, 62546, 62556,
+ 62566, 62576, 62586, 62596, 62606, 62616, 62626, 62635,
+ 62645, 62655, 62665, 62675, 62685, 62695, 62704, 62714,
+ 62724, 62734, 62743, 62753, 62763, 62772, 62782, 62792,
+ 62801, 62811, 62821, 62830, 62840, 62849, 62859, 62868,
+ 62878, 62887, 62897, 62906, 62916, 62925, 62935, 62944,
+ 62953, 62963, 62972, 62981, 62991, 63000, 63009, 63018,
+ 63028, 63037, 63046, 63055, 63064, 63074, 63083, 63092,
+ 63101, 63110, 63119, 63128, 63137, 63146, 63155, 63164,
+ 63173, 63182, 63191, 63200, 63209, 63218, 63227, 63236,
+ 63245, 63253, 63262, 63271, 63280, 63289, 63297, 63306,
+ 63315, 63324, 63332, 63341, 63350, 63358, 63367, 63375,
+ 63384, 63393, 63401, 63410, 63418, 63427, 63435, 63444,
+ 63452, 63461, 63469, 63477, 63486, 63494, 63502, 63511,
+ 63519, 63527, 63536, 63544, 63552, 63561, 63569, 63577,
+ 63585, 63593, 63601, 63610, 63618, 63626, 63634, 63642,
+ 63650, 63658, 63666, 63674, 63682, 63690, 63698, 63706,
+ 63714, 63722, 63730, 63738, 63745, 63753, 63761, 63769,
+ 63777, 63784, 63792, 63800, 63808, 63815, 63823, 63831,
+ 63838, 63846, 63854, 63861, 63869, 63876, 63884, 63892,
+ 63899, 63907, 63914, 63922, 63929, 63936, 63944, 63951,
+ 63959, 63966, 63973, 63981, 63988, 63995, 64003, 64010,
+ 64017, 64024, 64032, 64039, 64046, 64053, 64060, 64068,
+ 64075, 64082, 64089, 64096, 64103, 64110, 64117, 64124,
+ 64131, 64138, 64145, 64152, 64159, 64166, 64173, 64179,
+ 64186, 64193, 64200, 64207, 64213, 64220, 64227, 64234,
+ 64240, 64247, 64254, 64260, 64267, 64274, 64280, 64287,
+ 64294, 64300, 64307, 64313, 64320, 64326, 64333, 64339,
+ 64346, 64352, 64358, 64365, 64371, 64377, 64384, 64390,
+ 64396, 64403, 64409, 64415, 64422, 64428, 64434, 64440,
+ 64446, 64452, 64459, 64465, 64471, 64477, 64483, 64489,
+ 64495, 64501, 64507, 64513, 64519, 64525, 64531, 64537,
+ 64543, 64549, 64554, 64560, 64566, 64572, 64578, 64583,
+ 64589, 64595, 64601, 64606, 64612, 64618, 64623, 64629,
+ 64635, 64640, 64646, 64651, 64657, 64662, 64668, 64673,
+ 64679, 64684, 64690, 64695, 64701, 64706, 64711, 64717,
+ 64722, 64728, 64733, 64738, 64743, 64749, 64754, 64759,
+ 64764, 64770, 64775, 64780, 64785, 64790, 64795, 64800,
+ 64805, 64810, 64815, 64820, 64825, 64830, 64835, 64840,
+ 64845, 64850, 64855, 64860, 64865, 64870, 64874, 64879,
+ 64884, 64889, 64894, 64898, 64903, 64908, 64912, 64917,
+ 64922, 64926, 64931, 64936, 64940, 64945, 64949, 64954,
+ 64958, 64963, 64967, 64972, 64976, 64981, 64985, 64989,
+ 64994, 64998, 65003, 65007, 65011, 65015, 65020, 65024,
+ 65028, 65032, 65037, 65041, 65045, 65049, 65053, 65057,
+ 65061, 65065, 65070, 65074, 65078, 65082, 65086, 65090,
+ 65094, 65097, 65101, 65105, 65109, 65113, 65117, 65121,
+ 65125, 65128, 65132, 65136, 65140, 65143, 65147, 65151,
+ 65154, 65158, 65162, 65165, 65169, 65173, 65176, 65180,
+ 65183, 65187, 65190, 65194, 65197, 65201, 65204, 65207,
+ 65211, 65214, 65218, 65221, 65224, 65228, 65231, 65234,
+ 65237, 65241, 65244, 65247, 65250, 65253, 65256, 65260,
+ 65263, 65266, 65269, 65272, 65275, 65278, 65281, 65284,
+ 65287, 65290, 65293, 65296, 65299, 65302, 65304, 65307,
+ 65310, 65313, 65316, 65319, 65321, 65324, 65327, 65329,
+ 65332, 65335, 65337, 65340, 65343, 65345, 65348, 65350,
+ 65353, 65356, 65358, 65361, 65363, 65366, 65368, 65370,
+ 65373, 65375, 65378, 65380, 65382, 65385, 65387, 65389,
+ 65391, 65394, 65396, 65398, 65400, 65403, 65405, 65407,
+ 65409, 65411, 65413, 65415, 65417, 65419, 65421, 65423,
+ 65425, 65427, 65429, 65431, 65433, 65435, 65437, 65439,
+ 65441, 65442, 65444, 65446, 65448, 65449, 65451, 65453,
+ 65455, 65456, 65458, 65460, 65461, 65463, 65464, 65466,
+ 65468, 65469, 65471, 65472, 65474, 65475, 65477, 65478,
+ 65479, 65481, 65482, 65484, 65485, 65486, 65488, 65489,
+ 65490, 65491, 65493, 65494, 65495, 65496, 65497, 65499,
+ 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507,
+ 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515,
+ 65515, 65516, 65517, 65518, 65519, 65519, 65520, 65521,
+ 65522, 65522, 65523, 65524, 65524, 65525, 65526, 65526,
+ 65527, 65527, 65528, 65528, 65529, 65529, 65530, 65530,
+ 65531, 65531, 65531, 65532, 65532, 65532, 65533, 65533,
+ 65533, 65534, 65534, 65534, 65534, 65535, 65535, 65535,
+ 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
+ 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
+ 65535, 65535, 65535, 65534, 65534, 65534, 65534, 65533,
+ 65533, 65533, 65532, 65532, 65532, 65531, 65531, 65531,
+ 65530, 65530, 65529, 65529, 65528, 65528, 65527, 65527,
+ 65526, 65526, 65525, 65524, 65524, 65523, 65522, 65522,
+ 65521, 65520, 65519, 65519, 65518, 65517, 65516, 65515,
+ 65515, 65514, 65513, 65512, 65511, 65510, 65509, 65508,
+ 65507, 65506, 65505, 65504, 65503, 65502, 65501, 65500,
+ 65499, 65497, 65496, 65495, 65494, 65493, 65491, 65490,
+ 65489, 65488, 65486, 65485, 65484, 65482, 65481, 65479,
+ 65478, 65477, 65475, 65474, 65472, 65471, 65469, 65468,
+ 65466, 65464, 65463, 65461, 65460, 65458, 65456, 65455,
+ 65453, 65451, 65449, 65448, 65446, 65444, 65442, 65441,
+ 65439, 65437, 65435, 65433, 65431, 65429, 65427, 65425,
+ 65423, 65421, 65419, 65417, 65415, 65413, 65411, 65409,
+ 65407, 65405, 65403, 65400, 65398, 65396, 65394, 65391,
+ 65389, 65387, 65385, 65382, 65380, 65378, 65375, 65373,
+ 65370, 65368, 65366, 65363, 65361, 65358, 65356, 65353,
+ 65350, 65348, 65345, 65343, 65340, 65337, 65335, 65332,
+ 65329, 65327, 65324, 65321, 65319, 65316, 65313, 65310,
+ 65307, 65304, 65302, 65299, 65296, 65293, 65290, 65287,
+ 65284, 65281, 65278, 65275, 65272, 65269, 65266, 65263,
+ 65260, 65256, 65253, 65250, 65247, 65244, 65241, 65237,
+ 65234, 65231, 65228, 65224, 65221, 65218, 65214, 65211,
+ 65207, 65204, 65201, 65197, 65194, 65190, 65187, 65183,
+ 65180, 65176, 65173, 65169, 65165, 65162, 65158, 65154,
+ 65151, 65147, 65143, 65140, 65136, 65132, 65128, 65125,
+ 65121, 65117, 65113, 65109, 65105, 65101, 65097, 65094,
+ 65090, 65086, 65082, 65078, 65074, 65070, 65065, 65061,
+ 65057, 65053, 65049, 65045, 65041, 65037, 65032, 65028,
+ 65024, 65020, 65015, 65011, 65007, 65003, 64998, 64994,
+ 64989, 64985, 64981, 64976, 64972, 64967, 64963, 64958,
+ 64954, 64949, 64945, 64940, 64936, 64931, 64926, 64922,
+ 64917, 64912, 64908, 64903, 64898, 64894, 64889, 64884,
+ 64879, 64874, 64870, 64865, 64860, 64855, 64850, 64845,
+ 64840, 64835, 64830, 64825, 64820, 64815, 64810, 64805,
+ 64800, 64795, 64790, 64785, 64780, 64775, 64770, 64764,
+ 64759, 64754, 64749, 64743, 64738, 64733, 64728, 64722,
+ 64717, 64711, 64706, 64701, 64695, 64690, 64684, 64679,
+ 64673, 64668, 64662, 64657, 64651, 64646, 64640, 64635,
+ 64629, 64623, 64618, 64612, 64606, 64601, 64595, 64589,
+ 64583, 64578, 64572, 64566, 64560, 64554, 64549, 64543,
+ 64537, 64531, 64525, 64519, 64513, 64507, 64501, 64495,
+ 64489, 64483, 64477, 64471, 64465, 64459, 64452, 64446,
+ 64440, 64434, 64428, 64422, 64415, 64409, 64403, 64396,
+ 64390, 64384, 64377, 64371, 64365, 64358, 64352, 64346,
+ 64339, 64333, 64326, 64320, 64313, 64307, 64300, 64294,
+ 64287, 64280, 64274, 64267, 64260, 64254, 64247, 64240,
+ 64234, 64227, 64220, 64213, 64207, 64200, 64193, 64186,
+ 64179, 64173, 64166, 64159, 64152, 64145, 64138, 64131,
+ 64124, 64117, 64110, 64103, 64096, 64089, 64082, 64075,
+ 64068, 64060, 64053, 64046, 64039, 64032, 64024, 64017,
+ 64010, 64003, 63995, 63988, 63981, 63973, 63966, 63959,
+ 63951, 63944, 63936, 63929, 63922, 63914, 63907, 63899,
+ 63892, 63884, 63876, 63869, 63861, 63854, 63846, 63838,
+ 63831, 63823, 63815, 63808, 63800, 63792, 63784, 63777,
+ 63769, 63761, 63753, 63745, 63738, 63730, 63722, 63714,
+ 63706, 63698, 63690, 63682, 63674, 63666, 63658, 63650,
+ 63642, 63634, 63626, 63618, 63610, 63601, 63593, 63585,
+ 63577, 63569, 63561, 63552, 63544, 63536, 63527, 63519,
+ 63511, 63502, 63494, 63486, 63477, 63469, 63461, 63452,
+ 63444, 63435, 63427, 63418, 63410, 63401, 63393, 63384,
+ 63375, 63367, 63358, 63350, 63341, 63332, 63324, 63315,
+ 63306, 63297, 63289, 63280, 63271, 63262, 63253, 63245,
+ 63236, 63227, 63218, 63209, 63200, 63191, 63182, 63173,
+ 63164, 63155, 63146, 63137, 63128, 63119, 63110, 63101,
+ 63092, 63083, 63074, 63064, 63055, 63046, 63037, 63028,
+ 63018, 63009, 63000, 62991, 62981, 62972, 62963, 62953,
+ 62944, 62935, 62925, 62916, 62906, 62897, 62887, 62878,
+ 62868, 62859, 62849, 62840, 62830, 62821, 62811, 62801,
+ 62792, 62782, 62772, 62763, 62753, 62743, 62734, 62724,
+ 62714, 62704, 62695, 62685, 62675, 62665, 62655, 62645,
+ 62635, 62626, 62616, 62606, 62596, 62586, 62576, 62566,
+ 62556, 62546, 62536, 62526, 62516, 62505, 62495, 62485,
+ 62475, 62465, 62455, 62445, 62434, 62424, 62414, 62404,
+ 62393, 62383, 62373, 62362, 62352, 62342, 62331, 62321,
+ 62311, 62300, 62290, 62279, 62269, 62258, 62248, 62237,
+ 62227, 62216, 62206, 62195, 62185, 62174, 62163, 62153,
+ 62142, 62131, 62121, 62110, 62099, 62089, 62078, 62067,
+ 62056, 62046, 62035, 62024, 62013, 62002, 61991, 61980,
+ 61970, 61959, 61948, 61937, 61926, 61915, 61904, 61893,
+ 61882, 61871, 61860, 61849, 61837, 61826, 61815, 61804,
+ 61793, 61782, 61771, 61759, 61748, 61737, 61726, 61714,
+ 61703, 61692, 61681, 61669, 61658, 61647, 61635, 61624,
+ 61612, 61601, 61590, 61578, 61567, 61555, 61544, 61532,
+ 61521, 61509, 61498, 61486, 61474, 61463, 61451, 61440,
+ 61428, 61416, 61405, 61393, 61381, 61369, 61358, 61346,
+ 61334, 61322, 61311, 61299, 61287, 61275, 61263, 61251,
+ 61240, 61228, 61216, 61204, 61192, 61180, 61168, 61156,
+ 61144, 61132, 61120, 61108, 61096, 61084, 61071, 61059,
+ 61047, 61035, 61023, 61011, 60999, 60986, 60974, 60962,
+ 60950, 60937, 60925, 60913, 60900, 60888, 60876, 60863,
+ 60851, 60839, 60826, 60814, 60801, 60789, 60777, 60764,
+ 60752, 60739, 60727, 60714, 60701, 60689, 60676, 60664,
+ 60651, 60638, 60626, 60613, 60600, 60588, 60575, 60562,
+ 60550, 60537, 60524, 60511, 60499, 60486, 60473, 60460,
+ 60447, 60434, 60422, 60409, 60396, 60383, 60370, 60357,
+ 60344, 60331, 60318, 60305, 60292, 60279, 60266, 60253,
+ 60240, 60227, 60213, 60200, 60187, 60174, 60161, 60148,
+ 60134, 60121, 60108, 60095, 60082, 60068, 60055, 60042,
+ 60028, 60015, 60002, 59988, 59975, 59962, 59948, 59935,
+ 59921, 59908, 59894, 59881, 59867, 59854, 59840, 59827,
+ 59813, 59800, 59786, 59773, 59759, 59745, 59732, 59718,
+ 59704, 59691, 59677, 59663, 59650, 59636, 59622, 59608,
+ 59595, 59581, 59567, 59553, 59539, 59525, 59512, 59498,
+ 59484, 59470, 59456, 59442, 59428, 59414, 59400, 59386,
+ 59372, 59358, 59344, 59330, 59316, 59302, 59288, 59274,
+ 59260, 59246, 59231, 59217, 59203, 59189, 59175, 59160,
+ 59146, 59132, 59118, 59103, 59089, 59075, 59061, 59046,
+ 59032, 59018, 59003, 58989, 58974, 58960, 58946, 58931,
+ 58917, 58902, 58888, 58873, 58859, 58844, 58830, 58815,
+ 58801, 58786, 58771, 58757, 58742, 58728, 58713, 58698,
+ 58684, 58669, 58654, 58640, 58625, 58610, 58595, 58581,
+ 58566, 58551, 58536, 58521, 58506, 58492, 58477, 58462,
+ 58447, 58432, 58417, 58402, 58387, 58372, 58357, 58342,
+ 58327, 58312, 58297, 58282, 58267, 58252, 58237, 58222,
+ 58207, 58192, 58177, 58162, 58146, 58131, 58116, 58101,
+ 58086, 58070, 58055, 58040, 58025, 58009, 57994, 57979,
+ 57963, 57948, 57933, 57917, 57902, 57887, 57871, 57856,
+ 57840, 57825, 57809, 57794, 57779, 57763, 57748, 57732,
+ 57716, 57701, 57685, 57670, 57654, 57639, 57623, 57607,
+ 57592, 57576, 57560, 57545, 57529, 57513, 57498, 57482,
+ 57466, 57450, 57435, 57419, 57403, 57387, 57371, 57356,
+ 57340, 57324, 57308, 57292, 57276, 57260, 57244, 57229,
+ 57213, 57197, 57181, 57165, 57149, 57133, 57117, 57101,
+ 57085, 57068, 57052, 57036, 57020, 57004, 56988, 56972,
+ 56956, 56940, 56923, 56907, 56891, 56875, 56859, 56842,
+ 56826, 56810, 56793, 56777, 56761, 56745, 56728, 56712,
+ 56696, 56679, 56663, 56646, 56630, 56614, 56597, 56581,
+ 56564, 56548, 56531, 56515, 56498, 56482, 56465, 56449,
+ 56432, 56416, 56399, 56382, 56366, 56349, 56333, 56316,
+ 56299, 56283, 56266, 56249, 56233, 56216, 56199, 56182,
+ 56166, 56149, 56132, 56115, 56099, 56082, 56065, 56048,
+ 56031, 56014, 55998, 55981, 55964, 55947, 55930, 55913,
+ 55896, 55879, 55862, 55845, 55828, 55811, 55794, 55777,
+ 55760, 55743, 55726, 55709, 55692, 55675, 55658, 55640,
+ 55623, 55606, 55589, 55572, 55555, 55537, 55520, 55503,
+ 55486, 55469, 55451, 55434, 55417, 55399, 55382, 55365,
+ 55347, 55330, 55313, 55295, 55278, 55261, 55243, 55226,
+ 55208, 55191, 55174, 55156, 55139, 55121, 55104, 55086,
+ 55069, 55051, 55034, 55016, 54999, 54981, 54963, 54946,
+ 54928, 54911, 54893, 54875, 54858, 54840, 54822, 54805,
+ 54787, 54769, 54752, 54734, 54716, 54698, 54681, 54663,
+ 54645, 54627, 54609, 54592, 54574, 54556, 54538, 54520,
+ 54502, 54484, 54466, 54449, 54431, 54413, 54395, 54377,
+ 54359, 54341, 54323, 54305, 54287, 54269, 54251, 54233,
+ 54215, 54197, 54179, 54160, 54142, 54124, 54106, 54088,
+ 54070, 54052, 54034, 54015, 53997, 53979, 53961, 53943,
+ 53924, 53906, 53888, 53870, 53851, 53833, 53815, 53796,
+ 53778, 53760, 53741, 53723, 53705, 53686, 53668, 53650,
+ 53631, 53613, 53594, 53576, 53557, 53539, 53520, 53502,
+ 53483, 53465, 53446, 53428, 53409, 53391, 53372, 53354,
+ 53335, 53317, 53298, 53279, 53261, 53242, 53224, 53205,
+ 53186, 53168, 53149, 53130, 53111, 53093, 53074, 53055,
+ 53037, 53018, 52999, 52980, 52961, 52943, 52924, 52905,
+ 52886, 52867, 52849, 52830, 52811, 52792, 52773, 52754,
+ 52735, 52716, 52697, 52678, 52660, 52641, 52622, 52603,
+ 52584, 52565, 52546, 52527, 52508, 52489, 52469, 52450,
+ 52431, 52412, 52393, 52374, 52355, 52336, 52317, 52298,
+ 52278, 52259, 52240, 52221, 52202, 52183, 52163, 52144,
+ 52125, 52106, 52086, 52067, 52048, 52029, 52009, 51990,
+ 51971, 51951, 51932, 51913, 51893, 51874, 51855, 51835,
+ 51816, 51796, 51777, 51758, 51738, 51719, 51699, 51680,
+ 51660, 51641, 51621, 51602, 51582, 51563, 51543, 51524,
+ 51504, 51485, 51465, 51446, 51426, 51407, 51387, 51367,
+ 51348, 51328, 51308, 51289, 51269, 51250, 51230, 51210,
+ 51190, 51171, 51151, 51131, 51112, 51092, 51072, 51052,
+ 51033, 51013, 50993, 50973, 50953, 50934, 50914, 50894,
+ 50874, 50854, 50834, 50815, 50795, 50775, 50755, 50735,
+ 50715, 50695, 50675, 50655, 50635, 50615, 50596, 50576,
+ 50556, 50536, 50516, 50496, 50476, 50456, 50436, 50415,
+ 50395, 50375, 50355, 50335, 50315, 50295, 50275, 50255,
+ 50235, 50215, 50194, 50174, 50154, 50134, 50114, 50094,
+ 50073, 50053, 50033, 50013, 49993, 49972, 49952, 49932,
+ 49912, 49891, 49871, 49851, 49830, 49810, 49790, 49769,
+ 49749, 49729, 49708, 49688, 49668, 49647, 49627, 49607,
+ 49586, 49566, 49545, 49525, 49505, 49484, 49464, 49443,
+ 49423, 49402, 49382, 49361, 49341, 49320, 49300, 49279,
+ 49259, 49238, 49218, 49197, 49177, 49156, 49135, 49115,
+ 49094, 49074, 49053, 49032, 49012, 48991, 48971, 48950,
+ 48929, 48909, 48888, 48867, 48847, 48826, 48805, 48784,
+ 48764, 48743, 48722, 48701, 48681, 48660, 48639, 48618,
+ 48598, 48577, 48556, 48535, 48514, 48494, 48473, 48452,
+ 48431, 48410, 48389, 48368, 48348, 48327, 48306, 48285,
+ 48264, 48243, 48222, 48201, 48180, 48159, 48138, 48117,
+ 48097, 48076, 48055, 48034, 48013, 47992, 47971, 47950,
+ 47929, 47907, 47886, 47865, 47844, 47823, 47802, 47781,
+ 47760, 47739, 47718, 47697, 47676, 47655, 47633, 47612,
+ 47591, 47570, 47549, 47528, 47506, 47485, 47464, 47443,
+ 47422, 47401, 47379, 47358, 47337, 47316, 47294, 47273,
+ 47252, 47231, 47209, 47188, 47167, 47145, 47124, 47103,
+ 47082, 47060, 47039, 47018, 46996, 46975, 46954, 46932,
+ 46911, 46889, 46868, 46847, 46825, 46804, 46783, 46761,
+ 46740, 46718, 46697, 46675, 46654, 46632, 46611, 46590,
+ 46568, 46547, 46525, 46504, 46482, 46461, 46439, 46418,
+ 46396, 46375, 46353, 46331, 46310, 46288, 46267, 46245,
+ 46224, 46202, 46180, 46159, 46137, 46116, 46094, 46072,
+ 46051, 46029, 46008, 45986, 45964, 45943, 45921, 45899,
+ 45878, 45856, 45834, 45812, 45791, 45769, 45747, 45726,
+ 45704, 45682, 45660, 45639, 45617, 45595, 45573, 45552,
+ 45530, 45508, 45486, 45465, 45443, 45421, 45399, 45377,
+ 45355, 45334, 45312, 45290, 45268, 45246, 45224, 45203,
+ 45181, 45159, 45137, 45115, 45093, 45071, 45049, 45027,
+ 45006, 44984, 44962, 44940, 44918, 44896, 44874, 44852,
+ 44830, 44808, 44786, 44764, 44742, 44720, 44698, 44676,
+ 44654, 44632, 44610, 44588, 44566, 44544, 44522, 44500,
+ 44478, 44456, 44434, 44412, 44390, 44368, 44346, 44323,
+ 44301, 44279, 44257, 44235, 44213, 44191, 44169, 44147,
+ 44124, 44102, 44080, 44058, 44036, 44014, 43992, 43969,
+ 43947, 43925, 43903, 43881, 43859, 43836, 43814, 43792,
+ 43770, 43747, 43725, 43703, 43681, 43659, 43636, 43614,
+ 43592, 43570, 43547, 43525, 43503, 43481, 43458, 43436,
+ 43414, 43391, 43369, 43347, 43324, 43302, 43280, 43258,
+ 43235, 43213, 43191, 43168, 43146, 43123, 43101, 43079,
+ 43056, 43034, 43012, 42989, 42967, 42945, 42922, 42900,
+ 42877, 42855, 42833, 42810, 42788, 42765, 42743, 42720,
+ 42698, 42676, 42653, 42631, 42608, 42586, 42563, 42541,
+ 42518, 42496, 42473, 42451, 42428, 42406, 42384, 42361,
+ 42339, 42316, 42293, 42271, 42248, 42226, 42203, 42181,
+ 42158, 42136, 42113, 42091, 42068, 42046, 42023, 42001,
+ 41978, 41955, 41933, 41910, 41888, 41865, 41842, 41820,
+ 41797, 41775, 41752, 41730, 41707, 41684, 41662, 41639,
+ 41616, 41594, 41571, 41549, 41526, 41503, 41481, 41458,
+ 41435, 41413, 41390, 41367, 41345, 41322, 41299, 41277,
+ 41254, 41231, 41209, 41186, 41163, 41140, 41118, 41095,
+ 41072, 41050, 41027, 41004, 40981, 40959, 40936, 40913,
+ 40891, 40868, 40845, 40822, 40800, 40777, 40754, 40731,
+ 40709, 40686, 40663, 40640, 40618, 40595, 40572, 40549,
+ 40526, 40504, 40481, 40458, 40435, 40412, 40390, 40367,
+ 40344, 40321, 40298, 40276, 40253, 40230, 40207, 40184,
+ 40161, 40139, 40116, 40093, 40070, 40047, 40024, 40002,
+ 39979, 39956, 39933, 39910, 39887, 39864, 39841, 39819,
+ 39796, 39773, 39750, 39727, 39704, 39681, 39658, 39636,
+ 39613, 39590, 39567, 39544, 39521, 39498, 39475, 39452,
+ 39429, 39406, 39384, 39361, 39338, 39315, 39292, 39269,
+ 39246, 39223, 39200, 39177, 39154, 39131, 39108, 39085,
+ 39062, 39039, 39017, 38994, 38971, 38948, 38925, 38902,
+ 38879, 38856, 38833, 38810, 38787, 38764, 38741, 38718,
+ 38695, 38672, 38649, 38626, 38603, 38580, 38557, 38534,
+ 38511, 38488, 38465, 38442, 38419, 38396, 38373, 38350,
+ 38327, 38304, 38281, 38258, 38235, 38212, 38189, 38166,
+ 38143, 38120, 38097, 38074, 38051, 38028, 38005, 37982,
+ 37958, 37935, 37912, 37889, 37866, 37843, 37820, 37797,
+ 37774, 37751, 37728, 37705, 37682, 37659, 37636, 37613,
+ 37590, 37567, 37544, 37520, 37497, 37474, 37451, 37428,
+ 37405, 37382, 37359, 37336, 37313, 37290, 37267, 37244,
+ 37220, 37197, 37174, 37151, 37128, 37105, 37082, 37059,
+ 37036, 37013, 36990, 36966, 36943, 36920, 36897, 36874,
+ 36851, 36828, 36805, 36782, 36759, 36736, 36712, 36689,
+ 36666, 36643, 36620, 36597, 36574, 36551, 36528, 36504,
+ 36481, 36458, 36435, 36412, 36389, 36366, 36343, 36320,
+ 36296, 36273, 36250, 36227, 36204, 36181, 36158, 36135,
+ 36112, 36088, 36065, 36042, 36019, 35996, 35973, 35950,
+ 35927, 35903, 35880, 35857, 35834, 35811, 35788, 35765,
+ 35742, 35718, 35695, 35672, 35649, 35626, 35603, 35580,
+ 35557, 35533, 35510, 35487, 35464, 35441, 35418, 35395,
+ 35372, 35348, 35325, 35302, 35279, 35256, 35233, 35210,
+ 35187, 35163, 35140, 35117, 35094, 35071, 35048, 35025,
+ 35002, 34978, 34955, 34932, 34909, 34886, 34863, 34840,
+ 34817, 34794, 34770, 34747, 34724, 34701, 34678, 34655,
+ 34632, 34609, 34585, 34562, 34539, 34516, 34493, 34470,
+ 34447, 34424, 34401, 34377, 34354, 34331, 34308, 34285,
+ 34262, 34239, 34216, 34193, 34169, 34146, 34123, 34100,
+ 34077, 34054, 34031, 34008, 33985, 33962, 33938, 33915,
+ 33892, 33869, 33846, 33823, 33800, 33777, 33754, 33731,
+ 33707, 33684, 33661, 33638, 33615, 33592, 33569, 33546,
+ 33523, 33500, 33477, 33454, 33430, 33407, 33384, 33361,
+ 33338, 33315, 33292, 33269, 33246, 33223, 33200, 33177,
+ 33154, 33131, 33108, 33084, 33061, 33038, 33015, 32992,
+ 32969, 32946, 32923, 32900, 32877, 32854, 32831, 32808,
+ 32785, 32762, 32739, 32716, 32693, 32670, 32647, 32624,
+ 32601, 32578, 32555, 32532, 32509, 32485, 32462, 32439,
+ 32416, 32393, 32370, 32347, 32324, 32301, 32278, 32255,
+ 32232, 32209, 32186, 32163, 32140, 32117, 32094, 32071,
+ 32048, 32025, 32003, 31980, 31957, 31934, 31911, 31888,
+ 31865, 31842, 31819, 31796, 31773, 31750, 31727, 31704,
+ 31681, 31658, 31635, 31612, 31589, 31566, 31543, 31520,
+ 31497, 31475, 31452, 31429, 31406, 31383, 31360, 31337,
+ 31314, 31291, 31268, 31245, 31222, 31200, 31177, 31154,
+ 31131, 31108, 31085, 31062, 31039, 31016, 30994, 30971,
+ 30948, 30925, 30902, 30879, 30856, 30833, 30811, 30788,
+ 30765, 30742, 30719, 30696, 30674, 30651, 30628, 30605,
+ 30582, 30559, 30537, 30514, 30491, 30468, 30445, 30422,
+ 30400, 30377, 30354, 30331, 30308, 30286, 30263, 30240,
+ 30217, 30195, 30172, 30149, 30126, 30103, 30081, 30058,
+ 30035, 30012, 29990, 29967, 29944, 29921, 29899, 29876,
+ 29853, 29830, 29808, 29785, 29762, 29740, 29717, 29694,
+ 29671, 29649, 29626, 29603, 29581, 29558, 29535, 29513,
+ 29490, 29467, 29445, 29422, 29399, 29377, 29354, 29331,
+ 29309, 29286, 29263, 29241, 29218, 29195, 29173, 29150,
+ 29128, 29105, 29082, 29060, 29037, 29014, 28992, 28969,
+ 28947, 28924, 28902, 28879, 28856, 28834, 28811, 28789,
+ 28766, 28744, 28721, 28698, 28676, 28653, 28631, 28608,
+ 28586, 28563, 28541, 28518, 28496, 28473, 28451, 28428,
+ 28406, 28383, 28361, 28338, 28316, 28293, 28271, 28248,
+ 28226, 28203, 28181, 28158, 28136, 28114, 28091, 28069,
+ 28046, 28024, 28001, 27979, 27957, 27934, 27912, 27889,
+ 27867, 27845, 27822, 27800, 27777, 27755, 27733, 27710,
+ 27688, 27666, 27643, 27621, 27599, 27576, 27554, 27532,
+ 27509, 27487, 27465, 27442, 27420, 27398, 27375, 27353,
+ 27331, 27309, 27286, 27264, 27242, 27219, 27197, 27175,
+ 27153, 27130, 27108, 27086, 27064, 27042, 27019, 26997,
+ 26975, 26953, 26930, 26908, 26886, 26864, 26842, 26820,
+ 26797, 26775, 26753, 26731, 26709, 26687, 26664, 26642,
+ 26620, 26598, 26576, 26554, 26532, 26510, 26488, 26465,
+ 26443, 26421, 26399, 26377, 26355, 26333, 26311, 26289,
+ 26267, 26245, 26223, 26201, 26179, 26157, 26135, 26113,
+ 26091, 26069, 26047, 26025, 26003, 25981, 25959, 25937,
+ 25915, 25893, 25871, 25849, 25827, 25805, 25783, 25761,
+ 25739, 25718, 25696, 25674, 25652, 25630, 25608, 25586,
+ 25564, 25543, 25521, 25499, 25477, 25455, 25433, 25412,
+ 25390, 25368, 25346, 25324, 25302, 25281, 25259, 25237,
+ 25215, 25194, 25172, 25150, 25128, 25107, 25085, 25063,
+ 25041, 25020, 24998, 24976, 24955, 24933, 24911, 24890,
+ 24868, 24846, 24825, 24803, 24781, 24760, 24738, 24716,
+ 24695, 24673, 24651, 24630, 24608, 24587, 24565, 24543,
+ 24522, 24500, 24479, 24457, 24436, 24414, 24393, 24371,
+ 24350, 24328, 24307, 24285, 24264, 24242, 24221, 24199,
+ 24178, 24156, 24135, 24113, 24092, 24070, 24049, 24028,
+ 24006, 23985, 23963, 23942, 23920, 23899, 23878, 23856,
+ 23835, 23814, 23792, 23771, 23750, 23728, 23707, 23686,
+ 23664, 23643, 23622, 23600, 23579, 23558, 23537, 23515,
+ 23494, 23473, 23452, 23430, 23409, 23388, 23367, 23346,
+ 23324, 23303, 23282, 23261, 23240, 23218, 23197, 23176,
+ 23155, 23134, 23113, 23092, 23071, 23049, 23028, 23007,
+ 22986, 22965, 22944, 22923, 22902, 22881, 22860, 22839,
+ 22818, 22797, 22776, 22755, 22734, 22713, 22692, 22671,
+ 22650, 22629, 22608, 22587, 22566, 22545, 22524, 22503,
+ 22482, 22462, 22441, 22420, 22399, 22378, 22357, 22336,
+ 22316, 22295, 22274, 22253, 22232, 22211, 22191, 22170,
+ 22149, 22128, 22108, 22087, 22066, 22045, 22025, 22004,
+ 21983, 21962, 21942, 21921, 21900, 21880, 21859, 21838,
+ 21818, 21797, 21776, 21756, 21735, 21715, 21694, 21673,
+ 21653, 21632, 21612, 21591, 21570, 21550, 21529, 21509,
+ 21488, 21468, 21447, 21427, 21406, 21386, 21365, 21345,
+ 21324, 21304, 21284, 21263, 21243, 21222, 21202, 21181,
+ 21161, 21141, 21120, 21100, 21080, 21059, 21039, 21019,
+ 20998, 20978, 20958, 20937, 20917, 20897, 20876, 20856,
+ 20836, 20816, 20795, 20775, 20755, 20735, 20715, 20694,
+ 20674, 20654, 20634, 20614, 20594, 20573, 20553, 20533,
+ 20513, 20493, 20473, 20453, 20433, 20413, 20392, 20372,
+ 20352, 20332, 20312, 20292, 20272, 20252, 20232, 20212,
+ 20192, 20172, 20152, 20132, 20113, 20093, 20073, 20053,
+ 20033, 20013, 19993, 19973, 19953, 19933, 19914, 19894,
+ 19874, 19854, 19834, 19814, 19795, 19775, 19755, 19735,
+ 19716, 19696, 19676, 19656, 19637, 19617, 19597, 19578,
+ 19558, 19538, 19519, 19499, 19479, 19460, 19440, 19420,
+ 19401, 19381, 19362, 19342, 19322, 19303, 19283, 19264,
+ 19244, 19225, 19205, 19186, 19166, 19147, 19127, 19108,
+ 19088, 19069, 19049, 19030, 19011, 18991, 18972, 18952,
+ 18933, 18914, 18894, 18875, 18856, 18836, 18817, 18798,
+ 18778, 18759, 18740, 18720, 18701, 18682, 18663, 18643,
+ 18624, 18605, 18586, 18567, 18547, 18528, 18509, 18490,
+ 18471, 18452, 18432, 18413, 18394, 18375, 18356, 18337,
+ 18318, 18299, 18280, 18261, 18242, 18223, 18204, 18185,
+ 18166, 18147, 18128, 18109, 18090, 18071, 18052, 18033,
+ 18014, 17995, 17977, 17958, 17939, 17920, 17901, 17882,
+ 17863, 17845, 17826, 17807, 17788, 17769, 17751, 17732,
+ 17713, 17695, 17676, 17657, 17638, 17620, 17601, 17582,
+ 17564, 17545, 17526, 17508, 17489, 17471, 17452, 17433,
+ 17415, 17396, 17378, 17359, 17341, 17322, 17304, 17285,
+ 17267, 17248, 17230, 17211, 17193, 17174, 17156, 17138,
+ 17119, 17101, 17082, 17064, 17046, 17027, 17009, 16991,
+ 16972, 16954, 16936, 16917, 16899, 16881, 16863, 16844,
+ 16826, 16808, 16790, 16772, 16753, 16735, 16717, 16699,
+ 16681, 16663, 16645, 16626, 16608, 16590, 16572, 16554,
+ 16536, 16518, 16500, 16482, 16464, 16446, 16428, 16410,
+ 16392, 16374, 16356, 16338, 16320, 16302, 16285, 16267,
+ 16249, 16231, 16213, 16195, 16177, 16160, 16142, 16124,
+ 16106, 16088, 16071, 16053, 16035, 16018, 16000, 15982,
+ 15964, 15947, 15929, 15911, 15894, 15876, 15858, 15841,
+ 15823, 15806, 15788, 15771, 15753, 15735, 15718, 15700,
+ 15683, 15665, 15648, 15630, 15613, 15596, 15578, 15561,
+ 15543, 15526, 15508, 15491, 15474, 15456, 15439, 15422,
+ 15404, 15387, 15370, 15353, 15335, 15318, 15301, 15283,
+ 15266, 15249, 15232, 15215, 15197, 15180, 15163, 15146,
+ 15129, 15112, 15095, 15078, 15060, 15043, 15026, 15009,
+ 14992, 14975, 14958, 14941, 14924, 14907, 14890, 14873,
+ 14856, 14840, 14823, 14806, 14789, 14772, 14755, 14738,
+ 14721, 14705, 14688, 14671, 14654, 14637, 14621, 14604,
+ 14587, 14570, 14554, 14537, 14520, 14504, 14487, 14470,
+ 14454, 14437, 14420, 14404, 14387, 14371, 14354, 14337,
+ 14321, 14304, 14288, 14271, 14255, 14238, 14222, 14205,
+ 14189, 14172, 14156, 14140, 14123, 14107, 14091, 14074,
+ 14058, 14041, 14025, 14009, 13993, 13976, 13960, 13944,
+ 13927, 13911, 13895, 13879, 13863, 13846, 13830, 13814,
+ 13798, 13782, 13766, 13750, 13734, 13717, 13701, 13685,
+ 13669, 13653, 13637, 13621, 13605, 13589, 13573, 13557,
+ 13541, 13525, 13510, 13494, 13478, 13462, 13446, 13430,
+ 13414, 13398, 13383, 13367, 13351, 13335, 13320, 13304,
+ 13288, 13272, 13257, 13241, 13225, 13210, 13194, 13178,
+ 13163, 13147, 13131, 13116, 13100, 13085, 13069, 13054,
+ 13038, 13023, 13007, 12992, 12976, 12961, 12945, 12930,
+ 12914, 12899, 12884, 12868, 12853, 12837, 12822, 12807,
+ 12792, 12776, 12761, 12746, 12730, 12715, 12700, 12685,
+ 12669, 12654, 12639, 12624, 12609, 12594, 12579, 12563,
+ 12548, 12533, 12518, 12503, 12488, 12473, 12458, 12443,
+ 12428, 12413, 12398, 12383, 12368, 12353, 12338, 12323,
+ 12309, 12294, 12279, 12264, 12249, 12234, 12220, 12205,
+ 12190, 12175, 12160, 12146, 12131, 12116, 12102, 12087,
+ 12072, 12058, 12043, 12028, 12014, 11999, 11985, 11970,
+ 11955, 11941, 11926, 11912, 11897, 11883, 11868, 11854,
+ 11840, 11825, 11811, 11796, 11782, 11767, 11753, 11739,
+ 11724, 11710, 11696, 11682, 11667, 11653, 11639, 11625,
+ 11610, 11596, 11582, 11568, 11554, 11539, 11525, 11511,
+ 11497, 11483, 11469, 11455, 11441, 11427, 11413, 11399,
+ 11385, 11371, 11357, 11343, 11329, 11315, 11301, 11287,
+ 11273, 11259, 11245, 11232, 11218, 11204, 11190, 11176,
+ 11163, 11149, 11135, 11121, 11108, 11094, 11080, 11067,
+ 11053, 11039, 11026, 11012, 10999, 10985, 10971, 10958,
+ 10944, 10931, 10917, 10904, 10890, 10877, 10863, 10850,
+ 10836, 10823, 10810, 10796, 10783, 10770, 10756, 10743,
+ 10730, 10716, 10703, 10690, 10676, 10663, 10650, 10637,
+ 10624, 10610, 10597, 10584, 10571, 10558, 10545, 10532,
+ 10519, 10506, 10492, 10479, 10466, 10453, 10440, 10427,
+ 10414, 10402, 10389, 10376, 10363, 10350, 10337, 10324,
+ 10311, 10299, 10286, 10273, 10260, 10247, 10235, 10222,
+ 10209, 10196, 10184, 10171, 10158, 10146, 10133, 10121,
+ 10108, 10095, 10083, 10070, 10058, 10045, 10033, 10020,
+ 10008, 9995, 9983, 9970, 9958, 9945, 9933, 9921,
+ 9908, 9896, 9884, 9871, 9859, 9847, 9834, 9822,
+ 9810, 9798, 9785, 9773, 9761, 9749, 9737, 9725,
+ 9712, 9700, 9688, 9676, 9664, 9652, 9640, 9628,
+ 9616, 9604, 9592, 9580, 9568, 9556, 9544, 9532,
+ 9521, 9509, 9497, 9485, 9473, 9461, 9450, 9438,
+ 9426, 9414, 9403, 9391, 9379, 9367, 9356, 9344,
+ 9332, 9321, 9309, 9298, 9286, 9275, 9263, 9251,
+ 9240, 9228, 9217, 9205, 9194, 9183, 9171, 9160,
+ 9148, 9137, 9126, 9114, 9103, 9092, 9080, 9069,
+ 9058, 9047, 9035, 9024, 9013, 9002, 8990, 8979,
+ 8968, 8957, 8946, 8935, 8924, 8913, 8902, 8891,
+ 8880, 8869, 8858, 8847, 8836, 8825, 8814, 8803,
+ 8792, 8781, 8770, 8759, 8749, 8738, 8727, 8716,
+ 8705, 8695, 8684, 8673, 8662, 8652, 8641, 8630,
+ 8620, 8609, 8599, 8588, 8577, 8567, 8556, 8546,
+ 8535, 8525, 8514, 8504, 8493, 8483, 8472, 8462,
+ 8452, 8441, 8431, 8421, 8410, 8400, 8390, 8379,
+ 8369, 8359, 8349, 8338, 8328, 8318, 8308, 8298,
+ 8288, 8277, 8267, 8257, 8247, 8237, 8227, 8217,
+ 8207, 8197, 8187, 8177, 8167, 8157, 8147, 8137,
+ 8128, 8118, 8108, 8098, 8088, 8078, 8069, 8059,
+ 8049, 8039, 8030, 8020, 8010, 8001, 7991, 7981,
+ 7972, 7962, 7952, 7943, 7933, 7924, 7914, 7905,
+ 7895, 7886, 7876, 7867, 7857, 7848, 7839, 7829,
+ 7820, 7811, 7801, 7792, 7783, 7773, 7764, 7755,
+ 7746, 7736, 7727, 7718, 7709, 7700, 7691, 7681,
+ 7672, 7663, 7654, 7645, 7636, 7627, 7618, 7609,
+ 7600, 7591, 7582, 7573, 7564, 7555, 7547, 7538,
+ 7529, 7520, 7511, 7502, 7494, 7485, 7476, 7467,
+ 7459, 7450, 7441, 7433, 7424, 7415, 7407, 7398,
+ 7390, 7381, 7373, 7364, 7355, 7347, 7338, 7330,
+ 7322, 7313, 7305, 7296, 7288, 7280, 7271, 7263,
+ 7255, 7246, 7238, 7230, 7221, 7213, 7205, 7197,
+ 7189, 7180, 7172, 7164, 7156, 7148, 7140, 7132,
+ 7124, 7116, 7108, 7100, 7092, 7084, 7076, 7068,
+ 7060, 7052, 7044, 7036, 7029, 7021, 7013, 7005,
+ 6997, 6990, 6982, 6974, 6966, 6959, 6951, 6943,
+ 6936, 6928, 6920, 6913, 6905, 6898, 6890, 6883,
+ 6875, 6868, 6860, 6853, 6845, 6838, 6830, 6823,
+ 6815, 6808, 6801, 6793, 6786, 6779, 6772, 6764,
+ 6757, 6750, 6743, 6735, 6728, 6721, 6714, 6707,
+ 6700, 6693, 6686, 6678, 6671, 6664, 6657, 6650,
+ 6643, 6636, 6630, 6623, 6616, 6609, 6602, 6595,
+ 6588, 6581, 6575, 6568, 6561, 6554, 6548, 6541,
+ 6534, 6527, 6521, 6514, 6507, 6501, 6494, 6488,
+ 6481, 6475, 6468, 6461, 6455, 6448, 6442, 6436,
+ 6429, 6423, 6416, 6410, 6404, 6397, 6391, 6385,
+ 6378, 6372, 6366, 6359, 6353, 6347, 6341, 6335,
+ 6329, 6322, 6316, 6310, 6304, 6298, 6292, 6286,
+ 6280, 6274, 6268, 6262, 6256, 6250, 6244, 6238,
+ 6232, 6226, 6221, 6215, 6209, 6203, 6197, 6192,
+ 6186, 6180, 6174, 6169, 6163, 6157, 6152, 6146,
+ 6140, 6135, 6129, 6124, 6118, 6113, 6107, 6102,
+ 6096, 6091, 6085, 6080, 6074, 6069, 6064, 6058,
+ 6053, 6048, 6042, 6037, 6032, 6027, 6021, 6016,
+ 6011, 6006, 6001, 5995, 5990, 5985, 5980, 5975,
+ 5970, 5965, 5960, 5955, 5950, 5945, 5940, 5935,
+ 5930, 5925, 5920, 5915, 5911, 5906, 5901, 5896,
+ 5891, 5887, 5882, 5877, 5872, 5868, 5863, 5858,
+ 5854, 5849, 5845, 5840, 5835, 5831, 5826, 5822,
+ 5817, 5813, 5808, 5804, 5799, 5795, 5791, 5786,
+ 5782, 5778, 5773, 5769, 5765, 5760, 5756, 5752,
+ 5748, 5743, 5739, 5735, 5731, 5727, 5723, 5719,
+ 5714, 5710, 5706, 5702, 5698, 5694, 5690, 5686,
+ 5682, 5678, 5675, 5671, 5667, 5663, 5659, 5655,
+ 5651, 5648, 5644, 5640, 5636, 5633, 5629, 5625,
+ 5622, 5618, 5614, 5611, 5607, 5604, 5600, 5596,
+ 5593, 5589, 5586, 5582, 5579, 5576, 5572, 5569,
+ 5565, 5562, 5559, 5555, 5552, 5549, 5545, 5542,
+ 5539, 5536, 5532, 5529, 5526, 5523, 5520, 5517,
+ 5514, 5511, 5507, 5504, 5501, 5498, 5495, 5492,
+ 5489, 5486, 5484, 5481, 5478, 5475, 5472, 5469,
+ 5466, 5464, 5461, 5458, 5455, 5452, 5450, 5447,
+ 5444, 5442, 5439, 5436, 5434, 5431, 5429, 5426,
+ 5424, 5421, 5419, 5416, 5414, 5411, 5409, 5406,
+ 5404, 5401, 5399, 5397, 5394, 5392, 5390, 5388,
+ 5385, 5383, 5381, 5379, 5376, 5374, 5372, 5370,
+ 5368, 5366, 5364, 5362, 5360, 5358, 5356, 5354,
+ 5352, 5350, 5348, 5346, 5344, 5342, 5340, 5338,
+ 5336, 5335, 5333, 5331, 5329, 5328, 5326, 5324,
+ 5322, 5321, 5319, 5317, 5316, 5314, 5313, 5311,
+ 5309, 5308, 5306, 5305, 5303, 5302, 5301, 5299,
+ 5298, 5296, 5295, 5294, 5292, 5291, 5290, 5288,
+ 5287, 5286, 5285, 5283, 5282, 5281, 5280, 5279,
+ 5278, 5276, 5275, 5274, 5273, 5272, 5271, 5270,
+ 5269, 5268, 5267, 5266, 5265, 5265, 5264, 5263,
+ 5262, 5261, 5260, 5260, 5259, 5258, 5257, 5257,
+ 5256, 5255, 5255, 5254, 5253, 5253, 5252, 5251,
+ 5251, 5250, 5250, 5249, 5249, 5248, 5248, 5247,
+ 5247, 5247, 5246, 5246, 5246, 5245, 5245, 5245,
+ 5244, 5244, 5244, 5244, 5243, 5243, 5243, 5243,
+ 5243, 5243, 5243, 5243, 5242, 5242, 5242, 5242,
+};
diff --git a/fmdriver/fmdriver.h b/fmdriver/fmdriver.h
index aebe27e..b31c31e 100644
--- a/fmdriver/fmdriver.h
+++ b/fmdriver/fmdriver.h
@@ -101,11 +101,17 @@ struct fmdriver_work {
uint8_t ssg_noise_freq;
struct fmdriver_track_status track_status[FMDRIVER_TRACK_NUM];
uint8_t loop_cnt;
+ // timerb value
+ uint8_t timerb;
// current timerb count
uint32_t timerb_cnt;
- // loop length
+ // current timerb count, reset on loop
+ uint32_t timerb_cnt_loop;
+ // loop length, calculated before playing
uint32_t loop_timerb_cnt;
// fm3ex part map
+ bool playing;
+ bool paused;
};
#endif // MYON_FMDRIVER_H_INCLUDED
diff --git a/fmdriver/fmdriver_fmp.c b/fmdriver/fmdriver_fmp.c
index 41d0a48..5e01089 100644
--- a/fmdriver/fmdriver_fmp.c
+++ b/fmdriver/fmdriver_fmp.c
@@ -304,6 +304,7 @@ static bool fmp_cmd62_tempo(struct fmdriver_work *work,
uint8_t tempo = fmp_part_cmdload(fmp, part);
fmp->timerb_bak = tempo;
fmp->timerb = tempo;
+ work->timerb = fmp->timerb;
fmp_set_tempo(work, fmp);
return true;
}
@@ -876,6 +877,7 @@ static bool fmp_cmd74_loop(struct fmdriver_work *work,
// 248c
fmp->loop_cnt++;
work->loop_cnt = fmp->loop_cnt;
+ work->timerb_cnt_loop = 0;
fmp->part_loop_bit = fmp->part_playing_bit;
// al=2; 1b64();
}
@@ -2854,6 +2856,7 @@ static void fmp_timerb(struct fmdriver_work *work, struct driver_fmp *fmp) {
if (fmp->status.stopped) {
// TODO: stopped
// jmp 18c7
+ work->playing = false;
}
// 1829
if (!--fmp->clock_divider) {
@@ -2989,6 +2992,7 @@ static void fmp_init_parts(struct fmdriver_work *work,
// work->opna_writereg(work, 0x110, 0x80);
fmp->timerb = 0xca;
+ work->timerb = fmp->timerb;
fmp->timerb_bak = 0xca;
// 3c79
@@ -3150,7 +3154,10 @@ static void fmp_opna_interrupt(struct fmdriver_work *work) {
struct driver_fmp *fmp = (struct driver_fmp *)work->driver;
if (work->opna_status(work, 0) & 0x02) {
fmp_timerb(work, fmp);
- work->timerb_cnt++;
+ if (work->playing) {
+ work->timerb_cnt++;
+ work->timerb_cnt_loop++;
+ }
}
}
@@ -3495,6 +3502,7 @@ void fmp_init(struct fmdriver_work *work, struct driver_fmp *fmp) {
fmp_work_status_init(work, fmp);
fmdriver_fillpcmname(work->pcmname[0], fmp->pvi_name);
fmdriver_fillpcmname(work->pcmname[1], fmp->ppz_name);
+ work->playing = true;
}
// 4235
diff --git a/fmdriver/fmdriver_pmd.c b/fmdriver/fmdriver_pmd.c
index 14459a5..ac2cad2 100644
--- a/fmdriver/fmdriver_pmd.c
+++ b/fmdriver/fmdriver_pmd.c
@@ -353,8 +353,8 @@ static void pmd_calc_tempo_rev(
int timerb = 0;
if (tempo) {
timerb = 0x112c / tempo;
- if (0x112c % tempo) timerb++;
timerb = 0x100 - timerb;
+ if ((0x112c % tempo) & 0x80) timerb--;
if (timerb < 0) timerb = 0;
}
pmd->timerb = timerb;
@@ -377,6 +377,7 @@ static void pmd_reset_timer(
struct driver_pmd *pmd
) {
pmd->timerb = 200;
+ work->timerb = pmd->timerb;
pmd->timerb_bak = pmd->timerb;
pmd_calc_tempo(pmd);
pmd_timerb_write(work, pmd);
@@ -2345,6 +2346,7 @@ static void pmd_cmdfc_tempo(
pmd->tempo_bak = tempo;
pmd_calc_tempo_rev(pmd);
}
+ work->timerb = pmd->timerb;
}
// 236b
@@ -5537,9 +5539,12 @@ static void pmd_proc_parts(
}
// 130d
if (!pmd->loop.looped || !pmd->loop.ended || pmd->loop.env) {
+ work->timerb_cnt_loop = 0;
if (++pmd->status2 == 0xff) pmd->status2 = 1;
} else {
pmd->status2 = 0xff;
+ // stop
+ work->playing = false;
}
work->loop_cnt = pmd->status2;
}
@@ -5627,7 +5632,10 @@ static void pmd_timer(
}
if (status & 2) {
pmd_timerb(work, pmd);
- work->timerb_cnt++;
+ if (work->playing) {
+ work->timerb_cnt++;
+ work->timerb_cnt_loop++;
+ }
}
}
@@ -5887,6 +5895,7 @@ void pmd_init(struct fmdriver_work *work,
}
fmdriver_fillpcmname(work->pcmname[0], pmd->ppcfile);
fmdriver_fillpcmname(work->pcmname[1], pmd->ppzfile);
+ work->playing = true;
}
enum {
diff --git a/fmdsp/fmdsp-vramlookup-neon.s b/fmdsp/fmdsp-vramlookup-neon.s
index 3cfb957..c5d6db2 100644
--- a/fmdsp/fmdsp-vramlookup-neon.s
+++ b/fmdsp/fmdsp-vramlookup-neon.s
@@ -22,9 +22,8 @@ fmdsp_vramlookup_neon:
push {lr}
@ load palette
vld3.8 {d26, d28, d30}, [r2]!
- vld1.8 {d27}, [r2]!
- vld1.8 {d29}, [r2]!
- vld1.8 {d31}, [r2]!
+ vld3.8 {d27[0], d29[0], d31[0]}, [r2]!
+ vld3.8 {d27[1], d29[1], d31[1]}, [r2]!
mov r14, #400
.loopcol:
diff --git a/fmdsp/fmdsp.c b/fmdsp/fmdsp.c
index fdec110..8f3499e 100644
--- a/fmdsp/fmdsp.c
+++ b/fmdsp/fmdsp.c
@@ -4,6 +4,8 @@
#include "fmdriver/fmdriver.h"
#include <stdio.h>
#include "libopna/opna.h"
+#include "fmdsp_platform_info.h"
+#include "version.h"
fmdsp_vramlookup_type fmdsp_vramlookup_func = fmdsp_vramlookup_c;
@@ -45,7 +47,7 @@ void fmdsp_init(struct fmdsp *fmdsp, const struct fmdsp_font *font98) {
fmdsp->target_palette[i] = s_palettes[0][i];
}
fmdsp->font98 = font98;
- fmdsp->style = FMDSP_DISPSTYLE_DEFAULT;
+ fmdsp->style = FMDSP_DISPSTYLE_ORIGINAL;
fmdsp->style_updated = true;
}
@@ -225,6 +227,7 @@ static void fmdsp_track_init_13(struct fmdsp *fmdsp,
}
}
}
+
static void fmdsp_track_init_10(struct fmdsp *fmdsp,
uint8_t *vram) {
for (int y = 0; y < TRACK_H*FMDSP_TRACK_DISP_CNT_DEFAULT; y++) {
@@ -234,7 +237,7 @@ static void fmdsp_track_init_10(struct fmdsp *fmdsp,
}
for (int i = 0; i < FMDSP_TRACK_DISP_CNT_DEFAULT; i++) {
int t;
- if (fmdsp->style == FMDSP_DISPSTYLE_DEFAULT) t = track_disp_table_default[i];
+ if (fmdsp->style == FMDSP_DISPSTYLE_DEFAULT || fmdsp->style == FMDSP_DISPSTYLE_ORIGINAL) t = track_disp_table_default[i];
else if (fmdsp->style == FMDSP_DISPSTYLE_OPN) t = track_disp_table_opn[i];
else t = track_disp_table_ppz8[i];
if (t < 0) continue;
@@ -270,6 +273,133 @@ static void fmdsp_track_init_10(struct fmdsp *fmdsp,
s_bar, BAR_W, BAR_H, 3);
}
}
+ if (fmdsp->style == FMDSP_DISPSTYLE_ORIGINAL) {
+ vramblit(vram, LOGO_FM_X, LOGO_Y, s_logo_fm, LOGO_FM_W, LOGO_H);
+ vramblit(vram, LOGO_DS_X, LOGO_Y, s_logo_ds, LOGO_DS_W, LOGO_H);
+ vramblit(vram, LOGO_P_X, LOGO_Y, s_logo_p, LOGO_P_W, LOGO_H);
+ fmdsp_putline("MUS", vram, &font_fmdsp_small, TOP_MUS_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("IC", vram, &font_fmdsp_small, TOP_IC_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("F", vram, &font_fmdsp_small, TOP_F_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("ILE", vram, &font_fmdsp_small, TOP_ILE_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("SELECTOR", vram, &font_fmdsp_small, TOP_SELECTOR_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("&", vram, &font_fmdsp_small, TOP_AND_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("STATUS", vram, &font_fmdsp_small, TOP_STATUS_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("D", vram, &font_fmdsp_small, TOP_D_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline("ISPLAY", vram, &font_fmdsp_small, TOP_ISPLAY_X, TOP_MUSIC_Y, 2, true);
+ vramblit(vram, TOP_VER_X, VER_Y, s_ver, VER_W, VER_H);
+ fmdsp_putline(FMPLAYER_VERSION_0 ".", vram, &font_fmdsp_small, VER_0_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline(FMPLAYER_VERSION_1 ".", vram, &font_fmdsp_small, VER_1_X, TOP_MUSIC_Y, 2, true);
+ fmdsp_putline(FMPLAYER_VERSION_2, vram, &font_fmdsp_small, VER_2_X, TOP_MUSIC_Y, 2, true);
+
+ vramblit(vram, TOP_MUS_X, TOP_TEXT_Y, s_text, TOP_TEXT_W, TOP_TEXT_H);
+
+ fmdsp_putline("DR", vram, &font_fmdsp_small, DRIVER_TEXT_X, DRIVER_TEXT_Y, 7, true);
+ fmdsp_putline("IVER", vram, &font_fmdsp_small, DRIVER_TEXT_2_X, DRIVER_TEXT_Y, 7, true);
+ vramblit_color(vram, DRIVER_TRI_X, DRIVER_TRI_Y, s_filebar_tri, FILEBAR_TRI_W, FILEBAR_TRI_H, 7);
+ vramblit(vram, CURL_LEFT_X, CURL_Y, s_curl_left, CURL_W, CURL_H);
+ vramblit(vram, CURL_RIGHT_X, CURL_Y, s_curl_right, CURL_W, CURL_H);
+
+ for (int x = 0; x < 82; x++) {
+ vram[14*PC98_W+312+x] = 2;
+ }
+ for (int x = 0; x < 239; x++) {
+ vram[14*PC98_W+395+x] = 7;
+ }
+ for (int x = 0; x < TIME_BAR_W; x++) {
+ for (int y = 0; y < TIME_BAR_H; y++) {
+ vram[(TIME_Y-2+y)*PC98_W+TIME_BAR_X+x] = 2;
+ vram[(CLOCK_Y-2+y)*PC98_W+TIME_BAR_X+x] = 2;
+ vram[(TIMERB_Y-2+y)*PC98_W+TIME_BAR_X+x] = 2;
+ vram[(LOOPCNT_Y-2+y)*PC98_W+TIME_BAR_X+x] = 2;
+ vram[(VOLDOWN_Y-2+y)*PC98_W+TIME_BAR_X+x] = 2;
+ vram[(PGMNUM_Y-2+y)*PC98_W+TIME_BAR_X+x] = 2;
+ }
+ }
+ for (int i = 0; i < 6; i++) {
+ vramblit(vram, TIME_TRI_X, TIME_Y+8+19*i, s_filebar_tri, FILEBAR_TRI_W, FILEBAR_TRI_H);
+ }
+ fmdsp_putline("PASSED", vram, &font_fmdsp_small, TIME_TEXT_X, TIME_Y-2, 2, true);
+ fmdsp_putline("T", vram, &font_fmdsp_small, TIME_TEXT_X+11, TIME_Y+5, 2, true);
+ fmdsp_putline("IME", vram, &font_fmdsp_small, TIME_TEXT_X+15, TIME_Y+5, 2, true);
+ fmdsp_putline("CLOCK", vram, &font_fmdsp_small, TIME_TEXT_X, CLOCK_Y-2, 2, true);
+ fmdsp_putline(" COUNT", vram, &font_fmdsp_small, TIME_TEXT_X, CLOCK_Y+5, 2, true);
+ fmdsp_putline("T", vram, &font_fmdsp_small, TIME_TEXT_X, TIMERB_Y-2, 2, true);
+ fmdsp_putline("IMER", vram, &font_fmdsp_small, TIME_TEXT_X+4, TIMERB_Y-2, 2, true);
+ fmdsp_putline(" CYCLE", vram, &font_fmdsp_small, TIME_TEXT_X, TIMERB_Y+5, 2, true);
+ fmdsp_putline("LOOP", vram, &font_fmdsp_small, TIME_TEXT_X, LOOPCNT_Y-2, 2, true);
+ fmdsp_putline(" COUNT", vram, &font_fmdsp_small, TIME_TEXT_X, LOOPCNT_Y+5, 2, true);
+ fmdsp_putline("VOLUME", vram, &font_fmdsp_small, TIME_TEXT_X, VOLDOWN_Y-2, 2, true);
+ fmdsp_putline(" DOWN", vram, &font_fmdsp_small, TIME_TEXT_X, VOLDOWN_Y+5, 2, true);
+ fmdsp_putline("PGM", vram, &font_fmdsp_small, TIME_TEXT_X, PGMNUM_Y-2, 2, true);
+ fmdsp_putline("NUMBER", vram, &font_fmdsp_small, TIME_TEXT_X, PGMNUM_Y+5, 2, true);
+
+ for (int x = 0; x < TIME_BAR_W; x++) {
+ for (int y = 0; y < TIME_BAR_H; y++) {
+ vram[(CPU_Y+y)*PC98_W+CPU_BAR_X+x] = 2;
+ }
+ }
+ fmdsp_putline("CPU", vram, &font_fmdsp_small, CPU_X, CPU_Y, 2, true);
+ fmdsp_putline("POWER", vram, &font_fmdsp_small, CPU_X+17, CPU_Y, 2, true);
+ fmdsp_putline("COUNT", vram, &font_fmdsp_small, CPU_X+17, CPU_Y+7, 2, true);
+ vramblit(vram, CPU_TRI_X, CPU_TRI_Y, s_filebar_tri, FILEBAR_TRI_W, FILEBAR_TRI_H);
+ for (int x = 0; x < TIME_BAR_W; x++) {
+ for (int y = 0; y < TIME_BAR_H; y++) {
+ vram[(CPU_Y+y)*PC98_W+FPS_BAR_X+x] = 2;
+ }
+ }
+ fmdsp_putline("FRAMES", vram, &font_fmdsp_small, FPS_X, CPU_Y, 2, true);
+ fmdsp_putline("PER", vram, &font_fmdsp_small, FPS_X+32, CPU_Y, 2, true);
+ fmdsp_putline("SECOND", vram, &font_fmdsp_small, FPS_X+17, CPU_Y+7, 2, true);
+ vramblit(vram, FPS_TRI_X, CPU_TRI_Y, s_filebar_tri, FILEBAR_TRI_W, FILEBAR_TRI_H);
+ for (int x = 0; x < 322; x++) {
+ vram[132*PC98_W+312+x] = 7;
+ }
+ fmdsp_putline("SENS", vram, &font_fmdsp_small, SPECTRUM_X-40, SPECTRUM_Y-6, 7, true);
+ fmdsp_putline("-48", vram, &font_fmdsp_small, SPECTRUM_X-19, SPECTRUM_Y-6, 7, true);
+ fmdsp_putline("0", vram, &font_fmdsp_small, SPECTRUM_X-9, SPECTRUM_Y-63, 7, true);
+ fmdsp_putline("dB", vram, &font_fmdsp_small, SPECTRUM_X-14, SPECTRUM_Y-71, 7, true);
+ fmdsp_putline("SPECTRUM", vram, &font_fmdsp_small, SPECTRUM_X+197, SPECTRUM_Y-71, 7, true);
+ fmdsp_putline("ANAL", vram, &font_fmdsp_small, SPECTRUM_X+241, SPECTRUM_Y-71, 7, true);
+ fmdsp_putline("YzER", vram, &font_fmdsp_small, SPECTRUM_X+260, SPECTRUM_Y-71, 7, true);
+ for (int y = 0; y < 63; y++) {
+ vram[(SPECTRUM_Y-y)*PC98_W+SPECTRUM_X-2] = 2;
+ if (!(y % 2)) {
+ vram[(SPECTRUM_Y-y)*PC98_W+SPECTRUM_X-3] = 2;
+ }
+ if (!(y % 8)) {
+ vram[(SPECTRUM_Y-y)*PC98_W+SPECTRUM_X-4] = 2;
+ }
+ }
+ fmdsp_putline("FREQ", vram, &font_fmdsp_small, SPECTRUM_X-24, SPECTRUM_Y+1, 1, true);
+ for (int x = 0; x < 17; x++) {
+ vram[(SPECTRUM_Y+4)*PC98_W+SPECTRUM_X+1+2*x] = 1;
+ }
+ fmdsp_putline("250", vram, &font_fmdsp_small, SPECTRUM_X+36, SPECTRUM_Y+1, 1, true);
+ for (int x = 0; x < 15; x++) {
+ vram[(SPECTRUM_Y+4)*PC98_W+SPECTRUM_X+52+2*x] = 1;
+ }
+ fmdsp_putline("500", vram, &font_fmdsp_small, SPECTRUM_X+83, SPECTRUM_Y+1, 1, true);
+ for (int x = 0; x < 17; x++) {
+ vram[(SPECTRUM_Y+4)*PC98_W+SPECTRUM_X+99+2*x] = 1;
+ }
+ fmdsp_putline("1", vram, &font_fmdsp_small, SPECTRUM_X+133, SPECTRUM_Y+1, 1, true);
+ fmdsp_putline("k", vram, &font_fmdsp_small, SPECTRUM_X+133+6, SPECTRUM_Y+1, 1, true);
+ for (int x = 0; x < 19; x++) {
+ vram[(SPECTRUM_Y+4)*PC98_W+SPECTRUM_X+144+2*x] = 1;
+ }
+ fmdsp_putline("2k", vram, &font_fmdsp_small, SPECTRUM_X+183, SPECTRUM_Y+1, 1, true);
+ for (int x = 0; x < 18; x++) {
+ vram[(SPECTRUM_Y+4)*PC98_W+SPECTRUM_X+193+2*x] = 1;
+ }
+ fmdsp_putline("4k", vram, &font_fmdsp_small, SPECTRUM_X+230, SPECTRUM_Y+1, 1, true);
+ for (int x = 0; x < 20; x++) {
+ vram[(SPECTRUM_Y+4)*PC98_W+SPECTRUM_X+240+2*x] = 1;
+ }
+ fmdsp_putline("ON/OFF", vram, &font_fmdsp_small, LEVEL_TEXT_X, LEVEL_TEXT_Y, 1, true);
+ fmdsp_putline("PANPOT", vram, &font_fmdsp_small, LEVEL_TEXT_X, LEVEL_TEXT_Y+8, 1, true);
+ fmdsp_putline("PROGRAM", vram, &font_fmdsp_small, LEVEL_TEXT_X-5, LEVEL_TEXT_Y+16, 1, true);
+ fmdsp_putline("KEYCODE", vram, &font_fmdsp_small, LEVEL_TEXT_X-5, LEVEL_TEXT_Y+23, 1, true);
+ }
}
void fmdsp_vram_init(struct fmdsp *fmdsp,
@@ -551,7 +681,8 @@ static void fmdsp_track_without_key(
fmdsp_putline("TN:", vram, &font_fmdsp_small, TDETAIL_TN_X, y+6, 1, true);
snprintf(numbuf, sizeof(numbuf), "%03d", track->tonenum);
fmdsp_putline(numbuf, vram, &font_fmdsp_small, TDETAIL_TN_V_X, y+6, 1, true);
- fmdsp_putline("VL:", vram, &font_fmdsp_small, TDETAIL_VL_X, y+6, 1, true);
+ fmdsp_putline("Vl", vram, &font_fmdsp_small, TDETAIL_VL_X, y+6, 1, true);
+ fmdsp_putline(":", vram, &font_fmdsp_small, TDETAIL_VL_C_X, y+6, 1, true);
snprintf(numbuf, sizeof(numbuf), "%03d", track->volume);
fmdsp_putline(numbuf, vram, &font_fmdsp_small, TDETAIL_VL_V_X, y+6, 1, true);
fmdsp_putline("GT:", vram, &font_fmdsp_small, TDETAIL_GT_X, y+6, 1, true);
@@ -583,45 +714,50 @@ static void fmdsp_track_without_key(
static void fmdsp_update_10(struct fmdsp *fmdsp,
const struct fmdriver_work *work,
const struct opna *opna,
- uint8_t *vram) {
- for (int y = 0; y < 320; y++) {
- for (int x = 320; x < PC98_W; x++) {
- vram[y*PC98_W+x] = 0;
+ uint8_t *vram,
+ struct fmplayer_fft_input_data *idata) {
+ if (fmdsp->style != FMDSP_DISPSTYLE_ORIGINAL) {
+ for (int y = 0; y < 320; y++) {
+ for (int x = 320; x < PC98_W; x++) {
+ vram[y*PC98_W+x] = 0;
+ }
}
}
for (int it = 0; it < FMDSP_TRACK_DISP_CNT_DEFAULT; it++) {
int t;
- if (fmdsp->style == FMDSP_DISPSTYLE_DEFAULT) t = track_disp_table_default[it];
+ if (fmdsp->style == FMDSP_DISPSTYLE_DEFAULT || fmdsp->style == FMDSP_DISPSTYLE_ORIGINAL) t = track_disp_table_default[it];
else if (fmdsp->style == FMDSP_DISPSTYLE_OPN) t = track_disp_table_opn[it];
else t = track_disp_table_ppz8[it];
if (t < 0) continue;
const struct fmdriver_track_status *track = &work->track_status[t];
- if (((track->info == FMDRIVER_TRACK_INFO_PPZ8)
- || (track->info == FMDRIVER_TRACK_INFO_PDZF))
- && track->ppz8_ch) {
- fmdsp_track_info_ppz8(work->ppz8, track->ppz8_ch-1,
- 320, TRACK_H*it+6, vram);
- } else {
- switch (track_type_table[t].type) {
- case FMDRIVER_TRACKTYPE_FM:
- fmdsp_track_info_fm(opna,
- track_type_table[t].num-1,
- track->info == FMDRIVER_TRACK_INFO_FM3EX ? track->fmslotmask : 0,
- 320, TRACK_H*it+6, vram);
- break;
- case FMDRIVER_TRACKTYPE_SSG:
- fmdsp_track_info_ssg(opna,
- track_type_table[t].num-1,
- 320, TRACK_H*it+6, vram);
- break;
- case FMDRIVER_TRACKTYPE_ADPCM:
- fmdsp_track_info_adpcm(opna, 320, TRACK_H*it+6, vram);
- break;
- case FMDRIVER_TRACKTYPE_PPZ8:
- fmdsp_track_info_ppz8(work->ppz8, track_type_table[t].num-1,
+ if (fmdsp->style != FMDSP_DISPSTYLE_ORIGINAL) {
+ if (((track->info == FMDRIVER_TRACK_INFO_PPZ8)
+ || (track->info == FMDRIVER_TRACK_INFO_PDZF))
+ && track->ppz8_ch) {
+ fmdsp_track_info_ppz8(work->ppz8, track->ppz8_ch-1,
320, TRACK_H*it+6, vram);
- break;
+ } else {
+ switch (track_type_table[t].type) {
+ case FMDRIVER_TRACKTYPE_FM:
+ fmdsp_track_info_fm(opna,
+ track_type_table[t].num-1,
+ track->info == FMDRIVER_TRACK_INFO_FM3EX ? track->fmslotmask : 0,
+ 320, TRACK_H*it+6, vram);
+ break;
+ case FMDRIVER_TRACKTYPE_SSG:
+ fmdsp_track_info_ssg(opna,
+ track_type_table[t].num-1,
+ 320, TRACK_H*it+6, vram);
+ break;
+ case FMDRIVER_TRACKTYPE_ADPCM:
+ fmdsp_track_info_adpcm(opna, 320, TRACK_H*it+6, vram);
+ break;
+ case FMDRIVER_TRACKTYPE_PPZ8:
+ fmdsp_track_info_ppz8(work->ppz8, track_type_table[t].num-1,
+ 320, TRACK_H*it+6, vram);
+ break;
+ }
}
}
fmdsp_track_without_key(fmdsp, work, track, t, TRACK_H*it, vram);
@@ -642,6 +778,167 @@ static void fmdsp_update_10(struct fmdsp *fmdsp,
}
}
}
+ if (fmdsp->style == FMDSP_DISPSTYLE_ORIGINAL) {
+ // control status
+ bool playing = work->playing && !work->paused;
+ bool stopped = !work->playing;
+ bool paused = work->paused;
+ vramblit_color(vram, PLAY_X, PLAY_Y, s_play, PLAY_W, PLAY_H, playing ? 2 : 3);
+ vramblit_color(vram, STOP_X, STOP_Y, s_stop, STOP_W, STOP_H, stopped ? 2 : 3);
+ vramblit_color(vram, PAUSE_X, PAUSE_Y, s_pause, PAUSE_W, PAUSE_H, paused ? 2 : 3);
+ vramblit(vram, FADE_X, FADE_Y, s_fade, FADE_W, FADE_H);
+ vramblit(vram, FF_X, FF_Y, s_ff, FF_W, FF_H);
+ vramblit(vram, REW_X, REW_Y, s_rew, REW_W, REW_H);
+ vramblit(vram, FLOPPY_X, FLOPPY_Y, s_floppy, FLOPPY_W, FLOPPY_H);
+ const uint8_t *num[8];
+ // passed time
+ {
+ uint64_t frames = opna->generated_frames;
+ int ssec = (int)(frames % 55467u) * 100 / 55467;
+ uint64_t sec = frames / 55467u;
+ uint64_t min = sec / 60u;
+ sec %= 60u;
+ num[0] = s_num[(min/10)%10];
+ num[1] = s_num[min%10];
+ vramblit(vram, TIME_X+NUM_W*0, TIME_Y, num[0], NUM_W, NUM_H);
+ vramblit(vram, TIME_X+NUM_W*1, TIME_Y, num[1], NUM_W, NUM_H);
+ vramblit(vram, TIME_X+NUM_W*2, TIME_Y, s_num_colon[sec%2u], NUM_W, NUM_H);
+ num[0] = s_num[(sec/10)%10];
+ num[1] = s_num[sec%10];
+ vramblit(vram, TIME_X+NUM_W*3, TIME_Y, num[0], NUM_W, NUM_H);
+ vramblit(vram, TIME_X+NUM_W*4, TIME_Y, num[1], NUM_W, NUM_H);
+ vramblit(vram, TIME_X+NUM_W*5, TIME_Y, s_num_bar, NUM_W, NUM_H);
+ num[0] = s_num[(ssec/10)%10];
+ num[1] = s_num[ssec%10];
+ vramblit(vram, TIME_X+NUM_W*6, TIME_Y, num[0], NUM_W, NUM_H);
+ vramblit(vram, TIME_X+NUM_W*7, TIME_Y, num[1], NUM_W, NUM_H);
+ }
+ // clock count
+ {
+ uint64_t clock = work->timerb_cnt;
+ for (int i = 0; i < 8; i++) {
+ num[7-i] = s_num[clock%10u];
+ clock /= 10u;
+ }
+ for (int i = 0; i < 8; i++) {
+ vramblit(vram, TIME_X+NUM_W*i, CLOCK_Y, num[i], NUM_W, NUM_H);
+ }
+ }
+ // timerb
+ {
+ uint8_t timerb = work->timerb;
+ for (int i = 0; i < 3; i++) {
+ num[2-i] = s_num[timerb%10];
+ timerb /= 10;
+ }
+ for (int i = 0; i < 3; i++) {
+ vramblit(vram, TIME_X+NUM_W*(5+i), TIMERB_Y, num[i], NUM_W, NUM_H);
+ }
+ }
+ // loop count
+ {
+ uint8_t loop = work->loop_cnt;
+ for (int i = 0; i < 4; i++) {
+ num[3-i] = s_num[loop%10];
+ loop /= 10;
+ }
+ for (int i = 0; i < 4; i++) {
+ vramblit(vram, TIME_X+NUM_W*(4+i), LOOPCNT_Y, num[i], NUM_W, NUM_H);
+ }
+ }
+ //
+ int pos = 0;
+ if (work->loop_timerb_cnt) pos = work->timerb_cnt_loop * (72+1-4) / work->loop_timerb_cnt;
+ for (int x = 0; x < 72; x++) {
+ if (x == 0 || x == 36 || x == 71) {
+ vram[(70-2)*PC98_W+352+x*2] = 7;
+ } else if (!(x % 9)) {
+ vram[(70-2)*PC98_W+352+x*2] = 3;
+ }
+ uint8_t c = 3;
+ if (work->playing && ((pos <= x) && (x < (pos+4)))) c = 2;
+ for (int y = 0; y < 4; y++) {
+ vram[(70+y)*PC98_W+352+x*2] = c;
+ }
+ }
+ for (int x = 0; x < 16; x++) {
+ for (int y = 0; y < 4; y++) {
+ vram[(70+y)*PC98_W+496+x] = work->loop_cnt ? 7 : 3;
+ }
+ }
+ // cpu
+ int cpuusage = fmdsp->cpuusage;
+ for (int i = 0; i < 3; i++) {
+ num[2-i] = s_num[cpuusage % 10];
+ cpuusage /= 10;
+ }
+ for (int i = 0; i < 3; i++) {
+ vramblit(vram, CPU_NUM_X+NUM_W*i, CPU_NUM_Y, num[i], NUM_W, NUM_H);
+ }
+ // fps
+ int fps = fmdsp->fps;
+ for (int i = 0; i < 3; i++) {
+ num[2-i] = s_num[fps % 10];
+ fps /= 10;
+ }
+ for (int i = 0; i < 3; i++) {
+ vramblit(vram, FPS_NUM_X+NUM_W*i, CPU_NUM_Y, num[i], NUM_W, NUM_H);
+ }
+ // circle
+ for (int y = 0; y < CIRCLE_H; y++) {
+ for (int x = 0; x < CIRCLE_W; x++) {
+ int c = 0;
+ int clock = (work->timerb_cnt / 8) % 8;
+ int p;
+ if ((p = s_circle[y*CIRCLE_W+x])) {
+ c = (work->playing && (!work->paused || (fmdsp->framecnt % 60) < 30) && (p == (clock + 1))) ? 2 : 3;
+ }
+ vram[(CIRCLE_Y+y)*PC98_W+CIRCLE_X+x] = c;
+ }
+ }
+ // fft
+ struct fmplayer_fft_disp_data ddata;
+ fft_calc(&ddata, idata);
+ for (int x = 0; x < FFTDISPLEN; x++) {
+ for (int y = 0; y < 32; y++) {
+ int px = SPECTRUM_X+x*4;
+ int py = SPECTRUM_Y-y*2;
+ int c = y < ddata.buf[x] ? 2 : 3;
+ vram[py*PC98_W+px+0] = c;
+ vram[py*PC98_W+px+1] = c;
+ vram[py*PC98_W+px+2] = c;
+ }
+ }
+ for (int i = 0; i < FFTDISPLEN; i++) {
+ if (fmdsp->fftdata[i] <= ddata.buf[i]) {
+ fmdsp->fftdata[i] = ddata.buf[i];
+ fmdsp->fftcnt[i] = 30;
+ } else {
+ if (fmdsp->fftcnt[i]) {
+ fmdsp->fftcnt[i]--;
+ } else {
+ if (fmdsp->fftdata[i]) {
+ if (fmdsp->fftdropdiv[i]) {
+ fmdsp->fftdropdiv[i]--;
+ } else {
+ static const uint8_t divtab[16] = {
+ 32, 16, 8, 8, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
+ };
+ fmdsp->fftdropdiv[i] = divtab[fmdsp->fftdata[i] / 2];
+ fmdsp->fftdata[i]--;
+ }
+ }
+ }
+ }
+ }
+ for (int x = 0; x < FFTDISPLEN; x++) {
+ int px = SPECTRUM_X+x*4;
+ int py = SPECTRUM_Y-fmdsp->fftdata[x]*2;
+ vram[py*PC98_W+px+0] = 7;
+ vram[py*PC98_W+px+1] = 7;
+ vram[py*PC98_W+px+2] = 7;
+ }
+ }
}
static void fmdsp_update_13(struct fmdsp *fmdsp,
const struct fmdriver_work *work,
@@ -701,7 +998,8 @@ static void fmdsp_update_13(struct fmdsp *fmdsp,
void fmdsp_update(struct fmdsp *fmdsp,
const struct fmdriver_work *work,
const struct opna *opna,
- uint8_t *vram) {
+ uint8_t *vram,
+ struct fmplayer_fft_input_data *idata) {
if (fmdsp->style_updated) {
if (fmdsp->style == FMDSP_DISPSTYLE_13) {
fmdsp_track_init_13(fmdsp, vram);
@@ -739,9 +1037,14 @@ void fmdsp_update(struct fmdsp *fmdsp,
if (fmdsp->style == FMDSP_DISPSTYLE_13) {
fmdsp_update_13(fmdsp, work, opna, vram);
} else {
- fmdsp_update_10(fmdsp, work, opna, vram);
+ fmdsp_update_10(fmdsp, work, opna, vram, idata);
}
fmdsp_palette_fade(fmdsp);
+ if (!(fmdsp->framecnt % 30)) {
+ fmdsp->cpuusage = fmdsp_cpu_usage();
+ fmdsp->fps = fmdsp_fps_30();
+ }
+ fmdsp->framecnt++;
}
void fmdsp_vrampalette(struct fmdsp *fmdsp, const uint8_t *vram, uint8_t *vram32, int stride) {
diff --git a/fmdsp/fmdsp.h b/fmdsp/fmdsp.h
index 1aba5d9..6a98707 100644
--- a/fmdsp/fmdsp.h
+++ b/fmdsp/fmdsp.h
@@ -5,6 +5,7 @@
#include <stdbool.h>
#include "font.h"
#include "fmdriver/fmdriver.h"
+#include "fft/fft.h"
#ifdef __cplusplus
extern "C" {
@@ -18,10 +19,11 @@ enum {
};
enum {
- FMDSP_PALETTE_COLORS = 9
+ FMDSP_PALETTE_COLORS = 10
};
enum FMDSP_DISPSTYLE {
+ FMDSP_DISPSTYLE_ORIGINAL,
FMDSP_DISPSTYLE_DEFAULT,
FMDSP_DISPSTYLE_OPN,
FMDSP_DISPSTYLE_PPZ8,
@@ -36,6 +38,12 @@ struct fmdsp {
enum FMDSP_DISPSTYLE style;
bool style_updated;
bool masked[FMDRIVER_TRACK_NUM];
+ uint8_t fftdata[FFTDISPLEN];
+ uint8_t fftcnt[FFTDISPLEN];
+ uint8_t fftdropdiv[FFTDISPLEN];
+ uint64_t framecnt;
+ int cpuusage;
+ int fps;
};
struct fmdriver_work;
@@ -44,7 +52,9 @@ void fmdsp_vram_init(struct fmdsp *fmdsp,
struct fmdriver_work *work,
uint8_t *vram);
void fmdsp_update(struct fmdsp *fmdsp, const struct fmdriver_work *work,
- const struct opna *opna, uint8_t *vram);
+ const struct opna *opna, uint8_t *vram,
+ struct fmplayer_fft_input_data *idata
+ );
void fmdsp_vrampalette(struct fmdsp *fmdsp, const uint8_t *vram, uint8_t *vram32, int stride);
void fmdsp_font_from_fontrom(uint8_t *font, const uint8_t *fontrom);
void fmdsp_palette_set(struct fmdsp *fmdsp, int p);
diff --git a/fmdsp/fmdsp_platform_info.h b/fmdsp/fmdsp_platform_info.h
new file mode 100644
index 0000000..9afb2d6
--- /dev/null
+++ b/fmdsp/fmdsp_platform_info.h
@@ -0,0 +1,9 @@
+#ifndef MYON_FMPLAYER_FMDSP_PLATFORM_INFO_H_INCLUDED
+#define MYON_FMPLAYER_FMDSP_PLATFORM_INFO_H_INCLUDED
+
+int fmdsp_cpu_usage(void);
+
+// call once per 30 frames to obtain fps
+int fmdsp_fps_30(void);
+
+#endif // MYON_FMPLAYER_FMDSP_PLATFORM_INFO_H_INCLUDED
diff --git a/fmdsp/fmdsp_platform_unix.c b/fmdsp/fmdsp_platform_unix.c
new file mode 100644
index 0000000..446cee7
--- /dev/null
+++ b/fmdsp/fmdsp_platform_unix.c
@@ -0,0 +1,44 @@
+#include "fmdsp_platform_info.h"
+#include <sys/times.h>
+#include <time.h>
+#include <limits.h>
+#include <stdint.h>
+
+static struct {
+ clock_t lastall;
+ clock_t lastcpu;
+ struct timespec lasttimespec;
+} g;
+
+int fmdsp_cpu_usage(void) {
+ struct tms tmsbuf;
+ clock_t all = times(&tmsbuf);
+ clock_t cpu = tmsbuf.tms_utime + tmsbuf.tms_stime;
+ clock_t percentage = 0;
+ clock_t alld = all - g.lastall;
+ clock_t cpud = cpu - g.lastcpu;
+ if (alld) percentage = cpud * 100 / alld;
+ g.lastall = all;
+ g.lastcpu = cpu;
+ if (!g.lastall) percentage = 0;
+ if (percentage > INT_MAX) percentage = INT_MAX;
+ if (percentage < 0) percentage = 0;
+ return percentage;
+}
+
+int fmdsp_fps_30(void) {
+ struct timespec time;
+ clock_gettime(CLOCK_MONOTONIC, &time);
+ uint64_t fps = 0;
+ if (g.lasttimespec.tv_sec || g.lasttimespec.tv_nsec) {
+ uint64_t diffns = time.tv_sec - g.lasttimespec.tv_sec;
+ diffns *= 1000000000ull;
+ diffns += time.tv_nsec - g.lasttimespec.tv_nsec;
+ if (diffns) {
+ fps = 30ull * 1000000000ull / diffns;
+ }
+ }
+ g.lasttimespec = time;
+ if (fps > INT_MAX) fps = INT_MAX;
+ return fps;
+}
diff --git a/fmdsp/fmdsp_platform_win.c b/fmdsp/fmdsp_platform_win.c
new file mode 100644
index 0000000..3dc4074
--- /dev/null
+++ b/fmdsp/fmdsp_platform_win.c
@@ -0,0 +1,57 @@
+#include "fmdsp_platform_info.h"
+#include <stdint.h>
+#include <limits.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+static struct {
+ HANDLE currproc;
+ uint64_t lastall;
+ uint64_t lastcpu;
+ uint64_t lastfpstime;
+} g;
+
+int fmdsp_cpu_usage(void) {
+ if (!g.currproc) g.currproc = GetCurrentProcess();
+ FILETIME ft_sys, ft_creat, ft_exit, ft_kern, ft_user;
+ GetSystemTimeAsFileTime(&ft_sys);
+ GetProcessTimes(g.currproc, &ft_creat, &ft_exit, &ft_kern, &ft_user);
+ uint64_t all = ft_sys.dwHighDateTime;
+ all <<= 32;
+ all |= ft_sys.dwLowDateTime;
+ uint64_t kern = ft_kern.dwHighDateTime;
+ kern <<= 32;
+ kern |= ft_kern.dwLowDateTime;
+ uint64_t user = ft_user.dwHighDateTime;
+ user <<= 32;
+ user |= ft_user.dwLowDateTime;
+ uint64_t cpu = kern + user;
+ uint64_t alld = all - g.lastall;
+ uint64_t cpud = cpu - g.lastcpu;
+ int percentage = 0;
+ if (alld) percentage = cpud * 100 / alld;
+ g.lastall = all;
+ g.lastcpu = cpu;
+ if (!g.lastall) return 0;
+ if (percentage > INT_MAX) percentage = INT_MAX;
+ if (percentage < 0) percentage = 0;
+ return percentage;
+}
+
+int fmdsp_fps_30(void) {
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ uint64_t time = ft.dwHighDateTime;
+ time <<= 32;
+ time |= ft.dwLowDateTime;
+ uint64_t fps = 0;
+ if (g.lastfpstime) {
+ uint64_t diff = time - g.lastfpstime;
+ if (diff) {
+ fps = 30ull * 10000000ull / diff;
+ }
+ }
+ g.lastfpstime = time;
+ if (fps > INT_MAX) fps = INT_MAX;
+ return fps;
+}
diff --git a/fmdsp/fmdsp_sprites.h b/fmdsp/fmdsp_sprites.h
index cb011a6..d9d71ac 100644
--- a/fmdsp/fmdsp_sprites.h
+++ b/fmdsp/fmdsp_sprites.h
@@ -3,36 +3,37 @@ enum {
TRACK_H_S = 24,
TNAME_W = 26,
TNAME_H = 5,
- TINFO_X = 48,
- TDETAIL_X = 69,
+ TINFO_X = 47,
+ TDETAIL_X = 67,
TDETAIL_KN_V_X = TDETAIL_X+13,
- TDETAIL_TN_X = TDETAIL_KN_V_X+27,
+ TDETAIL_TN_X = TDETAIL_KN_V_X+28,
TDETAIL_TN_V_X = TDETAIL_TN_X+13,
TDETAIL_VL_X = TDETAIL_TN_V_X+20,
- TDETAIL_VL_V_X = TDETAIL_VL_X+13,
- TDETAIL_GT_X = TDETAIL_VL_V_X+20,
+ TDETAIL_VL_C_X = TDETAIL_VL_X+9,
+ TDETAIL_VL_V_X = TDETAIL_VL_X+12,
+ TDETAIL_GT_X = TDETAIL_VL_V_X+19,
TDETAIL_GT_V_X = TDETAIL_GT_X+13,
- TDETAIL_DT_X = TDETAIL_GT_V_X+20,
+ TDETAIL_DT_X = TDETAIL_GT_V_X+23,
TDETAIL_DT_S_X = TDETAIL_DT_X+12,
- TDETAIL_DT_V_X = TDETAIL_DT_S_X+4,
- TDETAIL_M_X = 250,
+ TDETAIL_DT_V_X = TDETAIL_DT_S_X+5,
+ TDETAIL_M_X = 249,
TDETAIL_M_V_X = TDETAIL_M_X+8,
NUM_X = 31,
NUM_W = 8,
NUM_H = 11,
- KEY_X = 8,
+ KEY_X = 7,
KEY_Y = 14,
KEY_W = 35,
KEY_H = 17,
KEY_S_OFFSET = KEY_W*4,
KEY_H_S = KEY_H - 8,
- KEY_LEFT_X = 1,
+ KEY_LEFT_X = 0,
KEY_LEFT_W = 6,
KEY_LEFT_S_OFFSET = KEY_LEFT_W*4,
KEY_RIGHT_W = 11,
KEY_RIGHT_S_OFFSET = KEY_RIGHT_W*4,
KEY_OCTAVES = 8,
- BAR_L_X = 68,
+ BAR_L_X = 66,
BAR_L_W = 14,
BAR_X = BAR_L_X + BAR_L_W,
BAR_Y = 1,
@@ -45,8 +46,8 @@ enum {
PLAYING_Y = 324,
PLAYING_W = 72,
PLAYING_H = 9,
- FILEBAR_X = 80,
- FILEBAR_MUS_X = FILEBAR_X + 5,
+ FILEBAR_X = 78,
+ FILEBAR_MUS_X = FILEBAR_X + 6,
FILEBAR_IC_X = FILEBAR_MUS_X + 14,
FILEBAR_F_X = FILEBAR_IC_X + 11,
FILEBAR_ILE_X = FILEBAR_F_X + 4,
@@ -67,6 +68,104 @@ enum {
PCM2FILENAME_X = PCM2FILETRI_X + 8,
DT_SIGN_W = 3,
DT_SIGN_H = 3,
+ SPECTRUM_X = 352,
+ SPECTRUM_Y = 207,
+ CPU_Y = 115,
+ CPU_X = 320,
+ CPU_BAR_X = CPU_X-6,
+ CPU_NUM_X = CPU_X+56,
+ CPU_NUM_Y = CPU_Y+2,
+ CPU_TRI_X = CPU_X+43,
+ CPU_TRI_Y = CPU_Y+10,
+ FPS_X = CPU_X+100,
+ FPS_BAR_X = FPS_X-6,
+ FPS_NUM_X = FPS_X+61,
+ FPS_TRI_X = FPS_X+48,
+ TIME_TEXT_X = 530,
+ TIME_X = TIME_TEXT_X+38,
+ TIME_BAR_X = TIME_TEXT_X-6,
+ TIME_TRI_X = TIME_TEXT_X+31,
+ TIME_BAR_W = 3,
+ TIME_BAR_H = 14,
+ TIME_Y = 22,
+ CLOCK_Y = TIME_Y+19,
+ TIMERB_Y = CLOCK_Y+19,
+ LOOPCNT_Y = TIMERB_Y+19,
+ VOLDOWN_Y = LOOPCNT_Y+19,
+ PGMNUM_Y = VOLDOWN_Y+19,
+ LOGO_NUM = 1,
+ LOGO_Y = 1,
+ LOGO_FM_W = 31,
+ LOGO_DS_W = 32,
+ LOGO_P_W = 15,
+ LOGO_H = 12,
+ LOGO_FM_X = 312,
+ LOGO_DS_X = LOGO_FM_X+LOGO_FM_W+2,
+ LOGO_P_X = LOGO_DS_X+LOGO_DS_W+2,
+ CIRCLE_W = 31,
+ CIRCLE_H = 31,
+ CIRCLE_X = 312,
+ CIRCLE_Y = 70,
+ TOP_MUS_X = 397,
+ TOP_MUSIC_Y = 7,
+ TOP_IC_X = TOP_MUS_X+14,
+ TOP_F_X = TOP_IC_X+12,
+ TOP_ILE_X = TOP_F_X+4,
+ TOP_SELECTOR_X = TOP_ILE_X+17,
+ TOP_AND_X = TOP_SELECTOR_X+42,
+ TOP_STATUS_X = TOP_AND_X+7,
+ TOP_D_X = TOP_STATUS_X+32,
+ TOP_ISPLAY_X = TOP_D_X+4,
+ TOP_VER_X = TOP_ISPLAY_X+32,
+ TOP_TEXT_W = 231,
+ TOP_TEXT_H = 5,
+ TOP_TEXT_Y = TOP_MUSIC_Y-6,
+ VER_W = 13,
+ VER_H = 5,
+ VER_Y = 8,
+ VER_0_X = TOP_VER_X+15,
+ VER_1_X = VER_0_X+7,
+ VER_2_X = VER_1_X+7,
+ DRIVER_TEXT_X = 312,
+ DRIVER_TEXT_Y = 27,
+ DRIVER_TEXT_2_X = DRIVER_TEXT_X+9,
+ DRIVER_TRI_X = DRIVER_TEXT_2_X+26,
+ DRIVER_TRI_Y = DRIVER_TEXT_Y+3,
+ CURL_W = 11,
+ CURL_H = 11,
+ CURL_LEFT_X = 347,
+ CURL_RIGHT_X = 509,
+ CURL_Y = 80,
+ PLAY_W = 30,
+ PLAY_H = 7,
+ PLAY_X = 354,
+ PLAY_Y = 77,
+ STOP_W = 31,
+ STOP_H = 7,
+ STOP_X = 393,
+ STOP_Y = 77,
+ PAUSE_W = 37,
+ PAUSE_H = 7,
+ PAUSE_X = 433,
+ PAUSE_Y = 77,
+ FADE_W = 31,
+ FADE_H = 7,
+ FADE_X = 481,
+ FADE_Y = 77,
+ FF_W = 20,
+ FF_H = 7,
+ FF_X = 360,
+ FF_Y = 87,
+ REW_W = 26,
+ REW_H = 7,
+ REW_X = 392,
+ REW_Y = 87,
+ FLOPPY_W = 74,
+ FLOPPY_H = 7,
+ FLOPPY_X = 432,
+ FLOPPY_Y = 87,
+ LEVEL_TEXT_X = 318,
+ LEVEL_TEXT_Y = 290,
};
enum {
@@ -100,6 +199,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
136, 255, 68,
51, 51, 238,
0, 187, 255,
+ 68, 102, 170,
},
{
0, 0, 0,
@@ -111,6 +211,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
153, 255, 119,
102, 85, 255,
0, 204, 255,
+ 85, 119, 170,
},
{
0, 0, 0,
@@ -122,6 +223,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
255, 221, 85,
255, 102, 0,
255, 85, 0,
+ 170, 119, 85,
},
{
0, 0, 0,
@@ -133,6 +235,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
119, 255, 34,
136, 68, 221,
0, 187, 255,
+ 136, 102, 187,
},
{
0, 0, 0,
@@ -144,6 +247,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
255, 68, 0,
85, 85, 255,
255, 119, 255,
+ 119, 119, 187,
},
{
0, 0, 0,
@@ -155,6 +259,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
255, 221, 0,
255, 0, 51,
255, 0, 51,
+ 170, 136, 0,
},
{
102, 170, 238,
@@ -166,6 +271,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
0, 51, 136,
34, 102, 187,
0, 85, 204,
+ 68, 136, 255,
},
{
0, 0, 0,
@@ -177,6 +283,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
85, 255, 68,
34, 17, 255,
0, 170, 255,
+ 68, 85, 170,
},
{
LCDB(255),
@@ -188,6 +295,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
LCDB(218),
LCDB(109),
LCDB(218),
+ LCDB(0),
},
{
LCD(255),
@@ -199,6 +307,7 @@ static const uint8_t s_palettes[PALETTE_NUM][FMDSP_PALETTE_COLORS*3] = {
LCD(0),
LCD(109),
LCD(0),
+ LCD(0),
},
};
@@ -356,6 +465,50 @@ static const uint8_t s_num[11][NUM_W*NUM_H] = {
0, 0, 3, 3, 3, 0, 0, 0,
}
};
+
+static const uint8_t s_num_colon[2][NUM_W*NUM_H] = {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+};
+
+static const uint8_t s_num_bar[NUM_W*NUM_H] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 2, 0, 0, 0,
+};
+
static const uint8_t s_key_bg[KEY_W*KEY_H] = {
4,4,4,0,0,0,4,4,0,0,0,4,4,4,0,4,4,4,0,0,0,4,4,0,0,0,4,4,0,0,0,4,4,4,0,
4,4,4,0,0,0,4,4,0,0,0,4,4,4,0,4,4,4,0,0,0,4,4,0,0,0,4,4,0,0,0,4,4,4,0,
@@ -488,3 +641,229 @@ static const uint8_t s_dt_sign[3][DT_SIGN_W*DT_SIGN_H] = {
0, 1, 0,
}
};
+
+static const uint8_t s_logo_fm[LOGO_FM_W*LOGO_H] = {
+ 0,9,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,9,2,2,2,0,0,0,0,0,2,2,2,9,0,
+ 9,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,9,2,2,2,2,2,0,0,0,2,2,2,2,2,9,
+ 2,2,2,9,3,3,3,3,3,3,3,3,3,3,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,2,2,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,2,2,2,0,0,0,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,3,3,3,3,3,3,3,3,3,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+};
+
+static const uint8_t s_logo_ds[LOGO_DS_W*LOGO_H] = {
+ 2,2,2,2,2,2,2,2,2,2,2,2,9,0,0,0,0,0,9,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,9,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,3,3,3,3,3,3,3,3,9,2,2,9,0,0,2,2,2,9,3,3,3,3,3,3,3,3,3,3,3,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,9,0,0,0,0,0,0,0,0,0,0,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,9,2,2,2,2,2,2,2,2,2,2,2,2,9,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,9,2,2,2,2,2,2,2,2,2,2,2,2,9,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,3,3,3,3,3,3,3,3,9,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,9,2,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,9,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9,
+ 2,2,2,2,2,2,2,2,2,2,2,2,9,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,9,0,
+};
+
+static const uint8_t s_logo_p[LOGO_P_W*LOGO_H] = {
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,9,0,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,9,
+ 2,2,2,3,3,3,3,3,3,3,3,9,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,
+ 2,2,2,0,0,0,0,0,0,0,0,9,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,9,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,9,0,
+ 2,2,2,3,3,3,3,3,3,3,3,3,3,0,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
+ 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const uint8_t s_circle[CIRCLE_W*CIRCLE_H] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,8,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,8,0,8,0,0,0,1,0,1,0,0,0,2,0,2,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,8,0,0,8,0,0,1,0,1,0,0,2,0,0,2,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,7,0,0,0,8,0,8,0,0,1,0,1,0,0,2,0,2,0,0,0,3,0,0,0,0,0,
+ 0,0,0,0,7,0,7,0,0,8,0,0,8,0,1,0,1,0,2,0,0,2,0,0,3,0,3,0,0,0,0,
+ 0,0,0,0,0,7,0,7,0,0,8,0,8,0,1,0,1,0,2,0,2,0,0,3,0,3,0,0,0,0,0,
+ 0,0,0,0,0,0,7,0,7,0,8,0,0,0,0,0,0,0,0,0,2,0,3,0,3,0,0,0,0,0,0,
+ 0,0,6,6,0,0,0,7,0,7,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,0,0,4,4,0,0,
+ 0,0,0,0,6,6,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,4,4,0,0,0,0,
+ 0,6,6,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,4,4,0,
+ 0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,
+ 0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,
+ 0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,
+ 0,4,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,6,6,0,
+ 0,0,0,0,4,4,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,6,6,0,0,0,0,
+ 0,0,4,4,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,0,7,0,7,0,0,0,6,6,0,0,
+ 0,0,0,0,0,0,3,0,3,0,2,0,0,0,0,0,0,0,0,0,8,0,7,0,7,0,0,0,0,0,0,
+ 0,0,0,0,0,3,0,3,0,0,2,0,2,0,1,0,1,0,8,0,8,0,0,7,0,7,0,0,0,0,0,
+ 0,0,0,0,3,0,3,0,0,2,0,0,2,0,1,0,1,0,8,0,0,8,0,0,7,0,7,0,0,0,0,
+ 0,0,0,0,0,3,0,0,0,2,0,2,0,0,1,0,1,0,0,8,0,8,0,0,0,7,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,0,2,0,0,1,0,1,0,0,8,0,0,8,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,2,0,2,0,0,0,1,0,1,0,0,0,8,0,8,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,1,0,0,0,8,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const uint8_t s_text[TOP_TEXT_W*TOP_TEXT_H] = {
+ 0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,7,0,7,0,0,7,0,7,7,7,0,7,0,0,7,0,0,0,0,0,
+ 7,0,0,0,0,7,7,7,0,7,0,0,7,0,7,0,0,7,0,7,0,0,7,0,0,0,0,7,7,7,0,7,7,7,7,0,7,0,
+ 0,7,0,0,0,0,0,0,7,7,7,0,0,0,0,0,7,0,0,7,0,0,7,7,0,0,0,7,7,0,0,0,0,0,0,0,7,7,
+ 0,0,7,0,0,7,0,7,7,7,0,0,0,7,7,0,0,0,0,7,0,0,0,0,0,0,0,7,7,0,0,7,7,7,0,0,7,0,
+ 0,7,0,0,0,0,7,0,0,0,0,0,7,0,0,7,0,7,7,7,0,7,0,0,7,0,7,7,7,0,0,0,7,7,0,0,7,0,
+ 0,7,0,0,7,7,7,0,0,0,0,7,7,0,0,0,7,7,0,0,0,7,7,0,0,0,7,7,0,0,0,0,0,0,7,0,0,0,
+ 7,7,0,0,7,0,0,0,7,7,0,0,7,0,7,0,0,0,7,0,0,7,0,7,7,0,7,0,0,7,0,0,0,7,7,0,0,0,
+ 0,7,0,7,0,0,0,0,0,7,0,0,7,7,0,7,0,7,0,0,7,0,0,7,7,0,0,0,0,7,0,0,0,0,0,0,0,0,
+ 0,7,0,7,0,0,0,7,0,0,0,0,0,0,7,0,0,0,0,0,7,7,0,0,7,0,0,7,0,7,0,0,0,0,0,0,7,0,
+ 7,0,0,7,0,7,7,7,7,0,7,0,0,7,0,7,0,0,0,0,0,7,7,0,0,0,0,7,0,7,0,0,7,0,7,0,0,7,
+ 0,7,7,7,7,0,0,0,7,0,7,0,0,0,0,7,0,0,7,0,0,7,0,0,7,7,0,7,0,7,0,0,7,0,7,0,0,7,
+ 0,7,0,0,7,0,7,0,0,0,0,0,0,7,0,0,7,0,7,0,0,7,0,7,0,0,7,0,7,0,0,7,0,0,0,0,7,7,
+ 0,0,7,0,0,7,7,7,7,0,7,0,0,7,0,7,7,0,0,0,0,7,0,0,7,0,7,0,7,7,0,0,7,0,0,0,0,0,
+ 0,0,0,7,0,0,7,0,0,0,0,0,7,0,0,7,0,7,7,0,7,0,0,7,0,0,0,0,0,0,0,0,7,0,7,7,0,0,
+ 7,7,0,0,7,0,0,0,0,7,7,7,0,0,0,7,7,0,0,0,0,0,0,0,0,0,0,0,7,7,0,0,7,7,7,0,0,0,
+ 7,0,0,7,0,0,7,0,7,0,0,7,0,7,0,0,7,0,7,7,7,0,0,7,0,7,0,0,0,7,0,0,7,0,0,7,0,7,
+ 0,0,7,0,7,0,0,7,0,0,0,0,7,0,7,0,0,0,7,0,0,7,0,0,7,0,0,7,0,7,7,0,7,0,0,7,0,7,
+ 0,0,7,0,7,0,0,7,0,0,7,7,0,0,0,0,0,0,7,0,0,7,0,0,7,0,7,0,0,7,0,7,0,0,7,0,7,7,
+ 0,0,7,0,0,7,0,0,7,0,7,0,0,7,0,0,7,0,7,0,0,0,0,0,7,0,0,7,0,7,0,0,7,0,0,7,0,0,
+ 0,7,7,0,0,7,0,0,0,7,0,0,0,0,0,7,0,0,7,0,0,7,0,7,0,0,7,0,0,7,7,0,0,0,0,7,0,0,
+ 7,0,0,7,7,0,0,7,0,7,0,0,0,7,0,0,0,0,0,0,7,0,0,0,0,0,7,7,0,0,7,0,0,7,0,7,0,0,
+ 7,0,7,0,0,0,7,0,7,7,0,7,0,0,7,0,0,0,0,7,0,7,0,0,7,0,7,7,7,7,0,7,0,0,0,7,0,7,
+ 7,0,7,0,7,0,0,7,0,0,7,0,0,0,7,0,7,0,0,0,0,7,7,7,7,0,0,7,0,0,7,0,0,7,0,0,0,0,
+ 7,0,7,0,0,7,0,7,7,7,7,0,0,0,0,7,0,0,0,0,7,0,0,0,7,0,0,7,0,7,0,0,7,0,7,0,0,7,
+ 0,0,0,0,0,7,0,0,7,0,0,7,0,7,0,0,0,7,7,0,0,7,0,0,0,0,0,0,7,7,0,0,7,0,0,7,0,7,
+ 7,7,0,7,0,0,7,0,0,0,0,0,0,7,7,7,0,7,7,7,0,7,0,0,7,0,0,7,7,0,0,7,0,0,7,0,0,0,
+ 0,7,7,7,0,0,7,7,0,0,7,0,0,7,0,0,0,0,0,0,7,7,7,0,0,0,0,0,7,0,0,7,0,0,7,7,0,0,
+ 0,7,7,0,0,0,0,0,0,7,0,0,7,0,7,0,0,7,0,7,7,7,0,0,0,7,7,0,0,0,0,7,0,0,0,0,0,0,
+ 7,0,0,7,0,7,0,0,7,0,7,0,0,7,0,0,0,0,7,0,7,0,0,0,7,0,0,7,0,7,7,7,0,7,0,0,7,0,
+ 7,7,7,0,0,0,7,7,0,0,7,0,0,7,0,7,7,7,0,0,0,0,7,7,7,7,0,0,7,7,0,0,0,7,7,0,0,0,
+ 7,7,0,0,0,0,0,7,7,7,0,0,7,7,0
+};
+
+static const uint8_t s_ver[VER_W*VER_H] = {
+ 2,0,0,2,0,0,0,0,0,0,0,0,0,
+ 2,0,0,2,0,0,2,2,0,0,2,0,2,
+ 2,0,0,2,0,2,2,2,2,0,2,2,0,
+ 0,2,2,0,0,2,0,0,0,0,2,0,0,
+ 0,2,2,0,0,0,2,2,2,0,2,0,0,
+};
+
+static const uint8_t s_curl_left[CURL_W*CURL_H] = {
+ 0,3,3,3,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 3,0,0,0,0,0,0,0,0,0,0,
+ 0,3,3,3,3,3,3,3,3,3,3,
+};
+
+static const uint8_t s_curl_right[CURL_W*CURL_H] = {
+ 0,0,0,0,0,0,0,3,3,3,0,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 0,0,0,0,0,0,0,0,0,0,3,
+ 3,3,3,3,3,3,3,3,3,3,0,
+};
+
+static const uint8_t s_play[PLAY_W*PLAY_H] = {
+ 1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,1,
+ 1,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,
+ 1,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,
+ 1,1,1,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,
+ 1,1,1,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,0,0,
+ 1,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,
+ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,1,0,0,0,1,0,0,
+};
+
+static const uint8_t s_stop[STOP_W*STOP_H] = {
+ 0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,
+ 1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,
+ 1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,
+ 1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,
+ 1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,0,
+ 1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,1,1,1,0,0,1,0,0,0,0,
+};
+
+static const uint8_t s_pause[PAUSE_W*PAUSE_H] = {
+ 0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,3,3,3,0,0,3,0,0,0,3,0,0,3,3,3,3,0,0,3,3,3,3,
+ 3,3,0,3,3,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,0,3,0,0,0,0,
+ 3,3,0,3,3,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,0,3,0,0,0,0,
+ 3,3,0,3,3,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,3,0,0,3,3,3,0,0,3,3,3,3,0,
+ 3,3,0,3,3,0,0,0,3,3,3,3,0,0,3,3,3,3,3,0,3,0,0,0,3,0,0,0,0,0,3,0,3,0,0,0,0,
+ 3,3,0,3,3,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,0,0,0,0,3,0,3,0,0,0,0,
+ 0,0,0,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,0,3,3,3,0,0,3,3,3,3,0,0,0,3,3,3,3,
+};
+
+static const uint8_t s_fade[FADE_W*FADE_H] = {
+ 0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,3,3,3,0,0,3,3,3,3,0,0,0,3,3,3,3,
+ 3,0,0,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,
+ 3,0,0,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,
+ 3,0,3,0,0,0,0,0,3,3,3,3,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,3,3,3,0,
+ 3,0,3,0,0,0,0,0,3,0,0,0,0,0,3,3,3,3,3,0,3,0,0,0,3,0,3,0,0,0,0,
+ 3,0,3,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,3,0,0,0,0,
+ 3,0,3,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,3,3,3,0,0,0,3,3,3,3,
+};
+
+static const uint8_t s_ff[FF_W*FF_H] = {
+ 3,0,0,3,0,0,0,0,0,0,3,3,3,3,0,0,3,3,3,3,
+ 3,3,0,3,3,0,0,0,0,3,0,0,0,0,0,3,0,0,0,0,
+ 3,3,0,3,3,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,
+ 3,3,0,3,3,3,3,0,0,3,3,3,3,0,0,3,3,3,3,0,
+ 3,3,0,3,3,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,
+ 3,3,0,3,3,0,0,0,0,3,0,0,0,0,0,3,0,0,0,0,
+ 3,0,0,3,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,0,
+};
+
+static const uint8_t s_rew[REW_W*REW_H] = {
+ 0,0,0,3,0,0,3,0,0,3,3,3,3,0,0,0,3,3,3,3,0,3,0,0,0,3,
+ 0,0,3,3,0,3,3,0,0,3,0,0,0,3,0,3,0,0,0,0,0,3,0,3,0,3,
+ 0,3,3,3,0,3,3,0,0,3,0,0,0,3,0,3,0,0,0,0,0,3,0,3,0,3,
+ 3,3,3,3,0,3,3,0,0,3,0,0,3,0,0,3,3,3,3,0,0,3,0,3,0,3,
+ 0,3,3,3,0,3,3,0,0,3,3,3,0,0,0,3,0,0,0,0,0,3,0,3,0,3,
+ 0,0,3,3,0,3,3,0,0,3,0,0,3,0,0,3,0,0,0,0,0,3,0,3,0,3,
+ 0,0,0,3,0,0,3,0,0,3,0,0,0,3,0,0,3,3,3,3,0,0,3,0,3,0,
+};
+
+static uint8_t s_floppy[FLOPPY_W*FLOPPY_H] = {
+ 3,3,3,3,3,3,3,0,0,0,3,3,3,3,0,0,3,3,3,0,0,3,0,0,0,0,0,0,3,3,3,3,0,3,3,3,3,0,
+ 0,0,3,3,3,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,3,3,3,0,0,0,3,3,3,0,0,0,0,0,3,0,3,3,
+ 3,3,3,3,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,
+ 0,0,0,3,0,3,3,0,3,3,0,0,3,3,0,0,0,3,0,0,0,3,0,3,0,0,0,3,0,0,0,3,3,0,3,3,3,0,
+ 3,3,3,0,0,3,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,0,0,
+ 0,0,0,3,0,3,0,3,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,3,0,0,3,0,3,0,3,3,0,0,0,3,
+ 3,0,0,3,3,3,3,0,0,0,0,3,0,0,0,3,0,0,0,0,0,3,3,3,3,0,0,3,0,0,0,3,0,3,0,0,0,0,
+ 0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,3,3,0,0,3,0,0,3,0,3,3,3,0,3,3,3,0,
+ 0,3,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,0,3,3,3,3,0,0,3,0,0,0,0,0,3,
+ 0,0,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,
+ 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,0,0,3,0,0,0,3,0,3,0,0,
+ 0,3,0,0,0,3,0,0,0,0,3,0,0,0,0,3,0,0,0,3,0,0,0,0,3,0,3,3,3,3,3,3,3,0,0,3,0,0,
+ 0,0,0,0,3,3,3,0,0,0,3,3,3,3,0,0,3,3,3,3,0,3,0,0,0,0,0,0,3,3,3,0,0,3,0,0,0,3,
+ 0,0,3,3,3,0,0,3,3,3,3,3,0,0,3,3,3,0,0,0,0,0,3,0,
+};
diff --git a/fmdsp/font_fmdsp_small_data.h b/fmdsp/font_fmdsp_small_data.h
index d5f9105..60ee56a 100644
--- a/fmdsp/font_fmdsp_small_data.h
+++ b/fmdsp/font_fmdsp_small_data.h
@@ -1,5 +1,4 @@
-static const unsigned char fontdat[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+static unsigned char fontdat[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -19,10 +18,11 @@ static const unsigned char fontdat[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0xa0, 0x50, 0xa0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe0, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x20, 0x40, 0x00,
0x00, 0x60, 0x90, 0x90, 0x90, 0x60, 0x00, 0x20, 0x60, 0x20, 0x20, 0x70,
0x00, 0x60, 0x90, 0x20, 0x40, 0xf0, 0x00, 0xe0, 0x10, 0x60, 0x10, 0xe0,
0x00, 0x20, 0x60, 0xa0, 0xf0, 0x20, 0x00, 0xf0, 0x80, 0xe0, 0x10, 0xe0,
@@ -49,18 +49,18 @@ static const unsigned char fontdat[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x80, 0xb0, 0x80, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x70, 0x90, 0x80, 0x70, 0x00, 0xf0, 0x80, 0xb0, 0x80, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xa0, 0xc0, 0xa0, 0x90,
+ 0x00, 0x80, 0x80, 0x80, 0x80, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x20, 0x40, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -128,4 +128,3 @@ static const unsigned char fontdat[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index fb06655..8777418 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -16,7 +16,8 @@ FMDRIVER_SRC=../fmdriver/fmdriver_fmp.c \
FMDSP_SRC=../fmdsp/fmdsp.c \
../fmdsp/fmdsp-vramlookup-c.c \
../fmdsp/font_rom.c \
- ../fmdsp/font_fmdsp_small.c
+ ../fmdsp/font_fmdsp_small.c \
+ ../fmdsp/fmdsp_platform_unix.c
#fmplayer_CFLAGS=$(CFLAGS)
#CFLAGS=
@@ -48,6 +49,7 @@ fmplayer_SOURCES=main.c \
../common/fmplayer_file_gio.c \
../common/fmplayer_work_opna.c \
../common/fmplayer_drumrom_unix.c \
+ ../fft/fft.c \
$(LIBOPNA_SRC) \
$(FMDRIVER_SRC) \
$(FMDSP_SRC)
diff --git a/gtk/fmplayer.xpm b/gtk/fmplayer.xpm
index d52d9f4..87ae7a6 100644
--- a/gtk/fmplayer.xpm
+++ b/gtk/fmplayer.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char *fmplayer_xpm_16[] = {
+static const char *fmplayer_xpm_16[] = {
/* columns rows colors chars-per-pixel */
"16 16 4 1 ",
" c #40A040",
diff --git a/gtk/fmplayer32.xpm b/gtk/fmplayer32.xpm
index 062d12e..a97a327 100644
--- a/gtk/fmplayer32.xpm
+++ b/gtk/fmplayer32.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char *fmplayer_xpm_32[] = {
+static const char *fmplayer_xpm_32[] = {
/* columns rows colors chars-per-pixel */
"32 32 8 1 ",
" c gray25",
diff --git a/gtk/main.c b/gtk/main.c
index f0d5633..ba84df8 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -19,6 +19,7 @@
#include "oscilloview.h"
#include "wavesave.h"
#include "common/fmplayer_common.h"
+#include "fft/fft.h"
#include "fmplayer.xpm"
#include "fmplayer32.xpm"
@@ -58,8 +59,12 @@ static struct {
const char *current_uri;
bool oscillo_should_update;
struct oscillodata oscillodata_audiothread[LIBOPNA_OSCILLO_TRACK_COUNT];
+ atomic_flag at_fftdata_flag;
+ struct fmplayer_fft_data at_fftdata;
+ struct fmplayer_fft_input_data fftdata;
} g = {
- .oscillo_should_update = true
+ .oscillo_should_update = true,
+ .at_fftdata_flag = ATOMIC_FLAG_INIT,
};
static void quit(void) {
@@ -140,6 +145,11 @@ static int pastream_cb(const void *inptr, void *outptr, unsigned long frames,
atomic_flag_clear_explicit(&oscilloview_g.flag, memory_order_release);
}
}
+ if (!atomic_flag_test_and_set_explicit(
+ &g.at_fftdata_flag, memory_order_acquire)) {
+ fft_write(&g.at_fftdata, buf, frames);
+ atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release);
+ }
return paContinue;
}
@@ -228,6 +238,7 @@ static bool openfile(const char *uri) {
fmdsp_vram_init(&g.fmdsp, &g.work, g.vram);
Pa_StartStream(g.pastream);
g.pa_paused = false;
+ g.work.paused = false;
{
const char *turi = strdup(uri);
free((void *)g.current_uri);
@@ -282,7 +293,12 @@ static gboolean draw_cb(GtkWidget *w,
gpointer p) {
(void)w;
(void)p;
- fmdsp_update(&g.fmdsp, &g.work, &g.opna, g.vram);
+ if (!atomic_flag_test_and_set_explicit(
+ &g.at_fftdata_flag, memory_order_acquire)) {
+ memcpy(&g.fftdata.fdata, &g.at_fftdata, sizeof(g.fftdata));
+ atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release);
+ }
+ fmdsp_update(&g.fmdsp, &g.work, &g.opna, g.vram, &g.fftdata);
fmdsp_vrampalette(&g.fmdsp, g.vram, g.vram32, g.vram32_stride);
cairo_surface_t *s = cairo_image_surface_create_for_data(
g.vram32, CAIRO_FORMAT_RGB24, PC98_W, PC98_H, g.vram32_stride);
@@ -391,9 +407,11 @@ static gboolean key_press_cb(GtkWidget *w,
if (g.pa_paused) {
Pa_StartStream(g.pastream);
g.pa_paused = false;
+ g.work.paused = false;
} else {
Pa_StopStream(g.pastream);
g.pa_paused = true;
+ g.work.paused = true;
}
break;
case GDK_KEY_F11:
@@ -481,6 +499,7 @@ int main(int argc, char **argv) {
if (__builtin_cpu_supports("sse2")) opna_ssg_sinc_calc_func = opna_ssg_sinc_calc_sse2;
if (__builtin_cpu_supports("ssse3")) fmdsp_vramlookup_func = fmdsp_vramlookup_ssse3;
#endif
+ fft_init_table();
load_fontrom();
gtk_init(&argc, &argv);
{
diff --git a/libopna/opna.c b/libopna/opna.c
index 567c913..9f87ff3 100644
--- a/libopna/opna.c
+++ b/libopna/opna.c
@@ -9,6 +9,7 @@ void opna_reset(struct opna *opna) {
opna_drum_reset(&opna->drum);
opna_adpcm_reset(&opna->adpcm);
opna->mask = 0;
+ opna->generated_frames = 0;
}
void opna_writereg(struct opna *opna, unsigned reg, unsigned val) {
@@ -42,6 +43,7 @@ void opna_mix_oscillo(struct opna *opna, int16_t *buf, unsigned samples, struct
oscillo ? &oscillo[6] : 0, offset);
opna_drum_mix(&opna->drum, buf, samples);
opna_adpcm_mix(&opna->adpcm, buf, samples);
+ opna->generated_frames += samples;
}
unsigned opna_get_mask(const struct opna *opna) {
diff --git a/libopna/opna.h b/libopna/opna.h
index 2ebca0d..a49a5f8 100644
--- a/libopna/opna.h
+++ b/libopna/opna.h
@@ -41,6 +41,7 @@ struct opna {
struct opna_adpcm adpcm;
struct opna_ssg_resampler resampler;
unsigned mask;
+ uint64_t generated_frames;
};
void opna_reset(struct opna *opna);
diff --git a/win32/amd64/Makefile b/win32/amd64/Makefile
index 22ef073..97e46dc 100644
--- a/win32/amd64/Makefile
+++ b/win32/amd64/Makefile
@@ -4,6 +4,7 @@ vpath %.c ../../libopna
vpath %.c ../../fmdsp
vpath %.c ../../tonedata
vpath %.c ../../common
+vpath %.c ../../fft
vpath %.rc ..
include ../fmplayer.mak
diff --git a/win32/fmplayer.mak b/win32/fmplayer.mak
index 9a514b2..d62861c 100644
--- a/win32/fmplayer.mak
+++ b/win32/fmplayer.mak
@@ -21,11 +21,13 @@ LIBOPNA_OBJS=opna \
FMDSP_OBJS=fmdsp \
fmdsp-vramlookup-c \
font_rom \
- font_fmdsp_small
+ font_fmdsp_small \
+ fmdsp_platform_win
TONEDATA_OBJS=tonedata
SSEOBJBASE=opnassg-sinc-sse2 \
fmdsp-vramlookup-ssse3
OBJBASE=main \
+ fft \
toneview \
oscilloview \
wavesave \
diff --git a/win32/main.c b/win32/main.c
index 66a1bf0..c1df7a7 100644
--- a/win32/main.c
+++ b/win32/main.c
@@ -22,6 +22,7 @@
#include "about.h"
#include "common/fmplayer_common.h"
#include "wavesave.h"
+#include "fft/fft.h"
enum {
ID_OPENFILE = 0x10,
@@ -74,7 +75,12 @@ static struct {
HBITMAP bitmap_vram;
uint8_t *vram32;
bool drum_loaded;
-} g;
+ atomic_flag at_fftdata_flag;
+ struct fmplayer_fft_data at_fftdata;
+ struct fmplayer_fft_input_data fftdata;
+} g = {
+ .at_fftdata_flag = ATOMIC_FLAG_INIT,
+};
HWND g_currentdlg;
@@ -92,6 +98,11 @@ static void sound_cb(void *p, int16_t *buf, unsigned frames) {
memcpy(oscilloview_g.oscillodata, g.oscillodata_audiothread, sizeof(oscilloview_g.oscillodata));
atomic_flag_clear_explicit(&oscilloview_g.flag, memory_order_release);
}
+ if (!atomic_flag_test_and_set_explicit(
+ &g.at_fftdata_flag, memory_order_acquire)) {
+ fft_write(&g.at_fftdata, buf, frames);
+ atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release);
+ }
}
static bool loadfontrom(void) {
@@ -170,6 +181,7 @@ static void openfile(HWND hwnd, const wchar_t *path) {
if (!g.sound) goto err;
g.sound->pause(g.sound, 0);
g.paused = false;
+ g.work.paused = false;
wchar_t *pathcpy = HeapAlloc(g.heap, 0, (lstrlen(path)+1)*sizeof(wchar_t));
if (pathcpy) {
lstrcpy(pathcpy, path);
@@ -333,6 +345,7 @@ static bool proc_key(UINT vk, bool down, int repeat) {
case VK_F7:
if (g.sound) {
g.paused = !g.paused;
+ g.work.paused = g.paused;
g.sound->pause(g.sound, g.paused);
}
return true;
@@ -549,6 +562,7 @@ static void on_command(HWND hwnd, int id, HWND hwnd_c, UINT code) {
case ID_PAUSE:
if (g.sound) {
g.paused = !g.paused;
+ g.work.paused = g.paused;
g.sound->pause(g.sound, g.paused);
}
break;
@@ -611,7 +625,12 @@ static void on_destroy(HWND hwnd) {
}
static void on_paint(HWND hwnd) {
- fmdsp_update(&g.fmdsp, &g.work, &g.opna, g.vram);
+ if (!atomic_flag_test_and_set_explicit(
+ &g.at_fftdata_flag, memory_order_acquire)) {
+ memcpy(&g.fftdata.fdata, &g.at_fftdata, sizeof(g.fftdata));
+ atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release);
+ }
+ fmdsp_update(&g.fmdsp, &g.work, &g.opna, g.vram, &g.fftdata);
fmdsp_vrampalette(&g.fmdsp, g.vram, g.vram32, PC98_W*4);
PAINTSTRUCT ps;
HDC dc = BeginPaint(hwnd, &ps);
@@ -738,6 +757,8 @@ int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst,
if (__builtin_cpu_supports("sse2")) opna_ssg_sinc_calc_func = opna_ssg_sinc_calc_sse2;
if (__builtin_cpu_supports("ssse3")) fmdsp_vramlookup_func = fmdsp_vramlookup_ssse3;
+ fft_init_table();
+
const wchar_t *argfile = 0;
{
wchar_t *cmdline = GetCommandLine();
diff --git a/win32/wavewrite.c b/win32/wavewrite.c
index 7c2d6da..37f6145 100644
--- a/win32/wavewrite.c
+++ b/win32/wavewrite.c
@@ -3,6 +3,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
+#include <stdio.h>
struct wavefile {
HANDLE file;
@@ -67,17 +68,16 @@ size_t wavewrite_write(struct wavefile *wavefile, const int16_t *buf, size_t fra
}
void wavewrite_close(struct wavefile *wavefile) {
- LONG fp;
uint32_t size;
DWORD written;
- if ((SetFilePointer(wavefile->file, 40, &fp, FILE_BEGIN) == INVALID_SET_FILE_POINTER) || (fp != 40)) {
+ if (SetFilePointer(wavefile->file, 40, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
goto cleanup;
}
size = wavefile->written_frames * 4;
if (!WriteFile(wavefile->file, &size, sizeof(size), &written, 0) || (written != sizeof(size))) {
goto cleanup;
}
- if ((SetFilePointer(wavefile->file, 4, &fp, FILE_BEGIN) == INVALID_SET_FILE_POINTER) || (fp != 4)) {
+ if (SetFilePointer(wavefile->file, 4, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
goto cleanup;
}
size += 4 + 8 + 16 + 8;
diff --git a/win32/x86/Makefile b/win32/x86/Makefile
index 6146d28..ea2e16e 100644
--- a/win32/x86/Makefile
+++ b/win32/x86/Makefile
@@ -4,6 +4,7 @@ vpath %.c ../../libopna
vpath %.c ../../fmdsp
vpath %.c ../../tonedata
vpath %.c ../../common
+vpath %.c ../../fft
vpath %.rc ..
include ../fmplayer.mak