diff options
Diffstat (limited to 'src/libui_sdl')
-rw-r--r-- | src/libui_sdl/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/libui_sdl/DlgVideoSettings.cpp | 26 | ||||
-rw-r--r-- | src/libui_sdl/PlatformConfig.cpp | 2 | ||||
-rw-r--r-- | src/libui_sdl/PlatformConfig.h | 1 | ||||
-rw-r--r-- | src/libui_sdl/libui/windows/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/libui_sdl/main.cpp | 124 |
6 files changed, 118 insertions, 49 deletions
diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 63e9f48..64206bf 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -14,6 +14,10 @@ SET(SOURCES_LIBUI OSD.cpp ) +if (WIN32) + set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -i <SOURCE> -o <OBJECT>") +endif() + option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) set(BUILD_SHARED_LIBS OFF) add_subdirectory(libui) @@ -39,11 +43,11 @@ if (UNIX) ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER}) add_custom_command(OUTPUT melon_grc.c - COMMAND glib-compile-resources --sourcedir="${CMAKE_SOURCE_DIR}" - --target="${CMAKE_CURRENT_BINARY_DIR}/melon_grc.c" + COMMAND glib-compile-resources --sourcedir=${CMAKE_SOURCE_DIR} + --target=${CMAKE_CURRENT_BINARY_DIR}/melon_grc.c --generate-source "${CMAKE_SOURCE_DIR}/melon_grc.xml" - COMMAND glib-compile-resources --sourcedir="${CMAKE_SOURCE_DIR}" - --target="${CMAKE_CURRENT_BINARY_DIR}/melon_grc.h" + COMMAND glib-compile-resources --sourcedir=${CMAKE_SOURCE_DIR} + --target=${CMAKE_CURRENT_BINARY_DIR}/melon_grc.h --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 7d876e2..155fe8b 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -39,12 +39,14 @@ uiWindow* win; uiRadioButtons* rbRenderer; uiCheckbox* cbGLDisplay; +uiCheckbox* cbVSync; uiCheckbox* cbThreaded3D; uiCombobox* cbResolution; uiCheckbox* cbAntialias; int old_renderer; int old_gldisplay; +int old_vsync; int old_threaded3D; int old_resolution; int old_antialias; @@ -89,6 +91,11 @@ void RevertSettings() { Config::ScreenUseGL = old_gldisplay; } + if (old_vsync != Config::ScreenVSync) + { + Config::ScreenVSync = old_vsync; + ApplyNewSettings(4); + } if (old_usegl != new_usegl) { apply2 = true; @@ -134,17 +141,25 @@ void OnRendererChanged(uiRadioButtons* rb, void* blarg) ApplyNewSettings(2); else ApplyNewSettings(3); - + uiControlSetFocus(uiControl(win)); } void OnGLDisplayChanged(uiCheckbox* cb, void* blarg) { Config::ScreenUseGL = uiCheckboxChecked(cb); + if (Config::ScreenUseGL) uiControlEnable(uiControl(cbVSync)); + else uiControlDisable(uiControl(cbVSync)); ApplyNewSettings(2); uiControlSetFocus(uiControl(win)); } +void OnVSyncChanged(uiCheckbox* cb, void* blarg) +{ + Config::ScreenVSync = uiCheckboxChecked(cb); + ApplyNewSettings(4); +} + void OnThreaded3DChanged(uiCheckbox* cb, void* blarg) { Config::Threaded3D = uiCheckboxChecked(cb); @@ -232,6 +247,10 @@ void Open() cbGLDisplay = uiNewCheckbox("OpenGL display"); uiCheckboxOnToggled(cbGLDisplay, OnGLDisplayChanged, NULL); uiBoxAppend(in_ctrl, uiControl(cbGLDisplay), 0); + + cbVSync = uiNewCheckbox("VSync"); + uiCheckboxOnToggled(cbVSync, OnVSyncChanged, NULL); + uiBoxAppend(in_ctrl, uiControl(cbVSync), 0); } { @@ -300,17 +319,22 @@ void Open() old_renderer = Config::_3DRenderer; old_gldisplay = Config::ScreenUseGL; + old_vsync = Config::ScreenVSync; old_threaded3D = Config::Threaded3D; old_resolution = Config::GL_ScaleFactor; old_antialias = Config::GL_Antialias; uiCheckboxSetChecked(cbGLDisplay, Config::ScreenUseGL); + uiCheckboxSetChecked(cbVSync, Config::ScreenVSync); uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D); uiComboboxSetSelected(cbResolution, Config::GL_ScaleFactor-1); //uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias); uiRadioButtonsSetSelected(rbRenderer, Config::_3DRenderer); UpdateControls(); + if (Config::ScreenUseGL) uiControlEnable(uiControl(cbVSync)); + else uiControlDisable(uiControl(cbVSync)); + uiControlShow(uiControl(win)); } diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index 7f45b59..fb31ccd 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -43,6 +43,7 @@ int ScreenSizing; int ScreenFilter; int ScreenUseGL; +int ScreenVSync; int ScreenRatio; int LimitFPS; @@ -118,6 +119,7 @@ ConfigEntry PlatformConfigFile[] = {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, + {"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0}, {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, {"LimitFPS", 0, &LimitFPS, 1, NULL, 0}, diff --git a/src/libui_sdl/PlatformConfig.h b/src/libui_sdl/PlatformConfig.h index 2c59e5d..2aede24 100644 --- a/src/libui_sdl/PlatformConfig.h +++ b/src/libui_sdl/PlatformConfig.h @@ -54,6 +54,7 @@ extern int ScreenSizing; extern int ScreenFilter; extern int ScreenUseGL; +extern int ScreenVSync; extern int ScreenRatio; extern int LimitFPS; diff --git a/src/libui_sdl/libui/windows/CMakeLists.txt b/src/libui_sdl/libui/windows/CMakeLists.txt index 9d5313a..24d4ad9 100644 --- a/src/libui_sdl/libui/windows/CMakeLists.txt +++ b/src/libui_sdl/libui/windows/CMakeLists.txt @@ -73,7 +73,7 @@ macro(_handle_static) add_custom_command( TARGET libui POST_BUILD COMMAND - ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:libui,BINARY_DIR>/CMakeFiles/libui.dir/windows/resources.rc.* ${_LIBUI_STATIC_RES} + ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:libui,BINARY_DIR>/CMakeFiles/libui.dir/windows/resources.rc.obj ${_LIBUI_STATIC_RES} COMMENT "Copying libui.res") endmacro() diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 38b734b..7fd02bb 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -158,6 +158,8 @@ bool LidStatus; int JoystickID; SDL_Joystick* Joystick; +int AudioFreq; +float AudioSampleFrac; SDL_AudioDeviceID AudioDevice, MicDevice; u32 MicBufferLength = 2048; @@ -560,26 +562,37 @@ void MicLoadWav(char* name) void AudioCallback(void* data, Uint8* stream, int len) { - // resampling: - // buffer length is 1024 samples - // which is 710 samples at the original sample rate + len /= (sizeof(s16) * 2); - s16 buf_in[710*2]; + // resample incoming audio to match the output sample rate + + float f_len_in = (len * 32823.6328125) / (float)AudioFreq; + f_len_in += AudioSampleFrac; + int len_in = (int)floor(f_len_in); + AudioSampleFrac = f_len_in - len_in; + + s16 buf_in[1024*2]; s16* buf_out = (s16*)stream; - int num_in = SPU::ReadOutput(buf_in, 710); - int num_out = 1024; -printf("took %d/%d samples\n", num_in, 710); + int num_in = SPU::ReadOutput(buf_in, len_in); + int num_out = len; + + if (num_in < 1) + { + memset(stream, 0, len*sizeof(s16)*2); + return; + } + int margin = 6; - if (num_in < 710-margin) + if (num_in < len_in-margin) { int last = num_in-1; if (last < 0) last = 0; - for (int i = num_in; i < 710-margin; i++) + for (int i = num_in; i < len_in-margin; i++) ((u32*)buf_in)[i] = ((u32*)buf_in)[last]; - num_in = 710-margin; + num_in = len_in-margin; } float res_incr = num_in / (float)num_out; @@ -588,12 +601,22 @@ printf("took %d/%d samples\n", num_in, 710); int volume = Config::AudioVolume; - for (int i = 0; i < 1024; i++) + for (int i = 0; i < len; i++) { - // TODO: interp!! buf_out[i*2 ] = (buf_in[res_pos*2 ] * volume) >> 8; buf_out[i*2+1] = (buf_in[res_pos*2+1] * volume) >> 8; + /*s16 s_l = buf_in[res_pos*2 ]; + s16 s_r = buf_in[res_pos*2+1]; + + float a = res_timer; + float b = 1.0 - a; + s_l = (s_l * a) + (buf_in[(res_pos-1)*2 ] * b); + s_r = (s_r * a) + (buf_in[(res_pos-1)*2+1] * b); + + buf_out[i*2 ] = (s_l * volume) >> 8; + buf_out[i*2+1] = (s_r * volume) >> 8;*/ + res_timer += res_incr; while (res_timer >= 1.0) { @@ -838,6 +861,7 @@ bool JoyButtonHeld(int btnid, int njoybuttons, Uint8* joybuttons, Uint32 hat) void UpdateWindowTitle(void* data) { + if (EmuStatus == 0) return; uiWindowSetTitle(MainWindow, (const char*)data); } @@ -880,6 +904,10 @@ int EmuThreadFunc(void* burp) u32 lasttick = starttick; u32 lastmeasuretick = lasttick; u32 fpslimitcount = 0; + u64 perfcount = SDL_GetPerformanceCounter(); + u64 perffreq = SDL_GetPerformanceFrequency(); + float samplesleft = 0; + u32 nsamples = 0; char melontitle[100]; while (EmuRunning != 0) @@ -959,43 +987,31 @@ int EmuThreadFunc(void* burp) } uiAreaQueueRedrawAll(MainDrawArea); - // framerate limiter based off SDL2_gfx - float framerate = (1000.0f * nlines) / (60.0f * 263.0f); - - /*fpslimitcount++; - u32 curtick = SDL_GetTicks(); - u32 delay = curtick - lasttick; - lasttick = curtick; - bool limitfps = Config::LimitFPS && !HotkeyDown(HK_FastForward); + bool vsync = Config::ScreenVSync && Screen_UseGL; + SPU::Sync(limitfps || vsync); - u32 wantedtick = starttick + (u32)((float)fpslimitcount * framerate); - if (curtick < wantedtick && limitfps) - { - SDL_Delay(wantedtick - curtick); - } - else - { - fpslimitcount = 0; - starttick = curtick; - }*/ + float framerate = (1000.0f * nlines) / (60.0f * 263.0f); - fpslimitcount++; - if (fpslimitcount >= 3) { u32 curtick = SDL_GetTicks(); u32 delay = curtick - lasttick; - bool limitfps = Config::LimitFPS && !HotkeyDown(HK_FastForward); - - u32 wantedtick = lasttick + (u32)((float)fpslimitcount * framerate); - if (curtick < wantedtick && limitfps) + if (limitfps) { - SDL_Delay(wantedtick - curtick); + float wantedtickF = starttick + (framerate * (fpslimitcount+1)); + u32 wantedtick = (u32)ceil(wantedtickF); + if (curtick < wantedtick) SDL_Delay(wantedtick - curtick); + + lasttick = SDL_GetTicks(); + fpslimitcount++; + if ((abs(wantedtickF - (float)wantedtick) < 0.001312) || (fpslimitcount > 60)) + { + fpslimitcount = 0; + nsamples = 0; + starttick = lasttick; + } } - - lasttick = SDL_GetTicks(); - fpslimitcount = 0; } nframes++; @@ -1517,6 +1533,8 @@ void Run() EmuRunning = 1; RunningSomething = true; + SPU::InitOutput(); + AudioSampleFrac = 0; SDL_PauseAudioDevice(AudioDevice, 0); SDL_PauseAudioDevice(MicDevice, 0); @@ -1555,6 +1573,7 @@ void TogglePause(void* blarg) EmuRunning = 2; uiMenuItemSetChecked(MenuItem_Pause, 1); + SPU::DrainOutput(); SDL_PauseAudioDevice(AudioDevice, 1); SDL_PauseAudioDevice(MicDevice, 1); @@ -1566,6 +1585,8 @@ void TogglePause(void* blarg) EmuRunning = 1; uiMenuItemSetChecked(MenuItem_Pause, 0); + SPU::InitOutput(); + AudioSampleFrac = 0; SDL_PauseAudioDevice(AudioDevice, 0); SDL_PauseAudioDevice(MicDevice, 0); @@ -1616,6 +1637,7 @@ void Stop(bool internal) uiAreaQueueRedrawAll(MainDrawArea); + SPU::DrainOutput(); SDL_PauseAudioDevice(AudioDevice, 1); SDL_PauseAudioDevice(MicDevice, 1); @@ -2239,6 +2261,19 @@ void ApplyNewSettings(int type) GPU3D::InitRenderer(Screen_UseGL); if (Screen_UseGL) uiGLMakeContextCurrent(NULL); } + else if (type == 4) // vsync + { + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + uiGLSetVSync(Config::ScreenVSync); + uiGLMakeContextCurrent(NULL); + } + else + { + // TODO eventually: VSync for non-GL screen? + } + } EmuRunning = prevstatus; } @@ -2448,7 +2483,7 @@ void CreateMainWindow(bool opengl) if (opengl_good) { uiGLMakeContextCurrent(GLContext); - uiGLSetVSync(0); // TODO: make configurable? + uiGLSetVSync(Config::ScreenVSync); if (!GLScreen_Init()) opengl_good = false; if (opengl_good) { @@ -2655,20 +2690,23 @@ int main(int argc, char** argv) uiMenuItemSetChecked(MenuItem_LimitFPS, Config::LimitFPS==1); uiMenuItemSetChecked(MenuItem_ShowOSD, Config::ShowOSD==1); + AudioFreq = 48000; // TODO: make configurable? SDL_AudioSpec whatIwant, whatIget; memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); - whatIwant.freq = 47340; + whatIwant.freq = AudioFreq; whatIwant.format = AUDIO_S16LSB; whatIwant.channels = 2; whatIwant.samples = 1024; whatIwant.callback = AudioCallback; - AudioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, 0); + AudioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); if (!AudioDevice) { printf("Audio init failed: %s\n", SDL_GetError()); } else { + AudioFreq = whatIget.freq; + printf("Audio output frequency: %d Hz\n", AudioFreq); SDL_PauseAudioDevice(AudioDevice, 1); } |