gp2x->common menu migration finished, gp2x now only uses input fwk
[libpicofe.git] / linux / 940ctl_ym2612.c
1 /* faked 940 code just uses local copy of ym2612 */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/mman.h>
7 #include <sys/ioctl.h>
8 #include <fcntl.h>
9 #include <errno.h>
10
11 #include "../../pico/sound/ym2612.h"
12 #include "../gp2x/gp2x.h"
13 #include "../gp2x/emu.h"
14 #include "../gp2x/code940/940shared.h"
15 #include "../common/helix/pub/mp3dec.h"
16 #include "../../pico/pico_int.h"
17
18
19 // static _940_data_t  shared_data_;
20 static _940_ctl_t   shared_ctl_;
21 // static _940_data_t *shared_data = &shared_data_;
22 _940_ctl_t  *shared_ctl = &shared_ctl_;
23
24 unsigned char *mp3_mem = 0;
25
26 #define MP3_SIZE_MAX (0x1000000 - 4*640*480)
27
28 /***********************************************************/
29
30
31 int YM2612Write_940(unsigned int a, unsigned int v, int scanline)
32 {
33         YM2612Write_(a, v);
34
35         return 0; // cause the engine to do updates once per frame only
36 }
37
38
39 void YM2612PicoStateLoad_940(void)
40 {
41         int i;
42
43         YM2612PicoStateLoad_();
44
45         for(i = 0; i < 0x100; i++) {
46                 YM2612Write_(0, i);
47                 YM2612Write_(1, ym2612.REGS[i]);
48         }
49         for(i = 0; i < 0x100; i++) {
50                 YM2612Write_(2, i);
51                 YM2612Write_(3, ym2612.REGS[i|0x100]);
52         }
53 }
54
55 void YM2612PicoStateSave2_940(int tat, int tbt)
56 {
57         YM2612PicoStateSave2(tat, tbt);
58 }
59
60 int YM2612PicoStateLoad2_940(int *tat, int *tbt)
61 {
62         return YM2612PicoStateLoad2(tat, tbt);
63 }
64
65
66 void sharedmem_init(void)
67 {
68         mp3_mem = malloc(MP3_SIZE_MAX);
69 }
70
71 void sharedmem_deinit(void)
72 {
73         free(mp3_mem);
74 }
75
76 void YM2612Init_940(int baseclock, int rate)
77 {
78         YM2612Init_(baseclock, rate);
79 }
80
81
82 void YM2612ResetChip_940(void)
83 {
84         YM2612ResetChip_();
85 }
86
87
88 #if 0
89 static void local_decode(void)
90 {
91         int mp3_offs = shared_ctl->mp3_offs;
92         unsigned char *readPtr = mp3_mem + mp3_offs;
93         int bytesLeft = shared_ctl->mp3_len - mp3_offs;
94         int offset; // frame offset from readPtr
95         int err = 0;
96
97         if (bytesLeft <= 0) return; // EOF, nothing to do
98
99         offset = MP3FindSyncWord(readPtr, bytesLeft);
100         if (offset < 0) {
101                 shared_ctl->mp3_offs = shared_ctl->mp3_len;
102                 return; // EOF
103         }
104         readPtr += offset;
105         bytesLeft -= offset;
106
107         err = MP3Decode(shared_data->mp3dec, &readPtr, &bytesLeft,
108                         shared_data->mp3_buffer[shared_ctl->mp3_buffsel], 0);
109         if (err) {
110                 if (err == ERR_MP3_INDATA_UNDERFLOW) {
111                         shared_ctl->mp3_offs = shared_ctl->mp3_len; // EOF
112                         return;
113                 } else if (err <= -6 && err >= -12) {
114                         // ERR_MP3_INVALID_FRAMEHEADER, ERR_MP3_INVALID_*
115                         // just try to skip the offending frame..
116                         readPtr++;
117                 }
118                 shared_ctl->mp3_errors++;
119                 shared_ctl->mp3_lasterr = err;
120         }
121         shared_ctl->mp3_offs = readPtr - mp3_mem;
122 }
123 #endif
124
125
126
127
128 static FILE *loaded_mp3 = 0;
129
130 int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty)
131 {
132 #if 0
133         int cdda_on, *ym_buffer = mix_buffer;
134         static int mp3_samples_ready = 0, mp3_buffer_offs = 0;
135         static int mp3_play_bufsel = 1;
136
137
138         YM2612UpdateOne_(buffer, length, stereo); // really writes to mix_buffer
139
140         // emulatind MCD, not data track, CDC is reading, playback was started, track not ended
141         cdda_on = (PicoMCD & 1) && !(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1)
142                         && loaded_mp3 && shared_ctl->mp3_offs < shared_ctl->mp3_len;
143
144         /* mix data from previous go */
145         if (cdda_on && mp3_samples_ready >= length)
146         {
147                 if (1152 - mp3_buffer_offs >= length) {
148                         mix_samples(buffer, ym_buffer, shared_data->mp3_buffer[mp3_play_bufsel] + mp3_buffer_offs*2, length, stereo);
149
150                         mp3_buffer_offs += length;
151                 } else {
152                         // collect from both buffers..
153                         int left = 1152 - mp3_buffer_offs;
154                         mix_samples(buffer, ym_buffer, shared_data->mp3_buffer[mp3_play_bufsel] + mp3_buffer_offs*2, left, stereo);
155                         mp3_play_bufsel ^= 1;
156                         mp3_buffer_offs = length - left;
157                         mix_samples(buffer + left * 2, ym_buffer + left * 2,
158                                 shared_data->mp3_buffer[mp3_play_bufsel], mp3_buffer_offs, stereo);
159                 }
160                 mp3_samples_ready -= length;
161         } else {
162                 mix_samples(buffer, ym_buffer, 0, length, stereo);
163         }
164
165         // make sure we will have enough mp3 samples next frame
166         if (cdda_on && mp3_samples_ready < length)
167         {
168                 shared_ctl->mp3_buffsel ^= 1;
169                 local_decode();
170                 mp3_samples_ready += 1152;
171         }
172 #else
173         return YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
174 #endif
175 }
176
177
178 void mp3_update(int *buffer, int length, int stereo)
179 {
180         // nothing..
181 }
182
183
184 /***********************************************************/
185
186 void mp3_start_play(FILE *f, int pos) // pos is 0-1023
187 {
188         int byte_offs = 0;
189
190         if (loaded_mp3 != f)
191         {
192                 printf("loading mp3... "); fflush(stdout);
193                 fseek(f, 0, SEEK_SET);
194                 fread(mp3_mem, 1, MP3_SIZE_MAX, f);
195                 if (feof(f)) printf("done.\n");
196                 else printf("done. mp3 too large, not all data loaded.\n");
197                 shared_ctl->mp3_len = ftell(f);
198                 loaded_mp3 = f;
199         }
200
201         // seek..
202         if (pos) {
203                 byte_offs  = (shared_ctl->mp3_len << 6) >> 10;
204                 byte_offs *= pos;
205                 byte_offs >>= 6;
206         }
207         printf("mp3 pos1024: %i, byte_offs %i/%i\n", pos, byte_offs, shared_ctl->mp3_len);
208
209         shared_ctl->mp3_offs = byte_offs;
210 }
211
212