📄 unix.cpp
字号:
perror ("ioctl SNDCTL_DSP_MAPOUTBUF");#endif printf ("Rate: %d, Buffer size: %d, 16-bit: %s, Stereo: %s, Encoded: %s\n", so.playback_rate, so.buffer_size, so.sixteen_bit ? "yes" : "no", so.stereo ? "yes" : "no", so.encoded ? "yes" : "no"); return (TRUE);}#endif#if !defined(NOSOUND) && (defined (__linux) || defined (__sun))void S9xUnixProcessSound (void){}static uint8 Buf[MAX_BUFFER_SIZE];#define FIXED_POINT 0x10000#define FIXED_POINT_SHIFT 16#define FIXED_POINT_REMAINDER 0xffffstatic volatile bool8 block_signal = FALSE;static volatile bool8 block_generate_sound = FALSE;static volatile bool8 pending_signal = FALSE;#endif#if defined(NOSOUND)static int Rates[8] ={ 0, 8000, 11025, 16000, 22050, 32000, 44100, 48000};static int BufferSizes [8] ={ 0, 256, 256, 256, 512, 512, 1024, 1024};bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size){ return false;}void S9xGenerateSound (){}void *S9xProcessSound (void *){ /* No sound version */}#endif#if !defined(NOSOUND) && (defined (__linux) || defined (__sun))void S9xGenerateSound (){ /* Linux and Sun versions */ int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far; if (Settings.SoundSync == 2) { // Assumes sound is signal driven while (so.samples_mixed_so_far >= so.buffer_size && !so.mute_sound) pause (); } else if (bytes_so_far >= so.buffer_size) return;#ifdef USE_THREADS if (Settings.ThreadSound) { if (block_generate_sound || pthread_mutex_trylock (&mutex)) return; }#endif block_signal = TRUE; so.err_counter += so.err_rate; if (so.err_counter >= FIXED_POINT) { int sample_count = so.err_counter >> FIXED_POINT_SHIFT; int byte_offset; int byte_count; so.err_counter &= FIXED_POINT_REMAINDER; if (so.stereo) sample_count <<= 1; byte_offset = bytes_so_far + so.play_position; do { int sc = sample_count; byte_count = sample_count; if (so.sixteen_bit) byte_count <<= 1; if ((byte_offset & SOUND_BUFFER_SIZE_MASK) + byte_count > SOUND_BUFFER_SIZE) { sc = SOUND_BUFFER_SIZE - (byte_offset & SOUND_BUFFER_SIZE_MASK); byte_count = sc; if (so.sixteen_bit) sc >>= 1; } if (bytes_so_far + byte_count > so.buffer_size) { byte_count = so.buffer_size - bytes_so_far; if (byte_count == 0) break; sc = byte_count; if (so.sixteen_bit) sc >>= 1; } S9xMixSamplesO (Buf, sc, byte_offset & SOUND_BUFFER_SIZE_MASK); so.samples_mixed_so_far += sc; sample_count -= sc; bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far; byte_offset += byte_count; } while (sample_count > 0); } block_signal = FALSE;#ifdef USE_THREADS if (Settings.ThreadSound) pthread_mutex_unlock (&mutex); else#endif if (pending_signal) { S9xProcessSound (NULL); pending_signal = FALSE; }}void *S9xProcessSound (void *){ /* Linux and Sun versions */ /* If threads in use, this is to loop indefinitely */ /* If not, this will be called by timer */ #ifdef __linux audio_buf_info info; if (!Settings.ThreadSound && (ioctl (so.sound_fd, SNDCTL_DSP_GETOSPACE, &info) == -1 || info.bytes < so.buffer_size)) { return (NULL); }#ifdef MMAP_SOUND count_info count; if (ioctl (so.sound_fd, SNDCTL_DSP_GETOPTR, &count) < 0) { printf ("F"); fflush (stdout); } else { printf ("<%d,%d>", count.blocks, count.bytes); fflush (stdout); return (NULL); }#endif#endif#ifdef __sun audio_info_t audio; if (!Settings.ThreadSound) { if (ioctl (so.sound_fd, AUDIO_GETINFO, &audio) < 0) return (NULL); if (audio.play.eof == 0) so.last_eof = -2; else if (audio.play.eof == so.last_eof) return (NULL); so.last_eof++; }#endif#ifdef USE_THREADS do {#endif /* Number of samples to generate now */ int sample_count = so.buffer_size; if (so.sixteen_bit) { /* to prevent running out of buffer space, * create less samples */ sample_count >>= 1; } #ifdef USE_THREADS if (Settings.ThreadSound) pthread_mutex_lock (&mutex); else#endif if (block_signal) { pending_signal = TRUE; return (NULL); } block_generate_sound = TRUE; /* If we need more audio samples */ if (so.samples_mixed_so_far < sample_count) { /* Where to put the samples to */ unsigned byte_offset = so.play_position + (so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far);//printf ("%d:", sample_count - so.samples_mixed_so_far); fflush (stdout); if (Settings.SoundSync == 2) { /*memset (Buf + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0, sample_count - so.samples_mixed_so_far);*/ } else { /* Mix the missing samples */ S9xMixSamplesO (Buf, sample_count - so.samples_mixed_so_far, byte_offset & SOUND_BUFFER_SIZE_MASK); } so.samples_mixed_so_far = sample_count; } // if (!so.mute_sound) { unsigned bytes_to_write = sample_count; if(so.sixteen_bit) bytes_to_write <<= 1; unsigned byte_offset = so.play_position; so.play_position += bytes_to_write; so.play_position &= SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */#ifdef USE_THREADS if (Settings.ThreadSound) pthread_mutex_unlock (&mutex);#endif block_generate_sound = FALSE; /* Feed the samples to the soundcard until nothing is left */ for(;;) { int I = bytes_to_write; if (byte_offset + I > SOUND_BUFFER_SIZE) { I = SOUND_BUFFER_SIZE - byte_offset; } if(I == 0) break; I = write (so.sound_fd, (char *) Buf + byte_offset, I); if (I > 0) { bytes_to_write -= I; byte_offset += I; byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */ } /* give up if an unrecoverable error happened */ if(I < 0 && errno != EINTR) break; } /* All data sent. */ } so.samples_mixed_so_far -= sample_count;#ifdef USE_THREADS } while (Settings.ThreadSound);#endif#ifdef __sun if (!Settings.ThreadSound) write (so.sound_fd, NULL, 0);#endif return (NULL);}#endifuint32 S9xReadJoypad (int which1){#ifdef _NETPLAY_SUPPORT if (Settings.NetPlay) return (S9xNetPlayGetJoypad (which1));#endif if (which1 < NumControllers) return (0x80000000 | joypads [which1]); return (0);}#if !defined(NOSOUND) && defined(__sun)uint8 int2ulaw(int ch){ int mask; if (ch < 0) { ch = -ch; mask = 0x7f; } else { mask = 0xff; } if (ch < 32) { ch = 0xF0 | ( 15 - (ch/2) ); } else if (ch < 96) { ch = 0xE0 | ( 15 - (ch-32)/4 ); } else if (ch < 224) { ch = 0xD0 | ( 15 - (ch-96)/8 ); } else if (ch < 480) { ch = 0xC0 | ( 15 - (ch-224)/16 ); } else if (ch < 992 ) { ch = 0xB0 | ( 15 - (ch-480)/32 ); } else if (ch < 2016) { ch = 0xA0 | ( 15 - (ch-992)/64 ); } else if (ch < 4064) { ch = 0x90 | ( 15 - (ch-2016)/128 ); } else if (ch < 8160) { ch = 0x80 | ( 15 - (ch-4064)/256 ); } else { ch = 0x80; } return (uint8)(mask & ch);}#endif#if 0void S9xParseConfigFile (){ int i, t = 0; char *b, buf[10]; struct ffblk f; set_config_file("SNES9X.CFG"); if (findfirst("SNES9X.CFG", &f, 0) != 0) { set_config_int("Graphics", "VideoMode", -1); set_config_int("Graphics", "AutoFrameskip", 1); set_config_int("Graphics", "Frameskip", 0); set_config_int("Graphics", "Shutdown", 1); set_config_int("Graphics", "FrameTimePAL", 20000); set_config_int("Graphics", "FrameTimeNTSC", 16667); set_config_int("Graphics", "Transparency", 0); set_config_int("Graphics", "HiColor", 0); set_config_int("Graphics", "Hi-ResSupport", 0); set_config_int("Graphics", "CPUCycles", 100); set_config_int("Graphics", "Scale", 0); set_config_int("Graphics", "VSync", 0); set_config_int("Sound", "APUEnabled", 1); set_config_int("Sound", "SoundPlaybackRate", 4); set_config_int("Sound", "Stereo", 1); set_config_int("Sound", "SoundBufferSize", 256); set_config_int("Sound", "SPCToCPURatio", 2); set_config_int("Sound", "Echo", 1); set_config_int("Sound", "SampleCaching", 1); set_config_int("Sound", "MasterVolume", 1); set_config_int("Peripherals", "Mouse", 1); set_config_int("Peripherals", "SuperScope", 1); set_config_int("Peripherals", "MultiPlayer5", 1); set_config_int("Peripherals", "Controller", 0); set_config_int("Controllers", "Type", JOY_TYPE_AUTODETECT); set_config_string("Controllers", "Button1", "A"); set_config_string("Controllers", "Button2", "B"); set_config_string("Controllers", "Button3", "X"); set_config_string("Controllers", "Button4", "Y"); set_config_string("Controllers", "Button5", "TL"); set_config_string("Controllers", "Button6", "TR"); set_config_string("Controllers", "Button7", "START"); set_config_string("Controllers", "Button8", "SELECT"); set_config_string("Controllers", "Button9", "NONE"); set_config_string("Controllers", "Button10", "NONE"); } mode = get_config_int("Graphics", "VideoMode", -1); Settings.SkipFrames = get_config_int("Graphics", "AutoFrameskip", 1); if (!Settings.SkipFrames) Settings.SkipFrames = get_config_int("Graphics", "Frameskip", AUTO_FRAMERATE); else Settings.SkipFrames = AUTO_FRAMERATE; Settings.ShutdownMaster = get_config_int("Graphics", "Shutdown", TRUE); Settings.FrameTimePAL = get_config_int("Graphics", "FrameTimePAL", 20000); Settings.FrameTimeNTSC = get_config_int("Graphics", "FrameTimeNTSC", 16667); Settings.FrameTime = Settings.FrameTimeNTSC; Settings.Transparency = get_config_int("Graphics", "Transparency", FALSE); Settings.SixteenBit = get_config_int("Graphics", "HiColor", FALSE); Settings.SupportHiRes = get_config_int("Graphics", "Hi-ResSupport", FALSE); i = get_config_int("Graphics", "CPUCycles", 100); Settings.H_Max = (i * SNES_CYCLES_PER_SCANLINE) / i; stretch = get_config_int("Graphics", "Scale", 0); _vsync = get_config_int("Graphics", "VSync", 0); Settings.APUEnabled = get_config_int("Sound", "APUEnabled", TRUE); Settings.SoundPlaybackRate = get_config_int("Sound", "SoundPlaybackRate", 4); Settings.Stereo = get_config_int("Sound", "Stereo", TRUE); Settings.SoundBufferSize = get_config_int("Sound", "SoundBufferSize", 256); Settings.SPCTo65c816Ratio = get_config_int("Sound", "SPCToCPURatio", 2); Settings.DisableSoundEcho = get_config_int("Sound", "Echo", TRUE) ? FALSE : TRUE; Settings.DisableSampleCaching = get_config_int("Sound", "SampleCaching", TRUE) ? FALSE : TRUE; Settings.DisableMasterVolume = get_config_int("Sound", "MasterVolume", TRUE) ? FALSE : TRUE; Settings.Mouse = get_config_int("Peripherals", "Mouse", TRUE); Settings.SuperScope = get_config_int("Peripherals", "SuperScope", TRUE); Settings.MultiPlayer5 = get_config_int("Peripherals", "MultiPlayer5", TRUE); Settings.ControllerOption = (uint32)get_config_int("Peripherals", "Controller", SNES_MULTIPLAYER5); joy_type = get_config_int("Controllers", "Type", JOY_TYPE_AUTODETECT); for (i = 0; i < 10; i++) { sprintf(buf, "Button%d", i+1); b = get_config_string("Controllers", buf, "NONE"); if (!strcasecmp(b, "A")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_A_MASK;} else if (!strcasecmp(b, "B")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_B_MASK;} else if (!strcasecmp(b, "X")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_X_MASK;} else if (!strcasecmp(b, "Y")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_Y_MASK;} else if (!strcasecmp(b, "TL")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_TL_MASK;} else if (!strcasecmp(b, "TR")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_TR_MASK;} else if (!strcasecmp(b, "START")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_START_MASK;} else if (!strcasecmp(b, "SELECT")) {JOY_BUTTON_INDEX[t] = i; SNES_BUTTON_MASKS[t++] = SNES_SELECT_MASK;} }}#endifstatic int S9xCompareSDD1IndexEntries (const void *p1, const void *p2){ return (*(uint32 *) p1 - *(uint32 *) p2);}void S9xLoadSDD1Data (){ char filename [_MAX_PATH + 1]; char index [_MAX_PATH + 1]; char data [_MAX_PATH + 1]; char patch [_MAX_PATH + 1]; Memory.FreeSDD1Data (); strcpy (filename, S9xGetSnapshotDirectory ()); Settings.SDD1Pack=FALSE; if (strncmp (Memory.ROMName, "Star Ocean", 10) == 0){ if(SDD1_pack) strcpy (filename, SDD1_pack);#ifdef SDD1_DECOMP else Settings.SDD1Pack=TRUE;#else strcat (filename, "/socnsdd1");#endif } else if(strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21)==0){ if(SDD1_pack) strcpy (filename, SDD1_pack);#ifdef SDD1_DECOMP else Settings.SDD1Pack=TRUE;#else strcat (filename, "/sfa2sdd1");#endif } else { if(SDD1_pack) strcpy (filename, SDD1_pack);#ifdef SDD1_DECOMP else Settings.SDD1Pack=TRUE;#else S9xMessage(S9X_WARNING, S9X_ROM_INFO, "WARNING: No default SDD1 pack for this ROM");#endif } if(Settings.SDD1Pack) return; DIR *dir = opendir (filename); index [0] = 0; data [0] = 0; patch [0] = 0; if (dir) { struct dirent *d; while ((d = readdir (dir))) { if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0) { strcpy (index, filename); strcat (index, "/"); strcat (index, d->d_name); } else if (strcasecmp (d->d_name, "SDD1GFX.DAT") == 0) { strcpy (data, filename); strcat (data, "/"); strcat (data, d->d_name); } if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0) { strcpy (patch, filename); strcat (patch, "/"); strcat (patch, d->d_name); } } closedir (dir); if (strlen (index) && strlen (data)) { FILE *fs = fopen (index, "rb"); int len = 0; if (fs) { // Index is stored as a sequence of entries, each entry being // 12 bytes consisting of: // 4 byte key: (24bit address & 0xfffff * 16) | translated block // 4 byte ROM offset // 4 byte length fseek (fs, 0, SEEK_END); len = ftell (fs); rewind (fs); Memory.SDD1Index = (uint8 *) malloc (len); fread (Memory.SDD1Index, 1, len, fs); fclose (fs); Memory.SDD1Entries = len / 12; if (!(fs = fopen (data, "rb"))) { free ((char *) Memory.SDD1Index); Memory.SDD1Index = NULL; Memory.SDD1Entries = 0; } else { fseek (fs, 0, SEEK_END); len = ftell (fs); rewind (fs); Memory.SDD1Data = (uint8 *) malloc (len); fread (Memory.SDD1Data, 1, len, fs); fclose (fs); if (strlen (patch) > 0 && (fs = fopen (patch, "rb"))) { fclose (fs); }#ifdef MSB_FIRST // Swap the byte order of the 32-bit value triplets on // MSBFirst machines. uint8 *ptr = Memory.SDD1Index; for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12) { SWAP_DWORD ((*(uint32 *) (ptr + 0))); SWAP_DWORD ((*(uint32 *) (ptr + 4))); SWAP_DWORD ((*(uint32 *) (ptr + 8))); }#endif qsort (Memory.SDD1Index, Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); } } } else { fprintf (stderr, "Decompressed data pack not found in '%s'.\n", filename); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -