Compare commits

...

10 Commits

Author SHA1 Message Date
vadosnaprimer 8598aedc55 micro-bump version to 0.9.9a/90901 2019-03-26 01:44:22 +03:00
zeromus 0523bceaa7
Merge pull request #261 from vadosnaprimer/release_0_9_9
Mic sample fixes for 0.9.9
2019-03-25 16:39:18 -04:00
vadosnaprimer 9967581aa8 support sample series having just digits in filenames: "0.wav" 2019-03-25 19:23:38 +03:00
vadosnaprimer 042afbaec5 fix crash when printing to non-existent osd 2019-03-25 18:52:24 +03:00
feos 40bf609a2c use the old logic for sample playback
this branch is meant to remain compatible with 0.9.9 release, and the goal is making movies sync with and without the patch, provided the movie format is converted accordingly (which is easy). since new sample replay logic introduced in master breaks sync with 0.9.9, it's a good idea to leave the new logic for a potential new release while remaining sync-compatible in this branch.
2019-03-24 01:02:43 +03:00
zeromus 3695f5b329 attempt to merge mic samples work from master 2019-03-21 15:20:23 -04:00
yabause c07d7945d8 version number => 0.9.9 2013-05-01 21:40:32 +00:00
yabause 60ffb9f6ef Applied change 4631 to 0.9.9 branch 2013-05-01 21:26:48 +00:00
mtabachenko 47c60130b8 - update change log; 2013-04-27 19:29:37 +00:00
zeromus 0b6de71565 make 099 release branch 2013-04-27 17:00:47 +00:00
13 changed files with 208 additions and 44 deletions

View File

@ -1,4 +1,4 @@
0.9.8 -> 0.9.9 (r4228-r4591-r4xxx)
0.9.8 -> 0.9.9 (r4228-r4591-r4623)
Yes, it's been a while since the last release, but we haven't been completely idle. There's a brand new jit cpu core which yields some impressive speedups!

View File

@ -1,7 +1,7 @@
dnl --- Package name is first argument to AC_INIT
dnl --- Release version is second argument to AC_INIT
AC_INIT(desmume, [svn])
AC_INIT(desmume, [0.9.9])
dnl -- find host architecture for some os specific libraries
AC_CANONICAL_HOST

View File

@ -12,7 +12,7 @@ DIST_SUBDIRS = . gdbstub cli gtk gtk-glade wx
noinst_LIBRARIES = libdesmume.a
libdesmume_a_SOURCES = \
armcpu.cpp armcpu.h \
arm_instructions.cpp arm_instructions.h \
arm_instructions.cpp \
agg2d.h agg2d.inl \
bios.cpp bios.h bits.h cp15.cpp cp15.h \
commandline.h commandline.cpp \
@ -23,6 +23,7 @@ libdesmume_a_SOURCES = \
firmware.cpp firmware.h GPU.cpp GPU.h \
fs.h \
GPU_osd.h \
instructions.h \
mem.h mc.cpp mc.h \
path.cpp path.h \
readwrite.cpp readwrite.h \
@ -38,7 +39,7 @@ libdesmume_a_SOURCES = \
SPU.cpp SPU.h \
matrix.cpp matrix.h \
gfx3d.cpp gfx3d.h \
thumb_instructions.cpp thumb_instructions.h types.h \
thumb_instructions.cpp types.h \
shaders.h \
movie.cpp movie.h \
PACKED.h PACKED_END.h \
@ -89,6 +90,10 @@ libdesmume_a_SOURCES = \
cheatSystem.cpp cheatSystem.h \
texcache.cpp texcache.h rasterize.cpp rasterize.h \
metaspu/metaspu.cpp metaspu/metaspu.h \
filter/2xsai.cpp filter/bilinear.cpp filter/epx.cpp filter/filter.h \
filter/hq2x.cpp filter/hq2x.h filter/hq4x.cpp filter/hq4x.dat filter/hq4x.h \
filter/interp.h filter/lq2x.cpp filter/lq2x.h filter/scanline.cpp \
filter/videofilter.cpp filter/videofilter.h \
version.cpp version.h \
desmume_config.cpp desmume_config.h
@ -96,7 +101,7 @@ if HAVE_JIT
libdesmume_a_SOURCES += \
arm_jit.cpp arm_jit.h instruction_attributes.h \
utils/AsmJit/AsmJit.h \
utils/AsmJit/config.h \
utils/AsmJit/Config.h \
utils/AsmJit/core.h \
utils/AsmJit/x86.h \
utils/AsmJit/core/apibegin.h \

View File

@ -80,6 +80,8 @@ int lagframecounter;
int LagFrameFlag;
int lastLag;
int TotalLagFrames;
u8 MicSampleSelection = 0;
std::vector<std::vector<u8>> micSamples;
TSCalInfo TSCal;
@ -2593,6 +2595,7 @@ void NDS_Reset()
LidClosed = FALSE;
countLid = 0;
MicSampleSelection = 0;
resetUserInput();

View File

@ -32,6 +32,7 @@
#include "types.h"
#include <string>
#include <vector>
#if defined(_WINDOWS) && !defined(WXPORT)
#include "pathsettings.h"
@ -398,6 +399,7 @@ struct UserTouch
struct UserMicrophone
{
u32 micButtonPressed;
u8 micSample;
};
struct UserInput
{
@ -628,6 +630,8 @@ extern struct TCommonSettings {
extern std::string InputDisplayString;
extern int LagFrameFlag;
extern int lastLag, TotalLagFrames;
extern u8 MicSampleSelection;
extern std::vector<std::vector<u8>> micSamples;
void MovieSRAM();

View File

@ -24,7 +24,7 @@
#ifdef WIN32
static char MicSampleName[256];
bool LoadSample(const char *name);
bool LoadSamples(const char *name);
#endif
extern int MicDisplay;

View File

@ -41,7 +41,9 @@ bool autoMovieBackup = true;
#define FCEU_PrintError LOG
#define MOVIE_VERSION 1
//version 1 - was the main version for a long time, most of 201x
//version 2 - march 2019, added mic sample
#define MOVIE_VERSION 2
#ifdef WIN32
#include ".\windows\main.h"
@ -105,9 +107,6 @@ bool MovieRecord::Compare(MovieRecord& compareRec)
//Check Stylus
if (this->touch.padding != compareRec.touch.padding) return false;
if (this->touch.touch != compareRec.touch.touch) return false;
if (this->touch.x != compareRec.touch.x) return false;
if (this->touch.y != compareRec.touch.y) return false;
//Check comamnds
//if new commands are ever recordable, they need to be added here if we go with this method
@ -165,6 +164,7 @@ void MovieRecord::parse(MovieData* md, EMUFILE* fp)
touch.x = u32DecFromIstream(fp);
touch.y = u32DecFromIstream(fp);
touch.touch = u32DecFromIstream(fp);
touch.micsample = u32DecFromIstream(fp);
fp->fgetc(); //eat the pipe
@ -183,7 +183,8 @@ void MovieRecord::dump(MovieData* md, EMUFILE* fp, int index)
dumpPad(fp, pad);
putdec<u8,3,true>(fp,touch.x); fp->fputc(' ');
putdec<u8,3,true>(fp,touch.y); fp->fputc(' ');
putdec<u8,1,true>(fp,touch.touch);
putdec<u8,1,true>(fp,touch.touch); fp->fputc(' ');
putdec<u8,3,true>(fp,touch.micsample);
fp->fputc('|');
//each frame is on a new line
@ -213,6 +214,18 @@ void MovieData::truncateAt(int frame)
}
void MovieData::installMicSample(std::string& key, std::string& val)
{
//which sample?
int which = atoi(key.c_str()+strlen("micsample"));
//make sure we have this many
if(micSamples.size()<which+1)
micSamples.resize(which+1);
BinaryDataFromString(val, &micSamples[which]);
}
void MovieData::installValue(std::string& key, std::string& val)
{
//todo - use another config system, or drive this from a little data structure. because this is gross
@ -288,6 +301,19 @@ void MovieData::installValue(std::string& key, std::string& val)
StringToBytes(val,&sram[0],len); // decodes either base64 or hex
}
}
for(int i=0;i<256;i++)
{
char tmp[256];
sprintf(tmp,"micsample%d",i);
if(key == tmp)
{
if(micSamples.size()<i+1)
micSamples.resize(i+1);
BinaryDataFromString(val, &micSamples[i]);
}
}
}
@ -350,6 +376,17 @@ int MovieData::dump(EMUFILE* fp, bool binary)
if(sram.size() != 0)
fp->fprintf("sram %s\n", BytesToString(&sram[0],sram.size()).c_str());
for(int i=0;i<256;i++)
{
//TODO - how do these get put in here
if(micSamples.size() > i)
{
char tmp[32];
sprintf(tmp,"micsample%d",i);
fp->fprintf("%s %s\n",tmp, BytesToString(&micSamples[i][0],micSamples[i].size()).c_str());
}
}
if(binary)
{
//put one | to start the binary dump
@ -377,8 +414,12 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
fp->fread(buf,9);
fp->fseek(curr, SEEK_SET);
// if(fp->fail()) return false;
if(memcmp(buf,"version 1",9))
return false;
bool version1 = memcmp(buf, "version 1", 9)==0;
bool version2 = memcmp(buf, "version 2", 9)==0;
if(version1) {}
else if(version2) {}
else return false;
std::string key,value;
enum {
@ -604,6 +645,11 @@ const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tas
bool success = MovieData::loadSramFrom(&currMovieData.sram);
if(!success) return "failed to load sram";
}
#ifdef _WIN32
::micSamples = currMovieData.micSamples;
#endif
freshMovie = true;
ClearAutoHold();
@ -688,6 +734,7 @@ void FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::stri
currMovieData.romSerial = gameInfo.ROMserial;
currMovieData.romFilename = path.GetRomName();
currMovieData.rtcStart = rtcstart;
currMovieData.micSamples = ::micSamples;
// reset firmware (some games can write to it)
if (CommonSettings.UseExtFirmware == false)
@ -755,6 +802,7 @@ void FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::stri
if(mr->command_microphone()) input.mic.micButtonPressed = 1;
else input.mic.micButtonPressed = 0;
input.mic.micSample = MicSampleSelection;
if(mr->command_reset()) NDS_Reset();
@ -833,6 +881,7 @@ void FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::stri
mr.touch.touch = input.touch.isTouch ? 1 : 0;
mr.touch.x = input.touch.isTouch ? input.touch.touchX >> 4 : 0;
mr.touch.y = input.touch.isTouch ? input.touch.touchY >> 4 : 0;
mr.touch.micsample = MicSampleSelection;
assert(mr.touch.touch || (!mr.touch.x && !mr.touch.y));
//assert(nds.touchX == input.touch.touchX && nds.touchY == input.touch.touchY);
@ -1268,3 +1317,13 @@ void FCEUI_MakeBackupMovie(bool dispMessage)
}
}
void BinaryDataFromString(std::string &inStringData, std::vector<u8> *outBinaryData)
{
int len = Base64StringToBytesLength(inStringData);
if(len == -1) len = HexStringToBytesLength(inStringData); // wasn't base64, try hex
if(len >= 1)
{
outBinaryData->resize(len);
StringToBytes(inStringData, &outBinaryData->front(), len); // decodes either base64 or hex
}
}

View File

@ -71,6 +71,7 @@ public:
struct {
u8 x, y;
u8 touch;
u8 micsample;
};
u32 padding;
@ -144,6 +145,7 @@ public:
std::vector<u8> sram;
std::vector<MovieRecord> records;
std::vector<std::wstring> comments;
std::vector<std::vector<u8> > micSamples;
int rerecordCount;
Desmume_Guid guid;
@ -185,6 +187,7 @@ public:
void truncateAt(int frame);
void installValue(std::string& key, std::string& val);
void installMicSample(std::string& key, std::string& val);
int dump(EMUFILE* fp, bool binary);
void clearRecordRange(int start, int len);
void insertEmpty(int at, int frames);
@ -228,4 +231,5 @@ extern bool movie_readonly;
extern bool ShowInputDisplay;
void FCEUI_MakeBackupMovie(bool dispMessage);
DateTime FCEUI_MovieGetRTCDefault();
void BinaryDataFromString(std::string &inStringData, std::vector<u8> *outBinaryData);
#endif

View File

@ -115,8 +115,8 @@
#define DESMUME_JIT ""
#endif
#define DESMUME_VERSION_NUMERIC 90900
#define DESMUME_VERSION_STRING " " "0.9.9" DESMUME_SUBVERSION_STRING DESMUME_FEATURE_STRING DESMUME_PLATFORM_STRING DESMUME_JIT DESMUME_CPUEXT_STRING
#define DESMUME_VERSION_NUMERIC 90901
#define DESMUME_VERSION_STRING " " "0.9.9a" DESMUME_SUBVERSION_STRING DESMUME_FEATURE_STRING DESMUME_PLATFORM_STRING DESMUME_JIT DESMUME_CPUEXT_STRING
#define DESMUME_NAME_AND_VERSION DESMUME_NAME DESMUME_VERSION_STRING
u32 EMU_DESMUME_VERSION_NUMERIC() { return DESMUME_VERSION_NUMERIC; }

View File

@ -289,6 +289,21 @@ void HK_StateQuickLoadSlot(int, bool justPressed)
void HK_MicrophoneKeyDown(int, bool justPressed) { NDS_setMic(1); }
void HK_MicrophoneKeyUp(int) { NDS_setMic(0); }
void Mic_NextSample();
void Mic_PrevSample();
void HK_NextSampleKeyDown(int, bool justPressed)
{
Mic_NextSample();
osd->addLine("Mic sample %d selected", MicSampleSelection);
}
void HK_PrevSampleKeyDown(int, bool justPressed)
{
Mic_PrevSample();
osd->addLine("Mic sample %d selected", MicSampleSelection);
}
void HK_AutoHoldKeyDown(int, bool justPressed) {AutoHoldPressed = true;}
void HK_AutoHoldKeyUp(int) {AutoHoldPressed = false;}
@ -652,6 +667,18 @@ void InitCustomKeys (SCustomKeys *keys)
keys->Microphone.page = HOTKEY_PAGE_MAIN;
keys->Microphone.key = NULL;
keys->PrevSample.handleKeyDown = HK_PrevSampleKeyDown;
keys->PrevSample.code = "Mic Prev Sample";
keys->PrevSample.name = L"Mic Prev Sample";
keys->PrevSample.page = HOTKEY_PAGE_MAIN;
keys->PrevSample.key = NULL;
keys->NextSample.handleKeyDown = HK_NextSampleKeyDown;
keys->NextSample.code = "Mic Next Sample";
keys->NextSample.name = L"Mic Next Sample";
keys->NextSample.page = HOTKEY_PAGE_MAIN;
keys->NextSample.key = NULL;
keys->AutoHold.handleKeyDown = HK_AutoHoldKeyDown;
keys->AutoHold.handleKeyUp = HK_AutoHoldKeyUp;
keys->AutoHold.code = "AutoHold";

View File

@ -79,7 +79,7 @@ struct SCustomKeys
#ifdef HAVE_JIT
SCustomKey CpuMode, JitBlockSizeDec, JitBlockSizeInc;
#endif
SCustomKey FrameAdvance, FastForward, FastForwardToggle, IncreaseSpeed, DecreaseSpeed, FrameLimitToggle, Microphone, IncreasePressure, DecreasePressure, ToggleStylusJitter;
SCustomKey FrameAdvance, FastForward, FastForwardToggle, IncreaseSpeed, DecreaseSpeed, FrameLimitToggle, Microphone, PrevSample, NextSample, IncreasePressure, DecreasePressure, ToggleStylusJitter;
SCustomKey PlayMovie, RecordMovie, StopMovie, ToggleReadOnly;

View File

@ -2772,14 +2772,18 @@ static void RefreshMicSettings()
Mic_DeInit_Physical();
if(CommonSettings.micMode == TCommonSettings::Sample)
{
if(!LoadSample(MicSampleName))
if(!LoadSamples(MicSampleName))
{
MessageBox(NULL, "Unable to read the mic sample", "DeSmuME", (MB_OK | MB_ICONEXCLAMATION));
}
else if (osd)
{
osd->addLine("Mic sample %d selected", MicSampleSelection);
}
}
else
{
LoadSample(NULL);
LoadSamples(NULL);
if(CommonSettings.micMode == TCommonSettings::Physical)
{
Mic_Init_Physical();

View File

@ -34,7 +34,6 @@
#include <fstream>
int MicDisplay;
int SampleLoaded=0;
#define MIC_CHECKERR(hr) if(hr != MMSYSERR_NOERROR) return FALSE;
@ -76,12 +75,8 @@ static int CALLBACK waveInProc(HWAVEIN wavein, UINT msg, DWORD instance, DWORD_P
return 0;
}
static char* samplebuffer = NULL;
static int samplebuffersize = 0;
static FILE* fp = NULL;
EMUFILE_MEMORY newWavData;
static bool dataChunk(EMUFILE* inf)
{
bool found = false;
@ -102,11 +97,14 @@ static bool dataChunk(EMUFILE* inf)
if (memcmp(chunk_id, "data", 4) == 0) {
found = true;
u8* temp = new u8[chunk_length];
if(inf->fread(temp,chunk_length) != chunk_length) {
if(inf->fread(temp,chunk_length) != chunk_length || chunk_length == 0) {
delete[] temp;
return false;
}
newWavData.fwrite(temp,chunk_length);
micSamples.resize(micSamples.size()+1);
std::vector<u8>& thisSample = micSamples[micSamples.size()-1];
thisSample.resize(chunk_length);
memcpy(&thisSample[0], temp, chunk_length);
delete[] temp;
chunk_length = 0;
}
@ -166,11 +164,27 @@ static bool formatChunk(EMUFILE* inf)
return false;
}
void Mic_PrevSample()
{
if(MicSampleSelection==0) return;
MicSampleSelection--;
}
void Mic_NextSample()
{
if(MicSampleSelection==255) return;
MicSampleSelection++;
if(MicSampleSelection >= micSamples.size())
{
if(micSamples.size()==0)
MicSampleSelection = 0;
else
MicSampleSelection = micSamples.size()-1;
}
}
bool LoadSample(const char *name)
{
SampleLoaded = 0;
if(!name) return true;
EMUFILE_FILE inf(name,"rb");
if(inf.fail()) return false;
@ -201,17 +215,63 @@ bool LoadSample(const char *name)
return false;
}
delete[] samplebuffer;
samplebuffersize = (int)newWavData.size();
samplebuffer = new char[samplebuffersize];
memcpy(samplebuffer,newWavData.buf(),samplebuffersize);
new(&newWavData) EMUFILE_MEMORY();
SampleLoaded=1;
return true;
}
bool LoadSamples(const char *name)
{
//unload any existing mic samples
micSamples.resize(0);
//select NO mic sample
micReadSamplePos = 0;
MicSampleSelection = 0;
//if we're disabling the mic samples system, just bail now
if (!name || !*name) return true;
//analyze the filename for _0 at the end. anything with _0 at the end is assumed to be the beginning of a series of files
//series with just digits in filenames also work: "0.wav". in those \ would be a remainder from the path
//(and if neither, it can still be loaded just fine)
const char* ext = strrchr(name,'.');
//in case the filename had no extension... it's an error.
if(!ext) return false;
const char* maybe_0 = ext-2;
//in case this was an absurdly short filename
if(ext<name)
return LoadSample(name);
//if it was not a _0 or a \0, just load it
if(strncmp(maybe_0,"_0",2) && strncmp(maybe_0,"\\0",2))
return LoadSample(name);
//otherwise replace it with increasing numbers and load all those
std::string prefix = name;
prefix.resize(maybe_0-name+1); //take care to keep the _ or \
//if found, it's a wildcard. load all those samples
//this is limited to 254 entries in order to prevent some surprises, because I was stupid and used a byte for the MicSampleSelection.
//I should probably change that. But it has to be limited somehow...
for(int i=0;i<255;i++)
{
char tmp[32];
sprintf(tmp,"%d",i);
std::string trial = prefix + tmp + ".wav";
printf("Trying sample %s\n",trial.c_str());
bool ok = LoadSample(trial.c_str());
if(!ok)
{
if(i==0) return false;
break;
}
}
//OK, we loaded some samples. that's all we have to do
return true;
}
BOOL Mic_DeInit_Physical()
{
if(!Mic_Inited)
@ -333,17 +393,15 @@ u8 Mic_ReadSample()
{
if(NDS_getFinalUserInput().mic.micButtonPressed)
{
if(SampleLoaded)
if(micSamples.size() > 0)
{
//use a sample
//TODO: what if a movie is active?
// for now I'm going to hope that if anybody records a movie with a sample loaded,
// either they know what they're doing and plan to distribute the sample,
// or they're playing a game where it doesn't even matter or they never press the mic button.
tmp = samplebuffer[micReadSamplePos >> 1];
tmp = micSamples[MicSampleSelection][micReadSamplePos >> 1];
micReadSamplePos++;
if(micReadSamplePos == samplebuffersize*2)
if(micReadSamplePos == micSamples[MicSampleSelection].size()*2)
{
micReadSamplePos=0;
printf("Ended mic sample MicSampleSelection\n");
}
}
else
{