diff --git a/src/computer.c b/src/computer.c index 0c8af8b..0338dcd 100644 --- a/src/computer.c +++ b/src/computer.c @@ -178,6 +178,7 @@ void computer_init () { //Called only on start-up ordenador.npixels=4; ordenador.progressive=0; ordenador.audio_mode=2; //ACB + ordenador.low_filter=480; } void computer_set_palete() { @@ -1122,8 +1123,6 @@ inline void read_keyboard () { joy_axis_y[joy_n] = SDL_JoystickGetAxis(ordenador.joystick_sdl[joy_n], 1); - - if (joy_axis_x[joy_n] > 16384) ordenador.joy_axis_x_state[joy_n] = JOY_RIGHT; else if (joy_axis_x[joy_n] < -16384) ordenador.joy_axis_x_state[joy_n] = JOY_LEFT; else ordenador.joy_axis_x_state[joy_n] = JOY_CENTER_X; @@ -1155,10 +1154,10 @@ inline void read_keyboard () { status_hat[joy_n] = SDL_JoystickGetHat(ordenador.joystick_sdl[joy_n], 0); if(!ordenador.joypad_as_joystick[joy_n]) { - joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][18])] = (status_hat[joy_n] & SDL_HAT_UP); - joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][19])] = (status_hat[joy_n] & SDL_HAT_DOWN); - joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][20])] = (status_hat[joy_n] & SDL_HAT_LEFT); - joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][21])] = (status_hat[joy_n] & SDL_HAT_RIGHT); + joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][19])] = (status_hat[joy_n] & SDL_HAT_UP); + joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][20])] = (status_hat[joy_n] & SDL_HAT_DOWN); + joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][21])] = (status_hat[joy_n] & SDL_HAT_LEFT); + joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][22])] = (status_hat[joy_n] & SDL_HAT_RIGHT); } } } @@ -1660,7 +1659,7 @@ void ResetComputer () { ordenador.tape_current_mode = TAP_TRASH; rewind_tape (ordenador.tap_file,1); } - ordenador.precision=ordenador.precision_old; + ordenador.precision=ordenador.precision_old; //in case the machine is reset during loading } // check if there's contention and waits the right number of tstates @@ -1977,6 +1976,10 @@ void Z80free_Out (register word Port, register byte Value) { ordenador.sound_bit = 1; else ordenador.sound_bit = 0; // assign to SOUND_BIT the value + if (Value & 0x08) + ordenador.sound_bit_mic = 1; + else + ordenador.sound_bit_mic = 0; // assign to SOUND_BIT_MIC the value } } diff --git a/src/computer.h b/src/computer.h index 26bed6a..30273a1 100644 --- a/src/computer.h +++ b/src/computer.h @@ -123,11 +123,13 @@ struct computer { int increment; // quantity to add to jump to the next sample unsigned char volume; // volume unsigned char sample1[4]; // buffer with precalculated sample 1 (for buzzer) -currently not used - unsigned char sample1b[4]; // buffer with prec. sample 1 (for AY-3-8912) + unsigned char sample1b[4]; // buffer with prec. sample 1 (for AY-3-8912) -currently not used //unsigned char sample0[4]; // buffer with precalculated sample 0 unsigned char sound_bit; + unsigned char sound_bit_mic; unsigned int tstados_counter_sound; - unsigned char *current_buffer; + unsigned int low_filter; + unsigned int *current_buffer; unsigned char num_buff; unsigned int sound_cuantity; // counter for the buffer unsigned char ay_registers[16]; // registers for the AY emulation @@ -135,7 +137,7 @@ struct computer { unsigned char ayval_a,ayval_b,ayval_c,ayval_n; unsigned char ay_emul; // 0: no AY emulation; 1: AY emulation unsigned char audio_mode; //mono, ABC, ACB, BAC - unsigned char vol_a,vol_b,vol_c; + unsigned int vol_a,vol_b,vol_c; unsigned int tst_ay; unsigned int ay_latch; signed char ay_envel_value; @@ -232,7 +234,7 @@ struct computer { SDL_Joystick *joystick_sdl[2]; unsigned char joy_axis_x_state[2]; unsigned char joy_axis_y_state[2]; - unsigned int joybuttonkey[2][22]; + unsigned int joybuttonkey[2][23]; unsigned char joypad_as_joystick[2]; unsigned char rumble[2]; unsigned char vk_auto; diff --git a/src/emulator.c b/src/emulator.c index 45ff677..9dd3278 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -67,7 +67,7 @@ Z80FREE procesador; struct computer ordenador; SDL_Surface *screen; char salir,sound_aborted; -unsigned char *sound[NUM_SNDBUF]; +unsigned int *sound[NUM_SNDBUF]; char path_snaps[2049]; char path_taps[2049]; char path_mdrs[2049]; @@ -577,8 +577,8 @@ int bucle, bucle2,ret2; for(bucle2=0;bucle2precision=precision; + object->precision_old=precision; } if (bw<2) { object->bw=bw; diff --git a/src/emulator.h b/src/emulator.h index 43c16a6..c58c00a 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -31,7 +31,7 @@ extern char debug_var; extern SDL_Surface *screen; extern Z80FREE procesador; extern struct computer ordenador; -extern unsigned char *sound[NUM_SNDBUF]; +extern unsigned int *sound[NUM_SNDBUF]; extern char path_snaps[2049]; extern char path_taps[2049]; extern char path_mdrs[2049]; diff --git a/src/gui_sdl.c b/src/gui_sdl.c index 8a24c11..9638a67 100644 --- a/src/gui_sdl.c +++ b/src/gui_sdl.c @@ -51,6 +51,8 @@ extern FILE *fdebug; #define MAX_TRAINER 50 extern int countdown_buffer; +extern unsigned int beeper; + void clean_screen(); @@ -95,8 +97,10 @@ static const char *audio_messages[] = { /*04*/ "^|on|off", /*05*/ " ", /*06*/ "Audio mode", - /*07*/ "^|mono|ABC|ACB|BAC", - + /*07*/ "^|mono|ABC|ACB|BAC", + /*08 " ", + /*09 "Beeper low pass filter", + /*10 "^|0|1|2|3|4|5|6|7|max",*/ NULL }; @@ -575,9 +579,43 @@ static void emulation_settings(void) } } +unsigned int get_value_filter (unsigned int value) +{ + switch (value) + { + case 480: + return(0); + case 240: + return(1); + case 160: + return(2); + case 120: + return(3); + case 80: + return(4); + case 60: + return(5); + case 40: + return(6); + case 24: + return(7); + case 10: + return(8); + default: + return(0); + } +} + +unsigned int set_value_filter (unsigned int value) +{ + unsigned int set[9] = {480,240,160,120,80,60,40,24,10}; + beeper=0; + return set[value]; +} + static void audio_settings(void) { - unsigned int submenus[3]; + unsigned int submenus[4]; int opt; @@ -587,6 +625,7 @@ static void audio_settings(void) submenus[0] = ordenador.volume/2; submenus[1] = !ordenador.ay_emul; submenus[2] = ordenador.audio_mode; + submenus[3] = get_value_filter(ordenador.low_filter); opt = menu_select_title("Audio settings menu", @@ -598,6 +637,7 @@ static void audio_settings(void) ordenador.volume = submenus[0]*2; ordenador.ay_emul = !submenus[1]; ordenador.audio_mode = submenus[2]; + ordenador.low_filter= set_value_filter(submenus[3]); } @@ -660,7 +700,7 @@ static void setup_joystick(int joy, unsigned int sdl_key, int joy_key) int loop; //Cancel the previous assignement - it is not possible to assign a same sdl_key to 2 joybuttons - for (loop=0; loop<22; loop++) + for (loop=0; loop<23; loop++) if (ordenador.joybuttonkey[joy][loop] == sdl_key) ordenador.joybuttonkey[joy][loop] =0; ordenador.joybuttonkey[joy][joy_key] = sdl_key; @@ -672,7 +712,7 @@ static void input_options(int joy) const unsigned int wiimote_to_sdl[] = {0, 1, 2, 3, 4,5}; const unsigned int nunchuk_to_sdl[] = {7, 8}; const unsigned int classic_to_sdl[] = {9, 10, 11, 12, 13, 14, 15, 16, 17,18}; - const unsigned int pad_to_sdl[] = {18, 19, 20, 21}; + const unsigned int pad_to_sdl[] = {19, 20, 21, 22}; int joy_key = 1; unsigned int sdl_key; unsigned int submenus[7]; diff --git a/src/sound.c b/src/sound.c index 500609a..b398f9e 100644 --- a/src/sound.c +++ b/src/sound.c @@ -182,7 +182,7 @@ int sound_init_asnd() { ASND_Init(); ASND_Pause(0); ordenador.sign=0; - ordenador.format=0; //8 bit + ordenador.format=1; //16 bit ordenador.channels=2; //stereo ordenador.freq=48000; ordenador.buffer_len=4096; @@ -495,8 +495,8 @@ void sound_play() { #ifdef GEKKO case SOUND_ASND: // ASND if (!started_sound_asnd) { - ASND_SetVoice(1,VOICE_STEREO_8BIT_U,ordenador.freq,0,sound[0],ordenador.buffer_len*ordenador.increment, - MID_VOLUME, MID_VOLUME, callback); + ASND_SetVoice(1,VOICE_STEREO_16BIT_BE,ordenador.freq,0,sound[0],ordenador.buffer_len*ordenador.increment, + 255, 255, callback); started_sound_asnd = 1; } //Double buffer diff --git a/src/spk_ay.c b/src/spk_ay.c index 6313c5c..88106db 100644 --- a/src/spk_ay.c +++ b/src/spk_ay.c @@ -24,6 +24,8 @@ #include "sound.h" #include +unsigned int beeper = 0; + /* emulates the AY-3-8912 during TSTADOS tstates */ inline void play_ay (unsigned int tstados) { @@ -45,7 +47,7 @@ inline void play_ay (unsigned int tstados) { 0x92, 0xAF, 0xD9, 0xFF }; - if (!ordenador.ay_emul) + if ((!ordenador.ay_emul)||(ordenador.turbo_state)) return; ordenador.tst_ay += tstados; @@ -312,8 +314,7 @@ inline void play_ay (unsigned int tstados) { inline void play_sound (unsigned int tstados) { - int value, lvalue, rvalue; - + int lvalue, rvalue; ordenador.tstados_counter_sound += tstados; @@ -321,51 +322,57 @@ inline void play_sound (unsigned int tstados) { ordenador.tstados_counter_sound -= ordenador.tst_sample; - if (ordenador.sound_bit) value=ordenador.volume*6; //Sound bit volume max 96 - else value=0; - - //Each channel max 51 - + /* + //Low pass filter + if (ordenador.sound_bit) + { + if (beeper<480) beeper = beeper + ordenador.low_filter; //Sound bit volume max 480*vol + } + else if (beeper>0) beeper = beeper - ordenador.low_filter; + */ + + if (ordenador.sound_bit) + { + if (ordenador.sound_bit_mic) beeper = 544; //480 + 64 - MIC is audible only if EAR is on + else beeper = 480; //Sound bit volume max 480*vol + } + else beeper =0; + + //Each channel max 256*vol + if (ordenador.ay_emul) { switch (ordenador.audio_mode) { case 0: //Mono - lvalue = value + (ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume/80; - rvalue = value + (ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume/80; + lvalue = (beeper + ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume; + rvalue = (beeper + ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume; break; case 1: //ABC - lvalue = value + (ordenador.vol_a*2 + ordenador.vol_b)*ordenador.volume/80; - rvalue = value + (ordenador.vol_b + ordenador.vol_c*2)*ordenador.volume/80; + lvalue = (beeper + ordenador.vol_a*2 + ordenador.vol_b)*ordenador.volume; + rvalue = (beeper + ordenador.vol_b + ordenador.vol_c*2)*ordenador.volume; break; case 2: //ACB - lvalue = value + (ordenador.vol_a*2 + ordenador.vol_c)*ordenador.volume/80; - rvalue = value + (ordenador.vol_c + ordenador.vol_b*2)*ordenador.volume/80; + lvalue = (beeper + ordenador.vol_a*2 + ordenador.vol_c)*ordenador.volume; + rvalue = (beeper + ordenador.vol_c + ordenador.vol_b*2)*ordenador.volume; break; case 3: //BAC - lvalue = value + (ordenador.vol_b*2 + ordenador.vol_a)*ordenador.volume/80; - rvalue = value + (ordenador.vol_a + ordenador.vol_c*2)*ordenador.volume/80; + lvalue = (beeper + ordenador.vol_b*2 + ordenador.vol_a)*ordenador.volume; + rvalue = (beeper + ordenador.vol_a + ordenador.vol_c*2)*ordenador.volume; break; default: //No emulation - rvalue = value; - lvalue = value; + rvalue = beeper*ordenador.volume; + lvalue = beeper*ordenador.volume; break; } } else { - rvalue = value; - lvalue = value; + rvalue = beeper*ordenador.volume; + lvalue = beeper*ordenador.volume; } - - /* - if (rvalue > 255) rvalue = 255; - if (lvalue > 255) lvalue = 255; - */ - - *ordenador.current_buffer = (unsigned char)(rvalue - (unsigned int)ordenador.sign); - ordenador.current_buffer++; - *ordenador.current_buffer = (unsigned char)(lvalue - (unsigned int)ordenador.sign); + + *ordenador.current_buffer = (lvalue<<16)|(rvalue); ordenador.current_buffer++; ordenador.sound_cuantity++;