📄 win32.cpp
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and * Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and * Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: www.snes9x.com * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#include "snes9x.h"#include "..\directx.h"#include "..\Render.h"#include "memmap.h"#include "debug.h"#include "cpuexec.h"#include "ppu.h"#include "snapshot.h"#include "apu.h"#include "display.h"#include "gfx.h"#include "soundux.h"#include "netplay.h"#include <io.h>#ifdef FMOD_SUPPORT#include "fmod.h"#endif//#define GENERATE_OFFSETS_H#ifdef GENERATE_OFFSETS_HFILE *offsets_h = NULL;#define main generate_offsets_h#define S9xSTREAM offsets_h#include "offsets.cpp"#endifstruct SJoyState Joystick [16];uint32 joypads [5];static void S9xWinScanJoypads ();typedef struct{ uint8 red; uint8 green; uint8 blue;} Colour;void ConvertDepth (SSurface *src, SSurface *dst, RECT *);static Colour FixedColours [256];static uint8 palette [0x10000];FILE *trace_fs = NULL;int __fastcall Normalize (int cur, int min, int max){ int Result = 0; if ((max - min) == 0) return (Result); Result = cur - min; Result = (Result * 200) / (max - min); Result -= 100; return (Result);}void S9xTextMode( void){}void S9xGraphicsMode (){}void S9xExit( void){ SendMessage (GUI.hWnd, WM_COMMAND, ID_FILE_EXIT, 0);}extern "C" const char *S9xGetFilename (const char *e){ static char filename [_MAX_PATH + 1]; char drive [_MAX_DRIVE + 1]; char dir [_MAX_DIR + 1]; char fname [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; if (strlen (GUI.FreezeFileDir)) { _splitpath (Memory.ROMFilename, drive, dir, fname, ext); strcpy (filename, GUI.FreezeFileDir); strcat (filename, "\\"); strcat (filename, fname); strcat (filename, e); } else { _splitpath (Memory.ROMFilename, drive, dir, fname, ext); _makepath (filename, drive, dir, fname, e); } return (filename);}const char *S9xGetFilenameInc (const char *e){ static char filename [_MAX_PATH + 1]; char drive [_MAX_DRIVE + 1]; char dir [_MAX_DIR + 1]; char fname [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; char *ptr; if (strlen (GUI.FreezeFileDir)) { _splitpath (Memory.ROMFilename, drive, dir, fname, ext); strcpy (filename, GUI.FreezeFileDir); strcat (filename, "\\"); strcat (filename, fname); ptr = filename + strlen (filename); strcat (filename, "00/"); strcat (filename, e); } else { _splitpath (Memory.ROMFilename, drive, dir, fname, ext); strcat (fname, "00/"); _makepath (filename, drive, dir, fname, e); ptr = strstr (filename, "00/"); } do { if (++*(ptr + 2) > '9') { *(ptr + 2) = '0'; if (++*(ptr + 1) > '9') { *(ptr + 1) = '0'; if (++*ptr > '9') break; } } } while (_access (filename, 0) == 0); return (filename);}bool8 S9xOpenSnapshotFile( const char *fname, bool8 read_only, STREAM *file){ char filename [_MAX_PATH + 1]; char drive [_MAX_DRIVE + 1]; char dir [_MAX_DIR + 1]; char fn [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; _splitpath( fname, drive, dir, fn, ext); _makepath( filename, drive, dir, fn, ext[0] == '\0' ? ".000" : ext); if (read_only) { if ((*file = OPEN_STREAM (filename, "rb"))) return (TRUE); } else { if ((*file = OPEN_STREAM (filename, "wb"))) return (TRUE); FILE *fs = fopen (filename, "rb"); if (fs) { sprintf (String, "Freeze file \"%s\" exists but is read only", filename); fclose (fs); S9xMessage (S9X_ERROR, S9X_FREEZE_FILE_NOT_FOUND, String); } else { sprintf (String, "Cannot create freeze file \"%s\". Directory is read-only or does not exist.", filename); S9xMessage (S9X_ERROR, S9X_FREEZE_FILE_NOT_FOUND, String); } } return (FALSE);}void S9xCloseSnapshotFile( STREAM file){ CLOSE_STREAM (file);}void S9xMessage (int, int, const char *str){#ifdef DEBUGGER static FILE *out = NULL; if (out == NULL) out = fopen ("out.txt", "w"); fprintf (out, "%s\n", str);#endif S9xSetInfoString (str);}unsigned long _interval = 10;long _buffernos = 4;long _blocksize = 4400;long _samplecount = 440;long _maxsamplecount = 0;long _buffersize = 0;uint8 *SoundBuffer = NULL;bool StartPlaying = false;DWORD _lastblock = 0;bool8 pending_setup = false;long pending_rate = 0;bool8 pending_16bit = false;bool8 pending_stereo = false;bool8 SetupSound (long rate, bool8 sixteen_bit, bool8 stereo){#ifdef FMOD_SUPPORT if (Settings.SoundDriver >= WIN_FMOD_DIRECT_SOUND_DRIVER) { so.mute_sound = TRUE; if (SoundBuffer) { SoundBuffer -= 32 * 1024; delete SoundBuffer; SoundBuffer = NULL; } _interval = 20; if (Settings.SoundBufferSize < 1) Settings.SoundBufferSize = 1; if (Settings.SoundBufferSize > 64) Settings.SoundBufferSize = 64; _buffernos = 4 * Settings.SoundBufferSize; int s = (rate * _interval * (Settings.Stereo ? 2 : 1) * (Settings.SixteenBitSound ? 2 : 1)) / 1000; _blocksize = 64; while (_blocksize < s) _blocksize *= 2; _buffersize = _blocksize * _buffernos; _lastblock = 0; StartPlaying = false; so.playback_rate = Settings.SoundPlaybackRate; so.stereo = Settings.Stereo; so.sixteen_bit = Settings.SixteenBitSound; so.buffer_size = _blocksize; so.encoded = FALSE; if (DirectX.SetSoundMode ()) { SoundBuffer = new uint8 [_blocksize * _buffernos + 1024 * 64]; SoundBuffer += 32 * 1024; ZeroMemory (SoundBuffer, _blocksize * _buffernos); S9xSetPlaybackRate (so.playback_rate); } _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); } else {#endif pending_setup = TRUE; pending_rate = rate; pending_16bit = sixteen_bit; pending_stereo = stereo;#ifdef FMOD_SUPPORT }#endif return (TRUE);}bool8 RealSetupSound (long rate, bool8 sixteen_bit, bool8 stereo){ so.mute_sound = TRUE; if (SoundBuffer) { SoundBuffer -= 32 * 1024; delete SoundBuffer; SoundBuffer = NULL; }#if 0 OSVERSIONINFO info; info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (GetVersionEx (&info) && info.dwPlatformId == VER_PLATFORM_WIN32_NT && info.dwMajorVersion == 4) { _interval = 20; } else { _interval = 10; }#endif _interval = Settings.SoundMixInterval; if (Settings.SoundBufferSize < 1) Settings.SoundBufferSize = 1; if (Settings.SoundBufferSize > 64) Settings.SoundBufferSize = 64; _buffernos = 4 * Settings.SoundBufferSize; int s = (rate * _interval * (Settings.Stereo ? 2 : 1) * (Settings.SixteenBitSound ? 2 : 1)) / 1000; _blocksize = 64; while (_blocksize < s) _blocksize *= 2; _buffersize = _blocksize * _buffernos; _lastblock = 0; StartPlaying = false; so.playback_rate = Settings.SoundPlaybackRate; so.stereo = Settings.Stereo; so.sixteen_bit = Settings.SixteenBitSound; so.buffer_size = _blocksize; so.encoded = FALSE; if (!DirectX.DSAvailable) return (false); if (DirectX.SetSoundMode ()) { SoundBuffer = new uint8 [_blocksize * _buffernos + 1024 * 64]; SoundBuffer += 32 * 1024; ZeroMemory (SoundBuffer, _blocksize * _buffernos); S9xSetPlaybackRate (so.playback_rate); } _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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -