diff --git a/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java b/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java index 0ac1448fd..01b584202 100644 --- a/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java +++ b/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java @@ -1,25 +1,41 @@ package org.tildearrow.furnace; +import android.content.Context; import android.content.Intent; +import android.net.Uri; +import android.widget.Toast; import org.libsdl.app.SDLActivity; public class MainActivity extends SDLActivity { static final int TA_FILE_REQUEST=1000; + static final int TA_FILE_SAVE_REQUEST=1001; - public boolean showFileDialog() { + public void showFileDialog() { Intent picker=new Intent(Intent.ACTION_GET_CONTENT); picker.setType("*/*"); picker=Intent.createChooser(picker,"test"); startActivityForResult(picker,TA_FILE_REQUEST); + } - return true; + public void showSaveFileDialog() { + Intent picker=new Intent(Intent.ACTION_CREATE_DOCUMENT); + picker.addCategory(Intent.CATEGORY_OPENABLE); + picker.setType("*/*"); + + startActivityForResult(picker,TA_FILE_SAVE_REQUEST); } @Override protected void onActivityResult(int request, int result, Intent intent) { super.onActivityResult(request,result,intent); if (request==TA_FILE_REQUEST) { - // TODO: fire an event here + if (result==RESULT_OK) { + Uri path=intent.getData(); + + Context context=getApplicationContext(); + Toast toast=Toast.makeText(context,path.toString(),Toast.LENGTH_SHORT); + toast.show(); + } } } } diff --git a/demos/Midnight_Dog_Orchestra.fur b/demos/Midnight_Dog_Orchestra.fur new file mode 100644 index 000000000..caa705d48 Binary files /dev/null and b/demos/Midnight_Dog_Orchestra.fur differ diff --git a/demos/Swaggin_Dragon.dmf b/demos/Swaggin_Dragon.dmf new file mode 100644 index 000000000..20c358049 Binary files /dev/null and b/demos/Swaggin_Dragon.dmf differ diff --git a/demos/The_Good_Times_Arcade.fur b/demos/The_Good_Times_Arcade.fur new file mode 100644 index 000000000..f67b6d1d7 Binary files /dev/null and b/demos/The_Good_Times_Arcade.fur differ diff --git a/extern/igfd/ImGuiFileDialog.cpp b/extern/igfd/ImGuiFileDialog.cpp index 3a30ac2b5..36bd122b7 100644 --- a/extern/igfd/ImGuiFileDialog.cpp +++ b/extern/igfd/ImGuiFileDialog.cpp @@ -74,11 +74,14 @@ SOFTWARE. #define IMGUI_DEFINE_MATH_OPERATORS #endif // IMGUI_DEFINE_MATH_OPERATORS #include "imgui_internal.h" +#include #include #include #include +#define DOUBLE_CLICKED ((singleClickSel && ImGui::IsMouseReleased(0)) || (!singleClickSel && ImGui::IsMouseDoubleClicked(0))) + #ifdef USE_THUMBNAILS #ifndef DONT_DEFINE_AGAIN__STB_IMAGE_IMPLEMENTATION #ifndef STB_IMAGE_IMPLEMENTATION @@ -117,7 +120,7 @@ namespace IGFD #endif // IMGUI_BUTTON // locales #ifndef createDirButtonString -#define createDirButtonString "+" +#define createDirButtonString ICON_FA_PLUS #endif // createDirButtonString #ifndef okButtonString #define okButtonString "OK" @@ -126,13 +129,13 @@ namespace IGFD #define cancelButtonString "Cancel" #endif // cancelButtonString #ifndef resetButtonString -#define resetButtonString "R" +#define resetButtonString ICON_FA_REPEAT #endif // resetButtonString #ifndef drivesButtonString #define drivesButtonString "Drives" #endif // drivesButtonString #ifndef editPathButtonString -#define editPathButtonString "E" +#define editPathButtonString ICON_FA_PENCIL #endif // editPathButtonString #ifndef searchString #define searchString "Search" @@ -147,10 +150,10 @@ namespace IGFD #define fileEntryString "[File]" #endif // fileEntryString #ifndef fileNameString -#define fileNameString "File Name:" +#define fileNameString "Name:" #endif // fileNameString #ifndef dirNameString -#define dirNameString "Directory Path:" +#define dirNameString "Path:" #endif // dirNameString #ifndef buttonResetSearchString #define buttonResetSearchString "Reset search" @@ -3319,7 +3322,7 @@ namespace IGFD //// FILE DIALOG CONSTRUCTOR / DESTRUCTOR /////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// - IGFD::FileDialog::FileDialog() : BookMarkFeature(), KeyExplorerFeature(), ThumbnailFeature() {DpiScale=1.0f;} + IGFD::FileDialog::FileDialog() : BookMarkFeature(), KeyExplorerFeature(), ThumbnailFeature() {DpiScale=1.0f; singleClickSel=false; mobileMode=false;} IGFD::FileDialog::~FileDialog() = default; ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3936,7 +3939,7 @@ namespace IGFD vsnprintf(fdi.puVariadicBuffer, MAX_FILE_DIALOG_NAME_BUFFER, vFmt, args); va_end(args); - float h = 0.0f; + float h = /*mobileMode?(ImGui::GetFontSize()+10.0f*DpiScale):*/0.0f; #ifdef USE_THUMBNAILS if (prDisplayMode == DisplayModeEnum::THUMBNAILS_LIST) h = DisplayMode_ThumbailsList_ImageHeight; @@ -3972,7 +3975,7 @@ namespace IGFD } else // no nav system => classic behavior { - if (ImGui::IsMouseDoubleClicked(0)) // 0 -> left mouse button double click + if (DOUBLE_CLICKED) // 0 -> left mouse button double click { isSelectingDir=true; fdi.puPathClicked = fdi.SelectDirectory(vInfos); @@ -3987,7 +3990,7 @@ namespace IGFD } else { - if (ImGui::IsMouseDoubleClicked(0)) { + if (DOUBLE_CLICKED) { fdi.SelectFileName(prFileDialogInternal, vInfos); prFileDialogInternal.puIsOk = true; return 2; diff --git a/extern/igfd/ImGuiFileDialog.h b/extern/igfd/ImGuiFileDialog.h index e5ba92d0c..2725223f5 100644 --- a/extern/igfd/ImGuiFileDialog.h +++ b/extern/igfd/ImGuiFileDialog.h @@ -1142,6 +1142,8 @@ namespace IGFD public: bool puAnyWindowsHovered = false; // not remember why haha :) todo : to check if we can remove double DpiScale; + bool singleClickSel; + bool mobileMode; public: static FileDialog* Instance() // Singleton for easier accces form anywhere but only one dialog at a time diff --git a/extern/imgui_patched/imgui.cpp b/extern/imgui_patched/imgui.cpp index d52945d4e..3539ca810 100644 --- a/extern/imgui_patched/imgui.cpp +++ b/extern/imgui_patched/imgui.cpp @@ -1178,6 +1178,9 @@ ImGuiIO::ImGuiIO() ConfigViewportsNoDecoration = true; ConfigViewportsNoDefaultParent = false; + // Inertial scrolling options (when ImGuiConfigFlags_InertialScrollEnable is set) + ConfigInertialScrollToleranceSqr = 36.0f; + // Miscellaneous options MouseDrawCursor = false; #ifdef __APPLE__ @@ -3313,6 +3316,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst TabId = GetID("#TAB"); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); + InertialScrollSpeed = ImVec2(0.0f, 0.0f); AutoFitFramesX = AutoFitFramesY = -1; AutoPosLastDirection = ImGuiDir_None; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; @@ -3443,6 +3447,10 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { g.ActiveIdIsAlive = id; g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustMovedToId == id) ? (ImGuiInputSource)ImGuiInputSource_Nav : ImGuiInputSource_Mouse; + // TODO: check whether this works + if (g.LastItemData.InFlags & ImGuiItemFlags_NoInertialScroll) { + g.InertialScrollInhibited=true; + } } // Clear declaration of inputs claimed by the widget @@ -3536,6 +3544,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) return false; if (!IsItemFocused()) return false; + if (window->InertialScroll) + return false; } else { @@ -3568,6 +3578,10 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) // Test if the item is disabled if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) return false; + + // Test for inertial scroll + if (window->InertialScroll) + return false; // Special handling for calling after Begin() which represent the title bar or tab. // When the window is skipped/collapsed (SkipItems==true) that last item (always ->MoveId submitted by Begin) @@ -3605,8 +3619,9 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) SetHoveredID(id); // When disabled we'll return false but still set HoveredId + // Same thing if swiping ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags); - if (item_flags & ImGuiItemFlags_Disabled) + if (item_flags & ImGuiItemFlags_Disabled || window->InertialScroll) { // Release active id if turning disabled if (g.ActiveId == id) @@ -4155,6 +4170,8 @@ static void ImGui::UpdateMouseInputs() // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) if (IsMousePosValid(&io.MousePos)) io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos); + + io.MouseDeltaPrev=io.MouseDelta; // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev)) @@ -4166,6 +4183,18 @@ static void ImGui::UpdateMouseInputs() if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) g.NavDisableMouseHover = false; + // Update mouse speed + if (ImFabs(io.MouseDelta.x)>ImFabs(io.MouseDeltaPrev.x)) { + io.MouseSpeed.x=io.MouseDelta.x; + } else { + io.MouseSpeed.x=io.MouseDeltaPrev.x; + } + if (ImFabs(io.MouseDelta.y)>ImFabs(io.MouseDeltaPrev.y)) { + io.MouseSpeed.y=io.MouseDelta.y; + } else { + io.MouseSpeed.y=io.MouseDeltaPrev.y; + } + io.MousePosPrev = io.MousePos; for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) { @@ -4435,6 +4464,7 @@ void ImGui::NewFrame() g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); g.FramerateSecPerFrameCount = ImMin(g.FramerateSecPerFrameCount + 1, IM_ARRAYSIZE(g.FramerateSecPerFrame)); g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)g.FramerateSecPerFrameCount)) : FLT_MAX; + g.IO.IsSomethingHappening = false; UpdateViewportsNewFrame(); @@ -5069,6 +5099,11 @@ void ImGui::EndFrame() g.DragDropWithinSource = false; } + // Check for inertial scroll inhibit status + if (!g.IO.MouseDown[ImGuiMouseButton_Left]) { + g.InertialScrollInhibited=false; + } + // End frame g.WithinFrameScope = false; g.FrameCountEnded = g.FrameCount; @@ -6893,6 +6928,74 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->ScrollMax.x = ImMax(0.0f, window->ContentSize.x + window->WindowPadding.x * 2.0f - window->InnerRect.GetWidth()); window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight()); + // Inertial scroll + if (g.IO.ConfigFlags & ImGuiConfigFlags_InertialScrollEnable) { + if ((g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow) == window) { + if ((g.IO.MouseDown[ImGuiMouseButton_Left] || g.IO.MouseReleased[ImGuiMouseButton_Left]) && + g.ActiveId!=GetWindowScrollbarID(window,ImGuiAxis_X) && + g.ActiveId!=GetWindowScrollbarID(window,ImGuiAxis_Y) && + !g.InertialScrollInhibited) { + // launch inertial scroll + if (g.IO.MouseClicked[ImGuiMouseButton_Left]) { + window->InertialScrollSpeed=ImVec2(0.0f,0.0f); + window->InertialScroll=false; + g.InertialScroll=false; + g.WasInertialScroll=false; + } else { + if (g.IO.MouseDragMaxDistanceSqr[ImGuiMouseButton_Left]>g.IO.ConfigInertialScrollToleranceSqr) { + if (g.IO.MouseReleased[ImGuiMouseButton_Left]) { + window->InertialScrollSpeed=ImVec2(window->ScrollbarX?-g.IO.MouseSpeed.x:0.0f,window->ScrollbarY?-g.IO.MouseSpeed.y:0.0f); + window->InertialScroll=false; + g.InertialScroll=false; + } else { + window->InertialScrollSpeed=ImVec2(window->ScrollbarX?-g.IO.MouseDelta.x:0.0f,window->ScrollbarY?-g.IO.MouseDelta.y:0.0f); + if (window->ScrollbarX || window->ScrollbarY) { + window->InertialScroll=true; + g.InertialScroll=true; + g.WasInertialScroll=true; + } + } + } else { + window->InertialScrollSpeed=ImVec2(0.0f,0.0f); + window->InertialScroll=false; + g.InertialScroll=false; + } + } + } else if (g.InertialScrollInhibited) { + window->InertialScrollSpeed=ImVec2(0.0f,0.0f); + window->InertialScroll=false; + g.InertialScroll=false; + } + } + + if (window->ScrollTarget.x == FLT_MAX && window->ScrollTarget.y == FLT_MAX) { + if (fabs(window->InertialScrollSpeed.x)>0.1f) { + window->Scroll.x=window->Scroll.x+window->InertialScrollSpeed.x; + window->InertialScrollSpeed.x*=0.95f; + g.IO.IsSomethingHappening = true; + } else { + window->InertialScrollSpeed.x=0.0f; + } + if (fabs(window->InertialScrollSpeed.y)>0.1f) { + window->Scroll.y=window->Scroll.y+window->InertialScrollSpeed.y; + window->InertialScrollSpeed.y*=0.95f; + g.IO.IsSomethingHappening = true; + } else { + window->InertialScrollSpeed.y=0.0f; + } + } else { + window->InertialScrollSpeed.x=0.0f; + window->InertialScrollSpeed.y=0.0f; + window->InertialScroll=false; + g.InertialScroll=false; + } + + if (g.IO.MouseDown[ImGuiMouseButton_Left]) { + window->InertialScrollSpeed.x=0.0f; + window->InertialScrollSpeed.y=0.0f; + } + } + // Apply scrolling window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); @@ -7455,6 +7558,35 @@ void ImGui::EndDisabled() g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); } +// IsInertialScroll() + +bool ImGui::IsInertialScroll() +{ + /* + ImGuiWindow* window = GetCurrentWindow(); + if (window==NULL) return false; + return window->InertialScroll; + */ + ImGuiContext& g = *GImGui; + return g.InertialScroll; +} + +// WasInertialScroll() + +bool ImGui::WasInertialScroll() +{ + ImGuiContext& g = *GImGui; + return g.WasInertialScroll; +} + +// InhibitInertialScroll() + +void ImGui::InhibitInertialScroll() +{ + ImGuiContext& g = *GImGui; + g.InertialScrollInhibited=true; +} + // FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system. void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) { @@ -18612,8 +18744,9 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label) (flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : ""); BulletText("WindowClassId: 0x%08X", window->WindowClass.ClassId); BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f) Scrollbar:%s%s", window->Scroll.x, window->ScrollMax.x, window->Scroll.y, window->ScrollMax.y, window->ScrollbarX ? "X" : "", window->ScrollbarY ? "Y" : ""); + BulletText("InertialScrollSpeed: %.2f,%.2f",window->InertialScrollSpeed.x,window->InertialScrollSpeed.y); BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1); - BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems); + BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d, InertialScroll: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems, window->InertialScroll); for (int layer = 0; layer < ImGuiNavLayer_COUNT; layer++) { ImRect r = window->NavRectRel[layer]; diff --git a/extern/imgui_patched/imgui.h b/extern/imgui_patched/imgui.h index 3d600ea2b..131784f8f 100644 --- a/extern/imgui_patched/imgui.h +++ b/extern/imgui_patched/imgui.h @@ -838,6 +838,11 @@ namespace ImGui IMGUI_API void BeginDisabled(bool disabled = true); IMGUI_API void EndDisabled(); + // Inertial scroll + IMGUI_API bool IsInertialScroll(); + IMGUI_API bool WasInertialScroll(); + IMGUI_API void InhibitInertialScroll(); + // Clipping // - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only. IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); @@ -1573,6 +1578,10 @@ enum ImGuiConfigFlags_ // [BETA] Docking ImGuiConfigFlags_DockingEnable = 1 << 6, // Docking enable flags. + // [CUSTOM] Inertial scroll + ImGuiConfigFlags_InertialScrollEnable = 1 << 7, // Docking enable flags. + ImGuiConfigFlags_NoHoverColors = 1 << 8, // Disable all "hovered" color changes (useful for mobile). + // [BETA] Viewports // When using viewports it is recommended that your default value for ImGuiCol_WindowBg is opaque (Alpha=1.0) so transition to a viewport won't be noticeable. ImGuiConfigFlags_ViewportsEnable = 1 << 10, // Viewport enable flags (require both ImGuiBackendFlags_PlatformHasViewports + ImGuiBackendFlags_RendererHasViewports set by the respective backends) @@ -2019,6 +2028,9 @@ struct ImGuiIO bool ConfigViewportsNoDecoration; // = true // Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size). bool ConfigViewportsNoDefaultParent; // = false // Disable default OS parenting to main viewport for secondary viewports. By default, viewports are marked with ParentViewportId = , expecting the platform backend to setup a parent/child relationship between the OS windows (some backend may ignore this). Set to true if you want the default to be 0, then all viewports will be top-level OS windows. + // Inertial scrolling options (when ImGuiConfigFlags_InertialScrollEnable is set) + float ConfigInertialScrollToleranceSqr;// = 36.0f // After a point moves past this distance, inertial scroll begins + // Miscellaneous options bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. @@ -2087,6 +2099,7 @@ struct ImGuiIO bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! + bool IsSomethingHappening; // This is set to true when inertial scrolling is happening. bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). float Framerate; // Rough estimate of application framerate, in frame per second. Solely for convenience. Rolling average estimation based on io.DeltaTime over 120 frames. @@ -2096,6 +2109,8 @@ struct ImGuiIO int MetricsActiveWindows; // Number of active windows int MetricsActiveAllocations; // Number of active allocations, updated by MemAlloc/MemFree based on current context. May be off if you have multiple imgui contexts. ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. + ImVec2 MouseDeltaPrev; // Previous mouse delta. + ImVec2 MouseSpeed; // Average mouse speed in a short timeframe. Used for inertial scroll. // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). diff --git a/extern/imgui_patched/imgui_internal.h b/extern/imgui_patched/imgui_internal.h index d72703734..c2e157645 100644 --- a/extern/imgui_patched/imgui_internal.h +++ b/extern/imgui_patched/imgui_internal.h @@ -815,7 +815,8 @@ enum ImGuiItemFlags_ ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. - ImGuiItemFlags_Inputable = 1 << 8 // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. + ImGuiItemFlags_Inputable = 1 << 8, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. + ImGuiItemFlags_NoInertialScroll = 1 << 9 // false // Disable inertial scroll when activated }; // Storage for LastItem data @@ -1935,6 +1936,11 @@ struct ImGuiContext float NavWindowingHighlightAlpha; bool NavWindowingToggleLayer; + // Inertial scroll + bool InertialScrollInhibited; // Is inertial scroll inhibited? (e.g. by ImGuiItemFlags_NoInertialScroll) + bool InertialScroll; // Is any window being scrolled? + bool WasInertialScroll; // Was ^? + // Render float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) ImGuiMouseCursor MouseCursor; @@ -2144,6 +2150,8 @@ struct ImGuiContext NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingToggleLayer = false; + InertialScrollInhibited = false; + DimBgRatio = 0.0f; MouseCursor = ImGuiMouseCursor_Arrow; @@ -2293,6 +2301,7 @@ struct IMGUI_API ImGuiWindow ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar. + ImVec2 InertialScrollSpeed; // current speed of inertial scroll (AKA "swipe") bool ScrollbarX, ScrollbarY; // Are scrollbars visible? bool ViewportOwned; bool Active; // Set to true on Begin(), unless Collapsed @@ -2306,6 +2315,7 @@ struct IMGUI_API ImGuiWindow bool IsFallbackWindow; // Set on the "Debug##Default" window. bool IsExplicitChild; // Set when passed _ChildWindow, left to false by BeginDocked() bool HasCloseButton; // Set when the window has a close button (p_open != NULL) + bool InertialScroll; // Set when inertial scrolling is active signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. diff --git a/extern/imgui_patched/imgui_widgets.cpp b/extern/imgui_patched/imgui_widgets.cpp index 4579400d4..737c6e093 100644 --- a/extern/imgui_patched/imgui_widgets.cpp +++ b/extern/imgui_patched/imgui_widgets.cpp @@ -998,7 +998,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // Render const ImU32 bg_col = GetColorU32(ImGuiCol_ScrollbarBg); - const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha); + const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : (hovered && !(g.IO.ConfigFlags&ImGuiConfigFlags_NoHoverColors)) ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha); window->DrawList->AddRectFilled(bb_frame.Min, bb_frame.Max, bg_col, window->WindowRounding, flags); ImRect grab_rect; if (axis == ImGuiAxis_X) @@ -2949,7 +2949,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0; ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0)) + if (!ItemAdd(total_bb, id, &frame_bb, (temp_input_allowed ? ImGuiItemFlags_Inputable : 0) | ImGuiItemFlags_NoInertialScroll)) return false; // Default format string when passing NULL @@ -3113,7 +3113,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(frame_bb, id)) + if (!ItemAdd(frame_bb, id, NULL, ImGuiItemFlags_NoInertialScroll)) return false; // Default format string when passing NULL @@ -6329,9 +6329,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // Render if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld)) hovered = true; - if (hovered || selected) + if ((hovered && !(g.IO.ConfigFlags&ImGuiConfigFlags_NoHoverColors)) || selected) { - const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : (hovered && !(g.IO.ConfigFlags&ImGuiConfigFlags_NoHoverColors)) ? ImGuiCol_HeaderHovered : ImGuiCol_Header); RenderFrame(bb.Min, bb.Max, col, false, 0.0f); } RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); diff --git a/instruments/FM/uhrwerk/B Series/b00.dmp b/instruments/FM/uhrwerk/B Series/b00.dmp new file mode 100644 index 000000000..0106bc0be Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b00.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b00a.dmp b/instruments/FM/uhrwerk/B Series/b00a.dmp new file mode 100644 index 000000000..d41a11dd5 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b00a.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b00b.dmp b/instruments/FM/uhrwerk/B Series/b00b.dmp new file mode 100644 index 000000000..d41a11dd5 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b00b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b01.dmp b/instruments/FM/uhrwerk/B Series/b01.dmp new file mode 100644 index 000000000..a5a1aefbf Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b01.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b01b.dmp b/instruments/FM/uhrwerk/B Series/b01b.dmp new file mode 100644 index 000000000..131a5dadb Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b01b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b02.dmp b/instruments/FM/uhrwerk/B Series/b02.dmp new file mode 100644 index 000000000..1fa9517cf Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b02.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b02b.dmp b/instruments/FM/uhrwerk/B Series/b02b.dmp new file mode 100644 index 000000000..13cf1abfc Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b02b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b02c MUTE.dmp b/instruments/FM/uhrwerk/B Series/b02c MUTE.dmp new file mode 100644 index 000000000..93c54d459 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b02c MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b02c.dmp b/instruments/FM/uhrwerk/B Series/b02c.dmp new file mode 100644 index 000000000..97febb87e Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b02c.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b03.dmp b/instruments/FM/uhrwerk/B Series/b03.dmp new file mode 100644 index 000000000..bb666c812 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b03.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b04.dmp b/instruments/FM/uhrwerk/B Series/b04.dmp new file mode 100644 index 000000000..441d1d71b Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b04.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b05.dmp b/instruments/FM/uhrwerk/B Series/b05.dmp new file mode 100644 index 000000000..c9c25d1f0 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b05.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b06.dmp b/instruments/FM/uhrwerk/B Series/b06.dmp new file mode 100644 index 000000000..a6e8400f7 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b06.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b07.dmp b/instruments/FM/uhrwerk/B Series/b07.dmp new file mode 100644 index 000000000..a3614deec Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b07.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b08.dmp b/instruments/FM/uhrwerk/B Series/b08.dmp new file mode 100644 index 000000000..e8e80559d Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b08.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b08b.dmp b/instruments/FM/uhrwerk/B Series/b08b.dmp new file mode 100644 index 000000000..5e7d1f29d Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b08b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b08c.dmp b/instruments/FM/uhrwerk/B Series/b08c.dmp new file mode 100644 index 000000000..a4fc3fd47 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b08c.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b09.dmp b/instruments/FM/uhrwerk/B Series/b09.dmp new file mode 100644 index 000000000..3fe896694 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b09.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b10.dmp b/instruments/FM/uhrwerk/B Series/b10.dmp new file mode 100644 index 000000000..b33394c2b Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b10.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b10b.dmp b/instruments/FM/uhrwerk/B Series/b10b.dmp new file mode 100644 index 000000000..64a108a45 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b10b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b11.dmp b/instruments/FM/uhrwerk/B Series/b11.dmp new file mode 100644 index 000000000..59de7f61d Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b11.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b12.dmp b/instruments/FM/uhrwerk/B Series/b12.dmp new file mode 100644 index 000000000..7c9704d79 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b12.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b13.dmp b/instruments/FM/uhrwerk/B Series/b13.dmp new file mode 100644 index 000000000..12be33a7f Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b13.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b14.dmp b/instruments/FM/uhrwerk/B Series/b14.dmp new file mode 100644 index 000000000..5bf58d03d Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b14.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b15.dmp b/instruments/FM/uhrwerk/B Series/b15.dmp new file mode 100644 index 000000000..78d6748a0 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b15.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b16.dmp b/instruments/FM/uhrwerk/B Series/b16.dmp new file mode 100644 index 000000000..cfd1fdd25 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b16.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b17.dmp b/instruments/FM/uhrwerk/B Series/b17.dmp new file mode 100644 index 000000000..532f1edf3 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b17.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b17b MUTE.dmp b/instruments/FM/uhrwerk/B Series/b17b MUTE.dmp new file mode 100644 index 000000000..0049b93bf Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b17b MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b17b SLAP (actual).dmp b/instruments/FM/uhrwerk/B Series/b17b SLAP (actual).dmp new file mode 100644 index 000000000..552c78737 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b17b SLAP (actual).dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b17b SLAP.dmp b/instruments/FM/uhrwerk/B Series/b17b SLAP.dmp new file mode 100644 index 000000000..0049b93bf Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b17b SLAP.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b17b.dmp b/instruments/FM/uhrwerk/B Series/b17b.dmp new file mode 100644 index 000000000..90ed59fca Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b17b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b18 MUTE.dmp b/instruments/FM/uhrwerk/B Series/b18 MUTE.dmp new file mode 100644 index 000000000..bf7c813db Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b18 MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b18 SLAP.dmp b/instruments/FM/uhrwerk/B Series/b18 SLAP.dmp new file mode 100644 index 000000000..b2a27f207 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b18 SLAP.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b18.dmp b/instruments/FM/uhrwerk/B Series/b18.dmp new file mode 100644 index 000000000..5a1061f6d Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b18.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b19 MUTE.dmp b/instruments/FM/uhrwerk/B Series/b19 MUTE.dmp new file mode 100644 index 000000000..d3f0f6702 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b19 MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b19 SLAP.dmp b/instruments/FM/uhrwerk/B Series/b19 SLAP.dmp new file mode 100644 index 000000000..abb3d8c5e Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b19 SLAP.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b19.dmp b/instruments/FM/uhrwerk/B Series/b19.dmp new file mode 100644 index 000000000..c0fb751ee Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b19.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b20.dmp b/instruments/FM/uhrwerk/B Series/b20.dmp new file mode 100644 index 000000000..78320e5db Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b20.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b21.dmp b/instruments/FM/uhrwerk/B Series/b21.dmp new file mode 100644 index 000000000..95578bbe6 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b21.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b21b.dmp b/instruments/FM/uhrwerk/B Series/b21b.dmp new file mode 100644 index 000000000..82e752d1c Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b21b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b21c.dmp b/instruments/FM/uhrwerk/B Series/b21c.dmp new file mode 100644 index 000000000..0a4186a62 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b21c.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22 MUTE.dmp b/instruments/FM/uhrwerk/B Series/b22 MUTE.dmp new file mode 100644 index 000000000..2257557f7 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22 MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22 SLAP.dmp b/instruments/FM/uhrwerk/B Series/b22 SLAP.dmp new file mode 100644 index 000000000..e277559c6 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22 SLAP.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22.dmp b/instruments/FM/uhrwerk/B Series/b22.dmp new file mode 100644 index 000000000..7f16bd2a6 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22b.dmp b/instruments/FM/uhrwerk/B Series/b22b.dmp new file mode 100644 index 000000000..3c469bae7 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22b.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22c MUTE.dmp b/instruments/FM/uhrwerk/B Series/b22c MUTE.dmp new file mode 100644 index 000000000..1814402d2 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22c MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22c SLAP.dmp b/instruments/FM/uhrwerk/B Series/b22c SLAP.dmp new file mode 100644 index 000000000..aec6f5fc2 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22c SLAP.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b22c.dmp b/instruments/FM/uhrwerk/B Series/b22c.dmp new file mode 100644 index 000000000..e7358f05a Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b22c.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b23 MUTE.dmp b/instruments/FM/uhrwerk/B Series/b23 MUTE.dmp new file mode 100644 index 000000000..154e19085 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b23 MUTE.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b23 SLAP.dmp b/instruments/FM/uhrwerk/B Series/b23 SLAP.dmp new file mode 100644 index 000000000..9d1d562b9 Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b23 SLAP.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b23.dmp b/instruments/FM/uhrwerk/B Series/b23.dmp new file mode 100644 index 000000000..d8c212b5b Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b23.dmp differ diff --git a/instruments/FM/uhrwerk/B Series/b69.dmp b/instruments/FM/uhrwerk/B Series/b69.dmp new file mode 100644 index 000000000..f924e4f2c Binary files /dev/null and b/instruments/FM/uhrwerk/B Series/b69.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p01.dmp b/instruments/FM/uhrwerk/P Series/p01.dmp new file mode 100644 index 000000000..7770128ee Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p01.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p01b.dmp b/instruments/FM/uhrwerk/P Series/p01b.dmp new file mode 100644 index 000000000..52cecdbed Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p01b.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p02.dmp b/instruments/FM/uhrwerk/P Series/p02.dmp new file mode 100644 index 000000000..928e0a37d Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p02.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p02b.dmp b/instruments/FM/uhrwerk/P Series/p02b.dmp new file mode 100644 index 000000000..5056a3286 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p02b.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p03.dmp b/instruments/FM/uhrwerk/P Series/p03.dmp new file mode 100644 index 000000000..8ff7d73c0 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p03.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p03b.dmp b/instruments/FM/uhrwerk/P Series/p03b.dmp new file mode 100644 index 000000000..1b4ba0574 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p03b.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p04.dmp b/instruments/FM/uhrwerk/P Series/p04.dmp new file mode 100644 index 000000000..637ce8e61 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p04.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p05.dmp b/instruments/FM/uhrwerk/P Series/p05.dmp new file mode 100644 index 000000000..997ae297c Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p05.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p06.dmp b/instruments/FM/uhrwerk/P Series/p06.dmp new file mode 100644 index 000000000..c7445a98f Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p06.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p06b.dmp b/instruments/FM/uhrwerk/P Series/p06b.dmp new file mode 100644 index 000000000..2f5891188 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p06b.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p06c.dmp b/instruments/FM/uhrwerk/P Series/p06c.dmp new file mode 100644 index 000000000..2f5891188 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p06c.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p07.dmp b/instruments/FM/uhrwerk/P Series/p07.dmp new file mode 100644 index 000000000..4e44e7149 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p07.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p08.dmp b/instruments/FM/uhrwerk/P Series/p08.dmp new file mode 100644 index 000000000..e118fb5bb Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p08.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p09.dmp b/instruments/FM/uhrwerk/P Series/p09.dmp new file mode 100644 index 000000000..5f2d7739e Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p09.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p10.dmp b/instruments/FM/uhrwerk/P Series/p10.dmp new file mode 100644 index 000000000..f3e63e442 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p10.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p10b.dmp b/instruments/FM/uhrwerk/P Series/p10b.dmp new file mode 100644 index 000000000..f69b3d7d2 Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p10b.dmp differ diff --git a/instruments/FM/uhrwerk/P Series/p11.dmp b/instruments/FM/uhrwerk/P Series/p11.dmp new file mode 100644 index 000000000..ae7d1800f Binary files /dev/null and b/instruments/FM/uhrwerk/P Series/p11.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/act 1 void of space.dmp b/instruments/FM/uhrwerk/R Series/act 1 void of space.dmp new file mode 100644 index 000000000..2fabf33d7 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/act 1 void of space.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r10.dmp b/instruments/FM/uhrwerk/R Series/r10.dmp new file mode 100644 index 000000000..060dcdaa9 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r10.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r10b.dmp b/instruments/FM/uhrwerk/R Series/r10b.dmp new file mode 100644 index 000000000..6ceeb7651 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r10b.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r11.dmp b/instruments/FM/uhrwerk/R Series/r11.dmp new file mode 100644 index 000000000..bae9dd4e7 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r11.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r12.dmp b/instruments/FM/uhrwerk/R Series/r12.dmp new file mode 100644 index 000000000..27bf989cf Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r12.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r13.dmp b/instruments/FM/uhrwerk/R Series/r13.dmp new file mode 100644 index 000000000..1e721b7c7 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r13.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r14.dmp b/instruments/FM/uhrwerk/R Series/r14.dmp new file mode 100644 index 000000000..3e290e916 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r14.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r15.dmp b/instruments/FM/uhrwerk/R Series/r15.dmp new file mode 100644 index 000000000..fd9623d94 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r15.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r16.dmp b/instruments/FM/uhrwerk/R Series/r16.dmp new file mode 100644 index 000000000..69414bd80 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r16.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r2.dmp b/instruments/FM/uhrwerk/R Series/r2.dmp new file mode 100644 index 000000000..a1fa7c6f0 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r2.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r27.dmp b/instruments/FM/uhrwerk/R Series/r27.dmp new file mode 100644 index 000000000..3f2c23bda Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r27.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r3.dmp b/instruments/FM/uhrwerk/R Series/r3.dmp new file mode 100644 index 000000000..6f88b4746 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r3.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r33.dmp b/instruments/FM/uhrwerk/R Series/r33.dmp new file mode 100644 index 000000000..603919413 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r33.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r4.dmp b/instruments/FM/uhrwerk/R Series/r4.dmp new file mode 100644 index 000000000..40be7198d Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r4.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r5.dmp b/instruments/FM/uhrwerk/R Series/r5.dmp new file mode 100644 index 000000000..28359737b Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r5.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r65.dmp b/instruments/FM/uhrwerk/R Series/r65.dmp new file mode 100644 index 000000000..cebea996e Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r65.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r6b.dmp b/instruments/FM/uhrwerk/R Series/r6b.dmp new file mode 100644 index 000000000..d444dfef4 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r6b.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r7.dmp b/instruments/FM/uhrwerk/R Series/r7.dmp new file mode 100644 index 000000000..9961282ab Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r7.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r7b.dmp b/instruments/FM/uhrwerk/R Series/r7b.dmp new file mode 100644 index 000000000..29ba00354 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r7b.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r7c.dmp b/instruments/FM/uhrwerk/R Series/r7c.dmp new file mode 100644 index 000000000..4f76903d8 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r7c.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r8.dmp b/instruments/FM/uhrwerk/R Series/r8.dmp new file mode 100644 index 000000000..b1d6b3906 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r8.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r8b.dmp b/instruments/FM/uhrwerk/R Series/r8b.dmp new file mode 100644 index 000000000..518f96ca4 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r8b.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r8c.dmp b/instruments/FM/uhrwerk/R Series/r8c.dmp new file mode 100644 index 000000000..451de941d Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r8c.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r9.dmp b/instruments/FM/uhrwerk/R Series/r9.dmp new file mode 100644 index 000000000..67d38c7f6 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r9.dmp differ diff --git a/instruments/FM/uhrwerk/R Series/r9b.dmp b/instruments/FM/uhrwerk/R Series/r9b.dmp new file mode 100644 index 000000000..bf0b69392 Binary files /dev/null and b/instruments/FM/uhrwerk/R Series/r9b.dmp differ diff --git a/instruments/FM/uhrwerk/README.txt b/instruments/FM/uhrwerk/README.txt new file mode 100644 index 000000000..c55093813 --- /dev/null +++ b/instruments/FM/uhrwerk/README.txt @@ -0,0 +1,23 @@ +Here you will find my patches that are within a series. These are mostly all custom made, very few are actually modified patches. It all started with the R series, which was basically me fucking around with the operators and making what I thought was cool synth sounds. From there, I slowly got better at making sounds. As I make more _ Series categories, I will be redistributing a lot of other series patches into the new categories and removing them from the old categories. This way my patches are more organised. This README will also be updated constantly. + +Enjoy! +-Uhrwerk + + +--THE SERIES-- + +R Series: Mostly synths, but some can be used as bass patches. + +Z Series: More refined synths, some xylophone and marimbas, mostly softer synths. + +B Series: Bass patches, a mix between slap bass, acoustic upright, synth, and plucked guitar. + +--COMING SOON-- + +P Series: Soft pad synths. Lots and lots of soft pad synths. (COMING SOON) + +R2 Series: Hard unison leads. (COMING SOON) + +X Series: Xylophones, bells, marimbas, chimes, basically almost any mallet instrument. (COMING SOON) + +T Series: Trumpets and other brass instruments (COMING SOON) \ No newline at end of file diff --git a/instruments/FM/uhrwerk/Z Series/z00.dmp b/instruments/FM/uhrwerk/Z Series/z00.dmp new file mode 100644 index 000000000..adafcee6c Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z00.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z01.dmp b/instruments/FM/uhrwerk/Z Series/z01.dmp new file mode 100644 index 000000000..e488963e8 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z01.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z02.dmp b/instruments/FM/uhrwerk/Z Series/z02.dmp new file mode 100644 index 000000000..547da27ae Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z02.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z02b.dmp b/instruments/FM/uhrwerk/Z Series/z02b.dmp new file mode 100644 index 000000000..8d657deb8 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z02b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z02c.dmp b/instruments/FM/uhrwerk/Z Series/z02c.dmp new file mode 100644 index 000000000..448805c0b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z02c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z03.dmp b/instruments/FM/uhrwerk/Z Series/z03.dmp new file mode 100644 index 000000000..17407ec14 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z03.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z04.dmp b/instruments/FM/uhrwerk/Z Series/z04.dmp new file mode 100644 index 000000000..52c9b607b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z04.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z04b.dmp b/instruments/FM/uhrwerk/Z Series/z04b.dmp new file mode 100644 index 000000000..e534cff99 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z04b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z04c.dmp b/instruments/FM/uhrwerk/Z Series/z04c.dmp new file mode 100644 index 000000000..061304957 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z04c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z05.dmp b/instruments/FM/uhrwerk/Z Series/z05.dmp new file mode 100644 index 000000000..5ee5b2d3f Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z05.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z05b.dmp b/instruments/FM/uhrwerk/Z Series/z05b.dmp new file mode 100644 index 000000000..ea9cbe36a Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z05b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z05c.dmp b/instruments/FM/uhrwerk/Z Series/z05c.dmp new file mode 100644 index 000000000..d3a61d1a3 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z05c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z05d.dmp b/instruments/FM/uhrwerk/Z Series/z05d.dmp new file mode 100644 index 000000000..4aa62ca1d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z05d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z06.dmp b/instruments/FM/uhrwerk/Z Series/z06.dmp new file mode 100644 index 000000000..7a37e0c25 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z06.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z06b.dmp b/instruments/FM/uhrwerk/Z Series/z06b.dmp new file mode 100644 index 000000000..cf3dfc927 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z06b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z07.dmp b/instruments/FM/uhrwerk/Z Series/z07.dmp new file mode 100644 index 000000000..642badb0e Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z07.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z08.dmp b/instruments/FM/uhrwerk/Z Series/z08.dmp new file mode 100644 index 000000000..545afaf1a Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z08.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z09.dmp b/instruments/FM/uhrwerk/Z Series/z09.dmp new file mode 100644 index 000000000..a7a29f0bb Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z09.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z10.dmp b/instruments/FM/uhrwerk/Z Series/z10.dmp new file mode 100644 index 000000000..214abfb3d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z10.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z10b.dmp b/instruments/FM/uhrwerk/Z Series/z10b.dmp new file mode 100644 index 000000000..11c449862 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z10b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z10c.dmp b/instruments/FM/uhrwerk/Z Series/z10c.dmp new file mode 100644 index 000000000..d70de1c8d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z10c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z10d.dmp b/instruments/FM/uhrwerk/Z Series/z10d.dmp new file mode 100644 index 000000000..8aa0673dc Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z10d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z10e.dmp b/instruments/FM/uhrwerk/Z Series/z10e.dmp new file mode 100644 index 000000000..b458397a1 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z10e.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z11.dmp b/instruments/FM/uhrwerk/Z Series/z11.dmp new file mode 100644 index 000000000..5994dc105 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z11.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z11b.dmp b/instruments/FM/uhrwerk/Z Series/z11b.dmp new file mode 100644 index 000000000..3f29f0101 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z11b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z11c.dmp b/instruments/FM/uhrwerk/Z Series/z11c.dmp new file mode 100644 index 000000000..1e5ec3804 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z11c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z11d.dmp b/instruments/FM/uhrwerk/Z Series/z11d.dmp new file mode 100644 index 000000000..4821d4080 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z11d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z11e.dmp b/instruments/FM/uhrwerk/Z Series/z11e.dmp new file mode 100644 index 000000000..37b312638 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z11e.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z12.dmp b/instruments/FM/uhrwerk/Z Series/z12.dmp new file mode 100644 index 000000000..0b43ad47a Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z12.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z13.dmp b/instruments/FM/uhrwerk/Z Series/z13.dmp new file mode 100644 index 000000000..306d31da3 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z13.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z14.dmp b/instruments/FM/uhrwerk/Z Series/z14.dmp new file mode 100644 index 000000000..67cf2beab Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z14.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z14b.dmp b/instruments/FM/uhrwerk/Z Series/z14b.dmp new file mode 100644 index 000000000..002c329bd Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z14b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z14c.dmp b/instruments/FM/uhrwerk/Z Series/z14c.dmp new file mode 100644 index 000000000..4b25048ae Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z14c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z14d.dmp b/instruments/FM/uhrwerk/Z Series/z14d.dmp new file mode 100644 index 000000000..b3752bf11 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z14d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z15.dmp b/instruments/FM/uhrwerk/Z Series/z15.dmp new file mode 100644 index 000000000..2f2cdc746 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z15.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z15b (quiet).dmp b/instruments/FM/uhrwerk/Z Series/z15b (quiet).dmp new file mode 100644 index 000000000..cf1ba08b1 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z15b (quiet).dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z15b.dmp b/instruments/FM/uhrwerk/Z Series/z15b.dmp new file mode 100644 index 000000000..6f083013b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z15b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z16.dmp b/instruments/FM/uhrwerk/Z Series/z16.dmp new file mode 100644 index 000000000..19c8cad4f Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z16.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z16b.dmp b/instruments/FM/uhrwerk/Z Series/z16b.dmp new file mode 100644 index 000000000..9c7c4ee61 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z16b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z16c.dmp b/instruments/FM/uhrwerk/Z Series/z16c.dmp new file mode 100644 index 000000000..e91fbacaa Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z16c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z16d.dmp b/instruments/FM/uhrwerk/Z Series/z16d.dmp new file mode 100644 index 000000000..0e7b9377d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z16d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z17.dmp b/instruments/FM/uhrwerk/Z Series/z17.dmp new file mode 100644 index 000000000..ba37c0b4e Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z17.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z17b.dmp b/instruments/FM/uhrwerk/Z Series/z17b.dmp new file mode 100644 index 000000000..d9aeff98b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z17b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z17c.dmp b/instruments/FM/uhrwerk/Z Series/z17c.dmp new file mode 100644 index 000000000..f0cd8d361 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z17c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z17d.dmp b/instruments/FM/uhrwerk/Z Series/z17d.dmp new file mode 100644 index 000000000..f7efff4b0 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z17d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z17e.dmp b/instruments/FM/uhrwerk/Z Series/z17e.dmp new file mode 100644 index 000000000..3f0594557 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z17e.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z18.dmp b/instruments/FM/uhrwerk/Z Series/z18.dmp new file mode 100644 index 000000000..be344f628 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z18.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z19.dmp b/instruments/FM/uhrwerk/Z Series/z19.dmp new file mode 100644 index 000000000..30a17fd8f Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z19.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z20.dmp b/instruments/FM/uhrwerk/Z Series/z20.dmp new file mode 100644 index 000000000..152bf07ce Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z20.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z20b.dmp b/instruments/FM/uhrwerk/Z Series/z20b.dmp new file mode 100644 index 000000000..a4f0f7c14 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z20b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z21.dmp b/instruments/FM/uhrwerk/Z Series/z21.dmp new file mode 100644 index 000000000..dbba75b0c Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z21.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z22.dmp b/instruments/FM/uhrwerk/Z Series/z22.dmp new file mode 100644 index 000000000..a43302d2d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z22.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z22b.dmp b/instruments/FM/uhrwerk/Z Series/z22b.dmp new file mode 100644 index 000000000..e3bb13fcb Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z22b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z23.dmp b/instruments/FM/uhrwerk/Z Series/z23.dmp new file mode 100644 index 000000000..d32b69727 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z23.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z24.dmp b/instruments/FM/uhrwerk/Z Series/z24.dmp new file mode 100644 index 000000000..61f87d45b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z24.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z24b.dmp b/instruments/FM/uhrwerk/Z Series/z24b.dmp new file mode 100644 index 000000000..3abff36c9 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z24b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z24c.dmp b/instruments/FM/uhrwerk/Z Series/z24c.dmp new file mode 100644 index 000000000..f342476d4 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z24c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z25.dmp b/instruments/FM/uhrwerk/Z Series/z25.dmp new file mode 100644 index 000000000..e86b0a114 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z25.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z26.dmp b/instruments/FM/uhrwerk/Z Series/z26.dmp new file mode 100644 index 000000000..701082a75 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z26.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z26b.dmp b/instruments/FM/uhrwerk/Z Series/z26b.dmp new file mode 100644 index 000000000..e938963b7 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z26b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z26c.dmp b/instruments/FM/uhrwerk/Z Series/z26c.dmp new file mode 100644 index 000000000..187f63aa8 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z26c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z26d.dmp b/instruments/FM/uhrwerk/Z Series/z26d.dmp new file mode 100644 index 000000000..87a5c88c9 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z26d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z26e.dmp b/instruments/FM/uhrwerk/Z Series/z26e.dmp new file mode 100644 index 000000000..79fb54148 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z26e.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z27.dmp b/instruments/FM/uhrwerk/Z Series/z27.dmp new file mode 100644 index 000000000..7092d91c1 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z27.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z28.dmp b/instruments/FM/uhrwerk/Z Series/z28.dmp new file mode 100644 index 000000000..24065a392 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z28.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z28b.dmp b/instruments/FM/uhrwerk/Z Series/z28b.dmp new file mode 100644 index 000000000..970d04d41 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z28b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z28c.dmp b/instruments/FM/uhrwerk/Z Series/z28c.dmp new file mode 100644 index 000000000..e38125f92 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z28c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z29.dmp b/instruments/FM/uhrwerk/Z Series/z29.dmp new file mode 100644 index 000000000..8a39e0be7 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z29.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z30.dmp b/instruments/FM/uhrwerk/Z Series/z30.dmp new file mode 100644 index 000000000..17a9f6f9a Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z30.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z30b.dmp b/instruments/FM/uhrwerk/Z Series/z30b.dmp new file mode 100644 index 000000000..352e851e9 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z30b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z30c.dmp b/instruments/FM/uhrwerk/Z Series/z30c.dmp new file mode 100644 index 000000000..1267ee24d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z30c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z31.dmp b/instruments/FM/uhrwerk/Z Series/z31.dmp new file mode 100644 index 000000000..f5b3f5832 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z31.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z32.dmp b/instruments/FM/uhrwerk/Z Series/z32.dmp new file mode 100644 index 000000000..6af238778 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z32.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z33.dmp b/instruments/FM/uhrwerk/Z Series/z33.dmp new file mode 100644 index 000000000..27240addf Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z33.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z33b.dmp b/instruments/FM/uhrwerk/Z Series/z33b.dmp new file mode 100644 index 000000000..3bb3d1175 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z33b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z33c.dmp b/instruments/FM/uhrwerk/Z Series/z33c.dmp new file mode 100644 index 000000000..53704a555 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z33c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z33d.dmp b/instruments/FM/uhrwerk/Z Series/z33d.dmp new file mode 100644 index 000000000..126a0f866 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z33d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z33e.dmp b/instruments/FM/uhrwerk/Z Series/z33e.dmp new file mode 100644 index 000000000..93709b62d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z33e.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z34.dmp b/instruments/FM/uhrwerk/Z Series/z34.dmp new file mode 100644 index 000000000..5279f358d Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z34.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z34b.dmp b/instruments/FM/uhrwerk/Z Series/z34b.dmp new file mode 100644 index 000000000..210f51498 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z34b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z35.dmp b/instruments/FM/uhrwerk/Z Series/z35.dmp new file mode 100644 index 000000000..8afd3f705 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z35.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z36.dmp b/instruments/FM/uhrwerk/Z Series/z36.dmp new file mode 100644 index 000000000..fc364bca4 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z36.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z37.dmp b/instruments/FM/uhrwerk/Z Series/z37.dmp new file mode 100644 index 000000000..fcf155e5e Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z37.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z38.dmp b/instruments/FM/uhrwerk/Z Series/z38.dmp new file mode 100644 index 000000000..01c0892f7 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z38.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z39.dmp b/instruments/FM/uhrwerk/Z Series/z39.dmp new file mode 100644 index 000000000..054e214c5 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z39.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z39b low vol.dmp b/instruments/FM/uhrwerk/Z Series/z39b low vol.dmp new file mode 100644 index 000000000..bb4d7983b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z39b low vol.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z39b.dmp b/instruments/FM/uhrwerk/Z Series/z39b.dmp new file mode 100644 index 000000000..bb4d7983b Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z39b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z39c.dmp b/instruments/FM/uhrwerk/Z Series/z39c.dmp new file mode 100644 index 000000000..b04346542 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z39c.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z39d.dmp b/instruments/FM/uhrwerk/Z Series/z39d.dmp new file mode 100644 index 000000000..7dec58ac3 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z39d.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z39e.dmp b/instruments/FM/uhrwerk/Z Series/z39e.dmp new file mode 100644 index 000000000..ab0845c57 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z39e.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z40.dmp b/instruments/FM/uhrwerk/Z Series/z40.dmp new file mode 100644 index 000000000..4d733c9b7 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z40.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z41.dmp b/instruments/FM/uhrwerk/Z Series/z41.dmp new file mode 100644 index 000000000..c6282f65e Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z41.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z41b.dmp b/instruments/FM/uhrwerk/Z Series/z41b.dmp new file mode 100644 index 000000000..ebfedcc87 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z41b.dmp differ diff --git a/instruments/FM/uhrwerk/Z Series/z42.dmp b/instruments/FM/uhrwerk/Z Series/z42.dmp new file mode 100644 index 000000000..ed3b57a26 Binary files /dev/null and b/instruments/FM/uhrwerk/Z Series/z42.dmp differ diff --git a/instruments/FM/uhrwerk/arbys.dmp b/instruments/FM/uhrwerk/arbys.dmp new file mode 100644 index 000000000..68fbd4304 Binary files /dev/null and b/instruments/FM/uhrwerk/arbys.dmp differ diff --git a/instruments/README.md b/instruments/README.md index 40cad4220..949aab10a 100644 --- a/instruments/README.md +++ b/instruments/README.md @@ -34,6 +34,7 @@ these are organized in the following categories: - theloredev - TheRealHedgehogSonic - tildearrow +- Uhrwerk Klockwerx - Weeppiko - Ygor G. - YohananDiamond diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index a97807ae7..88b54f132 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -591,6 +591,14 @@ class DivDispatch { virtual ~DivDispatch(); }; +// custom chip clock helper define. put in setFlags, but before rate is set. +#define CHECK_CUSTOM_CLOCK \ + if (flags.getInt("customClock",0)>0) { \ + chipClock=flags.getInt("customClock",1000000); \ + if (chipClock>20000000) chipClock=20000000; \ + if (chipClock<100000) chipClock=100000; \ + } + // pitch calculation: // - a DivDispatch usually contains four variables per channel: // - baseFreq: this changes on new notes, legato, arpeggio and slides. diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 65ccb0305..4c4f8f3a0 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1416,6 +1416,12 @@ void DivEngine::initSongWithDesc(const char* description, bool inBase64) { song.systemFlags[index].loadFromBase64(flags.c_str()); } song.systemLen=index; + + // extra attributes + song.subsong[0]->hz=c.getDouble("tickRate",60.0); + if (song.subsong[0]->hz!=60.0) { + song.subsong[0]->customTempo=true; + } } void DivEngine::createNew(const char* description, String sysName, bool inBase64) { diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index ab2c2c72f..b10cdfd8b 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -826,6 +826,7 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC/2.0; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/8; } for (int i=0; i<3; i++) { diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 821fa4fe4..2ec70048f 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -804,6 +804,7 @@ void DivPlatformAY8930::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC/2.0; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<3; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index c00b4ce2a..a43b8b1de 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -323,6 +323,7 @@ void DivPlatformBubSysWSG::notifyInsDeletion(void* ins) { void DivPlatformBubSysWSG::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC; + CHECK_CUSTOM_CLOCK; rate=chipClock; for (int i=0; i<2; i++) { oscBuf[i]->rate=rate/64; diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 9fb10d412..068dd1b33 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -535,17 +535,18 @@ void DivPlatformC64::setFP(bool fp) { void DivPlatformC64::setFlags(const DivConfig& flags) { switch (flags.getInt("clockSel",0)) { case 0x0: // NTSC C64 - rate=COLOR_NTSC*2.0/7.0; + chipClock=COLOR_NTSC*2.0/7.0; break; case 0x1: // PAL C64 - rate=COLOR_PAL*2.0/9.0; + chipClock=COLOR_PAL*2.0/9.0; break; case 0x2: // SSI 2001 default: - rate=14318180.0/16.0; + chipClock=14318180.0/16.0; break; } - chipClock=rate; + CHECK_CUSTOM_CLOCK; + rate=chipClock; for (int i=0; i<3; i++) { oscBuf[i]->rate=rate/16; } diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 5859be56f..ab4c228a6 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -454,13 +454,14 @@ void DivPlatformFDS::setNSFPlay(bool use) { void DivPlatformFDS::setFlags(const DivConfig& flags) { int clockSel=flags.getInt("clockSel",0); if (clockSel==2) { // Dendy - rate=COLOR_PAL*2.0/5.0; + chipClock=COLOR_PAL*2.0/5.0; } else if (clockSel==1) { // PAL - rate=COLOR_PAL*3.0/8.0; + chipClock=COLOR_PAL*3.0/8.0; } else { // NTSC - rate=COLOR_NTSC/2.0; + chipClock=COLOR_NTSC/2.0; } - chipClock=rate; + CHECK_CUSTOM_CLOCK; + rate=chipClock; oscBuf->rate=rate/32; if (useNP) { fds_NP->SetClock(rate); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 6a88d0f75..0bdd24349 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -655,6 +655,7 @@ void DivPlatformGB::setFlags(const DivConfig& flags) { int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { chipClock=4194304; + CHECK_CUSTOM_CLOCK; rate=chipClock/16; for (int i=0; i<4; i++) { isMuted[i]=false; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index fbc1e7dd0..c2bfaf49f 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1226,6 +1226,7 @@ void DivPlatformGenesis::setFlags(const DivConfig& flags) { ladder=flags.getBool("ladderEffect",false); noExtMacros=flags.getBool("noExtMacros",false); OPN2_SetChipType(ladder?ym3438_mode_ym2612:0); + CHECK_CUSTOM_CLOCK; if (useYMFM) { if (fm_ymfm!=NULL) delete fm_ymfm; if (ladder) { diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 66acdcd5e..e6704b64a 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -471,6 +471,7 @@ int DivPlatformLynx::init(DivEngine* p, int channels, int sugRate, const DivConf } chipClock = 16000000; + CHECK_CUSTOM_CLOCK; rate = chipClock/128; for (int i=0; i<4; i++) { diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index b52017e85..9feaabfcd 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -389,13 +389,14 @@ bool DivPlatformMMC5::keyOffAffectsArp(int ch) { void DivPlatformMMC5::setFlags(const DivConfig& flags) { int clockSel=flags.getInt("clockSel",0); if (clockSel==2) { // Dendy - rate=COLOR_PAL*2.0/5.0; + chipClock=COLOR_PAL*2.0/5.0; } else if (clockSel==1) { // PAL - rate=COLOR_PAL*3.0/8.0; + chipClock=COLOR_PAL*3.0/8.0; } else { // NTSC - rate=COLOR_NTSC/2.0; + chipClock=COLOR_NTSC/2.0; } - chipClock=rate; + CHECK_CUSTOM_CLOCK; + rate=chipClock; for (int i=0; i<3; i++) { oscBuf[i]->rate=rate/32; } diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index 84e8d91b4..a9a70092d 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -372,6 +372,7 @@ void DivPlatformMSM5232::notifyInsDeletion(void* ins) { void DivPlatformMSM5232::setFlags(const DivConfig& flags) { chipClock=2119040; + CHECK_CUSTOM_CLOCK; detune=flags.getInt("detune",0); msm->set_clock(chipClock+detune*1024); rate=msm->get_rate(); diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index 7111c84cb..ef11c7174 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -412,6 +412,7 @@ void DivPlatformMSM6258::setFlags(const DivConfig& flags) { chipClock=4000000; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/256; for (int i=0; i<1; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index 71b8d7cf7..3bf0b8eb4 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -438,6 +438,7 @@ void DivPlatformMSM6295::setFlags(const DivConfig& flags) { chipClock=4000000/4; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/3; for (int i=0; i<4; i++) { oscBuf[i]->rate=rate/22; diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index 26d42e454..50da45f06 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -624,18 +624,19 @@ void DivPlatformN163::poke(std::vector& wlist) { void DivPlatformN163::setFlags(const DivConfig& flags) { switch (flags.getInt("clockSel",0)) { case 1: // PAL - rate=COLOR_PAL*3.0/8.0; + chipClock=COLOR_PAL*3.0/8.0; break; case 2: // Dendy - rate=COLOR_PAL*2.0/5.0; + chipClock=COLOR_PAL*2.0/5.0; break; default: // NTSC - rate=COLOR_NTSC/2.0; + chipClock=COLOR_NTSC/2.0; break; } + CHECK_CUSTOM_CLOCK; initChanMax=chanMax=flags.getInt("channels",0)&7; multiplex=!flags.getBool("multiplex",false); // not accurate in real hardware - chipClock=rate; + rate=chipClock; rate/=15; n163.set_multiplex(multiplex); rWrite(0x7f,initChanMax<<4); diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index aab625b12..c1466b90b 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -532,6 +532,7 @@ void DivPlatformNamcoWSG::setDeviceType(int type) { void DivPlatformNamcoWSG::setFlags(const DivConfig& flags) { chipClock=3072000; + CHECK_CUSTOM_CLOCK; rate=chipClock/32; namco->device_clock_changed(rate); for (int i=0; iapu.type=apuType; } - chipClock=rate; + CHECK_CUSTOM_CLOCK; + rate=chipClock; for (int i=0; i<5; i++) { oscBuf[i]->rate=rate/32; } diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 5353fa6cd..4464508cb 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1694,6 +1694,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/72; chipRateBase=rate; break; @@ -1715,6 +1716,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC*4.0; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/288; chipRateBase=rate; break; @@ -1730,6 +1732,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC*8.0; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/768; chipRateBase=chipClock/684; break; diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index a8b51b107..77dea2e7c 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -958,6 +958,7 @@ void DivPlatformOPLL::setFlags(const DivConfig& flags) { } else { chipClock=COLOR_NTSC; } + CHECK_CUSTOM_CLOCK; rate=chipClock/36; patchSet=flags.getInt("patchSet",0); for (int i=0; i<11; i++) { diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index e8a308f17..f6a8df51e 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -565,6 +565,7 @@ void DivPlatformPCE::setFlags(const DivConfig& flags) { } else { chipClock=COLOR_NTSC; } + CHECK_CUSTOM_CLOCK; antiClickEnabled=!flags.getBool("noAntiClick",false); rate=chipClock/12; for (int i=0; i<6; i++) { diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index 226ee98ca..59154dcae 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -598,6 +598,7 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC/3.0; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/PCSPKR_DIVIDER; speakerType=flags.getInt("speakerType",0)&3; oscBuf->rate=rate; diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index 8a606ecfa..3722d52f5 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -300,6 +300,7 @@ int DivPlatformPET::init(DivEngine* p, int channels, int sugRate, const DivConfi dumpWrites=false; skipRegisterWrites=false; chipClock=1000000; + CHECK_CUSTOM_CLOCK; rate=chipClock/SAMP_DIVIDER; // = 250000kHz isMuted=false; oscBuf=new DivDispatchOscBuffer; diff --git a/src/engine/platform/pong.cpp b/src/engine/platform/pong.cpp index 1015fdda7..a98fe7baf 100644 --- a/src/engine/platform/pong.cpp +++ b/src/engine/platform/pong.cpp @@ -21,7 +21,7 @@ #include "../engine.h" #include "../../ta-log.h" -#define CHIP_DIVIDER 16 +#define CHIP_DIVIDER 1024 void DivPlatformPong::acquire(short* bufL, short* bufR, size_t start, size_t len) { int out=0; @@ -226,8 +226,9 @@ bool DivPlatformPong::keyOffAffectsArp(int ch) { } void DivPlatformPong::setFlags(const DivConfig& flags) { - chipClock=15625; - rate=chipClock; + chipClock=1000000; + CHECK_CUSTOM_CLOCK; + rate=chipClock/64; oscBuf->rate=rate; } diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index fce9f783c..cc411fa5f 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -245,6 +245,22 @@ const unsigned char q1_reg_map[Q1V_REG_COUNT][16] = { {0x06,0x0e,0x16,0x1e,0x26,0x2e,0x36,0x3e,0x46,0x4e,0x56,0x5e,0x66,0x6e,0x76,0x7e}, }; +const unsigned char q1a_start_map[3]={ + 0xca, 0xce, 0xd2 +}; + +const unsigned char q1a_end_map[3]={ + 0xcb, 0xcf, 0xd3 +}; + +const unsigned char q1a_bank_map[3]={ + 0xcc, 0xd0, 0xd4 +}; + +const unsigned char q1a_vol_map[3]={ + 0xcd, 0xd1, 0xd5 +}; + const char** DivPlatformQSound::getRegisterSheet() { return regCheatSheetQSound; } @@ -265,7 +281,7 @@ void DivPlatformQSound::acquire(short* bufL, short* bufR, size_t start, size_t l } void DivPlatformQSound::tick(bool sysTick) { - for (int i=0; i<16; i++) { + for (int i=0; i<19; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { if (chan[i].isNewQSound) { @@ -277,7 +293,11 @@ void DivPlatformQSound::tick(bool sysTick) { } // Check if enabled and write volume if (chan[i].active) { - rWrite(q1_reg_map[Q1V_VOL][i],chan[i].resVol); + if (i<16) { + rWrite(q1_reg_map[Q1V_VOL][i],chan[i].resVol); + } else { + rWrite(q1a_vol_map[i-16],chan[i].resVol); + } } } uint16_t qsound_bank = 0; @@ -286,8 +306,13 @@ void DivPlatformQSound::tick(bool sysTick) { uint16_t qsound_end = 0; if (chan[i].sample>=0 && chan[i].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[i].sample); - qsound_bank = 0x8000 | (offPCM[chan[i].sample] >> 16); - qsound_addr = offPCM[chan[i].sample] & 0xffff; + if (i<16) { + qsound_bank = 0x8000 | (offPCM[chan[i].sample] >> 16); + qsound_addr = offPCM[chan[i].sample] & 0xffff; + } else { + qsound_bank = 0x8000 | (offBS[chan[i].sample] >> 16); + qsound_addr = offBS[chan[i].sample] & 0xffff; + } int loopStart=s->loopStart; int length = s->loopEnd; @@ -295,10 +320,18 @@ void DivPlatformQSound::tick(bool sysTick) { length = 65536 - 16; } if (loopStart == -1 || loopStart >= length) { - qsound_end = offPCM[chan[i].sample] + length + 15; + if (i<16) { + qsound_end = offPCM[chan[i].sample] + length + 15; + } else { + qsound_end = offBS[chan[i].sample] + length + 15; + } qsound_loop = 15; } else { - qsound_end = offPCM[chan[i].sample] + length; + if (i<16) { + qsound_end = offPCM[chan[i].sample] + length; + } else { + qsound_end = offBS[chan[i].sample] + length; + } qsound_loop = length - loopStart; } } @@ -310,7 +343,9 @@ void DivPlatformQSound::tick(bool sysTick) { } if (chan[i].isNewQSound && chan[i].std.duty.had) { chan[i].echo=CLAMP(chan[i].std.duty.val,0,32767); - immWrite(Q1_ECHO+i,chan[i].echo&0x7fff); + if (i<16) { + immWrite(Q1_ECHO+i,chan[i].echo&0x7fff); + } } if (chan[i].isNewQSound && chan[i].std.ex1.had) { immWrite(Q1_ECHO_FEEDBACK,chan[i].std.ex1.val&0x3fff); @@ -355,11 +390,19 @@ void DivPlatformQSound::tick(bool sysTick) { chan[i].freq=off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2,440.0,4096.0); if (chan[i].freq>0xefff) chan[i].freq=0xefff; if (chan[i].keyOn) { - rWrite(q1_reg_map[Q1V_BANK][i], qsound_bank); - rWrite(q1_reg_map[Q1V_END][i], qsound_end); - rWrite(q1_reg_map[Q1V_LOOP][i], qsound_loop); - rWrite(q1_reg_map[Q1V_START][i], qsound_addr); - rWrite(q1_reg_map[Q1V_PHASE][i], 0x8000); + if (i<16) { + rWrite(q1_reg_map[Q1V_BANK][i], qsound_bank); + rWrite(q1_reg_map[Q1V_END][i], qsound_end); + rWrite(q1_reg_map[Q1V_LOOP][i], qsound_loop); + rWrite(q1_reg_map[Q1V_START][i], qsound_addr); + rWrite(q1_reg_map[Q1V_PHASE][i], 0x8000); + } else { + rWrite(Q1A_KEYON+(i-16),0); + rWrite(q1a_bank_map[i-16], qsound_bank); + rWrite(q1a_end_map[i-16], qsound_end); + rWrite(q1a_start_map[i-16], qsound_addr); + rWrite(Q1A_KEYON+(i-16),1); + } //logV("ch %d bank=%04x, addr=%04x, end=%04x, loop=%04x!",i,qsound_bank,qsound_addr,qsound_end,qsound_loop); // Write sample address. Enable volume if (!chan[i].std.vol.had) { @@ -368,16 +411,27 @@ void DivPlatformQSound::tick(bool sysTick) { } else { chan[i].resVol=chan[i].vol<<4; } - rWrite(q1_reg_map[Q1V_VOL][i],chan[i].resVol); + if (i<16) { + rWrite(q1_reg_map[Q1V_VOL][i],chan[i].resVol); + } else { + rWrite(q1a_vol_map[i-16],chan[i].resVol); + } } } if (chan[i].keyOff) { // Disable volume - rWrite(q1_reg_map[Q1V_VOL][i],0); - rWrite(q1_reg_map[Q1V_FREQ][i],0); + if (i<16) { + rWrite(q1_reg_map[Q1V_VOL][i],0); + rWrite(q1_reg_map[Q1V_FREQ][i],0); + } else { + rWrite(q1a_vol_map[i-16],0); + rWrite(Q1A_KEYON+(i-16),0); + } } else if (chan[i].active) { //logV("ch %d frequency set to %04x, off=%f, note=%d, %04x!",i,chan[i].freq,off,chan[i].note,QS_NOTE_FREQUENCY(chan[i].note)); - rWrite(q1_reg_map[Q1V_FREQ][i],chan[i].freq); + if (i<16) { + rWrite(q1_reg_map[Q1V_FREQ][i],chan[i].freq); + } } if (chan[i].keyOn) chan[i].keyOn=false; if (chan[i].keyOff) chan[i].keyOff=false; @@ -441,8 +495,12 @@ int DivPlatformQSound::dispatch(DivCommand c) { } else { chan[c.chan].resVol=chan[c.chan].outVol<<4; } - if (chan[c.chan].active && c.chan<16) { - rWrite(q1_reg_map[Q1V_VOL][c.chan],chan[c.chan].resVol); + if (chan[c.chan].active) { + if (c.chan<16) { + rWrite(q1_reg_map[Q1V_VOL][c.chan],chan[c.chan].resVol); + } else { + rWrite(q1a_vol_map[c.chan-16],chan[c.chan].resVol); + } } } } @@ -459,6 +517,7 @@ int DivPlatformQSound::dispatch(DivCommand c) { break; case DIV_CMD_QSOUND_ECHO_LEVEL: chan[c.chan].echo=c.value<<7; + if (c.chan>=16) break; immWrite(Q1_ECHO+c.chan,chan[c.chan].echo&0x7fff); break; case DIV_CMD_QSOUND_ECHO_FEEDBACK: @@ -532,7 +591,8 @@ void DivPlatformQSound::muteChannel(int ch, bool mute) { } void DivPlatformQSound::forceIns() { - for (int i=0; i<4; i++) { + // TODO: what? + for (int i=0; i<19; i++) { chan[i].insChanged=true; chan[i].freqChanged=true; chan[i].sample=-1; @@ -552,7 +612,7 @@ DivDispatchOscBuffer* DivPlatformQSound::getOscBuffer(int ch) { } void DivPlatformQSound::reset() { - for (int i=0; i<16; i++) { + for (int i=0; i<19; i++) { chan[i]=DivPlatformQSound::Channel(); chan[i].std.setEngine(parent); } @@ -582,8 +642,7 @@ void DivPlatformQSound::notifyInsChange(int ins) { } void DivPlatformQSound::notifyWaveChange(int wave) { - // TODO when wavetables are added - // TODO they probably won't be added unless the samples reside in RAM + // yeah won't add wavetables } void DivPlatformQSound::notifyInsDeletion(void* ins) { @@ -633,27 +692,32 @@ int DivPlatformQSound::getRegisterPoolDepth() { } const void* DivPlatformQSound::getSampleMem(int index) { - return index == 0 ? sampleMem : NULL; + return (index == 0 || index == 1) ? sampleMem : NULL; } size_t DivPlatformQSound::getSampleMemCapacity(int index) { - return index == 0 ? 16777216 : 0; + return (index == 0 || index == 1) ? 16777216 : 0; } size_t DivPlatformQSound::getSampleMemUsage(int index) { - return index == 0 ? sampleMemLen : 0; + return index == 0 ? sampleMemLen : index == 1 ? sampleMemLenBS : 0; } bool DivPlatformQSound::isSampleLoaded(int index, int sample) { - if (index!=0) return false; + if (index<0 || index>1) return false; if (sample<0 || sample>255) return false; + if (index==1) return sampleLoadedBS[sample]; return sampleLoaded[sample]; } -// TODO: ADPCM... come on... +const char* DivPlatformQSound::getSampleMemName(int index) { + return index == 0 ? "PCM" : index == 1 ? "ADPCM" : NULL; +} + void DivPlatformQSound::renderSamples(int sysID) { memset(sampleMem,0,getSampleMemCapacity()); memset(sampleLoaded,0,256*sizeof(bool)); + memset(sampleLoadedBS,0,256*sizeof(bool)); size_t memPos=0; for (int i=0; isong.sampleLen; i++) { @@ -689,6 +753,42 @@ void DivPlatformQSound::renderSamples(int sysID) { memPos+=length+16; } sampleMemLen=memPos+256; + + memPos=(memPos+0xffff)&0xff0000; + + for (int i=0; isong.sampleLen; i++) { + DivSample* s=parent->song.sample[i]; + if (!s->renderOn[1][sysID]) { + offBS[i]=0; + continue; + } + + int length=s->lengthQSoundA; + if (length>65536) { + length=65536; + } + if ((memPos&0xff0000)!=((memPos+length)&0xff0000)) { + memPos=(memPos+0xffff)&0xff0000; + } + if (memPos>=getSampleMemCapacity()) { + logW("out of QSound ADPCM memory for sample %d!",i); + break; + } + if (memPos+length>=getSampleMemCapacity()) { + for (unsigned int i=0; idataQSoundA[i]; + } + logW("out of QSound ADPCM memory for sample %d!",i); + } else { + for (int i=0; idataQSoundA[i]; + } + sampleLoaded[i]=true; + } + offBS[i]=memPos; + memPos+=length+16; + } + sampleMemLenBS=memPos+256; } int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { @@ -706,6 +806,7 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, const DivCo rate = qsound_start(&chip, chipClock); sampleMem=new unsigned char[getSampleMemCapacity()]; sampleMemLen=0; + sampleMemLenBS=0; chip.rom_data=sampleMem; chip.rom_mask=0xffffff; reset(); diff --git a/src/engine/platform/qsound.h b/src/engine/platform/qsound.h index 1f911a832..d141d5911 100644 --- a/src/engine/platform/qsound.h +++ b/src/engine/platform/qsound.h @@ -69,7 +69,9 @@ class DivPlatformQSound: public DivDispatch { unsigned char* sampleMem; size_t sampleMemLen; + size_t sampleMemLenBS; bool sampleLoaded[256]; + bool sampleLoadedBS[256]; struct qsound_chip chip; unsigned short regPool[512]; @@ -102,6 +104,7 @@ class DivPlatformQSound: public DivDispatch { void poke(std::vector& wlist); const char** getRegisterSheet(); const void* getSampleMem(int index = 0); + const char* getSampleMemName(int index=0); size_t getSampleMemCapacity(int index = 0); size_t getSampleMemUsage(int index = 0); bool isSampleLoaded(int index, int sample); diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index e33cfbf39..f13a25aa0 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -348,6 +348,7 @@ void DivPlatformRF5C68::setFlags(const DivConfig& flags) { case 2: chipClock=12500000; break; default: chipClock=8000000; break; } + CHECK_CUSTOM_CLOCK; chipType=flags.getInt("chipType",0); rate=chipClock/384; for (int i=0; i<8; i++) { diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 7f48bca43..c3e48f1fe 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -438,6 +438,7 @@ void DivPlatformSAA1099::setFlags(const DivConfig& flags) { } else { chipClock=8000000; } + CHECK_CUSTOM_CLOCK; rate=chipClock/32; for (int i=0; i<6; i++) { diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index a8fbcd7c2..a75496d55 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -375,6 +375,7 @@ void DivPlatformSCC::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC/2.0; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/8; for (int i=0; i<5; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 860f99264..25de33957 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -486,7 +486,8 @@ void DivPlatformSegaPCM::reset() { void DivPlatformSegaPCM::setFlags(const DivConfig& flags) { chipClock=8000000.0; - rate=31250; + CHECK_CUSTOM_CLOCK; + rate=chipClock/256; for (int i=0; i<16; i++) { oscBuf[i]->rate=rate; } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 9f65a9534..0ce4c8361 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -568,6 +568,7 @@ void DivPlatformSMS::setFlags(const DivConfig& flags) { stereo=false; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/divider; for (int i=0; i<4; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 931225b49..d85a9d94d 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -511,6 +511,7 @@ void DivPlatformSoundUnit::setFlags(const DivConfig& flags) { } else { chipClock=1236000; } + CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<8; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 222af4a55..852450a74 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -514,6 +514,7 @@ int DivPlatformSwan::init(DivEngine* p, int channels, int sugRate, const DivConf dumpWrites=false; skipRegisterWrites=false; chipClock=3072000; + CHECK_CUSTOM_CLOCK; rate=chipClock/16; // = 192000kHz, should be enough for (int i=0; i<4; i++) { isMuted[i]=false; diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index c6317e119..0d294836c 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -343,6 +343,7 @@ void DivPlatformT6W28::notifyInsDeletion(void* ins) { void DivPlatformT6W28::setFlags(const DivConfig& flags) { chipClock=3072000.0; + CHECK_CUSTOM_CLOCK; rate=chipClock/16; for (int i=0; i<4; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index d4703e284..2a28cb0a0 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -356,6 +356,7 @@ void DivPlatformTIA::setFlags(const DivConfig& flags) { } else { rate=COLOR_NTSC; } + CHECK_CUSTOM_CLOCK; chipClock=rate; mixingType=flags.getInt("mixingType",0)&3; for (int i=0; i<2; i++) { diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index a8baab3cf..1523a153c 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -486,6 +486,7 @@ void DivPlatformVB::notifyInsDeletion(void* ins) { void DivPlatformVB::setFlags(const DivConfig& flags) { chipClock=5000000.0; + CHECK_CUSTOM_CLOCK; rate=chipClock/16; for (int i=0; i<6; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 2966f9d1f..9294a3444 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -438,6 +438,7 @@ int DivPlatformVERA::init(DivEngine* p, int channels, int sugRate, const DivConf dumpWrites=false; skipRegisterWrites=false; chipClock=25000000; + CHECK_CUSTOM_CLOCK; rate=chipClock/512; for (int i=0; i<17; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index d6200a16c..52a08836e 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -307,6 +307,7 @@ void DivPlatformVIC20::setFlags(const DivConfig& flags) { } else { chipClock=COLOR_NTSC*2.0/7.0; } + CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<4; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 52a9350c9..56df0e83b 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -482,13 +482,14 @@ bool DivPlatformVRC6::keyOffAffectsArp(int ch) { void DivPlatformVRC6::setFlags(const DivConfig& flags) { int clockSel=flags.getInt("clockSel",0); if (clockSel==2) { // Dendy - rate=COLOR_PAL*2.0/5.0; + chipClock=COLOR_PAL*2.0/5.0; } else if (clockSel==1) { // PAL - rate=COLOR_PAL*3.0/8.0; + chipClock=COLOR_PAL*3.0/8.0; } else { // NTSC - rate=COLOR_NTSC/2.0; + chipClock=COLOR_NTSC/2.0; } - chipClock=rate; + CHECK_CUSTOM_CLOCK; + rate=chipClock; for (int i=0; i<3; i++) { oscBuf[i]->rate=rate/32; } diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 683b36a6e..b7382c284 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -922,6 +922,7 @@ void DivPlatformX1_010::setFlags(const DivConfig& flags) { chipClock=16000000; break; } + CHECK_CUSTOM_CLOCK; rate=chipClock/512; stereo=flags.getBool("stereo",false); for (int i=0; i<16; i++) { diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index b3dc596c1..3d6eaa8a6 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -952,6 +952,7 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) { ayDiv=16; break; } + CHECK_CUSTOM_CLOCK; noExtMacros=flags.getBool("noExtMacros",false); rate=fm->sample_rate(chipClock); for (int i=0; i<6; i++) { diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 63c84ad55..e15bf6b42 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -1407,6 +1407,7 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) { ayDiv=32; break; } + CHECK_CUSTOM_CLOCK; noExtMacros=flags.getBool("noExtMacros",false); rate=fm->sample_rate(chipClock); for (int i=0; i<16; i++) { diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index 065eb5f35..c2dce8aa5 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -294,6 +294,7 @@ template class DivPlatformYM2610Base: public DivPlatformOPN { chipClock=8000000.0; break; } + CHECK_CUSTOM_CLOCK; noExtMacros=flags.getBool("noExtMacros",false); rate=chipClock/16; for (int i=0; irate=rate; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 489758130..216607bdf 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1057,8 +1057,10 @@ void DivEngine::nextRow() { if (!(pat->data[curRow][0]==0 && pat->data[curRow][1]==0)) { if (pat->data[curRow][0]!=100 && pat->data[curRow][0]!=101 && pat->data[curRow][0]!=102) { if (!chan[i].legato) { + bool wantPreNote=false; if (disCont[dispatchOfChan[i]].dispatch!=NULL) { - if (disCont[dispatchOfChan[i]].dispatch->getWantPreNote()) dispatchCmd(DivCommand(DIV_CMD_PRE_NOTE,i,ticks)); + wantPreNote=disCont[dispatchOfChan[i]].dispatch->getWantPreNote(); + if (wantPreNote) dispatchCmd(DivCommand(DIV_CMD_PRE_NOTE,i,ticks)); } if (song.oneTickCut) { @@ -1076,7 +1078,7 @@ void DivEngine::nextRow() { } } } - if (doPrepareCut) chan[i].cut=ticks; + if (doPrepareCut && !wantPreNote && chan[i].cut<=0) chan[i].cut=ticks; } } } diff --git a/src/engine/sample.cpp b/src/engine/sample.cpp index 2c15f676c..5460aed32 100644 --- a/src/engine/sample.cpp +++ b/src/engine/sample.cpp @@ -58,7 +58,11 @@ void DivSample::putSampleData(SafeWriter* w) { w->writeI(loop?loopEnd:-1); for (int i=0; i<4; i++) { - w->writeI(0xffffffff); + unsigned int out=0; + for (int j=0; j<32; j++) { + if (renderOn[i][j]) out|=1<writeI(out); } #ifdef TA_BIG_ENDIAN @@ -130,7 +134,10 @@ DivDataErrors DivSample::readSampleData(SafeReader& reader, short version) { loop=(loopStart>=0)&&(loopEnd>=0); for (int i=0; i<4; i++) { - reader.readI(); + unsigned int outMask=(unsigned int)reader.readI(); + for (int j=0; j<32; j++) { + renderOn[i][j]=outMask&(1<song.oneTickCut); if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("when enabled, a one-tick note cut will be inserted between non-legato/non-portamento notes.\nthis simulates the behavior of some Amiga/SNES music engines."); + ImGui::SetTooltip("when enabled, a one-tick note cut will be inserted between non-legato/non-portamento notes.\nthis simulates the behavior of some Amiga/SNES music engines.\n\nineffective on C64."); } ImGui::Checkbox("Broken speed alternation",&e->song.brokenSpeedSel); if (ImGui::IsItemHovered()) { diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index 143ec23aa..0adef883d 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -42,7 +42,7 @@ void FurnaceGUI::drawDebug() { nextWindow=GUI_WINDOW_NOTHING; } if (!debugOpen) return; - ImGui::SetNextWindowSizeConstraints(ImVec2(400.0f*dpiScale,200.0f*dpiScale),ImVec2(canvasW,canvasH)); + ImGui::SetNextWindowSizeConstraints(ImVec2(100.0f*dpiScale,100.0f*dpiScale),ImVec2(canvasW,canvasH)); if (ImGui::Begin("Debug",&debugOpen,globalWinFlags|ImGuiWindowFlags_NoDocking)) { ImGui::Text("NOTE: use with caution."); if (ImGui::TreeNode("Debug Controls")) { diff --git a/src/gui/fileDialog.cpp b/src/gui/fileDialog.cpp index 9b13fff0d..94ffa94ef 100644 --- a/src/gui/fileDialog.cpp +++ b/src/gui/fileDialog.cpp @@ -116,7 +116,7 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c } jclass class_=jniEnv->GetObjectClass(activity); - jmethodID showFileDialog=jniEnv->GetMethodID(class_,"showFileDialog","()B"); + jmethodID showFileDialog=jniEnv->GetMethodID(class_,"showFileDialog","()V"); if (showFileDialog==NULL) { logE("method showFileDialog not found!"); @@ -126,12 +126,12 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c return false; } - jboolean mret=jniEnv->CallBooleanMethod(activity,showFileDialog); + jniEnv->CallVoidMethod(activity,showFileDialog); - if (!(bool)mret) { + /*if (!(bool)mret) { hasError=true; logW("could not open Android file picker..."); - } + }*/ jniEnv->DeleteLocalRef(class_); jniEnv->DeleteLocalRef(activity); @@ -142,7 +142,16 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c #endif } else { hasError=false; + +#ifdef ANDROID + if (!SDL_AndroidRequestPermission("android.permission.READ_EXTERNAL_STORAGE")) { + return false; + } +#endif + + ImGuiFileDialog::Instance()->singleClickSel=mobileUI; ImGuiFileDialog::Instance()->DpiScale=dpiScale; + ImGuiFileDialog::Instance()->mobileMode=mobileUI; ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,allowMultiple?999:1,nullptr,0,clickCallback); } opened=true; @@ -151,6 +160,13 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c bool FurnaceGUIFileDialog::openSave(String header, std::vector filter, const char* noSysFilter, String path, double dpiScale) { if (opened) return false; + +#ifdef ANDROID + if (!SDL_AndroidRequestPermission("android.permission.WRITE_EXTERNAL_STORAGE")) { + return false; + } +#endif + saving=true; curPath=path; @@ -171,14 +187,54 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector filter, c dialogS=new std::thread(_nfdThread,NFDState(true,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError); #endif #elif defined(ANDROID) - hasError=true; // TODO + hasError=false; + if (jniEnv==NULL) { + jniEnv=(JNIEnv*)SDL_AndroidGetJNIEnv(); + if (jniEnv==NULL) { + hasError=true; + logE("could not acquire JNI env!"); + return false; + } + } + + jobject activity=(jobject)SDL_AndroidGetActivity(); + if (activity==NULL) { + hasError=true; + logE("the Activity is NULL!"); + return false; + } + + jclass class_=jniEnv->GetObjectClass(activity); + jmethodID showSaveFileDialog=jniEnv->GetMethodID(class_,"showSaveFileDialog","()V"); + + if (showSaveFileDialog==NULL) { + logE("method showSaveFileDialog not found!"); + hasError=true; + jniEnv->DeleteLocalRef(class_); + jniEnv->DeleteLocalRef(activity); + return false; + } + + jniEnv->CallVoidMethod(activity,showSaveFileDialog); + + /*if (!(bool)mret) { + hasError=true; + logW("could not open Android file picker..."); + }*/ + + jniEnv->DeleteLocalRef(class_); + jniEnv->DeleteLocalRef(activity); + return true; #else dialogS=new pfd::save_file(header,path,filter); hasError=!pfd::settings::available(); #endif } else { hasError=false; + + ImGuiFileDialog::Instance()->singleClickSel=false; ImGuiFileDialog::Instance()->DpiScale=dpiScale; + ImGuiFileDialog::Instance()->mobileMode=mobileUI; ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite); } opened=true; diff --git a/src/gui/fileDialog.h b/src/gui/fileDialog.h index 0fbeeb469..6e91eddf8 100644 --- a/src/gui/fileDialog.h +++ b/src/gui/fileDialog.h @@ -47,6 +47,7 @@ class FurnaceGUIFileDialog { pfd::save_file* dialogS; #endif public: + bool mobileUI; bool openLoad(String header, std::vector filter, const char* noSysFilter, String path, double dpiScale, FileDialogSelectCallback clickCallback=NULL, bool allowMultiple=false); bool openSave(String header, std::vector filter, const char* noSysFilter, String path, double dpiScale); bool accepted(); @@ -65,5 +66,6 @@ class FurnaceGUIFileDialog { jniEnv(NULL), #endif dialogO(NULL), - dialogS(NULL) {} + dialogS(NULL), + mobileUI(false) {} }; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index ebd7dafa0..f0d96ee21 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2197,6 +2197,12 @@ void FurnaceGUI::processDrags(int dragX, int dragY) { sampleSelEnd=x; } } + if (orderScrollLocked) { + if (fabs(orderScrollRealOrigin.x-dragX)>2.0f*dpiScale || fabs(orderScrollRealOrigin.y-dragY)>2.0f*dpiScale) orderScrollTolerance=false; + orderScroll=(orderScrollSlideOrigin-dragX)/(40.0*dpiScale); + if (orderScroll<0.0f) orderScroll=0.0f; + if (orderScroll>(float)e->curSubSong->ordersLen-1) orderScroll=e->curSubSong->ordersLen-1; + } } #define checkExtension(x) \ @@ -2623,9 +2629,15 @@ void FurnaceGUI::toggleMobileUI(bool enable, bool force) { mobileUI=enable; if (mobileUI) { ImGui::GetIO().IniFilename=NULL; + ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_InertialScrollEnable; + ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_NoHoverColors; + fileDialog->mobileUI=true; } else { ImGui::GetIO().IniFilename=NULL; ImGui::LoadIniSettingsFromDisk(finalLayoutPath); + ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_InertialScrollEnable; + ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_NoHoverColors; + fileDialog->mobileUI=false; } } } @@ -2633,14 +2645,16 @@ void FurnaceGUI::toggleMobileUI(bool enable, bool force) { void FurnaceGUI::pushToggleColors(bool status) { ImVec4 toggleColor=status?uiColors[GUI_COLOR_TOGGLE_ON]:uiColors[GUI_COLOR_TOGGLE_OFF]; ImGui::PushStyleColor(ImGuiCol_Button,toggleColor); - if (settings.guiColorsBase) { - toggleColor.x*=0.8f; - toggleColor.y*=0.8f; - toggleColor.z*=0.8f; - } else { - toggleColor.x=CLAMP(toggleColor.x*1.3f,0.0f,1.0f); - toggleColor.y=CLAMP(toggleColor.y*1.3f,0.0f,1.0f); - toggleColor.z=CLAMP(toggleColor.z*1.3f,0.0f,1.0f); + if (!mobileUI) { + if (settings.guiColorsBase) { + toggleColor.x*=0.8f; + toggleColor.y*=0.8f; + toggleColor.z*=0.8f; + } else { + toggleColor.x=CLAMP(toggleColor.x*1.3f,0.0f,1.0f); + toggleColor.y=CLAMP(toggleColor.y*1.3f,0.0f,1.0f); + toggleColor.z=CLAMP(toggleColor.z*1.3f,0.0f,1.0f); + } } ImGui::PushStyleColor(ImGuiCol_ButtonHovered,toggleColor); if (settings.guiColorsBase) { @@ -2906,14 +2920,27 @@ void FurnaceGUI::pointUp(int x, int y, int button) { } } sampleDragActive=false; + if (orderScrollLocked) { + int targetOrder=round(orderScroll); + if (orderScrollTolerance) { + targetOrder=round(orderScroll+(orderScrollRealOrigin.x-((float)canvasW/2.0f))/(40.0f*dpiScale)); + } + if (targetOrder<0) targetOrder=0; + if (targetOrder>e->curSubSong->ordersLen-1) targetOrder=e->curSubSong->ordersLen-1; + if (curOrder!=targetOrder) setOrder(targetOrder); + } + orderScrollLocked=false; + orderScrollTolerance=false; if (selecting) { if (!selectingFull) cursor=selEnd; finishSelection(); - demandScrollX=true; - if (cursor.xCoarse==selStart.xCoarse && cursor.xFine==selStart.xFine && cursor.y==selStart.y && - cursor.xCoarse==selEnd.xCoarse && cursor.xFine==selEnd.xFine && cursor.y==selEnd.y) { - if (!settings.cursorMoveNoScroll) { - updateScroll(cursor.y); + if (!mobileUI) { + demandScrollX=true; + if (cursor.xCoarse==selStart.xCoarse && cursor.xFine==selStart.xFine && cursor.y==selStart.y && + cursor.xCoarse==selEnd.xCoarse && cursor.xFine==selEnd.xFine && cursor.y==selEnd.y) { + if (!settings.cursorMoveNoScroll) { + updateScroll(cursor.y); + } } } } @@ -2929,7 +2956,7 @@ void FurnaceGUI::pointMotion(int x, int y, int xrel, int yrel) { addScroll(1); } } - if (macroDragActive || macroLoopDragActive || waveDragActive || sampleDragActive) { + if (macroDragActive || macroLoopDragActive || waveDragActive || sampleDragActive || orderScrollLocked) { int distance=fabs((double)xrel); if (distance<1) distance=1; float start=x-xrel; @@ -3152,6 +3179,11 @@ bool FurnaceGUI::loop() { if (wantCaptureKeyboard) { WAKE_UP; } + + if (ImGui::GetIO().IsSomethingHappening) { + WAKE_UP; + } + if (ImGui::GetIO().MouseDown[0] || ImGui::GetIO().MouseDown[1] || ImGui::GetIO().MouseDown[2] || ImGui::GetIO().MouseDown[3] || ImGui::GetIO().MouseDown[4]) { WAKE_UP; } @@ -3656,6 +3688,7 @@ bool FurnaceGUI::loop() { if (ImGui::BeginMenu("help")) { if (ImGui::MenuItem("effect list",BIND_FOR(GUI_ACTION_WINDOW_EFFECT_LIST),effectListOpen)) effectListOpen=!effectListOpen; if (ImGui::MenuItem("debug menu",BIND_FOR(GUI_ACTION_WINDOW_DEBUG))) debugOpen=!debugOpen; + if (ImGui::MenuItem("inspector",BIND_FOR(GUI_ACTION_WINDOW_DEBUG))) inspectorOpen=!inspectorOpen; if (ImGui::MenuItem("panic",BIND_FOR(GUI_ACTION_PANIC))) e->syncReset(); if (ImGui::MenuItem("about...",BIND_FOR(GUI_ACTION_WINDOW_ABOUT))) { aboutOpen=true; @@ -3764,6 +3797,11 @@ bool FurnaceGUI::loop() { drawSampleEdit(); drawPiano(); break; + case GUI_SCENE_CHANNELS: + channelsOpen=true; + curWindow=GUI_WINDOW_CHANNELS; + drawChannels(); + break; case GUI_SCENE_CHIPS: sysManagerOpen=true; curWindow=GUI_WINDOW_SYS_MANAGER; @@ -5194,7 +5232,7 @@ bool FurnaceGUI::init() { #endif // initialize SDL - SDL_Init(SDL_INIT_VIDEO); + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_HAPTIC); const char* videoBackend=SDL_GetCurrentVideoDriver(); if (videoBackend!=NULL) { @@ -5417,6 +5455,17 @@ bool FurnaceGUI::init() { return curIns; }); + vibrator=SDL_HapticOpen(0); + if (vibrator==NULL) { + logD("could not open vibration device: %s",SDL_GetError()); + } else { + if (SDL_HapticRumbleInit(vibrator)==0) { + vibratorAvailable=true; + } else { + logD("vibration not available: %s",SDL_GetError()); + } + } + return true; } @@ -5547,6 +5596,10 @@ bool FurnaceGUI::finish() { SDL_DestroyRenderer(sdlRend); SDL_DestroyWindow(sdlWin); + if (vibrator) { + SDL_HapticClose(vibrator); + } + for (int i=0; istd.waveMacro.vScroll=-1; \ } +#define CHECK_LONG_HOLD (mobileUI && ImGui::GetIO().MouseDown[ImGuiMouseButton_Left] && ImGui::GetIO().MouseDownDuration[ImGuiMouseButton_Left]>=longThreshold && ImGui::GetIO().MouseDownDurationPrev[ImGuiMouseButton_Left] def); + FurnaceGUISysDef(const char* n, std::initializer_list def, const char* e=NULL); }; struct FurnaceGUISysCategory { @@ -1048,6 +1062,8 @@ class FurnaceGUI { SDL_Window* sdlWin; SDL_Renderer* sdlRend; + SDL_Haptic* vibrator; + bool vibratorAvailable; SDL_Texture* sampleTex; int sampleTexW, sampleTexH; @@ -1419,13 +1435,13 @@ class FurnaceGUI { SelectionPoint selStart, selEnd, cursor, cursorDrag, dragStart, dragEnd; bool selecting, selectingFull, dragging, curNibble, orderNibble, followOrders, followPattern, changeAllOrders, mobileUI; bool collapseWindow, demandScrollX, fancyPattern, wantPatName, firstFrame, tempoView, waveHex, waveSigned, waveGenVisible, lockLayout, editOptsVisible, latchNibble, nonLatchNibble; - bool keepLoopAlive; + bool keepLoopAlive, orderScrollLocked, orderScrollTolerance; FurnaceGUIWindows curWindow, nextWindow, curWindowLast; std::atomic curWindowThreadSafe; float peak[2]; float patChanX[DIV_MAX_CHANS+1]; float patChanSlideY[DIV_MAX_CHANS+1]; - float lastPatternWidth; + float lastPatternWidth, longThreshold; String nextDesc; String nextDescName; @@ -1562,7 +1578,9 @@ class FurnaceGUI { int bindSetTarget, bindSetPrevValue; bool bindSetActive, bindSetPending; - float nextScroll, nextAddScroll; + float nextScroll, nextAddScroll, orderScroll, orderScrollSlideOrigin; + + ImVec2 orderScrollRealOrigin; int layoutTimeBegin, layoutTimeEnd, layoutTimeDelta; int renderTimeBegin, renderTimeEnd, renderTimeDelta; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index a7e45a7cf..b9a6df353 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1378,6 +1378,7 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail PlotCustom("##IMacro",asFloat,totalFit,macroDragScroll,NULL,i.min+i.macro->vScroll,i.min+i.macro->vScroll+i.macro->vZoom,ImVec2(availableWidth,(i.macro->open&1)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),i.color,i.macro->len-macroDragScroll,i.hoverFunc,i.hoverFuncUser,i.blockMode,(i.macro->open&1)?genericGuide:NULL,doHighlight); } if ((i.macro->open&1) && (ImGui::IsItemClicked(ImGuiMouseButton_Left) || ImGui::IsItemClicked(ImGuiMouseButton_Right))) { + ImGui::InhibitInertialScroll(); macroDragStart=ImGui::GetItemRectMin(); macroDragAreaSize=ImVec2(availableWidth,i.height*dpiScale); if (i.isBitfield) { @@ -1466,6 +1467,7 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail if (i.bit30) { PlotCustom("##IMacroBit30",bit30Indicator,totalFit,macroDragScroll,NULL,0,1,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,¯oHoverBit30); if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { + ImGui::InhibitInertialScroll(); macroDragStart=ImGui::GetItemRectMin(); macroDragAreaSize=ImVec2(availableWidth,12.0f*dpiScale); macroDragInitialValueSet=false; @@ -1486,6 +1488,7 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail // loop area PlotCustom("##IMacroLoop",loopIndicator,totalFit,macroDragScroll,NULL,0,2,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,¯oHoverLoop); if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { + ImGui::InhibitInertialScroll(); macroLoopDragStart=ImGui::GetItemRectMin(); macroLoopDragAreaSize=ImVec2(availableWidth,12.0f*dpiScale); macroLoopDragLen=totalFit; @@ -1498,6 +1501,7 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y); } if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { + ImGui::InhibitInertialScroll(); if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { i.macro->rel=255; } else { @@ -4447,6 +4451,7 @@ void FurnaceGUI::drawInsEdit() { macroDragLineMode=false; macroDragLineInitial=ImVec2(0,0); processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y); + ImGui::InhibitInertialScroll(); } ImGui::EndTabItem(); } @@ -4476,6 +4481,7 @@ void FurnaceGUI::drawInsEdit() { macroDragLineMode=false; macroDragLineInitial=ImVec2(0,0); processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y); + ImGui::InhibitInertialScroll(); } ImGui::EndDisabled(); diff --git a/src/gui/orders.cpp b/src/gui/orders.cpp index 73fcb9147..32a4733d7 100644 --- a/src/gui/orders.cpp +++ b/src/gui/orders.cpp @@ -25,6 +25,20 @@ void FurnaceGUI::drawMobileOrderSel() { if (!portrait) return; + if (!orderScrollLocked) { + if (orderScroll>(float)curOrder-0.005f && orderScroll<(float)curOrder+0.005f) { + orderScroll=curOrder; + } else if (orderScrollcurOrder) orderScroll=curOrder; + WAKE_UP; + } else { + orderScroll-=MAX(0.05f,(orderScroll-curOrder)*0.2f); + if (orderScrollcurSubSong->ordersLen; i++) { + ImVec2 pos=centerPos; + ImVec4 color=uiColors[GUI_COLOR_TEXT]; + pos.x+=(i-orderScroll)*40.0*dpiScale; + if (pos.x<-200.0*dpiScale) continue; + if (pos.x>canvasW+200.0*dpiScale) break; + String text=fmt::sprintf("%.2X",i); + float targetSize=size.y-fabs(i-orderScroll)*2.0*dpiScale; + if (targetSize<8.0*dpiScale) targetSize=8.0*dpiScale; + color.w*=CLAMP(2.0f*(targetSize/size.y-0.5f),0.0f,1.0f); - ImVec2 pos=ImLerp(minArea,maxArea,ImVec2(0.5,0.0)); - ImGui::PushFont(bigFont); - ImVec2 textSize=ImGui::CalcTextSize(text.c_str()); - ImGui::PopFont(); + ImGui::PushFont(bigFont); + ImVec2 textSize=ImGui::CalcTextSize(text.c_str()); + ImGui::PopFont(); - pos.x-=textSize.x*0.5*(size.y/textSize.y); + pos.x-=textSize.x*0.5*(targetSize/textSize.y); + pos.y-=targetSize*0.5; - dl->AddText(bigFont,size.y,pos,col,text.c_str()); + dl->AddText(bigFont,targetSize,pos,ImGui::GetColorU32(color),text.c_str()); + } + } + if (ImGui::IsItemClicked()) { + orderScrollSlideOrigin=ImGui::GetMousePos().x+orderScroll*40.0f*dpiScale; + orderScrollRealOrigin=ImGui::GetMousePos(); + orderScrollLocked=true; + orderScrollTolerance=true; } } ImGui::End(); diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 483d66b53..798548026 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -128,6 +128,10 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int if (ImGui::IsItemClicked()) { startSelection(0,0,i,true); } + if (ImGui::IsItemActive() && CHECK_LONG_HOLD) { + ImGui::InhibitInertialScroll(); + NOTIFY_LONG_HOLD; + } ImGui::PopStyleColor(); // for each column for (int j=0; jdata[i][index+1]==-1) { @@ -323,6 +343,10 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) { updateSelection(j,index,i); } + if (ImGui::IsItemActive() && CHECK_LONG_HOLD) { + ImGui::InhibitInertialScroll(); + NOTIFY_LONG_HOLD; + } ImGui::PopStyleColor(); } } @@ -596,7 +620,7 @@ void FurnaceGUI::drawPattern() { ImGui::ItemSize(size,ImGui::GetStyle().FramePadding.y); if (ImGui::ItemAdd(rect,ImGui::GetID(chanID))) { bool hovered=ImGui::ItemHoverable(rect,ImGui::GetID(chanID)); - ImU32 col=hovered?ImGui::GetColorU32(ImGuiCol_HeaderHovered):ImGui::GetColorU32(ImGuiCol_Header); + ImU32 col=(hovered || (!mobileUI && ImGui::IsMouseDown(ImGuiMouseButton_Left)))?ImGui::GetColorU32(ImGuiCol_HeaderHovered):ImGui::GetColorU32(ImGuiCol_Header); dl->AddRectFilled(rect.Min,rect.Max,col); dl->AddText(ImVec2(minLabelArea.x,rect.Min.y),ImGui::GetColorU32(channelTextColor(i)),chanID); } @@ -609,13 +633,13 @@ void FurnaceGUI::drawPattern() { chanHeadBase.x, chanHeadBase.y, chanHeadBase.z, - hovered?0.25f:0.0f + (hovered && (!mobileUI || ImGui::IsMouseDown(ImGuiMouseButton_Left)))?0.25f:0.0f )); ImU32 fadeCol=ImGui::GetColorU32(ImVec4( chanHeadBase.x, chanHeadBase.y, chanHeadBase.z, - hovered?0.5f:MIN(1.0f,chanHeadBase.w*keyHit[i]*4.0f) + (hovered && (!mobileUI || ImGui::IsMouseDown(ImGuiMouseButton_Left)))?0.5f:MIN(1.0f,chanHeadBase.w*keyHit[i]*4.0f) )); dl->AddRectFilledMultiColor(rect.Min,rect.Max,fadeCol0,fadeCol0,fadeCol,fadeCol); dl->AddLine(ImVec2(rect.Min.x,rect.Max.y),ImVec2(rect.Max.x,rect.Max.y),ImGui::GetColorU32(chanHeadBase),2.0f*dpiScale); @@ -631,13 +655,13 @@ void FurnaceGUI::drawPattern() { chanHeadBase.x, chanHeadBase.y, chanHeadBase.z, - hovered?0.5f:MIN(1.0f,0.3f+chanHeadBase.w*keyHit[i]*1.5f) + (hovered && (!mobileUI || ImGui::IsMouseDown(ImGuiMouseButton_Left)))?0.5f:MIN(1.0f,0.3f+chanHeadBase.w*keyHit[i]*1.5f) )); ImU32 fadeCol=ImGui::GetColorU32(ImVec4( chanHeadBase.x, chanHeadBase.y, chanHeadBase.z, - hovered?0.3f:MIN(1.0f,0.2f+chanHeadBase.w*keyHit[i]*1.2f) + (hovered && (!mobileUI || ImGui::IsMouseDown(ImGuiMouseButton_Left)))?0.3f:MIN(1.0f,0.2f+chanHeadBase.w*keyHit[i]*1.2f) )); ImVec2 rMin=rect.Min; ImVec2 rMax=rect.Max; @@ -667,7 +691,7 @@ void FurnaceGUI::drawPattern() { chanHeadBase.x, chanHeadBase.y, chanHeadBase.z, - hovered?1.0f:MIN(1.0f,0.2f+chanHeadBase.w*keyHit[i]*4.0f) + (hovered && (!mobileUI || ImGui::IsMouseDown(ImGuiMouseButton_Left)))?1.0f:MIN(1.0f,0.2f+chanHeadBase.w*keyHit[i]*4.0f) )); ImVec2 rMin=rect.Min; ImVec2 rMax=rect.Max; @@ -688,7 +712,7 @@ void FurnaceGUI::drawPattern() { chanHeadBase.x, chanHeadBase.y, chanHeadBase.z, - hovered?1.0f:MIN(1.0f,0.2f+chanHeadBase.w*keyHit[i]*4.0f) + (hovered && (!mobileUI || ImGui::IsMouseDown(ImGuiMouseButton_Left)))?1.0f:MIN(1.0f,0.2f+chanHeadBase.w*keyHit[i]*4.0f) )); ImVec2 rMin=rect.Min; ImVec2 rMax=rect.Max; @@ -710,19 +734,36 @@ void FurnaceGUI::drawPattern() { ImGui::SetTooltip("%s",e->getChannelName(i)); } if (settings.channelFont==0) ImGui::PopFont(); - if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { - if (settings.soloAction!=1 && soloTimeout>0 && soloChan==i) { - e->toggleSolo(i); - soloTimeout=0; - } else { - e->toggleMute(i); - soloTimeout=20; - soloChan=i; + if (mobileUI) { + if (ImGui::IsItemHovered()) { + if (CHECK_LONG_HOLD) { + NOTIFY_LONG_HOLD; + e->toggleSolo(i); + soloChan=i; + } + if (ImGui::IsMouseReleased(ImGuiMouseButton_Left) && !ImGui::WasInertialScroll()) { + if (soloChan!=i) { + e->toggleMute(i); + } else { + soloChan=-1; + } + } + } + } else { + if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { + if (settings.soloAction!=1 && soloTimeout>0 && soloChan==i) { + e->toggleSolo(i); + soloTimeout=0; + } else { + e->toggleMute(i); + soloTimeout=20; + soloChan=i; + } } } if (muted) ImGui::PopStyleColor(); ImGui::PopStyleColor(4); - if (settings.soloAction!=2) if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { + if (settings.soloAction!=2 && !mobileUI) if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { inhibitMenu=true; e->toggleSolo(i); } diff --git a/src/gui/piano.cpp b/src/gui/piano.cpp index 98e83f351..7f1360cc8 100644 --- a/src/gui/piano.cpp +++ b/src/gui/piano.cpp @@ -222,6 +222,7 @@ void FurnaceGUI::drawPiano() { bool canInput=false; if (ImGui::ItemHoverable(rect,ImGui::GetID("pianoDisplay"))) { canInput=true; + ImGui::InhibitInertialScroll(); } if (view) { int notes=oct*12; @@ -414,7 +415,7 @@ void FurnaceGUI::drawPiano() { e->synchronized([this,note]() { e->autoNoteOn(-1,curIns,note); }); - if (edit) noteInput(note,0); + if (edit && curWindow!=GUI_WINDOW_INS_LIST && curWindow!=GUI_WINDOW_INS_EDIT) noteInput(note,0); break; } } diff --git a/src/gui/plot_nolerp.cpp b/src/gui/plot_nolerp.cpp index b75bda4f0..f1120ed4a 100644 --- a/src/gui/plot_nolerp.cpp +++ b/src/gui/plot_nolerp.cpp @@ -76,7 +76,7 @@ int PlotNoLerpEx(ImGuiPlotType plot_type, const char* label, float (*values_gett const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); ImGui::ItemSize(total_bb, style.FramePadding.y); - if (!ImGui::ItemAdd(total_bb, 0, &frame_bb)) + if (!ImGui::ItemAdd(total_bb, 0, &frame_bb, ImGuiItemFlags_NoInertialScroll)) return -1; const bool hovered = ImGui::ItemHoverable(frame_bb, id); @@ -203,7 +203,7 @@ int PlotBitfieldEx(const char* label, int (*values_getter)(void* data, int idx), const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); ImGui::ItemSize(total_bb, style.FramePadding.y); - if (!ImGui::ItemAdd(total_bb, 0, &frame_bb)) + if (!ImGui::ItemAdd(total_bb, 0, &frame_bb, ImGuiItemFlags_NoInertialScroll)) return -1; const bool hovered = ImGui::ItemHoverable(frame_bb, id); @@ -313,7 +313,7 @@ int PlotCustomEx(ImGuiPlotType plot_type, const char* label, float (*values_gett const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); ImGui::ItemSize(total_bb, style.FramePadding.y); - if (!ImGui::ItemAdd(total_bb, 0, &frame_bb)) + if (!ImGui::ItemAdd(total_bb, 0, &frame_bb, ImGuiItemFlags_NoInertialScroll)) return -1; const bool hovered = ImGui::ItemHoverable(frame_bb, id); diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index 0078cb1d5..033a074c9 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -198,12 +198,14 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "WonderSwan", { CH(DIV_SYSTEM_SWAN, 64, 0, "") - } + }, + "tickRate=75.47169811320754716981" ); ENTRY( "Virtual Boy", { CH(DIV_SYSTEM_VBOY, 64, 0, "") - } + }, + "tickRate=50.2734877734878" ); ENTRY( "Gamate", { @@ -220,7 +222,8 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "Commodore PET", { CH(DIV_SYSTEM_PET, 64, 0, "") - } + }, + "tickRate=50" ); ENTRY( "Commodore VIC-20", { @@ -230,65 +233,76 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "Commodore 64 (6581 SID)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (8580 SID)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (6581 SID + Sound Expander)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (6581 SID + Sound Expander in drums mode)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL_DRUMS, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (8580 SID + Sound Expander)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (8580 SID + Sound Expander in drums mode)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL_DRUMS, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (6581 SID + FM-YAM)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL2, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (6581 SID + FM-YAM in drums mode)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (8580 SID + FM-YAM)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL2, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (8580 SID + FM-YAM in drums mode)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1"), CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "") - } + }, + "tickRate=50.1245421" ); ENTRY( "Amiga", { - CH(DIV_SYSTEM_AMIGA, 64, 0, "") - } + CH(DIV_SYSTEM_AMIGA, 64, 0, "clockSel=1") + }, + "tickRate=50" ); ENTRY( "MSX", { @@ -1085,8 +1099,9 @@ void FurnaceGUI::initSystemPresets() { CATEGORY_BEGIN("Sample","chips/systems which use PCM or ADPCM samples for sound synthesis."); ENTRY( "Amiga", { - CH(DIV_SYSTEM_AMIGA, 64, 0, "") - } + CH(DIV_SYSTEM_AMIGA, 64, 0, "clockSel=1") + }, + "tickRate=50" ); ENTRY( "SegaPCM", { @@ -1149,7 +1164,8 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "Commodore PET (pseudo-wavetable)", { CH(DIV_SYSTEM_PET, 64, 0, "") - } + }, + "tickRate=50" ); ENTRY( "Konami Bubble System WSG", { @@ -1194,12 +1210,14 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "WonderSwan", { CH(DIV_SYSTEM_SWAN, 64, 0, "") - } + }, + "tickRate=75.47169811320754716981" ); ENTRY( "Virtual Boy", { CH(DIV_SYSTEM_VBOY, 64, 0, "") - } + }, + "tickRate=50.2734877734878" ); ENTRY( "Seta/Allumer X1-010", { @@ -1212,12 +1230,14 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "MOS Technology SID (6581)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1") - } + }, + "tickRate=50.1245421" ); ENTRY( "MOS Technology SID (8580)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1") - } + }, + "tickRate=50.1245421" ); ENTRY( "Microchip AY8930", { @@ -2171,12 +2191,14 @@ void FurnaceGUI::initSystemPresets() { ENTRY( "Commodore 64 (6581 SID)", { CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1") - } + }, + "tickRate=50.1245421" ); ENTRY( "Commodore 64 (8580 SID)", { CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1") - } + }, + "tickRate=50.1245421" ); ENTRY( "Arcade (YM2151 and SegaPCM)", { @@ -2197,8 +2219,9 @@ void FurnaceGUI::initSystemPresets() { CATEGORY_END; } -FurnaceGUISysDef::FurnaceGUISysDef(const char* n, std::initializer_list def): - name(n) { +FurnaceGUISysDef::FurnaceGUISysDef(const char* n, std::initializer_list def, const char* e): + name(n), + extra(e) { std::vector uncompiled=def; int index=0; for (FurnaceGUISysDefChip& i: uncompiled) { @@ -2215,4 +2238,7 @@ FurnaceGUISysDef::FurnaceGUISysDef(const char* n, std::initializer_listmobileUI=mobileUI; } } diff --git a/src/gui/songInfo.cpp b/src/gui/songInfo.cpp index 151991871..493ad597d 100644 --- a/src/gui/songInfo.cpp +++ b/src/gui/songInfo.cpp @@ -43,10 +43,10 @@ void FurnaceGUI::drawSongInfo(bool asChild) { if (ImGui::InputText("##Name",&e->song.name,ImGuiInputTextFlags_UndoRedo)) { MARK_MODIFIED updateWindowTitle(); } - if (e->song.insLen==2) { + if (e->song.insLen==1) { unsigned int checker=0x11111111; unsigned int checker1=0; - DivInstrument* ins=e->getIns(1); + DivInstrument* ins=e->getIns(0); if (ins->name.size()==15 && e->curSubSong->ordersLen==8) { for (int i=0; i<15; i++) { checker^=ins->name[i]<=100000; + + if (ImGui::Checkbox("Custom clock rate",&usingCustomClock)) { + if (usingCustomClock) { + customClock=1000000; + } else { + customClock=0; + } + altered=true; + } + if (ImGui::InputInt("Hz",&customClock)) { + if (customClock<100000) customClock=0; + if (customClock>20000000) customClock=20000000; + altered=true; + } + + if (altered) { + e->lockSave([&]() { + flags.set("customClock",customClock); + }); + } + } + if (altered) { if (chan>=0) { e->updateSysFlags(chan,restart);