Merge branch 'scaling'
This commit is contained in:
commit
42f99f2cb2
|
@ -593,6 +593,7 @@ src/gui/piano.cpp
|
||||||
src/gui/presets.cpp
|
src/gui/presets.cpp
|
||||||
src/gui/regView.cpp
|
src/gui/regView.cpp
|
||||||
src/gui/sampleEdit.cpp
|
src/gui/sampleEdit.cpp
|
||||||
|
src/gui/scaling.cpp
|
||||||
src/gui/settings.cpp
|
src/gui/settings.cpp
|
||||||
src/gui/songInfo.cpp
|
src/gui/songInfo.cpp
|
||||||
src/gui/songNotes.cpp
|
src/gui/songNotes.cpp
|
||||||
|
|
|
@ -276,9 +276,6 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
{
|
{
|
||||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||||
#ifdef __APPLE__
|
|
||||||
|
|
||||||
#endif
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
int window_x, window_y;
|
int window_x, window_y;
|
||||||
|
@ -286,8 +283,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||||
mouse_pos.x += window_x;
|
mouse_pos.x += window_x;
|
||||||
mouse_pos.y += window_y;
|
mouse_pos.y += window_y;
|
||||||
}
|
}
|
||||||
#ifdef __APPLE__
|
// Fix for high DPI mac/idevice/wayland
|
||||||
// Fix for high DPI mac
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f)
|
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f)
|
||||||
{
|
{
|
||||||
|
@ -295,7 +291,6 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||||
mouse_pos.x *= std::ceil(platform_io.Monitors[0].DpiScale);
|
mouse_pos.x *= std::ceil(platform_io.Monitors[0].DpiScale);
|
||||||
mouse_pos.y *= std::ceil(platform_io.Monitors[0].DpiScale);
|
mouse_pos.y *= std::ceil(platform_io.Monitors[0].DpiScale);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -551,8 +546,7 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
||||||
mouse_x -= window_x;
|
mouse_x -= window_x;
|
||||||
mouse_y -= window_y;
|
mouse_y -= window_y;
|
||||||
}
|
}
|
||||||
#ifdef __APPLE__
|
// Fix for high DPI mac/idevice/wayland
|
||||||
// Fix for high DPI mac
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f)
|
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f)
|
||||||
{
|
{
|
||||||
|
@ -560,7 +554,6 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
||||||
mouse_x *= std::ceil(platform_io.Monitors[0].DpiScale);
|
mouse_x *= std::ceil(platform_io.Monitors[0].DpiScale);
|
||||||
mouse_y *= std::ceil(platform_io.Monitors[0].DpiScale);
|
mouse_y *= std::ceil(platform_io.Monitors[0].DpiScale);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -669,13 +662,7 @@ static void ImGui_ImplSDL2_UpdateMonitors()
|
||||||
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||||
#endif
|
#endif
|
||||||
#if SDL_HAS_PER_MONITOR_DPI
|
#if SDL_HAS_PER_MONITOR_DPI
|
||||||
#ifdef __APPLE__
|
monitor.DpiScale = 1.0f;
|
||||||
monitor.DpiScale=getMacDPIScale();
|
|
||||||
#else
|
|
||||||
float dpi = 0.0f;
|
|
||||||
if (!SDL_GetDisplayDPI(n, &dpi, NULL, NULL))
|
|
||||||
monitor.DpiScale = dpi / 96.0f;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
platform_io.Monitors.push_back(monitor);
|
platform_io.Monitors.push_back(monitor);
|
||||||
}
|
}
|
||||||
|
@ -701,15 +688,14 @@ void ImGui_ImplSDL2_NewFrame()
|
||||||
if (w > 0 && h > 0)
|
if (w > 0 && h > 0)
|
||||||
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
// On Apple and Wayland, The window size is reported in Low DPI, even when running in high DPI mode
|
||||||
// On Apple, The window size is reported in Low DPI, even when running in high DPI mode
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f && display_h != h)
|
if (!platform_io.Monitors.empty() /*&& platform_io.Monitors[0].DpiScale > 1.0f*/ && display_h != h)
|
||||||
{
|
{
|
||||||
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
||||||
io.DisplaySize = ImVec2((float)display_w, (float)display_h);
|
io.DisplaySize = ImVec2((float)display_w, (float)display_h);
|
||||||
|
platform_io.Monitors[0].DpiScale=(float)display_w/(float)w;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev121"
|
#define DIV_VERSION "dev122"
|
||||||
#define DIV_ENGINE_VERSION 121
|
#define DIV_ENGINE_VERSION 122
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
|
@ -23,18 +23,13 @@
|
||||||
|
|
||||||
const char* aboutLine[]={
|
const char* aboutLine[]={
|
||||||
"tildearrow",
|
"tildearrow",
|
||||||
"is not so happy to present",
|
"is proud to present",
|
||||||
"",
|
"",
|
||||||
("Furnace " DIV_VERSION),
|
("Furnace " DIV_VERSION),
|
||||||
"",
|
"",
|
||||||
"the biggest multi-system chiptune tracker!",
|
"the biggest multi-system chiptune tracker!",
|
||||||
"featuring DefleMask song compatibility.",
|
"featuring DefleMask song compatibility.",
|
||||||
"",
|
"",
|
||||||
"what a mess of a versioning scheme we have...",
|
|
||||||
"I mean it! these pre-releases are like normal releases",
|
|
||||||
"by now but only because I promised you to have SNES in",
|
|
||||||
"0.6pre2 I am doing this whole mess...",
|
|
||||||
"",
|
|
||||||
"> CREDITS <",
|
"> CREDITS <",
|
||||||
"",
|
"",
|
||||||
"-- program --",
|
"-- program --",
|
||||||
|
@ -187,7 +182,7 @@ void FurnaceGUI::drawAbout() {
|
||||||
// do stuff
|
// do stuff
|
||||||
if (ImGui::Begin("About Furnace",NULL,ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoDocking|ImGuiWindowFlags_NoTitleBar)) {
|
if (ImGui::Begin("About Furnace",NULL,ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoDocking|ImGuiWindowFlags_NoTitleBar)) {
|
||||||
ImGui::SetWindowPos(ImVec2(0,0));
|
ImGui::SetWindowPos(ImVec2(0,0));
|
||||||
ImGui::SetWindowSize(ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetWindowSize(ImVec2(canvasW,canvasH));
|
||||||
ImGui::PushFont(bigFont);
|
ImGui::PushFont(bigFont);
|
||||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||||
float r=0;
|
float r=0;
|
||||||
|
@ -195,47 +190,47 @@ void FurnaceGUI::drawAbout() {
|
||||||
float b=0;
|
float b=0;
|
||||||
float peakMix=settings.partyTime?((peak[0]+peak[1])*0.5):0.3;
|
float peakMix=settings.partyTime?((peak[0]+peak[1])*0.5):0.3;
|
||||||
ImGui::ColorConvertHSVtoRGB(aboutHue,1.0,0.25+MIN(0.75f,peakMix*0.75f),r,g,b);
|
ImGui::ColorConvertHSVtoRGB(aboutHue,1.0,0.25+MIN(0.75f,peakMix*0.75f),r,g,b);
|
||||||
dl->AddRectFilled(ImVec2(0,0),ImVec2(scrW*dpiScale,scrH*dpiScale),0xff000000);
|
dl->AddRectFilled(ImVec2(0,0),ImVec2(canvasW,canvasH),0xff000000);
|
||||||
bool skip=false;
|
bool skip=false;
|
||||||
bool skip2=false;
|
bool skip2=false;
|
||||||
for (int i=(-80-sin(double(aboutSin)*2*M_PI/120.0)*80.0)*2; i<scrW; i+=160) {
|
for (int i=(-80-sin(double(aboutSin)*2*M_PI/120.0)*80.0)*2*dpiScale; i<canvasW; i+=160*dpiScale) {
|
||||||
skip2=!skip2;
|
skip2=!skip2;
|
||||||
skip=skip2;
|
skip=skip2;
|
||||||
for (int j=(-80-cos(double(aboutSin)*2*M_PI/150.0)*80.0)*2; j<scrH; j+=160) {
|
for (int j=(-80-cos(double(aboutSin)*2*M_PI/150.0)*80.0)*2*dpiScale; j<canvasH; j+=160*dpiScale) {
|
||||||
skip=!skip;
|
skip=!skip;
|
||||||
if (skip) continue;
|
if (skip) continue;
|
||||||
dl->AddRectFilled(ImVec2(i*dpiScale,j*dpiScale),ImVec2((i+160)*dpiScale,(j+160)*dpiScale),ImGui::GetColorU32(ImVec4(r*0.25,g*0.25,b*0.25,1.0)));
|
dl->AddRectFilled(ImVec2(i,j),ImVec2(i+160*dpiScale,j+160*dpiScale),ImGui::GetColorU32(ImVec4(r*0.25,g*0.25,b*0.25,1.0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip=false;
|
skip=false;
|
||||||
skip2=false;
|
skip2=false;
|
||||||
for (int i=(-80-cos(double(aboutSin)*2*M_PI/120.0)*80.0)*2; i<scrW; i+=160) {
|
for (int i=(-80-cos(double(aboutSin)*2*M_PI/120.0)*80.0)*2*dpiScale; i<canvasW; i+=160*dpiScale) {
|
||||||
skip2=!skip2;
|
skip2=!skip2;
|
||||||
skip=skip2;
|
skip=skip2;
|
||||||
for (int j=(-80-sin(double(aboutSin)*2*M_PI/150.0)*80.0)*2; j<scrH; j+=160) {
|
for (int j=(-80-sin(double(aboutSin)*2*M_PI/150.0)*80.0)*2*dpiScale; j<canvasH; j+=160*dpiScale) {
|
||||||
skip=!skip;
|
skip=!skip;
|
||||||
if (skip) continue;
|
if (skip) continue;
|
||||||
dl->AddRectFilled(ImVec2(i*dpiScale,j*dpiScale),ImVec2((i+160)*dpiScale,(j+160)*dpiScale),ImGui::GetColorU32(ImVec4(r*0.5,g*0.5,b*0.5,1.0)));
|
dl->AddRectFilled(ImVec2(i,j),ImVec2(i+160*dpiScale,j+160*dpiScale),ImGui::GetColorU32(ImVec4(r*0.5,g*0.5,b*0.5,1.0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip=false;
|
skip=false;
|
||||||
skip2=false;
|
skip2=false;
|
||||||
for (int i=(-160+fmod(aboutSin*2,160))*2; i<scrW; i+=160) {
|
for (int i=(-160+fmod(aboutSin*2,160))*2*dpiScale; i<canvasW; i+=160*dpiScale) {
|
||||||
skip2=!skip2;
|
skip2=!skip2;
|
||||||
skip=skip2;
|
skip=skip2;
|
||||||
for (int j=(-240-cos(double(aboutSin*M_PI/300.0))*240.0)*2; j<scrH; j+=160) {
|
for (int j=(-240-cos(double(aboutSin*M_PI/300.0))*240.0)*2*dpiScale; j<canvasH; j+=160*dpiScale) {
|
||||||
skip=!skip;
|
skip=!skip;
|
||||||
if (skip) continue;
|
if (skip) continue;
|
||||||
dl->AddRectFilled(ImVec2(i*dpiScale,j*dpiScale),ImVec2((i+160)*dpiScale,(j+160)*dpiScale),ImGui::GetColorU32(ImVec4(r*0.75,g*0.75,b*0.75,1.0)));
|
dl->AddRectFilled(ImVec2(i,j),ImVec2(i+160*dpiScale,j+160*dpiScale),ImGui::GetColorU32(ImVec4(r*0.75,g*0.75,b*0.75,1.0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i=0; i<aboutCount; i++) {
|
for (size_t i=0; i<aboutCount; i++) {
|
||||||
double posX=(scrW*dpiScale/2.0)+(sin(double(i)*0.5+double(aboutScroll)/90.0)*120*dpiScale)-(ImGui::CalcTextSize(aboutLine[i]).x*0.5);
|
double posX=(canvasW/2.0)+(sin(double(i)*0.5+double(aboutScroll)/(90.0*dpiScale))*120*dpiScale)-(ImGui::CalcTextSize(aboutLine[i]).x*0.5);
|
||||||
double posY=(scrH-aboutScroll+42*i)*dpiScale;
|
double posY=(canvasH-aboutScroll+42*i*dpiScale);
|
||||||
if (posY<-80*dpiScale || posY>scrH*dpiScale) continue;
|
if (posY<-80*dpiScale || posY>canvasH) continue;
|
||||||
dl->AddText(bigFont,bigFont->FontSize,
|
dl->AddText(bigFont,bigFont->FontSize,
|
||||||
ImVec2(posX+dpiScale,posY+dpiScale),
|
ImVec2(posX+dpiScale,posY+dpiScale),
|
||||||
0xff000000,aboutLine[i]);
|
0xff000000,aboutLine[i]);
|
||||||
|
@ -257,12 +252,12 @@ void FurnaceGUI::drawAbout() {
|
||||||
float timeScale=60.0f*ImGui::GetIO().DeltaTime;
|
float timeScale=60.0f*ImGui::GetIO().DeltaTime;
|
||||||
|
|
||||||
aboutHue+=(0.001+peakMix*0.004)*timeScale;
|
aboutHue+=(0.001+peakMix*0.004)*timeScale;
|
||||||
aboutScroll+=(2+(peakMix>0.78)*3)*timeScale;
|
aboutScroll+=(2+(peakMix>0.78)*3)*timeScale*dpiScale;
|
||||||
aboutSin+=(1+(peakMix>0.75)*2)*timeScale;
|
aboutSin+=(1+(peakMix>0.75)*2)*timeScale;
|
||||||
|
|
||||||
while (aboutHue>1) aboutHue--;
|
while (aboutHue>1) aboutHue--;
|
||||||
while (aboutSin>=2400) aboutSin-=2400;
|
while (aboutSin>=2400) aboutSin-=2400;
|
||||||
if (aboutScroll>(42*aboutCount+scrH)) aboutScroll=-20;
|
if (aboutScroll>(42*dpiScale*aboutCount+canvasH)) aboutScroll=-20*dpiScale;
|
||||||
|
|
||||||
WAKE_UP;
|
WAKE_UP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ void FurnaceGUI::drawChanOsc() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!chanOscOpen) return;
|
if (!chanOscOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::Begin("Oscilloscope (per-channel)",&chanOscOpen,globalWinFlags|((chanOscOptions)?0:ImGuiWindowFlags_NoTitleBar))) {
|
if (ImGui::Begin("Oscilloscope (per-channel)",&chanOscOpen,globalWinFlags|((chanOscOptions)?0:ImGuiWindowFlags_NoTitleBar))) {
|
||||||
bool centerSettingReset=false;
|
bool centerSettingReset=false;
|
||||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||||
|
|
|
@ -42,7 +42,7 @@ void FurnaceGUI::drawDebug() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!debugOpen) return;
|
if (!debugOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::Begin("Debug",&debugOpen,globalWinFlags|ImGuiWindowFlags_NoDocking)) {
|
if (ImGui::Begin("Debug",&debugOpen,globalWinFlags|ImGuiWindowFlags_NoDocking)) {
|
||||||
ImGui::Text("NOTE: use with caution.");
|
ImGui::Text("NOTE: use with caution.");
|
||||||
if (ImGui::TreeNode("Debug Controls")) {
|
if (ImGui::TreeNode("Debug Controls")) {
|
||||||
|
|
|
@ -38,8 +38,8 @@ void FurnaceGUI::drawMobileControls() {
|
||||||
mobileMenuPos=0.0f;
|
mobileMenuPos=0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::SetNextWindowPos(portrait?ImVec2(0.0f,((1.0-mobileMenuPos*0.65)*scrH*dpiScale)-(0.16*scrW*dpiScale)):ImVec2(0.5*scrW*dpiScale*mobileMenuPos,0.0f));
|
ImGui::SetNextWindowPos(portrait?ImVec2(0.0f,((1.0-mobileMenuPos*0.65)*canvasH)-(0.16*canvasW)):ImVec2(0.5*canvasW*mobileMenuPos,0.0f));
|
||||||
ImGui::SetNextWindowSize(portrait?ImVec2(scrW*dpiScale,0.16*scrW*dpiScale):ImVec2(0.16*scrH*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSize(portrait?ImVec2(canvasW,0.16*canvasW):ImVec2(0.16*canvasH,canvasH));
|
||||||
if (ImGui::Begin("Mobile Controls",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
if (ImGui::Begin("Mobile Controls",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||||
float avail=portrait?ImGui::GetContentRegionAvail().y:ImGui::GetContentRegionAvail().x;
|
float avail=portrait?ImGui::GetContentRegionAvail().y:ImGui::GetContentRegionAvail().x;
|
||||||
ImVec2 buttonSize=ImVec2(avail,avail);
|
ImVec2 buttonSize=ImVec2(avail,avail);
|
||||||
|
@ -101,8 +101,8 @@ void FurnaceGUI::drawMobileControls() {
|
||||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_EDIT_CONTROLS;
|
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_EDIT_CONTROLS;
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(portrait?ImVec2(0.0f,((1.0-mobileMenuPos*0.65)*scrH*dpiScale)):ImVec2(0.5*scrW*dpiScale*(mobileMenuPos-1.0),0.0f));
|
ImGui::SetNextWindowPos(portrait?ImVec2(0.0f,((1.0-mobileMenuPos*0.65)*canvasH)):ImVec2(0.5*canvasW*(mobileMenuPos-1.0),0.0f));
|
||||||
ImGui::SetNextWindowSize(portrait?ImVec2(scrW*dpiScale,0.65*scrH*dpiScale):ImVec2(0.5*scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSize(portrait?ImVec2(canvasW,0.65*canvasH):ImVec2(0.5*canvasW,canvasH));
|
||||||
if (ImGui::Begin("Mobile Menu",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
if (ImGui::Begin("Mobile Menu",NULL,ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||||
if (ImGui::BeginTable("SceneSel",5)) {
|
if (ImGui::BeginTable("SceneSel",5)) {
|
||||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0f);
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0f);
|
||||||
|
|
|
@ -9,7 +9,7 @@ void FurnaceGUI::drawEffectList() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!effectListOpen) return;
|
if (!effectListOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(60.0f*dpiScale,20.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(60.0f*dpiScale,20.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::Begin("Effect List",&effectListOpen,globalWinFlags)) {
|
if (ImGui::Begin("Effect List",&effectListOpen,globalWinFlags)) {
|
||||||
ImGui::Text("Chip at cursor: %s",e->getSystemName(e->sysOfChan[cursor.xCoarse]));
|
ImGui::Text("Chip at cursor: %s",e->getSystemName(e->sysOfChan[cursor.xCoarse]));
|
||||||
if (ImGui::BeginTable("effectList",2)) {
|
if (ImGui::BeginTable("effectList",2)) {
|
||||||
|
|
|
@ -494,7 +494,7 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!findOpen) return;
|
if (!findOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::Begin("Find/Replace",&findOpen,globalWinFlags)) {
|
if (ImGui::Begin("Find/Replace",&findOpen,globalWinFlags)) {
|
||||||
if (curQuery.empty()) {
|
if (curQuery.empty()) {
|
||||||
curQuery.push_back(FurnaceGUIFindQuery());
|
curQuery.push_back(FurnaceGUIFindQuery());
|
||||||
|
|
195
src/gui/gui.cpp
195
src/gui/gui.cpp
|
@ -1,3 +1,5 @@
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
// OK, sorry for inserting the define here but I'm so tired of this extension
|
||||||
/**
|
/**
|
||||||
* Furnace Tracker - multi-system chiptune tracker
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
* Copyright (C) 2021-2022 tildearrow and contributors
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||||
|
@ -20,7 +22,7 @@
|
||||||
// I hate you clangd extension!
|
// I hate you clangd extension!
|
||||||
// how about you DON'T insert random headers before this freaking important
|
// how about you DON'T insert random headers before this freaking important
|
||||||
// define!!!!!!
|
// define!!!!!!
|
||||||
#define _USE_MATH_DEFINES
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "icon.h"
|
#include "icon.h"
|
||||||
|
@ -36,17 +38,12 @@
|
||||||
#include "plot_nolerp.h"
|
#include "plot_nolerp.h"
|
||||||
#include "guiConst.h"
|
#include "guiConst.h"
|
||||||
#include "intConst.h"
|
#include "intConst.h"
|
||||||
|
#include "scaling.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
extern "C" {
|
|
||||||
#include "macstuff.h"
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
@ -2754,12 +2751,8 @@ void FurnaceGUI::processPoint(SDL_Event& ev) {
|
||||||
TouchPoint* point=NULL;
|
TouchPoint* point=NULL;
|
||||||
FIND_POINT(point,-1);
|
FIND_POINT(point,-1);
|
||||||
if (point!=NULL) {
|
if (point!=NULL) {
|
||||||
point->x=ev.motion.x;
|
point->x=(double)ev.motion.x*((double)canvasW/(double)scrW);
|
||||||
point->y=ev.motion.y;
|
point->y=(double)ev.motion.y*((double)canvasH/(double)scrH);
|
||||||
#ifdef __APPLE__
|
|
||||||
point->x*=dpiScale;
|
|
||||||
point->y*=dpiScale;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2800,8 +2793,8 @@ void FurnaceGUI::processPoint(SDL_Event& ev) {
|
||||||
if (point!=NULL) {
|
if (point!=NULL) {
|
||||||
float prevX=point->x;
|
float prevX=point->x;
|
||||||
float prevY=point->y;
|
float prevY=point->y;
|
||||||
point->x=ev.tfinger.x*scrW*dpiScale;
|
point->x=ev.tfinger.x*canvasW;
|
||||||
point->y=ev.tfinger.y*scrH*dpiScale;
|
point->y=ev.tfinger.y*canvasH;
|
||||||
point->z=ev.tfinger.pressure;
|
point->z=ev.tfinger.pressure;
|
||||||
|
|
||||||
if (point->id==0) {
|
if (point->id==0) {
|
||||||
|
@ -2820,7 +2813,7 @@ void FurnaceGUI::processPoint(SDL_Event& ev) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TouchPoint newPoint(ev.tfinger.fingerId,ev.tfinger.x*scrW*dpiScale,ev.tfinger.y*scrH*dpiScale,ev.tfinger.pressure);
|
TouchPoint newPoint(ev.tfinger.fingerId,ev.tfinger.x*canvasW,ev.tfinger.y*canvasH,ev.tfinger.pressure);
|
||||||
activePoints.push_back(newPoint);
|
activePoints.push_back(newPoint);
|
||||||
pressedPoints.push_back(newPoint);
|
pressedPoints.push_back(newPoint);
|
||||||
|
|
||||||
|
@ -2986,16 +2979,10 @@ bool FurnaceGUI::loop() {
|
||||||
if (!doThreadedInput) processEvent(&ev);
|
if (!doThreadedInput) processEvent(&ev);
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
case SDL_MOUSEMOTION: {
|
case SDL_MOUSEMOTION: {
|
||||||
int motionX=ev.motion.x;
|
int motionX=(double)ev.motion.x*((double)canvasW/(double)scrW);
|
||||||
int motionY=ev.motion.y;
|
int motionY=(double)ev.motion.y*((double)canvasH/(double)scrH);
|
||||||
int motionXrel=ev.motion.xrel;
|
int motionXrel=(double)ev.motion.xrel*((double)canvasW/(double)scrW);
|
||||||
int motionYrel=ev.motion.yrel;
|
int motionYrel=(double)ev.motion.yrel*((double)canvasH/(double)scrH);
|
||||||
#ifdef __APPLE__
|
|
||||||
motionX*=dpiScale;
|
|
||||||
motionY*=dpiScale;
|
|
||||||
motionXrel*=dpiScale;
|
|
||||||
motionYrel*=dpiScale;
|
|
||||||
#endif
|
|
||||||
pointMotion(motionX,motionY,motionXrel,motionYrel);
|
pointMotion(motionX,motionY,motionXrel,motionYrel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3012,13 +2999,8 @@ bool FurnaceGUI::loop() {
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
switch (ev.window.event) {
|
switch (ev.window.event) {
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
case SDL_WINDOWEVENT_RESIZED:
|
||||||
#ifdef __APPLE__
|
|
||||||
scrW=ev.window.data1;
|
scrW=ev.window.data1;
|
||||||
scrH=ev.window.data2;
|
scrH=ev.window.data2;
|
||||||
#else
|
|
||||||
scrW=ev.window.data1/dpiScale;
|
|
||||||
scrH=ev.window.data2/dpiScale;
|
|
||||||
#endif
|
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
updateWindow=true;
|
updateWindow=true;
|
||||||
|
@ -3098,6 +3080,9 @@ bool FurnaceGUI::loop() {
|
||||||
scrConfW=scrW;
|
scrConfW=scrW;
|
||||||
scrConfH=scrH;
|
scrConfH=scrH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update canvas size as well
|
||||||
|
SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH);
|
||||||
}
|
}
|
||||||
|
|
||||||
wantCaptureKeyboard=ImGui::GetIO().WantTextInput;
|
wantCaptureKeyboard=ImGui::GetIO().WantTextInput;
|
||||||
|
@ -3776,10 +3761,10 @@ bool FurnaceGUI::loop() {
|
||||||
firstFrame=false;
|
firstFrame=false;
|
||||||
#ifdef IS_MOBILE
|
#ifdef IS_MOBILE
|
||||||
SDL_GetWindowSize(sdlWin,&scrW,&scrH);
|
SDL_GetWindowSize(sdlWin,&scrW,&scrH);
|
||||||
scrW/=dpiScale;
|
|
||||||
scrH/=dpiScale;
|
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
|
|
||||||
|
SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH);
|
||||||
#endif
|
#endif
|
||||||
if (patternOpen) nextWindow=GUI_WINDOW_PATTERN;
|
if (patternOpen) nextWindow=GUI_WINDOW_PATTERN;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -3797,12 +3782,12 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
ImDrawList* dl=ImGui::GetForegroundDrawList();
|
ImDrawList* dl=ImGui::GetForegroundDrawList();
|
||||||
dl->AddRectFilled(ImVec2(0.0f,0.0f),ImVec2(scrW*dpiScale,scrH*dpiScale),ImGui::ColorConvertFloat4ToU32(uiColors[GUI_COLOR_MODAL_BACKDROP]));
|
dl->AddRectFilled(ImVec2(0.0f,0.0f),ImVec2(canvasW,canvasH),ImGui::ColorConvertFloat4ToU32(uiColors[GUI_COLOR_MODAL_BACKDROP]));
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fileDialog->render(ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale))) {
|
if (fileDialog->render(ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH))) {
|
||||||
bool openOpen=false;
|
bool openOpen=false;
|
||||||
//ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_NavEnableKeyboard;
|
//ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
if ((curFileDialog==GUI_FILE_INS_OPEN || curFileDialog==GUI_FILE_INS_OPEN_REPLACE) && prevIns!=-3) {
|
if ((curFileDialog==GUI_FILE_INS_OPEN || curFileDialog==GUI_FILE_INS_OPEN_REPLACE) && prevIns!=-3) {
|
||||||
|
@ -4348,9 +4333,9 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::BeginPopupModal("New Song",NULL,ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollWithMouse|ImGuiWindowFlags_NoScrollbar)) {
|
if (ImGui::BeginPopupModal("New Song",NULL,ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollWithMouse|ImGuiWindowFlags_NoScrollbar)) {
|
||||||
ImGui::SetWindowPos(ImVec2(((scrW*dpiScale)-ImGui::GetWindowSize().x)*0.5,((scrH*dpiScale)-ImGui::GetWindowSize().y)*0.5));
|
ImGui::SetWindowPos(ImVec2(((canvasW)-ImGui::GetWindowSize().x)*0.5,((canvasH)-ImGui::GetWindowSize().y)*0.5));
|
||||||
drawNewSong();
|
drawNewSong();
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
@ -4718,8 +4703,8 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
bool anySelected=false;
|
bool anySelected=false;
|
||||||
float sizeY=ImGui::GetFrameHeightWithSpacing()*pendingIns.size();
|
float sizeY=ImGui::GetFrameHeightWithSpacing()*pendingIns.size();
|
||||||
if (sizeY>(scrH-180.0)*dpiScale) {
|
if (sizeY>(canvasH-180.0*dpiScale)) {
|
||||||
sizeY=(scrH-180.0)*dpiScale;
|
sizeY=canvasH-180.0*dpiScale;
|
||||||
if (sizeY<60.0*dpiScale) sizeY=60.0*dpiScale;
|
if (sizeY<60.0*dpiScale) sizeY=60.0*dpiScale;
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTable("PendingInsList",1,ImGuiTableFlags_ScrollY,ImVec2(0.0f,sizeY))) {
|
if (ImGui::BeginTable("PendingInsList",1,ImGuiTableFlags_ScrollY,ImVec2(0.0f,sizeY))) {
|
||||||
|
@ -4898,9 +4883,7 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FurnaceGUI::init() {
|
bool FurnaceGUI::init() {
|
||||||
#ifndef __APPLE__
|
logI("initializing GUI.");
|
||||||
float dpiScaleF;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
String homeDir=getHomeDir();
|
String homeDir=getHomeDir();
|
||||||
workingDir=e->getConfString("lastDir",homeDir);
|
workingDir=e->getConfString("lastDir",homeDir);
|
||||||
|
@ -5004,15 +4987,49 @@ bool FurnaceGUI::init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.dpiScale>=0.5f) {
|
|
||||||
dpiScale=settings.dpiScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
initSystemPresets();
|
initSystemPresets();
|
||||||
|
|
||||||
e->setAutoNotePoly(noteInputPoly);
|
e->setAutoNotePoly(noteInputPoly);
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER,"1");
|
||||||
|
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS,"0");
|
||||||
|
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS,"0");
|
||||||
|
// don't disable compositing on KWin
|
||||||
|
#if SDL_VERSION_ATLEAST(2,0,22)
|
||||||
|
logV("setting window type to NORMAL.");
|
||||||
|
SDL_SetHint(SDL_HINT_X11_WINDOW_TYPE,"_NET_WM_WINDOW_TYPE_NORMAL");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// initialize SDL
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
|
const char* videoBackend=SDL_GetCurrentVideoDriver();
|
||||||
|
if (videoBackend!=NULL) {
|
||||||
|
logV("video backend: %s",videoBackend);
|
||||||
|
if (strcmp(videoBackend,"wayland")==0 ||
|
||||||
|
strcmp(videoBackend,"cocoa")==0 ||
|
||||||
|
strcmp(videoBackend,"uikit")==0) {
|
||||||
|
sysManagedScale=true;
|
||||||
|
logV("scaling managed by system.");
|
||||||
|
} else {
|
||||||
|
logV("scaling managed by application.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logV("could not get video backend name!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get scale factor
|
||||||
|
if (settings.dpiScale>=0.5f) {
|
||||||
|
logD("setting UI scale factor from config (%f).",settings.dpiScale);
|
||||||
|
dpiScale=settings.dpiScale;
|
||||||
|
} else {
|
||||||
|
logD("auto-detecting UI scale factor.");
|
||||||
|
dpiScale=getScaleFactor(videoBackend);
|
||||||
|
logD("scale factor: %f",dpiScale);
|
||||||
|
}
|
||||||
|
|
||||||
#if !(defined(__APPLE__) || defined(_WIN32))
|
#if !(defined(__APPLE__) || defined(_WIN32))
|
||||||
|
// get the icon (on macOS and Windows the icon is bundled with the app)
|
||||||
unsigned char* furIcon=getFurnaceIcon();
|
unsigned char* furIcon=getFurnaceIcon();
|
||||||
SDL_Surface* icon=SDL_CreateRGBSurfaceFrom(furIcon,256,256,32,256*4,0xff,0xff00,0xff0000,0xff000000);
|
SDL_Surface* icon=SDL_CreateRGBSurfaceFrom(furIcon,256,256,32,256*4,0xff,0xff00,0xff0000,0xff000000);
|
||||||
#endif
|
#endif
|
||||||
|
@ -5032,20 +5049,26 @@ bool FurnaceGUI::init() {
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(IS_MOBILE)
|
// if old config, scale size as it was stored unscaled before
|
||||||
|
if (e->getConfInt("configVersion",0)<122 && !sysManagedScale) {
|
||||||
|
logD("scaling window size to scale factor because configVersion is not present.");
|
||||||
|
scrW*=dpiScale;
|
||||||
|
scrH*=dpiScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// predict the canvas size
|
||||||
|
if (sysManagedScale) {
|
||||||
|
canvasW=scrW*dpiScale;
|
||||||
|
canvasH=scrH*dpiScale;
|
||||||
|
} else {
|
||||||
|
canvasW=scrW;
|
||||||
|
canvasH=scrH;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef IS_MOBILE
|
||||||
SDL_Rect displaySize;
|
SDL_Rect displaySize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER,"1");
|
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS,"0");
|
|
||||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS,"0");
|
|
||||||
// don't disable compositing on KWin
|
|
||||||
#if SDL_VERSION_ATLEAST(2,0,22)
|
|
||||||
SDL_SetHint(SDL_HINT_X11_WINDOW_TYPE,"_NET_WM_WINDOW_TYPE_NORMAL");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
|
||||||
|
|
||||||
#ifndef IS_MOBILE
|
#ifndef IS_MOBILE
|
||||||
// if window would spawn out of bounds, force it to be get default position
|
// if window would spawn out of bounds, force it to be get default position
|
||||||
if (!detectOutOfBoundsWindow()) {
|
if (!detectOutOfBoundsWindow()) {
|
||||||
|
@ -5055,46 +5078,43 @@ bool FurnaceGUI::init() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sdlWin=SDL_CreateWindow("Furnace",scrX,scrY,scrW*dpiScale,scrH*dpiScale,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI|(scrMax?SDL_WINDOW_MAXIMIZED:0)|(fullScreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
logV("window size: %dx%d",scrW,scrH);
|
||||||
|
|
||||||
|
sdlWin=SDL_CreateWindow("Furnace",scrX,scrY,scrW,scrH,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI|(scrMax?SDL_WINDOW_MAXIMIZED:0)|(fullScreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||||
if (sdlWin==NULL) {
|
if (sdlWin==NULL) {
|
||||||
lastError=fmt::sprintf("could not open window! %s",SDL_GetError());
|
lastError=fmt::sprintf("could not open window! %s",SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __APPLE__
|
|
||||||
if (settings.dpiScale<0.5f) {
|
|
||||||
// TODO: replace with a function to actually detect the display scaling factor as it's unreliable.
|
|
||||||
SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(sdlWin),&dpiScaleF,NULL,NULL);
|
|
||||||
dpiScale=round(dpiScaleF/96.0f);
|
|
||||||
if (dpiScale<1) dpiScale=1;
|
|
||||||
#ifndef IS_MOBILE
|
#ifndef IS_MOBILE
|
||||||
if (dpiScale!=1) {
|
|
||||||
if (!fullScreen) {
|
|
||||||
SDL_SetWindowSize(sdlWin,scrW*dpiScale,scrH*dpiScale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(sdlWin),&displaySize)==0) {
|
if (SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(sdlWin),&displaySize)==0) {
|
||||||
if (scrW>((displaySize.w/dpiScale)-48) && scrH>((displaySize.h/dpiScale)-64)) {
|
bool mustChange=false;
|
||||||
|
if (scrW>((displaySize.w)-48) && scrH>((displaySize.h)-64)) {
|
||||||
// maximize
|
// maximize
|
||||||
SDL_MaximizeWindow(sdlWin);
|
SDL_MaximizeWindow(sdlWin);
|
||||||
|
logD("maximizing as it doesn't fit (%dx%d+%d+%d).",displaySize.w,displaySize.h,displaySize.x,displaySize.y);
|
||||||
}
|
}
|
||||||
if (scrW>displaySize.w/dpiScale) scrW=(displaySize.w/dpiScale)-32;
|
if (scrW>displaySize.w) {
|
||||||
if (scrH>displaySize.h/dpiScale) scrH=(displaySize.h/dpiScale)-32;
|
scrW=(displaySize.w)-32;
|
||||||
|
mustChange=true;
|
||||||
|
}
|
||||||
|
if (scrH>displaySize.h) {
|
||||||
|
scrH=(displaySize.h)-32;
|
||||||
|
mustChange=true;
|
||||||
|
}
|
||||||
|
if (mustChange) {
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
if (!fullScreen) {
|
if (!fullScreen) {
|
||||||
SDL_SetWindowSize(sdlWin,scrW*dpiScale,scrH*dpiScale);
|
logD("setting window size to %dx%d as it goes off bounds (%dx%d+%d+%d).",scrW,scrH,displaySize.w,displaySize.h,displaySize.x,displaySize.y);
|
||||||
|
SDL_SetWindowSize(sdlWin,scrW,scrH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IS_MOBILE
|
#ifdef IS_MOBILE
|
||||||
SDL_GetWindowSize(sdlWin,&scrW,&scrH);
|
SDL_GetWindowSize(sdlWin,&scrW,&scrH);
|
||||||
scrW/=dpiScale;
|
|
||||||
scrH/=dpiScale;
|
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
#endif
|
#endif
|
||||||
|
@ -5116,9 +5136,19 @@ bool FurnaceGUI::init() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
// try acquiring the canvas size
|
||||||
dpiScale=getMacDPIScale();
|
if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) {
|
||||||
#endif
|
logW("could not get renderer output size! %s",SDL_GetError());
|
||||||
|
} else {
|
||||||
|
logV("canvas size: %dx%d",canvasW,canvasH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special consideration for Wayland
|
||||||
|
if (settings.dpiScale<0.5f) {
|
||||||
|
if (strcmp(videoBackend,"wayland")==0) {
|
||||||
|
dpiScale=(double)canvasW/(double)scrW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
@ -5182,6 +5212,8 @@ bool FurnaceGUI::finish() {
|
||||||
SDL_DestroyRenderer(sdlRend);
|
SDL_DestroyRenderer(sdlRend);
|
||||||
SDL_DestroyWindow(sdlWin);
|
SDL_DestroyWindow(sdlWin);
|
||||||
|
|
||||||
|
e->setConf("configVersion",(int)DIV_ENGINE_VERSION);
|
||||||
|
|
||||||
e->setConf("lastDir",workingDir);
|
e->setConf("lastDir",workingDir);
|
||||||
e->setConf("lastDirSong",workingDirSong);
|
e->setConf("lastDirSong",workingDirSong);
|
||||||
e->setConf("lastDirIns",workingDirIns);
|
e->setConf("lastDirIns",workingDirIns);
|
||||||
|
@ -5353,11 +5385,14 @@ FurnaceGUI::FurnaceGUI():
|
||||||
scrH(800),
|
scrH(800),
|
||||||
scrConfW(1280),
|
scrConfW(1280),
|
||||||
scrConfH(800),
|
scrConfH(800),
|
||||||
|
canvasW(1280),
|
||||||
|
canvasH(800),
|
||||||
scrX(SDL_WINDOWPOS_CENTERED),
|
scrX(SDL_WINDOWPOS_CENTERED),
|
||||||
scrY(SDL_WINDOWPOS_CENTERED),
|
scrY(SDL_WINDOWPOS_CENTERED),
|
||||||
scrConfX(SDL_WINDOWPOS_CENTERED),
|
scrConfX(SDL_WINDOWPOS_CENTERED),
|
||||||
scrConfY(SDL_WINDOWPOS_CENTERED),
|
scrConfY(SDL_WINDOWPOS_CENTERED),
|
||||||
scrMax(false),
|
scrMax(false),
|
||||||
|
sysManagedScale(false),
|
||||||
dpiScale(1),
|
dpiScale(1),
|
||||||
aboutScroll(0),
|
aboutScroll(0),
|
||||||
aboutSin(0),
|
aboutSin(0),
|
||||||
|
|
|
@ -1062,9 +1062,9 @@ class FurnaceGUI {
|
||||||
|
|
||||||
FurnaceGUIFileDialog* fileDialog;
|
FurnaceGUIFileDialog* fileDialog;
|
||||||
|
|
||||||
int scrW, scrH, scrConfW, scrConfH;
|
int scrW, scrH, scrConfW, scrConfH, canvasW, canvasH;
|
||||||
int scrX, scrY, scrConfX, scrConfY;
|
int scrX, scrY, scrConfX, scrConfY;
|
||||||
bool scrMax;
|
bool scrMax, sysManagedScale;
|
||||||
|
|
||||||
double dpiScale;
|
double dpiScale;
|
||||||
|
|
||||||
|
|
|
@ -1903,12 +1903,12 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
}
|
}
|
||||||
if (!insEditOpen) return;
|
if (!insEditOpen) return;
|
||||||
if (mobileUI) {
|
if (mobileUI) {
|
||||||
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*scrH*dpiScale)):ImVec2((0.16*scrH*dpiScale)+0.5*scrW*dpiScale*mobileMenuPos,0.0f));
|
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*canvasH)):ImVec2((0.16*canvasH)+0.5*canvasW*mobileMenuPos,0.0f));
|
||||||
patWindowSize=(portrait?ImVec2(scrW*dpiScale,scrH*dpiScale-(0.16*scrW*dpiScale)-(pianoOpen?(0.4*scrW*dpiScale):0.0f)):ImVec2(scrW*dpiScale-(0.16*scrH*dpiScale),scrH*dpiScale-(pianoOpen?(0.3*scrH*dpiScale):0.0f)));
|
patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)-(pianoOpen?(0.4*canvasW):0.0f)):ImVec2(canvasW-(0.16*canvasH),canvasH-(pianoOpen?(0.3*canvasH):0.0f)));
|
||||||
ImGui::SetNextWindowPos(patWindowPos);
|
ImGui::SetNextWindowPos(patWindowPos);
|
||||||
ImGui::SetNextWindowSize(patWindowSize);
|
ImGui::SetNextWindowSize(patWindowSize);
|
||||||
} else {
|
} else {
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
}
|
}
|
||||||
if (ImGui::Begin("Instrument Editor",&insEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
if (ImGui::Begin("Instrument Editor",&insEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
||||||
if (curIns<0 || curIns>=(int)e->song.ins.size()) {
|
if (curIns<0 || curIns>=(int)e->song.ins.size()) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ void FurnaceGUI::drawMixer() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!mixerOpen) return;
|
if (!mixerOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::Begin("Mixer",&mixerOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
if (ImGui::Begin("Mixer",&mixerOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
||||||
char id[32];
|
char id[32];
|
||||||
if (ImGui::SliderFloat("Master Volume",&e->song.masterVol,0,3,"%.2fx")) {
|
if (ImGui::SliderFloat("Master Volume",&e->song.masterVol,0,3,"%.2fx")) {
|
||||||
|
|
|
@ -84,7 +84,7 @@ void FurnaceGUI::drawOsc() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!oscOpen) return;
|
if (!oscOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (settings.oscTakesEntireWindow) {
|
if (settings.oscTakesEntireWindow) {
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
||||||
|
|
|
@ -376,8 +376,8 @@ void FurnaceGUI::drawPattern() {
|
||||||
}
|
}
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0.0f,0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0.0f,0.0f));
|
||||||
if (mobileUI) {
|
if (mobileUI) {
|
||||||
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*scrH*dpiScale)):ImVec2((0.16*scrH*dpiScale)+0.5*scrW*dpiScale*mobileMenuPos,0.0f));
|
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*canvasH)):ImVec2((0.16*canvasH)+0.5*canvasW*mobileMenuPos,0.0f));
|
||||||
patWindowSize=(portrait?ImVec2(scrW*dpiScale,scrH*dpiScale-(0.16*scrW*dpiScale)-(pianoOpen?(0.4*scrW*dpiScale):0.0f)):ImVec2(scrW*dpiScale-(0.16*scrH*dpiScale),scrH*dpiScale-(pianoOpen?(0.3*scrH*dpiScale):0.0f)));
|
patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)-(pianoOpen?(0.4*canvasW):0.0f)):ImVec2(canvasW-(0.16*canvasH),canvasH-(pianoOpen?(0.3*canvasH):0.0f)));
|
||||||
ImGui::SetNextWindowPos(patWindowPos);
|
ImGui::SetNextWindowPos(patWindowPos);
|
||||||
ImGui::SetNextWindowSize(patWindowSize);
|
ImGui::SetNextWindowSize(patWindowSize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ void FurnaceGUI::drawPiano() {
|
||||||
if (!pianoOpen) return;
|
if (!pianoOpen) return;
|
||||||
if (mobileUI) {
|
if (mobileUI) {
|
||||||
ImGui::SetNextWindowPos(ImVec2(patWindowPos.x,patWindowPos.y+patWindowSize.y));
|
ImGui::SetNextWindowPos(ImVec2(patWindowPos.x,patWindowPos.y+patWindowSize.y));
|
||||||
ImGui::SetNextWindowSize(portrait?ImVec2(scrW*dpiScale,0.4*scrW*dpiScale):ImVec2(scrW*dpiScale-(0.16*scrH*dpiScale),0.3*scrH*dpiScale));
|
ImGui::SetNextWindowSize(portrait?ImVec2(canvasW,0.4*canvasW):ImVec2(canvasW-(0.16*canvasH),0.3*canvasH));
|
||||||
}
|
}
|
||||||
if (ImGui::Begin("Piano",&pianoOpen,((pianoOptions)?0:ImGuiWindowFlags_NoTitleBar)|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
if (ImGui::Begin("Piano",&pianoOpen,((pianoOptions)?0:ImGuiWindowFlags_NoTitleBar)|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoScrollWithMouse|globalWinFlags)) {
|
||||||
bool oldPianoKeyPressed[180];
|
bool oldPianoKeyPressed[180];
|
||||||
|
|
|
@ -39,8 +39,8 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
}
|
}
|
||||||
if (!sampleEditOpen) return;
|
if (!sampleEditOpen) return;
|
||||||
if (mobileUI) {
|
if (mobileUI) {
|
||||||
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*scrH*dpiScale)):ImVec2((0.16*scrH*dpiScale)+0.5*scrW*dpiScale*mobileMenuPos,0.0f));
|
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*canvasH)):ImVec2((0.16*canvasH)+0.5*canvasW*mobileMenuPos,0.0f));
|
||||||
patWindowSize=(portrait?ImVec2(scrW*dpiScale,scrH*dpiScale-(0.16*scrW*dpiScale)-(pianoOpen?(0.4*scrW*dpiScale):0.0f)):ImVec2(scrW*dpiScale-(0.16*scrH*dpiScale),scrH*dpiScale-(pianoOpen?(0.3*scrH*dpiScale):0.0f)));
|
patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)-(pianoOpen?(0.4*canvasW):0.0f)):ImVec2(canvasW-(0.16*canvasH),canvasH-(pianoOpen?(0.3*canvasH):0.0f)));
|
||||||
ImGui::SetNextWindowPos(patWindowPos);
|
ImGui::SetNextWindowPos(patWindowPos);
|
||||||
ImGui::SetNextWindowSize(patWindowSize);
|
ImGui::SetNextWindowSize(patWindowSize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,207 @@
|
||||||
|
/**
|
||||||
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "scaling.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
typedef HRESULT (*GDFM)(HMONITOR,int,UINT*,UINT*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
extern "C" {
|
||||||
|
#include "macstuff.h"
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(ANDROID)
|
||||||
|
#include <dlfcn.h>
|
||||||
|
typedef void* (*XOD)(const char*);
|
||||||
|
typedef int (*XCD)(void*);
|
||||||
|
typedef int (*XDS)(void*);
|
||||||
|
typedef int (*XDW)(void*,int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
double getScaleFactor(const char* driverHint) {
|
||||||
|
double ret=1.0;
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
#ifdef _WIN32
|
||||||
|
POINT nullPoint;
|
||||||
|
nullPoint.x=-1;
|
||||||
|
nullPoint.y=-1;
|
||||||
|
HMONITOR disp=MonitorFromPoint(nullPoint,MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
|
||||||
|
if (disp==NULL) {
|
||||||
|
logW("could not find a monitor - no scaling detection available!");
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE shcore=LoadLibraryW(L"shcore.dll");
|
||||||
|
if (shcore==NULL) {
|
||||||
|
logW("could not find shcore.dll (%.8x) - no scaling detection available!",GetLastError());
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
GDFM ta_GetDpiForMonitor=(GDFM)GetProcAddress(shcore,"GetDpiForMonitor");
|
||||||
|
if (ta_GetDpiForMonitor==NULL) {
|
||||||
|
logW("GetDpiForMonitor not found (%.8x) - no scaling detection available!",GetLastError());
|
||||||
|
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
logE("could not free shcore.dll (%.8x)!",GetLastError());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int dpiX=96;
|
||||||
|
unsigned int dpiY=96;
|
||||||
|
HRESULT result=ta_GetDpiForMonitor(disp,0,&dpiX,&dpiY);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logW("GetDpiForMonitor failure (%.8x) - no scaling detection available!",result);
|
||||||
|
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
logE("could not free shcore.dll (%.8x)!",GetLastError());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret=(double)(dpiX+dpiY)/192.0;
|
||||||
|
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
logE("could not free shcore.dll (%.8x)!",GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// macOS - backingScaleFactor
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (driverHint==NULL) {
|
||||||
|
return getMacDPIScale();
|
||||||
|
} else if (strcmp(driverHint,"cocoa")==0 || strcmp(driverHint,"uikit")==0) {
|
||||||
|
return getMacDPIScale();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(ANDROID)
|
||||||
|
if (driverHint==NULL) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// X11
|
||||||
|
if (strcmp(driverHint,"x11")==0) {
|
||||||
|
void* libX11=dlopen("libX11.so",RTLD_LAZY|RTLD_LOCAL);
|
||||||
|
if (libX11==NULL) {
|
||||||
|
logW("could not load libX11.so (%s) - no scaling detection available!",dlerror());
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XOD ta_XOpenDisplay=(XOD)dlsym(libX11,"XOpenDisplay");
|
||||||
|
if (ta_XOpenDisplay==NULL) {
|
||||||
|
logW("XOpenDisplay not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XCD ta_XCloseDisplay=(XCD)dlsym(libX11,"XCloseDisplay");
|
||||||
|
if (ta_XCloseDisplay==NULL) {
|
||||||
|
logW("XCloseDisplay not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDS ta_XDefaultScreen=(XDS)dlsym(libX11,"XDefaultScreen");
|
||||||
|
if (ta_XDefaultScreen==NULL) {
|
||||||
|
logW("XDefaultScreen not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDW ta_XDisplayWidth=(XDW)dlsym(libX11,"XDisplayWidth");
|
||||||
|
if (ta_XDisplayWidth==NULL) {
|
||||||
|
logW("XDisplayWidth not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDW ta_XDisplayWidthMM=(XDW)dlsym(libX11,"XDisplayWidthMM");
|
||||||
|
if (ta_XDisplayWidthMM==NULL) {
|
||||||
|
logW("XDisplayWidthMM not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dl mess
|
||||||
|
void* disp=NULL;
|
||||||
|
int screen=0;
|
||||||
|
int dpi=96;
|
||||||
|
|
||||||
|
disp=ta_XOpenDisplay(NULL);
|
||||||
|
if (disp==NULL) {
|
||||||
|
logW("couldn't open X display - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen=ta_XDefaultScreen(disp);
|
||||||
|
|
||||||
|
dpi=(int)(0.5+(25.4*(double)ta_XDisplayWidth(disp,screen)/(double)ta_XDisplayWidthMM(disp,screen)));
|
||||||
|
|
||||||
|
ta_XCloseDisplay(disp);
|
||||||
|
|
||||||
|
ret=round(dpi/96.0);
|
||||||
|
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wayland
|
||||||
|
if (strcmp(driverHint,"wayland")==0) {
|
||||||
|
// give up (we handle scaling factor detection after window creation)
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// SDL fallback
|
||||||
|
float dpiScaleF=96.0f;
|
||||||
|
if (SDL_GetDisplayDPI(0,&dpiScaleF,NULL,NULL)==0) {
|
||||||
|
ret=round(dpiScaleF/96.0f);
|
||||||
|
if (ret<1) ret=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// couldn't detect scaling factor :<
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
double getScaleFactor(const char* driverHint);
|
|
@ -11,7 +11,7 @@ void FurnaceGUI::drawSubSongs() {
|
||||||
nextWindow=GUI_WINDOW_NOTHING;
|
nextWindow=GUI_WINDOW_NOTHING;
|
||||||
}
|
}
|
||||||
if (!subSongsOpen) return;
|
if (!subSongsOpen) return;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
if (ImGui::Begin("Subsongs",&subSongsOpen,globalWinFlags)) {
|
if (ImGui::Begin("Subsongs",&subSongsOpen,globalWinFlags)) {
|
||||||
char id[1024];
|
char id[1024];
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*2.0f-ImGui::GetStyle().ItemSpacing.x);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*2.0f-ImGui::GetStyle().ItemSpacing.x);
|
||||||
|
|
|
@ -28,7 +28,7 @@ void FurnaceGUI::drawVolMeter() {
|
||||||
}
|
}
|
||||||
if (!volMeterOpen) return;
|
if (!volMeterOpen) return;
|
||||||
if (--isClipping<0) isClipping=0;
|
if (--isClipping<0) isClipping=0;
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(6.0f*dpiScale,6.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(6.0f*dpiScale,6.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0,0));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0,0));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
||||||
|
|
|
@ -177,12 +177,12 @@ void FurnaceGUI::drawWaveEdit() {
|
||||||
if (!waveEditOpen) return;
|
if (!waveEditOpen) return;
|
||||||
float wavePreview[257];
|
float wavePreview[257];
|
||||||
if (mobileUI) {
|
if (mobileUI) {
|
||||||
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*scrH*dpiScale)):ImVec2((0.16*scrH*dpiScale)+0.5*scrW*dpiScale*mobileMenuPos,0.0f));
|
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*canvasH)):ImVec2((0.16*canvasH)+0.5*canvasW*mobileMenuPos,0.0f));
|
||||||
patWindowSize=(portrait?ImVec2(scrW*dpiScale,scrH*dpiScale-(0.16*scrW*dpiScale)-(pianoOpen?(0.4*scrW*dpiScale):0.0f)):ImVec2(scrW*dpiScale-(0.16*scrH*dpiScale),scrH*dpiScale-(pianoOpen?(0.3*scrH*dpiScale):0.0f)));
|
patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)-(pianoOpen?(0.4*canvasW):0.0f)):ImVec2(canvasW-(0.16*canvasH),canvasH-(pianoOpen?(0.3*canvasH):0.0f)));
|
||||||
ImGui::SetNextWindowPos(patWindowPos);
|
ImGui::SetNextWindowPos(patWindowPos);
|
||||||
ImGui::SetNextWindowSize(patWindowSize);
|
ImGui::SetNextWindowSize(patWindowSize);
|
||||||
} else {
|
} else {
|
||||||
ImGui::SetNextWindowSizeConstraints(ImVec2(300.0f*dpiScale,300.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
|
ImGui::SetNextWindowSizeConstraints(ImVec2(300.0f*dpiScale,300.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||||
}
|
}
|
||||||
if (ImGui::Begin("Wavetable Editor",&waveEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
if (ImGui::Begin("Wavetable Editor",&waveEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking))) {
|
||||||
if (curWave<0 || curWave>=(int)e->song.wave.size()) {
|
if (curWave<0 || curWave>=(int)e->song.wave.size()) {
|
||||||
|
|
|
@ -332,12 +332,6 @@ int main(int argc, char** argv) {
|
||||||
if (coResult!=S_OK) {
|
if (coResult!=S_OK) {
|
||||||
logE("CoInitializeEx failed!");
|
logE("CoInitializeEx failed!");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if !(defined(__APPLE__) || defined(_WIN32) || defined(ANDROID) || defined(__HAIKU__))
|
|
||||||
// workaround for Wayland HiDPI issue
|
|
||||||
if (getenv("SDL_VIDEODRIVER")==NULL) {
|
|
||||||
setenv("SDL_VIDEODRIVER","x11",1);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
outName="";
|
outName="";
|
||||||
vgmOutName="";
|
vgmOutName="";
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "utfutils.h"
|
#include "utfutils.h"
|
||||||
|
|
||||||
|
typedef HRESULT (*SPDA)(int);
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, PSTR args, int state) {
|
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, PSTR args, int state) {
|
||||||
int argc=0;
|
int argc=0;
|
||||||
wchar_t** argw=CommandLineToArgvW(GetCommandLineW(),&argc);
|
wchar_t** argw=CommandLineToArgvW(GetCommandLineW(),&argc);
|
||||||
|
@ -29,5 +31,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, PSTR args, int state) {
|
||||||
argv[i]=new char[str.size()+1];
|
argv[i]=new char[str.size()+1];
|
||||||
strcpy(argv[i],str.c_str());
|
strcpy(argv[i],str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set DPI awareness
|
||||||
|
HMODULE shcore=LoadLibraryW(L"shcore.dll");
|
||||||
|
if (shcore!=NULL) {
|
||||||
|
SPDA ta_SetProcessDpiAwareness=(SPDA)GetProcAddress(shcore,"SetProcessDpiAwareness");
|
||||||
|
if (ta_SetProcessDpiAwareness!=NULL) {
|
||||||
|
HRESULT result=ta_SetProcessDpiAwareness(2);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
// ???
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
// ???
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return main(argc,argv);
|
return main(argc,argv);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue