diff --git a/desmume/ChangeLog b/desmume/ChangeLog index c49bfbc09..b7dae30db 100644 --- a/desmume/ChangeLog +++ b/desmume/ChangeLog @@ -1,7 +1,8 @@ -0.9.5 -> 0.9.6 (r3075-r3209-r3xxx) +0.9.5 -> 0.9.6 (r3075-r3303-r3xxx) General/Core: bug: emulate keypad interrupt + bug: spu overhaul, add capture support bug: fix dma address reloading bug: fix rom close memory corruption bug: fix div and sqrt busy flag bug @@ -9,9 +10,16 @@ General/Core: bug: fix lid savestate desync bug: fix texcache memory GB explosion when games use tons of tiny 3d sprites bug: fix huge rerecording movie file handle leak - bug: fix EXXXXXXX cheat codes + bug: fix EXXXXXXX cheat codes and some add/edit/save/load bugs bug: add 8MBit flash emulation bug: fix firmware booted-from-card flag + bug: fix some failures to wake + bug: fix some rtc calendar logic + bug: op_bkpt emulation + bug: correctly emulate POWCNT1 and POWCNT2 + bug: corrections to bootup stack configuration + bug: protect bios from being overwritten + bug: initialize save data to 0xFF instead of 0x00 enh: support devkitpro argv enh: add gbaslot-rom commandline @@ -23,6 +31,7 @@ Windows: bug: more fixes to multi-gamepads bug: cheat windows robustification bug: fix that sticky pause state when resetting and loading roms + bug: dont crash when no sound device is available enh: dont screensave while using gamepad enh: add EPX and EPX1.5X resize filters enh: add a japanese translation which will soon be stale like the others @@ -30,10 +39,12 @@ Windows: enh: add "lockdown" window mode to keep window safe from fast stylus action enh: add alt+enter fullscreen command enh: add card eject command + enh: add ddraw software mode forcer Linux/OSX: bug: fix building for nosse2 systems bug: fix --num-cores + bug: fix occasional touchscreen failures enh: add --nojoy=1 to fix laptops with accelerometers diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 2fe653480..9b62e9124 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -466,6 +466,7 @@ extern struct TCommonSettings { , micMode(InternalNoise) , spuInterpolationMode(SPUInterpolation_Linear) , manualBackupType(0) + , spu_advanced(false) { strcpy(ARM9BIOS, "biosnds9.bin"); strcpy(ARM7BIOS, "biosnds7.bin"); @@ -493,7 +494,7 @@ extern struct TCommonSettings { bool DebugConsole; bool EnsataEmulation; - + bool cheatsDisable; int num_cores; @@ -522,6 +523,7 @@ extern struct TCommonSettings { int manualBackupType; bool spu_muteChannels[16]; + bool spu_advanced; struct _ShowGpu { _ShowGpu() : main(true), sub(true) {} diff --git a/desmume/src/SPU.cpp b/desmume/src/SPU.cpp index f086355d2..de7d8b0ba 100644 --- a/desmume/src/SPU.cpp +++ b/desmume/src/SPU.cpp @@ -443,7 +443,7 @@ u8 SPU_struct::ReadByte(u32 addr) //SOUNDCNT case 0x500: return regs.mastervol; case 0x501: - return (regs.ctl_left)|(regs.ctl_right<<2)|(regs.ctl_ch1<<4)|(regs.ctl_ch2<<5)|(regs.masteren<<7); + return (regs.ctl_left)|(regs.ctl_right<<2)|(regs.ctl_ch1bypass<<4)|(regs.ctl_ch3bypass<<5)|(regs.masteren<<7); case 0x502: return 0; case 0x503: return 0; @@ -456,7 +456,7 @@ u8 SPU_struct::ReadByte(u32 addr) //SNDCAP0CNT/SNDCAP1CNT case 0x508: case 0x509: { - u32 which = 0x509-addr; + u32 which = addr-0x508; return regs.cap[which].add | (regs.cap[which].source<<1) | (regs.cap[which].oneshot<<2) @@ -552,8 +552,8 @@ void SPU_struct::WriteByte(u32 addr, u8 val) case 0x501: regs.ctl_left = (val>>0)&3; regs.ctl_right = (val>>2)&3; - regs.ctl_ch1 = (val>>4)&1; - regs.ctl_ch2 = (val>>5)&1; + regs.ctl_ch1bypass = (val>>4)&1; + regs.ctl_ch3bypass = (val>>5)&1; regs.masteren = (val>>7)&1; for(int i=0;i<16;i++) KeyProbe(i); @@ -570,13 +570,14 @@ void SPU_struct::WriteByte(u32 addr, u8 val) //SNDCAP0CNT/SNDCAP1CNT case 0x508: case 0x509: { - u32 which = 0x509-addr; + u32 which = addr-0x508; regs.cap[which].add = BIT0(val); regs.cap[which].source = BIT1(val); regs.cap[which].oneshot = BIT2(val); regs.cap[which].bits8 = BIT3(val); regs.cap[which].active = BIT7(val); ProbeCapture(which); + break; } //SNDCAP0DAD @@ -940,6 +941,7 @@ template FORCEINLINE static void SPU_Mix(SPU_struct* SPU, channel_ case 1: MixLR(SPU, chan, data); break; case 2: MixR(SPU, chan, data); break; } + SPU->lastdata = data; } //WORK @@ -1006,6 +1008,169 @@ FORCEINLINE static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* cons } } +//ENTERNEW +static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length) +{ + //the advanced spu function correctly handles all sound control mixing options, as well as capture + //this code is not entirely optimal, as it relies on sort of manhandling the core mixing functions + //in order to get the results it needs. + + //THIS IS MAX HACKS!!!! + //AND NEEDS TO BE REWRITTEN ALONG WITH THE DEEPEST PARTS OF THE SPU + //ONCE WE KNOW THAT IT WORKS + + //BIAS gets ignored since our spu is still not bit perfect, + //and it doesnt matter for purposes of capture + + //-----------DEBUG CODE + bool skipcap = false; + //----------------- + + s32 samp0[2]; + + //believe it or not, we are going to do this one sample at a time. + //like i said, it is slower. + for(int samp=0;sampsndbuf[0] = 0; + SPU->sndbuf[1] = 0; + SPU->buflength = 1; + + s32 chanout[16]; + s32 submix[32]; + + //generate each channel, and helpfully mix it at the same time + for(int i=0;i<16;i++) + { + channel_struct *chan = &SPU->channels[i]; + + if (chan->status == CHANSTAT_PLAY) + { + SPU->bufpos = 0; + + bool domix = actuallyMix && !CommonSettings.spu_muteChannels[i]; + bool bypass = false; + if(i==1 && SPU->regs.ctl_ch1bypass) bypass=true; + if(i==3 && SPU->regs.ctl_ch3bypass) bypass=true; + + //save our old mix accumulators so we can generate a clean panned sample + s32 save[] = {SPU->sndbuf[0],SPU->sndbuf[1]}; + SPU->sndbuf[0] = SPU->sndbuf[1] = 0; + + //get channel's next output sample. + _SPU_ChanUpdate(domix, SPU, chan); + chanout[i] = SPU->lastdata >> chan->datashift; + + //save the panned results + submix[i*2] = SPU->sndbuf[0]; + submix[i*2+1] = SPU->sndbuf[1]; + + //restore the old mix accumulator + SPU->sndbuf[0] = save[0]; + SPU->sndbuf[1] = save[1]; + + //mix in this sample, unless we were bypassing it + if(!bypass) + { + SPU->sndbuf[0] += submix[i*2]; + SPU->sndbuf[1] += submix[i*2+1]; + } + + } + else + { + chanout[i] = 0; + submix[i*2] = 0; + submix[i*2+1] = 0; + } + } + + s32 mixout[2] = {SPU->sndbuf[0],SPU->sndbuf[1]}; + s32 sndout[2]; + s32 capout[2]; + + //create SPU output + switch(SPU->regs.ctl_left) + { + case SPU_struct::REGS::LOM_LEFT_MIXER: sndout[0] = mixout[0]; break; + case SPU_struct::REGS::LOM_CH1: sndout[0] = submix[1*2+0]; break; + case SPU_struct::REGS::LOM_CH3: sndout[0] = submix[3*2+0]; break; + case SPU_struct::REGS::LOM_CH1_PLUS_CH3: sndout[0] = submix[1*2+0] + submix[3*2+0]; break; + } + switch(SPU->regs.ctl_right) + { + case SPU_struct::REGS::ROM_RIGHT_MIXER: sndout[1] = mixout[1]; break; + case SPU_struct::REGS::ROM_CH1: sndout[1] = submix[1*2+1]; break; + case SPU_struct::REGS::ROM_CH3: sndout[1] = submix[3*2+1]; break; + case SPU_struct::REGS::ROM_CH1_PLUS_CH3: sndout[1] = submix[1*2+1] + submix[3*2+1]; break; + } + + + //generate capture output ("capture bugs" from gbatek are not emulated) + if(SPU->regs.cap[0].source==0) + capout[0] = mixout[0]; //cap0 = L-mix + else if(SPU->regs.cap[0].add) + capout[0] = chanout[0] + chanout[1]; //cap0 = ch0+ch1 + else capout[0] = chanout[0]; //cap0 = ch0 + + if(SPU->regs.cap[1].source==0) + capout[1] = mixout[1]; //cap1 = R-mix + else if(SPU->regs.cap[1].add) + capout[1] = chanout[2] + chanout[3]; //cap1 = ch2+ch3 + else capout[1] = chanout[2]; //cap1 = ch2 + + //write the output sample where it is supposed to go + SPU->sndbuf[samp*2+0] = sndout[0]; + SPU->sndbuf[samp*2+1] = sndout[1]; + if(samp==0) { + samp0[0] = SPU->sndbuf[samp*2+0]; + samp0[1] = SPU->sndbuf[samp*2+1]; + } + + for(int capchan=0;capchan<2;capchan++) + { + if(SPU->regs.cap[capchan].runtime.running) + { + SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan]; + s32 sample = capout[capchan]; + //s32 sample = 0; + u32 last = sputrunc(cap.runtime.sampcnt); + cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc; + u32 curr = sputrunc(cap.runtime.sampcnt); + for(u32 j=last;j>8; + if(skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0); + else _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,sample8); + cap.runtime.curdad++; + multiplier = 4; + } + else + { + s16 sample16 = sample; + if(skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0); + else _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,sample16); + cap.runtime.curdad+=2; + multiplier = 2; + } + + if(cap.runtime.curdad>=cap.runtime.maxdad) { + cap.runtime.curdad = cap.dad; + cap.runtime.sampcnt -= cap.len*multiplier; + } + } //sampinc loop + } //if capchan running + } //capchan loop + } //main sample loop + + SPU->sndbuf[0] = samp0[0]; + SPU->sndbuf[1] = samp0[1]; +} + //ENTER static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length) { @@ -1015,6 +1180,38 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length) memset(SPU->outbuf, 0, length*2*2); } + //we used to use master enable here, and do nothing if audio is disabled. + //now, master enable is emulated better.. + //but for a speed optimization we will still do it + if(!SPU->regs.masteren) return; + + bool advanced = CommonSettings.spu_advanced ; + + //branch here so that slow computers don't have to take the advanced (slower) codepath. + //it remainds to be seen exactly how much slower it is + //if it isnt much slower then we should refactor everything to be simpler, once it is working + if(advanced && SPU == SPU_core) + { + SPU_MixAudio_Advanced(actuallyMix, SPU, length); + } + else + { + //non-advanced mode + for(int i=0;i<16;i++) + { + channel_struct *chan = &SPU->channels[i]; + + if (chan->status != CHANSTAT_PLAY) + continue; + + SPU->bufpos = 0; + SPU->buflength = length; + + // Mix audio + _SPU_ChanUpdate(!CommonSettings.spu_muteChannels[i] && actuallyMix, SPU, chan); + } + } + //we used to bail out if speakers were disabled. //this is technically wrong. sound may still be captured, or something. //in all likelihood, any game doing this probably master disabled the SPU also @@ -1022,89 +1219,8 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length) //later, we'll just silence the output bool speakers = T1ReadWord(MMU.ARM7_REG, 0x304) & 0x01; - //we used to use master enable here, and do nothing if audio is disabled. - //now, master enable is emulated better.. - //but for a speed optimization we will still do it - if(!SPU->regs.masteren) return; - u8 vol = SPU->regs.mastervol; - for(int i=0;i<16;i++) - { - channel_struct *chan = &SPU->channels[i]; - - if (chan->status != CHANSTAT_PLAY) - continue; - - SPU->bufpos = 0; - SPU->buflength = length; - - // Mix audio - _SPU_ChanUpdate(!CommonSettings.spu_muteChannels[i] && actuallyMix, SPU, chan); - //_SPU_ChanUpdate(actuallyMix, SPU, chan); - } - - //TODO - a lot of capture and output modes are not supported. - //this works in starfy, but not in nsmb, which requires the other modes. - //so, we'll have to support it soon - -#ifdef ENABLE_SOUND_CAPTURE - - bool skipcap = false; -#ifdef _MSC_VER - if(GetAsyncKeyState(VK_SHIFT)) skipcap=true; -#endif - - static FILE* test = NULL; - if(!test) test = fopen("d:\\raw.raw","wb"); - if(SPU==SPU_core) - { - for(int capchan=0;capchan<2;capchan++) - { - if(SPU->regs.cap[capchan].runtime.running) - { - SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan]; - for(int i=0;isndbuf[i*2+capchan]; - u32 last = sputrunc(cap.runtime.sampcnt); - cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc; - u32 curr = sputrunc(cap.runtime.sampcnt); - for(u32 j=last+1;j<=curr;j++) - { - u32 multiplier; - - if(cap.bits8) - { - s8 sample8 = sample>>8; - if(skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0); - else _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,sample8); - cap.runtime.curdad++; - multiplier = 4; - } - else - { - s16 sample16 = sample; - if(skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0); - else _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,sample16); - if(capchan==0) fwrite(&sample16,2,1,test); - cap.runtime.curdad+=2; - multiplier = 2; - } - - if(cap.runtime.curdad>=cap.runtime.maxdad) { - cap.runtime.curdad = cap.dad; - cap.runtime.sampcnt -= cap.len*multiplier; - } - } - } - } - } - } - -#endif - - // convert from 32-bit->16-bit if(actuallyMix && speakers) for (int i = 0; i < length*2; i++) @@ -1377,8 +1493,8 @@ void spu_savestate(EMUFILE* os) write8le(spu->regs.mastervol,os); write8le(spu->regs.ctl_left,os); write8le(spu->regs.ctl_right,os); - write8le(spu->regs.ctl_ch1,os); - write8le(spu->regs.ctl_ch2,os); + write8le(spu->regs.ctl_ch1bypass,os); + write8le(spu->regs.ctl_ch3bypass,os); write8le(spu->regs.masteren,os); write16le(spu->regs.soundbias,os); @@ -1462,8 +1578,8 @@ bool spu_loadstate(EMUFILE* is, int size) read8le(&spu->regs.mastervol,is); read8le(&spu->regs.ctl_left,is); read8le(&spu->regs.ctl_right,is); - read8le(&spu->regs.ctl_ch1,is); - read8le(&spu->regs.ctl_ch2,is); + read8le(&spu->regs.ctl_ch1bypass,is); + read8le(&spu->regs.ctl_ch3bypass,is); read8le(&spu->regs.masteren,is); read16le(&spu->regs.soundbias,is); } @@ -1491,6 +1607,7 @@ bool spu_loadstate(EMUFILE* is, int size) if(version<4) { spu->regs.mastervol = T1ReadByte(MMU.ARM7_REG, 0x500) & 0x7F; + spu->regs.masteren = BIT15(T1ReadWord(MMU.ARM7_REG, 0x500)); } diff --git a/desmume/src/SPU.h b/desmume/src/SPU.h index 75b00f16f..de16fd9da 100644 --- a/desmume/src/SPU.h +++ b/desmume/src/SPU.h @@ -111,6 +111,7 @@ public: u32 bufpos; u32 buflength; s32 *sndbuf; + s32 lastdata; //the last sample that a channel generated s16 *outbuf; u32 bufsize; channel_struct channels[16]; @@ -121,18 +122,28 @@ public: : mastervol(0) , ctl_left(0) , ctl_right(0) - , ctl_ch1(0) - , ctl_ch2(0) + , ctl_ch1bypass(0) + , ctl_ch3bypass(0) , masteren(0) , soundbias(0) {} u8 mastervol; u8 ctl_left, ctl_right; - u8 ctl_ch1, ctl_ch2; + u8 ctl_ch1bypass, ctl_ch3bypass; u8 masteren; u16 soundbias; + enum LeftOutputMode + { + LOM_LEFT_MIXER=0, LOM_CH1=1, LOM_CH3=2, LOM_CH1_PLUS_CH3=3 + }; + + enum RightOutputMode + { + ROM_RIGHT_MIXER=0, ROM_CH1=1, ROM_CH3=2, ROM_CH1_PLUS_CH3=3 + }; + struct CAP { CAP() : add(0), source(0), oneshot(0), bits8(0), active(0), dad(0), len(0) diff --git a/desmume/src/commandline.cpp b/desmume/src/commandline.cpp index 3873c3e68..e195512ef 100644 --- a/desmume/src/commandline.cpp +++ b/desmume/src/commandline.cpp @@ -1,6 +1,6 @@ /* commandline.cpp - Copyright (C) 2009 DeSmuME team + Copyright (C) 2009-2010 DeSmuME team This file is part of DeSmuME @@ -75,6 +75,7 @@ void CommandLine::loadCommonOptions() { "bios-arm9", 0, 0, G_OPTION_ARG_FILENAME, &_bios_arm9, "Uses the arm9 bios provided at the specified path", "BIOS_ARM9_PATH"}, { "bios-arm7", 0, 0, G_OPTION_ARG_FILENAME, &_bios_arm7, "Uses the arm7 bios provided at the specified path", "BIOS_ARM7_PATH"}, { "bios-swi", 0, 0, G_OPTION_ARG_INT, &_bios_swi, "Uses SWI from the provided bios files", "BIOS_SWI"}, + { "spu-advanced", 0, 0, G_OPTION_ARG_INT, &_spu_advanced, "Uses advanced SPU capture functions", "SPU_ADVANCED"}, { "num-cores", 0, 0, G_OPTION_ARG_INT, &_num_cores, "Override numcores detection and use this many", "NUM_CORES"}, { "scanline-filter-a", 0, 0, G_OPTION_ARG_INT, &scanline_filter_a, "Intensity of fadeout for scanlines filter (edge) (default 2)", "SCANLINE_FILTER_A"}, { "scanline-filter-b", 0, 0, G_OPTION_ARG_INT, &scanline_filter_b, "Intensity of fadeout for scanlines filter (corner) (default 4)", "SCANLINE_FILTER_B"}, @@ -112,7 +113,7 @@ bool CommandLine::parse(int argc,char **argv) if(_bios_arm9) { CommonSettings.UseExtBIOS = true; strcpy(CommonSettings.ARM9BIOS,_bios_arm9); } if(_bios_arm7) { CommonSettings.UseExtBIOS = true; strcpy(CommonSettings.ARM7BIOS,_bios_arm7); } if(_bios_swi) CommonSettings.SWIFromBIOS = true; - if(_bios_swi) CommonSettings.SWIFromBIOS = true; + if(_spu_advanced) CommonSettings.spu_advanced = true; if (argc == 2) nds_file = argv[1]; diff --git a/desmume/src/commandline.h b/desmume/src/commandline.h index 7f1f0cf19..87906fdf4 100644 --- a/desmume/src/commandline.h +++ b/desmume/src/commandline.h @@ -1,6 +1,6 @@ /* commandline.h - Copyright (C) 2009 DeSmuME team + Copyright (C) 2009-2010 DeSmuME team This file is part of DeSmuME @@ -80,6 +80,7 @@ private: char* _gbaslot_rom; char* _bios_arm9, *_bios_arm7; int _bios_swi; + int _spu_advanced; int _num_cores; }; diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 1a6ce5705..2df088859 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -2369,6 +2369,8 @@ int _main() FrameLimit = GetPrivateProfileBool("FrameLimit", "FrameLimit", true, IniName); CommonSettings.showGpu.main = GetPrivateProfileInt("Display", "MainGpu", 1, IniName) != 0; CommonSettings.showGpu.sub = GetPrivateProfileInt("Display", "SubGpu", 1, IniName) != 0; + CommonSettings.spu_advanced = GetPrivateProfileBool("Sound", "SpuAdvanced", false, IniName); + lostFocusPause = GetPrivateProfileBool("Focus", "BackgroundPause", false, IniName); //Get Ram-Watch values @@ -2638,17 +2640,17 @@ int _main() SPU_SetSynchMode(snd_synchmode,snd_synchmethod); } - CommonSettings.DebugConsole = GetPrivateProfileBool("Emulation", "DebugConsole", FALSE, IniName); - CommonSettings.EnsataEmulation = GetPrivateProfileBool("Emulation", "EnsataEmulation", FALSE, IniName); - CommonSettings.UseExtBIOS = GetPrivateProfileBool("BIOS", "UseExtBIOS", FALSE, IniName); + CommonSettings.DebugConsole = GetPrivateProfileBool("Emulation", "DebugConsole", false, IniName); + CommonSettings.EnsataEmulation = GetPrivateProfileBool("Emulation", "EnsataEmulation", false, IniName); + CommonSettings.UseExtBIOS = GetPrivateProfileBool("BIOS", "UseExtBIOS", false, IniName); GetPrivateProfileString("BIOS", "ARM9BIOSFile", "bios9.bin", CommonSettings.ARM9BIOS, 256, IniName); GetPrivateProfileString("BIOS", "ARM7BIOSFile", "bios7.bin", CommonSettings.ARM7BIOS, 256, IniName); - CommonSettings.SWIFromBIOS = GetPrivateProfileBool("BIOS", "SWIFromBIOS", FALSE, IniName); - CommonSettings.PatchSWI3 = GetPrivateProfileBool("BIOS", "PatchSWI3", FALSE, IniName); + CommonSettings.SWIFromBIOS = GetPrivateProfileBool("BIOS", "SWIFromBIOS", false, IniName); + CommonSettings.PatchSWI3 = GetPrivateProfileBool("BIOS", "PatchSWI3", false, IniName); - CommonSettings.UseExtFirmware = GetPrivateProfileBool("Firmware", "UseExtFirmware", FALSE, IniName); + CommonSettings.UseExtFirmware = GetPrivateProfileBool("Firmware", "UseExtFirmware", false, IniName); GetPrivateProfileString("Firmware", "FirmwareFile", "firmware.bin", CommonSettings.Firmware, 256, IniName); - CommonSettings.BootFromFirmware = GetPrivateProfileBool("Firmware", "BootFromFirmware", FALSE, IniName); + CommonSettings.BootFromFirmware = GetPrivateProfileBool("Firmware", "BootFromFirmware", false, IniName); video.currentfilter = GetPrivateProfileInt("Video", "Filter", video.NONE, IniName); FilterUpdate(MainWindow->getHWnd(),false); @@ -5835,6 +5837,9 @@ static LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_SETPOS, TRUE, sndvolume); SoundSettings_updateVolumeReadout(hDlg); + // Set spu advanced + CheckDlgItem(hDlg,IDC_SPU_ADVANCED,CommonSettings.spu_advanced); + timerid = SetTimer(hDlg, 1, 500, NULL); return TRUE; } @@ -5909,9 +5914,12 @@ static LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam //write interpolation type CommonSettings.spuInterpolationMode = (SPUInterpolationMode)SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_GETCURSEL, 0, 0); - //SPU_SetInterpolationMode(CommonSettings.spuInterpolationMode); WritePrivateProfileInt("Sound","SPUInterpolation",(int)CommonSettings.spuInterpolationMode, IniName); + //write spu advanced + CommonSettings.spu_advanced = IsDlgCheckboxChecked(hDlg,IDC_SPU_ADVANCED); + WritePrivateProfileBool("Sound","SpuAdvanced",CommonSettings.spu_advanced,IniName); + return TRUE; } case IDCANCEL: diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index aa23e26ec..cab5f2a39 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -350,11 +350,19 @@ #define IDC_VISIBLE 1019 #define IDC_USEPHYSICAL 1019 #define IDC_SPLIT1 1021 -#define IDC_PATCHSWI3 1022 +#define IDC_PATCHSWI3 1022 +#define IDC_CAP0_ADD 1023 +#define IDC_CAP0_CURDAD 1024 +#define IDC_CAP1_ADD 1025 +#define IDC_SPU_ADVANCED 1025 +#define IDC_CAP1_CURDAD 1026 #define IDC_DEFAULT 1027 #define IDC_3DCORE 1028 +#define IDC_SNDCTRL_ENABLE 1028 #define IDC_TXT_COMPILED 1029 +#define IDC_SNDCTRL_CH1NOMIX 1029 #define IDC_TXT_VERSION 1030 +#define IDC_SNDCTRL_CH3NOMIX 1030 #define IDC_ADDONS_LIST 1033 #define IDC_ADDONS_INFO 1034 #define IDC_BBROWSE 1035 @@ -392,11 +400,22 @@ #define IDC_SNUMBER 1071 #define IDC_CHECK1 1074 #define IDC_CHECK2 1075 +#define IDC_CAP0_SRC 1075 #define IDC_CHECK3 1076 +#define IDC_CAP0_ONESHOT 1076 #define IDC_CHECK4 1077 +#define IDC_CAP0_TYPE 1077 +#define IDC_CAP0_ACTIVE 1078 +#define IDC_CHECK10 1079 +#define IDC_CAP0_RUNNING 1079 #define IDC_CHECK6 1080 +#define IDC_CAP1_SRC 1080 +#define IDC_CAP1_ONESHOT 1081 #define IDC_CHECK7 1082 +#define IDC_CAP1_TYPE 1082 #define IDC_CHECK8 1083 +#define IDC_CAP1_ACTIVE 1083 +#define IDC_CAP1_RUNNING 1084 #define IDC_CHECK9 1088 #define IDM_FIRMSETTINGS 1100 #define IDD_FIRMSETTINGS 1101 @@ -609,6 +628,24 @@ #define IDC_SOUND5POSLEN 1451 #define IDC_SOUND6POSLEN 1452 #define IDC_SOUND7POSLEN 1453 +#define IDC_CAP0_DAD 1454 +#define IDC_CAP0_CTRL 1455 +#define IDC_CAP0_SRCTEXT 1456 +#define IDC_CAP0_TYPETEXT 1457 +#define IDC_CAP0_LEN 1458 +#define IDC_SOUND0POSLEN7 1459 +#define IDC_CAP1_DAD 1459 +#define IDC_CAP1_CTRL 1460 +#define IDC_CAP1_SRCTEXT 1461 +#define IDC_CAP1_TYPETEXT 1462 +#define IDC_CAP1_LEN 1463 +#define IDC_SNDCTRL_CTRL 1464 +#define IDC_SNDCTRL_VOL 1465 +#define IDC_SNDCTRL_BIAS 1466 +#define IDC_SNDCTRL_LEFTOUT 1467 +#define IDC_SNDCTRL_LEFTOUTTEXT 1468 +#define IDC_SNDCTRL_RIGHTOUT 1469 +#define IDC_SNDCTRL_RIGHTOUTTEXT 1470 #define IDC_SOUND0MUTE 2001 #define IDC_SOUND1MUTE 2002 #define IDC_SOUND2MUTE 2003 @@ -627,29 +664,81 @@ #define IDC_INTERPOLATECOLOR 4464 #define IDC_GI_FATSIZE 4465 #define IDC_3DSETTINGS_EDGEMARK 4465 +#define ID_LABEL_HK1 4465 #define IDC_GI_ICONTITLEOFS 4466 #define IDC_3DSETTINGS_FOG 4466 +#define ID_LABEL_HK2 4466 #define IDC_GI_USEDROMSIZE 4467 +#define ID_LABEL_HK3 4467 +#define ID_LABEL_HK4 4468 #define IDC_GI_ICON 4469 +#define ID_LABEL_HK5 4469 #define IDC_GI_TITLE 4470 +#define ID_LABEL_HK6 4470 #define IDC_GI_TITLEEN 4471 +#define ID_LABEL_HK7 4471 #define IDC_GI_TITLEFR 4472 +#define ID_LABEL_HK8 4472 #define IDC_GI_TITLEGE 4473 +#define ID_LABEL_HK9 4473 #define IDC_GI_TITLEIT 4474 +#define ID_LABEL_HK10 4474 #define IDC_GI_TITLESP 4475 +#define ID_LABEL_HK11 4475 #define IDC_GI_MAKERCODE 4476 +#define ID_LABEL_HK12 4476 #define IDC_GI_TITLEJP 4477 +#define ID_LABEL_HK13 4477 #define IDC_GI_CHIPSIZE 4478 +#define ID_LABEL_HK14 4478 #define IDC_GI_ARM9START 4479 +#define ID_LABEL_HK15 4479 #define IDC_GI_ARM9ENTRY 4480 +#define ID_LABEL_HK16 4480 #define IDC_GI_ARM9ROM 4481 +#define ID_LABEL_HK17 4481 #define IDC_GI_ARM9SIZE 4482 +#define ID_LABEL_HK18 4482 #define IDC_GI_ARM7ROM 4483 +#define ID_LABEL_HK19 4483 #define IDC_GI_ARM7ENTRY 4484 +#define ID_LABEL_HK20 4484 #define IDC_GI_ARM7START 4485 +#define ID_LABEL_HK21 4485 #define IDC_GI_ARM7SIZE 4486 +#define ID_LABEL_HK22 4486 #define IDC_GI_FNTOFS 4487 +#define ID_LABEL_HK23 4487 #define IDC_GI_FNTSIZE 4488 +#define ID_LABEL_HK24 4488 +#define ID_LABEL_HK25 4489 +#define ID_LABEL_HK26 4490 +#define ID_LABEL_HK27 4491 +#define ID_LABEL_HK28 4492 +#define ID_LABEL_HK29 4493 +#define ID_LABEL_HK30 4494 +#define ID_LABEL_HK31 4495 +#define ID_LABEL_HK32 4496 +#define ID_LABEL_HK33 4497 +#define ID_LABEL_HK34 4498 +#define ID_LABEL_HK35 4499 +#define ID_LABEL_HK36 4500 +#define ID_LABEL_HK37 4501 +#define ID_LABEL_HK38 4502 +#define ID_LABEL_HK39 4503 +#define ID_LABEL_HK40 4504 +#define ID_LABEL_HK41 4505 +#define ID_LABEL_HK42 4506 +#define ID_LABEL_HK43 4507 +#define ID_LABEL_HK44 4508 +#define ID_LABEL_HK45 4509 +#define ID_LABEL_HK46 4510 +#define ID_LABEL_HK47 4511 +#define ID_LABEL_HK48 4512 +#define ID_LABEL_HK49 4513 +#define ID_LABEL_HK50 4514 +#define ID_LABEL_HK51 4515 +#define ID_LABEL_HK52 4516 #define IDD_MICROPHONE 5000 #define IDM_MICROPHONESETTINGS 5001 #define IDC_MICSAMPLEBROWSE 5003 @@ -716,7 +805,7 @@ #define ID_CONFIG_DISPLAYMETHOD 40070 #define ID_DISPLAYMETHOD_DIRECTDRAWHW 40071 #define ID_DISPLAYMETHOD_DIRECTDRAWSW 40072 -#define ID_HOTKEYS_TITLE 40073 +#define ID_HOTKEYS_TITLE 40073 #define IDC_LABEL_UP 50000 #define IDC_LABEL_RIGHT 50001 #define IDC_LABEL_LEFT 50002 @@ -761,7 +850,7 @@ #define IDC_LUASCRIPT_RESERVE_END 58099 #define IDD_LUARECENT_RESERVE_START 58100 #define IDD_LUARECENT_RESERVE_END 58199 -#define IDC_FRAMEADVANCE 58200 +#define IDC_FRAMEADVANCE 58200 #define IDC_LABEL_HK1 60001 #define IDC_LABEL_HK2 60002 #define IDC_LABEL_HK3 60003 @@ -808,59 +897,6 @@ #define IDM_RENDER_HQ2XS 60081 #define IDM_RENDER_LQ2X 60082 #define IDM_RENDER_LQ2XS 60083 -#define ID_LABEL_HK1 70001 -#define ID_LABEL_HK2 70002 -#define ID_LABEL_HK3 70003 -#define ID_LABEL_HK4 70004 -#define ID_LABEL_HK5 70005 -#define ID_LABEL_HK6 70006 -#define ID_LABEL_HK7 70007 -#define ID_LABEL_HK8 70008 -#define ID_LABEL_HK9 70009 -#define ID_LABEL_HK10 70010 -#define ID_LABEL_HK11 70011 -#define ID_LABEL_HK12 70012 -#define ID_LABEL_HK13 70013 -#define ID_LABEL_HK14 70014 -#define ID_LABEL_HK15 70015 -#define ID_LABEL_HK16 70016 -#define ID_LABEL_HK17 70017 -#define ID_LABEL_HK18 70018 -#define ID_LABEL_HK19 70019 -#define ID_LABEL_HK20 70020 -#define ID_LABEL_HK21 70021 -#define ID_LABEL_HK22 70022 -#define ID_LABEL_HK23 70023 -#define ID_LABEL_HK24 70024 -#define ID_LABEL_HK25 70025 -#define ID_LABEL_HK26 70026 -#define ID_LABEL_HK27 70027 -#define ID_LABEL_HK28 70028 -#define ID_LABEL_HK29 70029 -#define ID_LABEL_HK30 70030 -#define ID_LABEL_HK31 70031 -#define ID_LABEL_HK32 70032 -#define ID_LABEL_HK33 70033 -#define ID_LABEL_HK34 70034 -#define ID_LABEL_HK35 70035 -#define ID_LABEL_HK36 70036 -#define ID_LABEL_HK37 70037 -#define ID_LABEL_HK38 70038 -#define ID_LABEL_HK39 70039 -#define ID_LABEL_HK40 70040 -#define ID_LABEL_HK41 70041 -#define ID_LABEL_HK42 70042 -#define ID_LABEL_HK43 70043 -#define ID_LABEL_HK44 70044 -#define ID_LABEL_HK45 70045 -#define ID_LABEL_HK46 70046 -#define ID_LABEL_HK47 70047 -#define ID_LABEL_HK48 70048 -#define ID_LABEL_HK49 70049 -#define ID_LABEL_HK50 70050 -#define ID_LABEL_HK51 70051 -#define ID_LABEL_HK52 70052 - // Next default values for new objects // @@ -868,7 +904,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 121 #define _APS_NEXT_COMMAND_VALUE 40074 -#define _APS_NEXT_CONTROL_VALUE 1022 +#define _APS_NEXT_CONTROL_VALUE 1026 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index b78d602a2..db0a6acf0 100644 Binary files a/desmume/src/windows/resources.rc and b/desmume/src/windows/resources.rc differ diff --git a/desmume/src/windows/soundView.cpp b/desmume/src/windows/soundView.cpp index 81778ed9f..64cf766fd 100644 --- a/desmume/src/windows/soundView.cpp +++ b/desmume/src/windows/soundView.cpp @@ -1,8 +1,8 @@ -/* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com +/* soundView.cpp - This file is part of DeSmuME + Copyright (C) 2009-2010 DeSmuME team + + This file is part of DeSmuME DeSmuME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +31,7 @@ #include #include #include "soundView.h" +#include "winutil.h" #include @@ -204,6 +205,96 @@ void SoundView_Refresh() SetDlgItemText(hDlg, IDC_SOUND0TMR+chanId, buf); SetDlgItemText(hDlg, IDC_SOUND0POSLEN+chanId, buf); } + } //chan loop + + //ctrl + { + CheckDlgItem(hDlg,IDC_SNDCTRL_ENABLE,SPU_core->regs.masteren!=0); + CheckDlgItem(hDlg,IDC_SNDCTRL_CH1NOMIX,SPU_core->regs.ctl_ch1bypass!=0); + CheckDlgItem(hDlg,IDC_SNDCTRL_CH3NOMIX,SPU_core->regs.ctl_ch3bypass!=0); + + sprintf(buf,"%04X",_MMU_ARM7_read16(0x04000500)); + SetDlgItemText(hDlg,IDC_SNDCTRL_CTRL,buf); + + sprintf(buf,"%04X",_MMU_ARM7_read16(0x04000504)); + SetDlgItemText(hDlg,IDC_SNDCTRL_BIAS,buf); + + sprintf(buf,"%02X",SPU_core->regs.mastervol); + SetDlgItemText(hDlg,IDC_SNDCTRL_VOL,buf); + + sprintf(buf,"%01X",SPU_core->regs.ctl_left); + SetDlgItemText(hDlg,IDC_SNDCTRL_LEFTOUT,buf); + + sprintf(buf,"%01X",SPU_core->regs.ctl_right); + SetDlgItemText(hDlg,IDC_SNDCTRL_RIGHTOUT,buf); + + static const char* leftouttext[] = {"L-Mix","Ch1","Ch3","Ch1+3"}; + static const char* rightouttext[] = {"R-Mix","Ch1","Ch3","Ch1+3"}; + + SetDlgItemText(hDlg,IDC_SNDCTRL_LEFTOUTTEXT,leftouttext[SPU_core->regs.ctl_left]); + + SetDlgItemText(hDlg,IDC_SNDCTRL_RIGHTOUTTEXT,rightouttext[SPU_core->regs.ctl_right]); + + } + + //cap0 + { + SPU_struct::REGS::CAP& cap = SPU_core->regs.cap[0]; + + CheckDlgItem(hDlg,IDC_CAP0_ADD,cap.add!=0); + CheckDlgItem(hDlg,IDC_CAP0_SRC,cap.source!=0); + CheckDlgItem(hDlg,IDC_CAP0_ONESHOT,cap.oneshot!=0); + CheckDlgItem(hDlg,IDC_CAP0_TYPE,cap.bits8!=0); + CheckDlgItem(hDlg,IDC_CAP0_ACTIVE,cap.active!=0); + CheckDlgItem(hDlg,IDC_CAP0_RUNNING,cap.runtime.running!=0); + + if(cap.source) SetDlgItemText(hDlg,IDC_CAP0_SRCTEXT,"Ch2"); + else SetDlgItemText(hDlg,IDC_CAP0_SRCTEXT,"L-Mix"); + + if(cap.bits8) SetDlgItemText(hDlg,IDC_CAP0_TYPETEXT,"Pcm8"); + else SetDlgItemText(hDlg,IDC_CAP0_TYPETEXT,"Pcm16"); + + sprintf(buf,"%02X",_MMU_ARM7_read08(0x04000508)); + SetDlgItemText(hDlg,IDC_CAP0_CTRL,buf); + + sprintf(buf,"%08X",cap.dad); + SetDlgItemText(hDlg,IDC_CAP0_DAD,buf); + + sprintf(buf,"%08X",cap.len); + SetDlgItemText(hDlg,IDC_CAP0_LEN,buf); + + sprintf(buf,"%08X",cap.runtime.curdad); + SetDlgItemText(hDlg,IDC_CAP0_CURDAD,buf); + } + + //cap1 + { + SPU_struct::REGS::CAP& cap = SPU_core->regs.cap[1]; + + CheckDlgItem(hDlg,IDC_CAP1_ADD,cap.add!=0); + CheckDlgItem(hDlg,IDC_CAP1_SRC,cap.source!=0); + CheckDlgItem(hDlg,IDC_CAP1_ONESHOT,cap.oneshot!=0); + CheckDlgItem(hDlg,IDC_CAP1_TYPE,cap.bits8!=0); + CheckDlgItem(hDlg,IDC_CAP1_ACTIVE,cap.active!=0); + CheckDlgItem(hDlg,IDC_CAP1_RUNNING,cap.runtime.running!=0); + + if(cap.source) SetDlgItemText(hDlg,IDC_CAP1_SRCTEXT,"Ch3"); //maybe call it "Ch3(+2)" if it fits + else SetDlgItemText(hDlg,IDC_CAP1_SRCTEXT,"R-Mix"); + + if(cap.bits8) SetDlgItemText(hDlg,IDC_CAP1_TYPETEXT,"Pcm8"); + else SetDlgItemText(hDlg,IDC_CAP1_TYPETEXT,"Pcm16"); + + sprintf(buf,"%02X",_MMU_ARM7_read08(0x04000509)); + SetDlgItemText(hDlg,IDC_CAP1_CTRL,buf); + + sprintf(buf,"%08X",cap.dad); + SetDlgItemText(hDlg,IDC_CAP1_DAD,buf); + + sprintf(buf,"%08X",cap.len); + SetDlgItemText(hDlg,IDC_CAP1_LEN,buf); + + sprintf(buf,"%08X",cap.runtime.curdad); + SetDlgItemText(hDlg,IDC_CAP1_CURDAD,buf); } }