| 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/menu.h" |
| 15 | #include "../gp2x/code940/940shared.h" |
| 16 | #include "../gp2x/helix/pub/mp3dec.h" |
| 17 | #include "../../Pico/PicoInt.h" |
| 18 | |
| 19 | |
| 20 | static YM2612 ym2612; |
| 21 | |
| 22 | YM2612 *ym2612_940 = &ym2612; |
| 23 | int mix_buffer_[44100/50*2]; /* this is where the YM2612 samples will be mixed to */ |
| 24 | int *mix_buffer = mix_buffer_; |
| 25 | |
| 26 | static _940_data_t shared_data_; |
| 27 | static _940_ctl_t shared_ctl_; |
| 28 | static _940_data_t *shared_data = &shared_data_; |
| 29 | static _940_ctl_t *shared_ctl = &shared_ctl_; |
| 30 | |
| 31 | unsigned char *mp3_mem = 0; |
| 32 | |
| 33 | #define MP3_SIZE_MAX (0x1000000 - 4*640*480) |
| 34 | |
| 35 | /***********************************************************/ |
| 36 | |
| 37 | #define MAXOUT (+32767) |
| 38 | #define MINOUT (-32768) |
| 39 | |
| 40 | /* limitter */ |
| 41 | #define Limit(val, max,min) { \ |
| 42 | if ( val > max ) val = max; \ |
| 43 | else if ( val < min ) val = min; \ |
| 44 | } |
| 45 | |
| 46 | |
| 47 | int YM2612Write_940(unsigned int a, unsigned int v) |
| 48 | { |
| 49 | YM2612Write_(a, v); |
| 50 | |
| 51 | return 0; // cause the engine to do updates once per frame only |
| 52 | } |
| 53 | |
| 54 | UINT8 YM2612Read_940(void) |
| 55 | { |
| 56 | return YM2612Read_(); |
| 57 | } |
| 58 | |
| 59 | |
| 60 | int YM2612PicoTick_940(int n) |
| 61 | { |
| 62 | YM2612PicoTick_(n); |
| 63 | |
| 64 | return 0; |
| 65 | } |
| 66 | |
| 67 | |
| 68 | void YM2612PicoStateLoad_940(void) |
| 69 | { |
| 70 | int i; |
| 71 | |
| 72 | YM2612PicoStateLoad_(); |
| 73 | |
| 74 | for(i = 0; i < 0x100; i++) { |
| 75 | YM2612Write_(0, i); |
| 76 | YM2612Write_(1, ym2612.REGS[i]); |
| 77 | } |
| 78 | for(i = 0; i < 0x100; i++) { |
| 79 | YM2612Write_(2, i); |
| 80 | YM2612Write_(3, ym2612.REGS[i|0x100]); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | |
| 85 | void YM2612Init_940(int baseclock, int rate) |
| 86 | { |
| 87 | mp3_mem = malloc(MP3_SIZE_MAX); |
| 88 | |
| 89 | YM2612Init_(baseclock, rate); |
| 90 | } |
| 91 | |
| 92 | |
| 93 | void YM2612ResetChip_940(void) |
| 94 | { |
| 95 | YM2612ResetChip_(); |
| 96 | } |
| 97 | |
| 98 | |
| 99 | static void mix_samples(short *dest_buf, int *ym_buf, short *mp3_buf, int len, int stereo) |
| 100 | { |
| 101 | if (mp3_buf) |
| 102 | { |
| 103 | if (stereo) |
| 104 | { |
| 105 | for (; len > 0; len--) |
| 106 | { |
| 107 | int l, r; |
| 108 | l = r = *dest_buf; |
| 109 | l += *ym_buf++; r += *ym_buf++; |
| 110 | l += *mp3_buf++; r += *mp3_buf++; |
| 111 | Limit( l, MAXOUT, MINOUT ); |
| 112 | Limit( r, MAXOUT, MINOUT ); |
| 113 | *dest_buf++ = l; *dest_buf++ = r; |
| 114 | } |
| 115 | } else { |
| 116 | for (; len > 0; len--) |
| 117 | { |
| 118 | int l = *ym_buf++; |
| 119 | l += *dest_buf; |
| 120 | l += *mp3_buf++; |
| 121 | Limit( l, MAXOUT, MINOUT ); |
| 122 | *dest_buf++ = l; |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | else |
| 127 | { |
| 128 | if (stereo) |
| 129 | { |
| 130 | for (; len > 0; len--) |
| 131 | { |
| 132 | int l, r; |
| 133 | l = r = *dest_buf; |
| 134 | l += *ym_buf++, r += *ym_buf++; |
| 135 | Limit( l, MAXOUT, MINOUT ); |
| 136 | Limit( r, MAXOUT, MINOUT ); |
| 137 | *dest_buf++ = l; *dest_buf++ = r; |
| 138 | } |
| 139 | } else { |
| 140 | for (; len > 0; len--) |
| 141 | { |
| 142 | int l = *ym_buf++; |
| 143 | l += *dest_buf; |
| 144 | Limit( l, MAXOUT, MINOUT ); |
| 145 | *dest_buf++ = l; |
| 146 | } |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | #if 0 |
| 152 | static void local_decode(void) |
| 153 | { |
| 154 | int mp3_offs = shared_ctl->mp3_offs; |
| 155 | unsigned char *readPtr = mp3_mem + mp3_offs; |
| 156 | int bytesLeft = shared_ctl->mp3_len - mp3_offs; |
| 157 | int offset; // frame offset from readPtr |
| 158 | int err = 0; |
| 159 | |
| 160 | if (bytesLeft <= 0) return; // EOF, nothing to do |
| 161 | |
| 162 | offset = MP3FindSyncWord(readPtr, bytesLeft); |
| 163 | if (offset < 0) { |
| 164 | shared_ctl->mp3_offs = shared_ctl->mp3_len; |
| 165 | return; // EOF |
| 166 | } |
| 167 | readPtr += offset; |
| 168 | bytesLeft -= offset; |
| 169 | |
| 170 | err = MP3Decode(shared_data->mp3dec, &readPtr, &bytesLeft, |
| 171 | shared_data->mp3_buffer[shared_ctl->mp3_buffsel], 0); |
| 172 | if (err) { |
| 173 | if (err == ERR_MP3_INDATA_UNDERFLOW) { |
| 174 | shared_ctl->mp3_offs = shared_ctl->mp3_len; // EOF |
| 175 | return; |
| 176 | } else if (err <= -6 && err >= -12) { |
| 177 | // ERR_MP3_INVALID_FRAMEHEADER, ERR_MP3_INVALID_* |
| 178 | // just try to skip the offending frame.. |
| 179 | readPtr++; |
| 180 | } |
| 181 | shared_ctl->mp3_errors++; |
| 182 | shared_ctl->mp3_lasterr = err; |
| 183 | } |
| 184 | shared_ctl->mp3_offs = readPtr - mp3_mem; |
| 185 | } |
| 186 | #endif |
| 187 | |
| 188 | |
| 189 | |
| 190 | |
| 191 | static FILE *loaded_mp3 = 0; |
| 192 | |
| 193 | void YM2612UpdateOne_940(short *buffer, int length, int stereo) |
| 194 | { |
| 195 | #if 0 |
| 196 | int cdda_on, *ym_buffer = mix_buffer; |
| 197 | static int mp3_samples_ready = 0, mp3_buffer_offs = 0; |
| 198 | static int mp3_play_bufsel = 1; |
| 199 | |
| 200 | |
| 201 | YM2612UpdateOne_(buffer, length, stereo); // really writes to mix_buffer |
| 202 | |
| 203 | // emulatind MCD, not data track, CDC is reading, playback was started, track not ended |
| 204 | cdda_on = (PicoMCD & 1) && !(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1) |
| 205 | && loaded_mp3 && shared_ctl->mp3_offs < shared_ctl->mp3_len; |
| 206 | |
| 207 | /* mix data from previous go */ |
| 208 | if (cdda_on && mp3_samples_ready >= length) |
| 209 | { |
| 210 | if (1152 - mp3_buffer_offs >= length) { |
| 211 | mix_samples(buffer, ym_buffer, shared_data->mp3_buffer[mp3_play_bufsel] + mp3_buffer_offs*2, length, stereo); |
| 212 | |
| 213 | mp3_buffer_offs += length; |
| 214 | } else { |
| 215 | // collect from both buffers.. |
| 216 | int left = 1152 - mp3_buffer_offs; |
| 217 | mix_samples(buffer, ym_buffer, shared_data->mp3_buffer[mp3_play_bufsel] + mp3_buffer_offs*2, left, stereo); |
| 218 | mp3_play_bufsel ^= 1; |
| 219 | mp3_buffer_offs = length - left; |
| 220 | mix_samples(buffer + left * 2, ym_buffer + left * 2, |
| 221 | shared_data->mp3_buffer[mp3_play_bufsel], mp3_buffer_offs, stereo); |
| 222 | } |
| 223 | mp3_samples_ready -= length; |
| 224 | } else { |
| 225 | mix_samples(buffer, ym_buffer, 0, length, stereo); |
| 226 | } |
| 227 | |
| 228 | // make sure we will have enough mp3 samples next frame |
| 229 | if (cdda_on && mp3_samples_ready < length) |
| 230 | { |
| 231 | shared_ctl->mp3_buffsel ^= 1; |
| 232 | local_decode(); |
| 233 | mp3_samples_ready += 1152; |
| 234 | } |
| 235 | #else |
| 236 | YM2612UpdateOne_(buffer, length, stereo); // really writes to mix_buffer |
| 237 | |
| 238 | mix_samples(buffer, mix_buffer, 0, length, stereo); |
| 239 | #endif |
| 240 | } |
| 241 | |
| 242 | |
| 243 | /***********************************************************/ |
| 244 | |
| 245 | void mp3_start_play(FILE *f, int pos) // pos is 0-1023 |
| 246 | { |
| 247 | int byte_offs = 0; |
| 248 | |
| 249 | if (loaded_mp3 != f) |
| 250 | { |
| 251 | printf("loading mp3... "); fflush(stdout); |
| 252 | fseek(f, 0, SEEK_SET); |
| 253 | fread(mp3_mem, 1, MP3_SIZE_MAX, f); |
| 254 | if (feof(f)) printf("done.\n"); |
| 255 | else printf("done. mp3 too large, not all data loaded.\n"); |
| 256 | shared_ctl->mp3_len = ftell(f); |
| 257 | loaded_mp3 = f; |
| 258 | } |
| 259 | |
| 260 | // seek.. |
| 261 | if (pos) { |
| 262 | byte_offs = (shared_ctl->mp3_len << 6) >> 10; |
| 263 | byte_offs *= pos; |
| 264 | byte_offs >>= 6; |
| 265 | } |
| 266 | printf("mp3 pos1024: %i, byte_offs %i/%i\n", pos, byte_offs, shared_ctl->mp3_len); |
| 267 | |
| 268 | shared_ctl->mp3_offs = byte_offs; |
| 269 | } |
| 270 | |
| 271 | |
| 272 | |