📄 win32.cpp
字号:
_samplecount = so.sixteen_bit ? _blocksize / 2 : _blocksize; _maxsamplecount = SOUND_BUFFER_SIZE; if (so.sixteen_bit) _maxsamplecount /= 2; if (so.stereo) _maxsamplecount /= 2; if (so.samples_mixed_so_far >= _maxsamplecount) so.samples_mixed_so_far = 0; so.mute_sound = FALSE; return (SoundBuffer != NULL);}#define FIXED_POINT 0x10000#define FIXED_POINT_SHIFT 16#define FIXED_POINT_REMAINDER 0xffffstatic bool8 block_signal = FALSE;static volatile bool8 pending_signal = FALSE;void ProcessSound ();extern "C" void S9xGenerateSound(void){ if (!SoundBuffer || so.samples_mixed_so_far >= _samplecount || so.mute_sound#ifdef FMOD_SUPPORT || Settings.SoundDriver >= WIN_FMOD_DIRECT_SOUND_DRIVER#endif ) return; 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; if (so.samples_mixed_so_far + sample_count > _samplecount) sample_count = _samplecount - so.samples_mixed_so_far; byte_count = sample_count; if (so.sixteen_bit) { byte_offset = so.samples_mixed_so_far << 1; byte_count <<= 1; } else byte_offset = so.samples_mixed_so_far; while (sample_count > _maxsamplecount) { S9xMixSamplesO (SoundBuffer, _maxsamplecount, byte_offset); so.samples_mixed_so_far += _maxsamplecount; sample_count -= _maxsamplecount; byte_offset += SOUND_BUFFER_SIZE; } S9xMixSamplesO (SoundBuffer, sample_count, byte_offset); so.samples_mixed_so_far += sample_count; } block_signal = FALSE; if (pending_signal) { ProcessSound (); pending_signal = FALSE; }}// Interval ms has passedvoid ProcessSound (void){#ifdef DEBUG_MK_APU static FILE* fp;#endif if (block_signal) { pending_signal = TRUE; return; } if (pending_setup) { pending_setup = false; RealSetupSound (pending_rate, pending_16bit, pending_stereo); } if (!DirectX.lpDSB || !SoundBuffer) return; bool8 mute = FALSE;#if 0 if (DirectX.IdleCount >= GUI.PausedFramesBeforeMutingSound) { if (!StartPlaying) { DirectX.lpDSB->Stop (); StartPlaying = TRUE; } return; }#else mute = DirectX.IdleCount >= GUI.PausedFramesBeforeMutingSound;#endif if (StartPlaying) { if (DirectX.lpDSB->Play (0, 0, DSBPLAY_LOOPING) != DS_OK) return; _lastblock = 0; StartPlaying = false; } DWORD play_pos = 0, write_pos = 0; HRESULT hResult; DirectX.lpDSB->GetCurrentPosition (&play_pos, &write_pos); DWORD curr_block = ((play_pos / _blocksize) + 1 * Settings.SoundBufferSize) % _buffernos;//printf ("play_pos = %d, write_pos = %d, curr_block = %d, lastblock = %d\n",// play_pos, write_pos, curr_block, _lastblock);//fflush (stdout); if (curr_block != _lastblock) { BYTE *B1, *B2; DWORD S1, S2; write_pos = curr_block * _blocksize; _lastblock = curr_block; hResult = DirectX.lpDSB->Lock (write_pos, _blocksize, (void **)&B1, &S1, (void **)&B2, &S2, 0); if (hResult == DSERR_BUFFERLOST) { DirectX.lpDSB->Restore (); hResult = DirectX.lpDSB->Lock (write_pos, _blocksize, (void **)&B1, &S1, (void **)&B2, &S2, 0); } if( hResult != DS_OK) return; if( mute || Settings.ForcedPause || Settings.Paused || Settings.StopEmulation || GUI.AVIOut) { if (so.sixteen_bit) { if (B1) ZeroMemory (B1, S1); if (B2) ZeroMemory (B2, S2); } else { if (B1) memset (B1, 128, S1); if (B2) memset (B2, 128, S2); } } else { unsigned int sample_count = so.buffer_size; int byte_offset; if (so.sixteen_bit) sample_count >>= 1; if (so.samples_mixed_so_far < (int32) sample_count) { byte_offset = (so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far); if (Settings.SoundSync == 2) { /*memset (SoundBuffer + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0, sample_count - so.samples_mixed_so_far);*/ } else { sample_count -= so.samples_mixed_so_far; while ((long) sample_count > _maxsamplecount) { S9xMixSamplesO (SoundBuffer, _maxsamplecount, byte_offset); sample_count -= _maxsamplecount; byte_offset += SOUND_BUFFER_SIZE; } S9xMixSamplesO (SoundBuffer, sample_count, byte_offset); } so.samples_mixed_so_far = 0; } else so.samples_mixed_so_far -= sample_count; if (Settings.Mute) { if (so.sixteen_bit) { if (B1) ZeroMemory (B1, S1); if (B2) ZeroMemory (B2, S2); } else { if (B1) memset (B1, 128, S1); if (B2) memset (B2, 128, S2); } } else { if (B1) { memmove (B1, SoundBuffer, S1);#ifdef DEBUG_MK_APU if(fp==NULL) { fp=fopen("FF2DS6.raw", "ab"); } fwrite(SoundBuffer,1, S1, fp);#endif } if (B2) { memmove (B2, SoundBuffer + S1, S2);#ifdef DEBUG_MK_APU if(fp==NULL) { fp=fopen("FF2DS6.raw", "ab"); } fwrite(SoundBuffer+S1,1, S2, fp);#endif } } } hResult = DirectX.lpDSB -> Unlock (B1, S1, B2, S2); if( hResult != DS_OK) return; } DWORD Status; hResult = DirectX.lpDSB->GetStatus (&Status); StartPlaying = !Status;#ifdef MK_APU if(SoundData.sample_cycles<0) SoundData.sample_cycles=0;#endif}bool8 S9xOpenSoundDevice (int mode, bool8 pStereo, int BufferSize){ return (TRUE);}int superscope_pause = 0;int superscope_turbo = 0;static RECT dstRect = { 0, 512, 0, 448 };bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons){ x = (GUI.MouseX); //not all games are 224 y = (GUI.MouseY) ; buttons = GUI.MouseButtons | (superscope_turbo << 2) | (superscope_pause << 3); return (TRUE);}extern unsigned long START;void S9xSyncSpeed( void){#ifdef NETPLAY_SUPPORT if (Settings.NetPlay) {#if defined (NP_DEBUG) && NP_DEBUG == 2 printf ("CLIENT: SyncSpeed @%d\n", timeGetTime () - START);#endif S9xWinScanJoypads (); // Send joypad position update to server S9xNPSendJoypadUpdate (joypads [0]); LONG prev; BOOL success; // Wait for heart beat from server if ((success = ReleaseSemaphore (GUI.ClientSemaphore, 1, &prev)) && prev == 0) { // No heartbeats already arrived, have to wait for one. // Mop up the ReleaseSemaphore test above... WaitForSingleObject (GUI.ClientSemaphore, 0); // ... and then wait for the real sync-signal from the // client loop thread. NetPlay.PendingWait4Sync = WaitForSingleObject (GUI.ClientSemaphore, 100) != WAIT_OBJECT_0;#if defined (NP_DEBUG) && NP_DEBUG == 2 if (NetPlay.PendingWait4Sync) printf ("CLIENT: PendingWait4Sync1 @%d\n", timeGetTime () - START);#endif IPPU.RenderThisFrame = TRUE; IPPU.SkippedFrames = 0; } else { if (success) { // Once for the ReleaseSemaphore above... WaitForSingleObject (GUI.ClientSemaphore, 0); if (prev == 4 && NetPlay.Waiting4EmulationThread) { // Reached the lower behind count threshold - tell the // server its safe to start sending sync pulses again. NetPlay.Waiting4EmulationThread = FALSE; S9xNPSendPause (FALSE); }#if defined (NP_DEBUG) && NP_DEBUG == 2 if (prev > 1) { printf ("CLIENT: SyncSpeed prev: %d @%d\n", prev, timeGetTime () - START); }#endif } else {#ifdef NP_DEBUG printf ("*** CLIENT: SyncSpeed: Release failed @ %d\n", timeGetTime () - START);#endif } // ... and again to mop up the already-waiting sync-signal NetPlay.PendingWait4Sync = WaitForSingleObject (GUI.ClientSemaphore, 200) != WAIT_OBJECT_0;#if defined (NP_DEBUG) && NP_DEBUG == 2 if (NetPlay.PendingWait4Sync) printf ("CLIENT: PendingWait4Sync2 @%d\n", timeGetTime () - START);#endif if (IPPU.SkippedFrames < NetPlay.MaxFrameSkip) { IPPU.SkippedFrames++; IPPU.RenderThisFrame = FALSE; } else { IPPU.RenderThisFrame = TRUE; IPPU.SkippedFrames = 0; } } // Give up remainder of time-slice to any other waiting threads, // if they need any time, that is. Sleep (0); if (!NetPlay.PendingWait4Sync) { NetPlay.FrameCount++; S9xNPStepJoypadHistory (); } } else#endif if (!Settings.TurboMode && Settings.SkipFrames == AUTO_FRAMERATE && !GUI.AVIOut) { if (!do_frame_adjust) { IPPU.RenderThisFrame = TRUE; IPPU.SkippedFrames = 0; } else { if (IPPU.SkippedFrames < Settings.AutoMaxSkipFrames) { IPPU.SkippedFrames++; IPPU.RenderThisFrame = FALSE; } else { IPPU.RenderThisFrame = TRUE; IPPU.SkippedFrames = 0; } } } else { uint32 SkipFrames; if(Settings.TurboMode) SkipFrames = Settings.TurboSkipFrames; else SkipFrames = (Settings.SkipFrames == AUTO_FRAMERATE) ? 0 : Settings.SkipFrames; if (++IPPU.FrameSkip >= SkipFrames) { IPPU.FrameSkip = 0; IPPU.SkippedFrames = 0; IPPU.RenderThisFrame = TRUE; } else { IPPU.SkippedFrames++; IPPU.RenderThisFrame = FALSE; } }}const char *S9xBasename (const char *f){ const char *p; if ((p = strrchr (f, '/')) != NULL || (p = strrchr (f, '\\')) != NULL) return (p + 1);#ifdef __DJGPP if (p = strrchr (f, SLASH_CHAR)) return (p + 1);#endif return (f);}bool8 S9xReadMousePosition (int which, int &x, int &y, uint32 &buttons){ if (which == 0) { x = GUI.MouseX; y = GUI.MouseY; buttons = GUI.MouseButtons; return (TRUE); } return (FALSE);}bool S9xGetState (WORD KeyIdent){ if (KeyIdent & 0x8000) { int j = (KeyIdent >> 8) & 15; switch (KeyIdent & 0xff) { case 0: return !Joystick [j].Left; case 1: return !Joystick [j].Right; case 2: return !Joystick [j].Up; case 3: return !Joystick [j].Down; case 4: return !Joystick [j].PovLeft; case 5: return !Joystick [j].PovRight; case 6: return !Joystick [j].PovUp; case 7: return !Joystick [j].PovDown; case 49: return !Joystick [j].PovDnLeft;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -